about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakub Bukaj <jakub@jakub.cc>2014-11-16 20:55:17 +0100
committerJakub Bukaj <jakub@jakub.cc>2014-11-17 21:49:41 +0100
commit54c76e6e8193e96b2ca15542f916a7520cfaa75f (patch)
tree155df15656dbd169f5210e30998c44ba3f716c97
parentf09279395b6ca40f1398277971586197f949738a (diff)
downloadrust-54c76e6e8193e96b2ca15542f916a7520cfaa75f.tar.gz
rust-54c76e6e8193e96b2ca15542f916a7520cfaa75f.zip
Fix an ICE when using struct patterns with traits
Fixes #18986.
-rw-r--r--src/librustc/diagnostics.rs3
-rw-r--r--src/librustc/middle/typeck/check/_match.rs34
-rw-r--r--src/test/compile-fail-fulldeps/issue-18986.rs20
3 files changed, 47 insertions, 10 deletions
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index 1792599783b..b5dafdb1807 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -143,5 +143,6 @@ register_diagnostics!(
     E0164,
     E0165,
     E0166,
-    E0167
+    E0167,
+    E0168
 )
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index 90c3d8c4f3f..a79edf28b36 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -297,22 +297,38 @@ pub fn check_pat_struct(pcx: &pat_ctxt, pat: &ast::Pat,
     let tcx = pcx.fcx.ccx.tcx;
 
     let def = tcx.def_map.borrow()[pat.id].clone();
-    let def_type = ty::lookup_item_type(tcx, def.def_id());
-    let (enum_def_id, variant_def_id) = match ty::get(def_type.ty).sty {
-        ty::ty_struct(struct_def_id, _) =>
-            (struct_def_id, struct_def_id),
-        ty::ty_enum(enum_def_id, _) if def == def::DefVariant(enum_def_id, def.def_id(), true) =>
-            (enum_def_id, def.def_id()),
-        _ => {
+    let (enum_def_id, variant_def_id) = match def {
+        def::DefTrait(_) => {
             let name = pprust::path_to_string(path);
-            span_err!(tcx.sess, pat.span, E0163,
-                "`{}` does not name a struct or a struct variant", name);
+            span_err!(tcx.sess, pat.span, E0168,
+                "use of trait `{}` in a struct pattern", name);
             fcx.write_error(pat.id);
 
             for field in fields.iter() {
                 check_pat(pcx, &*field.node.pat, ty::mk_err());
             }
             return;
+        },
+        _ => {
+            let def_type = ty::lookup_item_type(tcx, def.def_id());
+            match ty::get(def_type.ty).sty {
+                ty::ty_struct(struct_def_id, _) =>
+                    (struct_def_id, struct_def_id),
+                ty::ty_enum(enum_def_id, _)
+                    if def == def::DefVariant(enum_def_id, def.def_id(), true) =>
+                    (enum_def_id, def.def_id()),
+                _ => {
+                    let name = pprust::path_to_string(path);
+                    span_err!(tcx.sess, pat.span, E0163,
+                        "`{}` does not name a struct or a struct variant", name);
+                    fcx.write_error(pat.id);
+
+                    for field in fields.iter() {
+                        check_pat(pcx, &*field.node.pat, ty::mk_err());
+                    }
+                    return;
+                }
+            }
         }
     };
 
diff --git a/src/test/compile-fail-fulldeps/issue-18986.rs b/src/test/compile-fail-fulldeps/issue-18986.rs
new file mode 100644
index 00000000000..25d78c273e7
--- /dev/null
+++ b/src/test/compile-fail-fulldeps/issue-18986.rs
@@ -0,0 +1,20 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:use_from_trait_xc.rs
+
+extern crate use_from_trait_xc;
+pub use use_from_trait_xc::Trait;
+
+fn main() {
+    match () {
+        Trait { x: 42u } => () //~ ERROR use of trait `Trait` in a struct pattern
+    }
+}