span: Span,
variant: &'tcx ty::VariantDef,
ast_fields: &'gcx [hir::Field],
- check_completeness: bool) {
+ check_completeness: bool) -> bool {
let tcx = self.tcx;
let adt_ty_hint =
truncated_fields_error))
.emit();
}
+ error_happened
}
fn check_struct_fields_on_error(&self,
}
}
- self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
- base_expr.is_none());
+ let error_happened = self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span,
+ variant, fields, base_expr.is_none());
if let &Some(ref base_expr) = base_expr {
- self.check_expr_has_type_or_error(base_expr, struct_ty);
- match struct_ty.sty {
- ty::TyAdt(adt, substs) if adt.is_struct() => {
- let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
- self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
- }).collect();
-
- self.tables
- .borrow_mut()
- .fru_field_types_mut()
- .insert(expr.hir_id, fru_field_types);
- }
- _ => {
- span_err!(self.tcx.sess, base_expr.span, E0436,
- "functional record update syntax requires a struct");
+ // If check_expr_struct_fields hit an error, do not attempt to populate
+ // the fields with the base_expr. This could cause us to hit errors later
+ // when certain fields are assumed to exist that in fact do not.
+ if !error_happened {
+ self.check_expr_has_type_or_error(base_expr, struct_ty);
+ match struct_ty.sty {
+ ty::TyAdt(adt, substs) if adt.is_struct() => {
+ let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
+ self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
+ }).collect();
+
+ self.tables
+ .borrow_mut()
+ .fru_field_types_mut()
+ .insert(expr.hir_id, fru_field_types);
+ }
+ _ => {
+ span_err!(self.tcx.sess, base_expr.span, E0436,
+ "functional record update syntax requires a struct");
+ }
}
}
}
--- /dev/null
+// Copyright 2017 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.
+
+struct Point {
+ pub x: u64,
+ pub y: u64,
+}
+
+const TEMPLATE: Point = Point {
+ x: 0,
+ y: 0
+};
+
+fn main() {
+ let _ = || {
+ Point {
+ nonexistent: 0,
+ //~^ ERROR struct `Point` has no field named `nonexistent`
+ ..TEMPLATE
+ }
+ };
+}
--- /dev/null
+error[E0560]: struct `Point` has no field named `nonexistent`
+ --> $DIR/issue-50618.rs:24:13
+ |
+LL | nonexistent: 0,
+ | ^^^^^^^^^^^ `Point` does not have this field
+ |
+ = note: available fields are: `x`, `y`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0560`.