summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDan Robertson <danlrobertson89@gmail.com>2018-05-29 01:51:36 +0000
committerPietro Albini <pietro@pietroalbini.org>2018-06-03 12:04:24 +0200
commit724cfd84a379503b3a3c68b1107747cc06b57a41 (patch)
tree4467a159fcd1c6ca37670d03c7941243ef284720 /src
parentd2902174b593000ede7100c928c6a280befc5213 (diff)
downloadrust-724cfd84a379503b3a3c68b1107747cc06b57a41.tar.gz
rust-724cfd84a379503b3a3c68b1107747cc06b57a41.zip
typeck: Do not pass the field check on field error
If a struct pattern has a field error return an error.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/_match.rs13
-rw-r--r--src/test/ui/issue-51102.rs48
-rw-r--r--src/test/ui/issue-51102.stderr24
3 files changed, 82 insertions, 3 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 7a31c679d3a..a531e17a0ca 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -723,8 +723,11 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
         self.demand_eqtype(pat.span, expected, pat_ty);
 
         // Type check subpatterns.
-        self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm);
-        pat_ty
+        if self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm) {
+            pat_ty
+        } else {
+            self.tcx.types.err
+        }
     }
 
     fn check_pat_path(&self,
@@ -849,7 +852,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                                variant: &'tcx ty::VariantDef,
                                fields: &'gcx [Spanned<hir::FieldPat>],
                                etc: bool,
-                               def_bm: ty::BindingMode) {
+                               def_bm: ty::BindingMode) -> bool {
         let tcx = self.tcx;
 
         let (substs, adt) = match adt_ty.sty {
@@ -867,6 +870,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
 
         // Keep track of which fields have already appeared in the pattern.
         let mut used_fields = FxHashMap();
+        let mut no_field_errors = true;
 
         let mut inexistent_fields = vec![];
         // Typecheck each field.
@@ -882,6 +886,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                                     format!("multiple uses of `{}` in pattern", field.name))
                         .span_label(*occupied.get(), format!("first use of `{}`", field.name))
                         .emit();
+                    no_field_errors = false;
                     tcx.types.err
                 }
                 Vacant(vacant) => {
@@ -894,6 +899,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                         })
                         .unwrap_or_else(|| {
                             inexistent_fields.push((span, field.name));
+                            no_field_errors = false;
                             tcx.types.err
                         })
                 }
@@ -992,5 +998,6 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                 diag.emit();
             }
         }
+        no_field_errors
     }
 }
diff --git a/src/test/ui/issue-51102.rs b/src/test/ui/issue-51102.rs
new file mode 100644
index 00000000000..c8f106687ae
--- /dev/null
+++ b/src/test/ui/issue-51102.rs
@@ -0,0 +1,48 @@
+// Copyright 2018 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.
+
+enum SimpleEnum {
+    NoState,
+}
+
+struct SimpleStruct {
+    no_state_here: u64,
+}
+
+fn main() {
+    let _ = |simple| {
+        match simple {
+            SimpleStruct {
+                state: 0,
+                //~^ struct `SimpleStruct` does not have a field named `state` [E0026]
+                ..
+            } => (),
+        }
+    };
+
+    let _ = |simple| {
+        match simple {
+            SimpleStruct {
+                no_state_here: 0,
+                no_state_here: 1
+                //~^ ERROR field `no_state_here` bound multiple times in the pattern [E0025]
+            } => (),
+        }
+    };
+
+    let _ = |simple| {
+        match simple {
+            SimpleEnum::NoState {
+                state: 0
+                //~^ ERROR variant `SimpleEnum::NoState` does not have a field named `state` [E0026]
+            } => (),
+        }
+    };
+}
diff --git a/src/test/ui/issue-51102.stderr b/src/test/ui/issue-51102.stderr
new file mode 100644
index 00000000000..a4bd0fb914f
--- /dev/null
+++ b/src/test/ui/issue-51102.stderr
@@ -0,0 +1,24 @@
+error[E0026]: struct `SimpleStruct` does not have a field named `state`
+  --> $DIR/issue-51102.rs:23:17
+   |
+LL |                 state: 0,
+   |                 ^^^^^^^^ struct `SimpleStruct` does not have this field
+
+error[E0025]: field `no_state_here` bound multiple times in the pattern
+  --> $DIR/issue-51102.rs:34:17
+   |
+LL |                 no_state_here: 0,
+   |                 ---------------- first use of `no_state_here`
+LL |                 no_state_here: 1
+   |                 ^^^^^^^^^^^^^^^^ multiple uses of `no_state_here` in pattern
+
+error[E0026]: variant `SimpleEnum::NoState` does not have a field named `state`
+  --> $DIR/issue-51102.rs:43:17
+   |
+LL |                 state: 0
+   |                 ^^^^^^^^ variant `SimpleEnum::NoState` does not have this field
+
+error: aborting due to 3 previous errors
+
+Some errors occurred: E0025, E0026.
+For more information about an error, try `rustc --explain E0025`.