about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rustc/middle/typeck.rs17
-rw-r--r--src/test/compile-fail/issue-2330.rs13
2 files changed, 25 insertions, 5 deletions
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index 41ddedcb526..d8db45d8919 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -559,20 +559,27 @@ fn ast_path_to_ty<AC: ast_conv, RS: region_scope copy>(
 /*
   Instantiates the path for the given iface reference, assuming that
   it's bound to a valid iface type. Returns the def_id for the defining
-  iface
+  iface. Fails if the type is a type other than an iface type.
  */
 fn instantiate_iface_ref(ccx: @crate_ctxt, t: @ast::iface_ref,
                          rp: ast::region_param)
     -> (ast::def_id, ty_param_substs_and_ty) {
 
+    let sp = t.path.span, err = "can only implement interface types",
+        sess = ccx.tcx.sess;
+
     alt lookup_def_tcx(ccx.tcx, t.path.span, t.id) {
       ast::def_ty(t_id) {
-        (t_id, ast_path_to_ty(ccx, type_rscope(rp), t_id, t.path, t.id))
+        let tpt = ast_path_to_ty(ccx, type_rscope(rp), t_id, t.path, t.id);
+        alt ty::get(tpt.ty).struct {
+           ty::ty_iface(*) {
+              (t_id, tpt)
+           }
+           _ { sess.span_fatal(sp, err); }
+        }
       }
       _ {
-        ccx.tcx.sess.span_fatal(
-            t.path.span,
-            "can only implement interface types");
+          sess.span_fatal(sp, err);
       }
     }
 }
diff --git a/src/test/compile-fail/issue-2330.rs b/src/test/compile-fail/issue-2330.rs
new file mode 100644
index 00000000000..355b90bb2aa
--- /dev/null
+++ b/src/test/compile-fail/issue-2330.rs
@@ -0,0 +1,13 @@
+enum chan { }
+
+iface channel<T> {
+    fn send(v: T);
+}
+
+// `chan` is not an iface, it's an enum
+impl of chan for int { //! ERROR can only implement interface types
+    fn send(v: int) { fail }
+}
+
+fn main() {
+}