From 7769c9a7ec8aec50260956a6383c38f4e8dbdf35 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Wed, 21 Jun 2017 20:28:09 +0300 Subject: [PATCH] coerce fields to the expected field type Fully fixes #31260. This needs a crater run. --- src/librustc_typeck/check/mod.rs | 29 +++++++++----------- src/test/run-pass/issue-31260.rs | 5 +++- src/test/ui/mismatched_types/abridged.rs | 10 ++++--- src/test/ui/mismatched_types/abridged.stderr | 24 ++++------------ 4 files changed, 29 insertions(+), 39 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f7e23d289873a..9d93388edc76c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3159,11 +3159,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let adt_ty_hint = self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty]) - .get(0).cloned().unwrap_or(adt_ty); + .get(0).cloned().unwrap_or(adt_ty); + // re-link the regions that EIfEO can erase. + self.demand_eqtype(span, adt_ty_hint, adt_ty); - let (substs, hint_substs, adt_kind, kind_name) = match (&adt_ty.sty, &adt_ty_hint.sty) { - (&ty::TyAdt(adt, substs), &ty::TyAdt(_, hint_substs)) => { - (substs, hint_substs, adt.adt_kind(), adt.variant_descr()) + let (substs, adt_kind, kind_name) = match &adt_ty.sty{ + &ty::TyAdt(adt, substs) => { + (substs, adt.adt_kind(), adt.variant_descr()) } _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields") }; @@ -3179,14 +3181,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Typecheck each field. for field in ast_fields { - let final_field_type; - let field_type_hint; - let ident = tcx.adjust(field.name.node, variant.did, self.body_id).0; - if let Some(v_field) = remaining_fields.remove(&ident) { - final_field_type = self.field_ty(field.span, v_field, substs); - field_type_hint = self.field_ty(field.span, v_field, hint_substs); - + let field_type = if let Some(v_field) = remaining_fields.remove(&ident) { seen_fields.insert(field.name.node, field.span); // we don't look at stability attributes on @@ -3195,10 +3191,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if adt_kind != ty::AdtKind::Enum { tcx.check_stability(v_field.did, expr_id, field.span); } + + self.field_ty(field.span, v_field, substs) } else { error_happened = true; - final_field_type = tcx.types.err; - field_type_hint = tcx.types.err; if let Some(_) = variant.find_field_named(field.name.node) { let mut err = struct_span_err!(self.tcx.sess, field.name.span, @@ -3216,12 +3212,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else { self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name); } - } + + tcx.types.err + }; // Make sure to give a type to the field even if there's // an error, so we can continue typechecking - let ty = self.check_expr_with_hint(&field.expr, field_type_hint); - self.demand_coerce(&field.expr, ty, final_field_type); + self.check_expr_coercable_to_type(&field.expr, field_type); } // Make sure the programmer specified correct number of fields. diff --git a/src/test/run-pass/issue-31260.rs b/src/test/run-pass/issue-31260.rs index e771fc7464d00..d21ffb96bef2e 100644 --- a/src/test/run-pass/issue-31260.rs +++ b/src/test/run-pass/issue-31260.rs @@ -12,9 +12,12 @@ pub struct Struct { pub field: K, } -// Partial fix for #31260, doesn't work without {...}. static STRUCT: Struct<&'static [u8]> = Struct { field: {&[1]} }; +static STRUCT2: Struct<&'static [u8]> = Struct { + field: &[1] +}; + fn main() {} diff --git a/src/test/ui/mismatched_types/abridged.rs b/src/test/ui/mismatched_types/abridged.rs index c448ad955fab4..03f889224bedc 100644 --- a/src/test/ui/mismatched_types/abridged.rs +++ b/src/test/ui/mismatched_types/abridged.rs @@ -39,23 +39,25 @@ fn c() -> Result { } fn d() -> X, String> { - X { + let x = X { x: X { x: "".to_string(), y: 2, }, y: 3, - } + }; + x } fn e() -> X, String> { - X { + let x = X { x: X { x: "".to_string(), y: 2, }, y: "".to_string(), - } + }; + x } fn main() {} diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr index 78b5dcda1d9d2..8513da1e1d211 100644 --- a/src/test/ui/mismatched_types/abridged.stderr +++ b/src/test/ui/mismatched_types/abridged.stderr @@ -35,31 +35,19 @@ error[E0308]: mismatched types found type `Foo` error[E0308]: mismatched types - --> $DIR/abridged.rs:42:5 + --> $DIR/abridged.rs:49:5 | -42 | / X { -43 | | x: X { -44 | | x: "".to_string(), -45 | | y: 2, -46 | | }, -47 | | y: 3, -48 | | } - | |_____^ expected struct `std::string::String`, found integral variable +49 | x + | ^ expected struct `std::string::String`, found integral variable | = note: expected type `X, std::string::String>` found type `X, {integer}>` error[E0308]: mismatched types - --> $DIR/abridged.rs:52:5 + --> $DIR/abridged.rs:60:5 | -52 | / X { -53 | | x: X { -54 | | x: "".to_string(), -55 | | y: 2, -56 | | }, -57 | | y: "".to_string(), -58 | | } - | |_____^ expected struct `std::string::String`, found integral variable +60 | x + | ^ expected struct `std::string::String`, found integral variable | = note: expected type `X, _>` found type `X, _>`