Skip to content

Commit 8f64415

Browse files
committed
typeck: Do not pass the field check on field error
If a struct pattern has a field error return an error.
1 parent 30cae58 commit 8f64415

File tree

3 files changed

+82
-3
lines changed

3 files changed

+82
-3
lines changed

src/librustc_typeck/check/_match.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,11 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
720720
self.demand_eqtype(pat.span, expected, pat_ty);
721721

722722
// Type check subpatterns.
723-
self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm);
724-
pat_ty
723+
if self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm) {
724+
pat_ty
725+
} else {
726+
self.tcx.types.err
727+
}
725728
}
726729

727730
fn check_pat_path(&self,
@@ -846,7 +849,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
846849
variant: &'tcx ty::VariantDef,
847850
fields: &'gcx [Spanned<hir::FieldPat>],
848851
etc: bool,
849-
def_bm: ty::BindingMode) {
852+
def_bm: ty::BindingMode) -> bool {
850853
let tcx = self.tcx;
851854

852855
let (substs, adt) = match adt_ty.sty {
@@ -864,6 +867,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
864867

865868
// Keep track of which fields have already appeared in the pattern.
866869
let mut used_fields = FxHashMap();
870+
let mut no_field_errors = true;
867871

868872
let mut inexistent_fields = vec![];
869873
// Typecheck each field.
@@ -879,6 +883,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
879883
format!("multiple uses of `{}` in pattern", field.ident))
880884
.span_label(*occupied.get(), format!("first use of `{}`", field.ident))
881885
.emit();
886+
no_field_errors = false;
882887
tcx.types.err
883888
}
884889
Vacant(vacant) => {
@@ -891,6 +896,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
891896
})
892897
.unwrap_or_else(|| {
893898
inexistent_fields.push((span, field.ident));
899+
no_field_errors = false;
894900
tcx.types.err
895901
})
896902
}
@@ -989,5 +995,6 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
989995
diag.emit();
990996
}
991997
}
998+
no_field_errors
992999
}
9931000
}

src/test/ui/issue-51102.rs

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
enum SimpleEnum {
12+
NoState,
13+
}
14+
15+
struct SimpleStruct {
16+
no_state_here: u64,
17+
}
18+
19+
fn main() {
20+
let _ = |simple| {
21+
match simple {
22+
SimpleStruct {
23+
state: 0,
24+
//~^ struct `SimpleStruct` does not have a field named `state` [E0026]
25+
..
26+
} => (),
27+
}
28+
};
29+
30+
let _ = |simple| {
31+
match simple {
32+
SimpleStruct {
33+
no_state_here: 0,
34+
no_state_here: 1
35+
//~^ ERROR field `no_state_here` bound multiple times in the pattern [E0025]
36+
} => (),
37+
}
38+
};
39+
40+
let _ = |simple| {
41+
match simple {
42+
SimpleEnum::NoState {
43+
state: 0
44+
//~^ ERROR variant `SimpleEnum::NoState` does not have a field named `state` [E0026]
45+
} => (),
46+
}
47+
};
48+
}

src/test/ui/issue-51102.stderr

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0026]: struct `SimpleStruct` does not have a field named `state`
2+
--> $DIR/issue-51102.rs:23:17
3+
|
4+
LL | state: 0,
5+
| ^^^^^^^^ struct `SimpleStruct` does not have this field
6+
7+
error[E0025]: field `no_state_here` bound multiple times in the pattern
8+
--> $DIR/issue-51102.rs:34:17
9+
|
10+
LL | no_state_here: 0,
11+
| ---------------- first use of `no_state_here`
12+
LL | no_state_here: 1
13+
| ^^^^^^^^^^^^^^^^ multiple uses of `no_state_here` in pattern
14+
15+
error[E0026]: variant `SimpleEnum::NoState` does not have a field named `state`
16+
--> $DIR/issue-51102.rs:43:17
17+
|
18+
LL | state: 0
19+
| ^^^^^^^^ variant `SimpleEnum::NoState` does not have this field
20+
21+
error: aborting due to 3 previous errors
22+
23+
Some errors occurred: E0025, E0026.
24+
For more information about an error, try `rustc --explain E0025`.

0 commit comments

Comments
 (0)