mirror of https://github.com/rust-lang/rust.git
Auto merge of #42807 - arielb1:consistent-coercion, r=eddyb
Coerce fields to the expected field type Fully fixes #31260. This needs a crater run. I was supposed to do this last month but it slipped. Let's get this done.
This commit is contained in:
commit
e72580cf09
|
@ -3125,11 +3125,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
let adt_ty_hint =
|
let adt_ty_hint =
|
||||||
self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
|
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) {
|
let (substs, adt_kind, kind_name) = match &adt_ty.sty{
|
||||||
(&ty::TyAdt(adt, substs), &ty::TyAdt(_, hint_substs)) => {
|
&ty::TyAdt(adt, substs) => {
|
||||||
(substs, hint_substs, adt.adt_kind(), adt.variant_descr())
|
(substs, adt.adt_kind(), adt.variant_descr())
|
||||||
}
|
}
|
||||||
_ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
|
_ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
|
||||||
};
|
};
|
||||||
|
@ -3145,14 +3147,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
// Typecheck each field.
|
// Typecheck each field.
|
||||||
for field in ast_fields {
|
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;
|
let ident = tcx.adjust(field.name.node, variant.did, self.body_id).0;
|
||||||
if let Some(v_field) = remaining_fields.remove(&ident) {
|
let field_type = 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);
|
|
||||||
|
|
||||||
seen_fields.insert(field.name.node, field.span);
|
seen_fields.insert(field.name.node, field.span);
|
||||||
|
|
||||||
// we don't look at stability attributes on
|
// we don't look at stability attributes on
|
||||||
|
@ -3161,10 +3157,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
if adt_kind != ty::AdtKind::Enum {
|
if adt_kind != ty::AdtKind::Enum {
|
||||||
tcx.check_stability(v_field.did, expr_id, field.span);
|
tcx.check_stability(v_field.did, expr_id, field.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.field_ty(field.span, v_field, substs)
|
||||||
} else {
|
} else {
|
||||||
error_happened = true;
|
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) {
|
if let Some(_) = variant.find_field_named(field.name.node) {
|
||||||
let mut err = struct_span_err!(self.tcx.sess,
|
let mut err = struct_span_err!(self.tcx.sess,
|
||||||
field.name.span,
|
field.name.span,
|
||||||
|
@ -3182,12 +3178,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
|
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
|
// Make sure to give a type to the field even if there's
|
||||||
// an error, so we can continue typechecking
|
// an error, so we can continue typechecking
|
||||||
let ty = self.check_expr_with_hint(&field.expr, field_type_hint);
|
self.check_expr_coercable_to_type(&field.expr, field_type);
|
||||||
self.demand_coerce(&field.expr, ty, final_field_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the programmer specified correct number of fields.
|
// Make sure the programmer specified correct number of fields.
|
||||||
|
|
|
@ -12,9 +12,12 @@ pub struct Struct<K: 'static> {
|
||||||
pub field: K,
|
pub field: K,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Partial fix for #31260, doesn't work without {...}.
|
|
||||||
static STRUCT: Struct<&'static [u8]> = Struct {
|
static STRUCT: Struct<&'static [u8]> = Struct {
|
||||||
field: {&[1]}
|
field: {&[1]}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static STRUCT2: Struct<&'static [u8]> = Struct {
|
||||||
|
field: &[1]
|
||||||
|
};
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -39,23 +39,25 @@ fn c() -> Result<Foo, Bar> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn d() -> X<X<String, String>, String> {
|
fn d() -> X<X<String, String>, String> {
|
||||||
X {
|
let x = X {
|
||||||
x: X {
|
x: X {
|
||||||
x: "".to_string(),
|
x: "".to_string(),
|
||||||
y: 2,
|
y: 2,
|
||||||
},
|
},
|
||||||
y: 3,
|
y: 3,
|
||||||
}
|
};
|
||||||
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
fn e() -> X<X<String, String>, String> {
|
fn e() -> X<X<String, String>, String> {
|
||||||
X {
|
let x = X {
|
||||||
x: X {
|
x: X {
|
||||||
x: "".to_string(),
|
x: "".to_string(),
|
||||||
y: 2,
|
y: 2,
|
||||||
},
|
},
|
||||||
y: "".to_string(),
|
y: "".to_string(),
|
||||||
}
|
};
|
||||||
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -35,31 +35,19 @@ error[E0308]: mismatched types
|
||||||
found type `Foo`
|
found type `Foo`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/abridged.rs:42:5
|
--> $DIR/abridged.rs:49:5
|
||||||
|
|
|
|
||||||
42 | / X {
|
49 | x
|
||||||
43 | | x: X {
|
| ^ expected struct `std::string::String`, found integral variable
|
||||||
44 | | x: "".to_string(),
|
|
||||||
45 | | y: 2,
|
|
||||||
46 | | },
|
|
||||||
47 | | y: 3,
|
|
||||||
48 | | }
|
|
||||||
| |_____^ expected struct `std::string::String`, found integral variable
|
|
||||||
|
|
|
|
||||||
= note: expected type `X<X<_, std::string::String>, std::string::String>`
|
= note: expected type `X<X<_, std::string::String>, std::string::String>`
|
||||||
found type `X<X<_, {integer}>, {integer}>`
|
found type `X<X<_, {integer}>, {integer}>`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/abridged.rs:52:5
|
--> $DIR/abridged.rs:60:5
|
||||||
|
|
|
|
||||||
52 | / X {
|
60 | x
|
||||||
53 | | x: X {
|
| ^ expected struct `std::string::String`, found integral variable
|
||||||
54 | | x: "".to_string(),
|
|
||||||
55 | | y: 2,
|
|
||||||
56 | | },
|
|
||||||
57 | | y: "".to_string(),
|
|
||||||
58 | | }
|
|
||||||
| |_____^ expected struct `std::string::String`, found integral variable
|
|
||||||
|
|
|
|
||||||
= note: expected type `X<X<_, std::string::String>, _>`
|
= note: expected type `X<X<_, std::string::String>, _>`
|
||||||
found type `X<X<_, {integer}>, _>`
|
found type `X<X<_, {integer}>, _>`
|
||||||
|
|
Loading…
Reference in New Issue