Skip to content

Commit d8f28be

Browse files
committed
Check early on in typeck that types being implemented are actually iface types
Closes #2330.
1 parent 74096a7 commit d8f28be

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

src/rustc/middle/typeck.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -559,20 +559,27 @@ fn ast_path_to_ty<AC: ast_conv, RS: region_scope copy>(
559559
/*
560560
Instantiates the path for the given iface reference, assuming that
561561
it's bound to a valid iface type. Returns the def_id for the defining
562-
iface
562+
iface. Fails if the type is a type other than an iface type.
563563
*/
564564
fn instantiate_iface_ref(ccx: @crate_ctxt, t: @ast::iface_ref,
565565
rp: ast::region_param)
566566
-> (ast::def_id, ty_param_substs_and_ty) {
567567

568+
let sp = t.path.span, err = "can only implement interface types",
569+
sess = ccx.tcx.sess;
570+
568571
alt lookup_def_tcx(ccx.tcx, t.path.span, t.id) {
569572
ast::def_ty(t_id) {
570-
(t_id, ast_path_to_ty(ccx, type_rscope(rp), t_id, t.path, t.id))
573+
let tpt = ast_path_to_ty(ccx, type_rscope(rp), t_id, t.path, t.id);
574+
alt ty::get(tpt.ty).struct {
575+
ty::ty_iface(*) {
576+
(t_id, tpt)
577+
}
578+
_ { sess.span_fatal(sp, err); }
579+
}
571580
}
572581
_ {
573-
ccx.tcx.sess.span_fatal(
574-
t.path.span,
575-
"can only implement interface types");
582+
sess.span_fatal(sp, err);
576583
}
577584
}
578585
}

src/test/compile-fail/issue-2330.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
enum chan { }
2+
3+
iface channel<T> {
4+
fn send(v: T);
5+
}
6+
7+
// `chan` is not an iface, it's an enum
8+
impl of chan for int { //! ERROR can only implement interface types
9+
fn send(v: int) { fail }
10+
}
11+
12+
fn main() {
13+
}

0 commit comments

Comments
 (0)