Skip to content

Commit

Permalink
Rollup merge of rust-lang#51146 - dlrobertson:fix_51102, r=estebank
Browse files Browse the repository at this point in the history
typeck: Do not pass the field check on field error

If a struct pattern has a field error return an error.

Fixes: rust-lang#51102
  • Loading branch information
kennytm committed May 30, 2018
2 parents b7c3ff7 + 18ff09d commit 0b7c748
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,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,
Expand Down Expand Up @@ -846,7 +849,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 {
Expand All @@ -864,6 +867,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.
Expand All @@ -879,6 +883,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
format!("multiple uses of `{}` in pattern", field.ident))
.span_label(*occupied.get(), format!("first use of `{}`", field.ident))
.emit();
no_field_errors = false;
tcx.types.err
}
Vacant(vacant) => {
Expand All @@ -891,6 +896,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
})
.unwrap_or_else(|| {
inexistent_fields.push((span, field.ident));
no_field_errors = false;
tcx.types.err
})
}
Expand Down Expand Up @@ -989,5 +995,6 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
diag.emit();
}
}
no_field_errors
}
}
48 changes: 48 additions & 0 deletions src/test/ui/issue-51102.rs
Original file line number Diff line number Diff line change
@@ -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]
} => (),
}
};
}
24 changes: 24 additions & 0 deletions src/test/ui/issue-51102.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 0b7c748

Please sign in to comment.