Skip to content

Commit 7769c9a

Browse files
committed
coerce fields to the expected field type
Fully fixes #31260. This needs a crater run.
1 parent 03198da commit 7769c9a

File tree

4 files changed

+29
-39
lines changed

4 files changed

+29
-39
lines changed

src/librustc_typeck/check/mod.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3159,11 +3159,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
31593159

31603160
let adt_ty_hint =
31613161
self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3162-
.get(0).cloned().unwrap_or(adt_ty);
3162+
.get(0).cloned().unwrap_or(adt_ty);
3163+
// re-link the regions that EIfEO can erase.
3164+
self.demand_eqtype(span, adt_ty_hint, adt_ty);
31633165

3164-
let (substs, hint_substs, adt_kind, kind_name) = match (&adt_ty.sty, &adt_ty_hint.sty) {
3165-
(&ty::TyAdt(adt, substs), &ty::TyAdt(_, hint_substs)) => {
3166-
(substs, hint_substs, adt.adt_kind(), adt.variant_descr())
3166+
let (substs, adt_kind, kind_name) = match &adt_ty.sty{
3167+
&ty::TyAdt(adt, substs) => {
3168+
(substs, adt.adt_kind(), adt.variant_descr())
31673169
}
31683170
_ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
31693171
};
@@ -3179,14 +3181,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
31793181

31803182
// Typecheck each field.
31813183
for field in ast_fields {
3182-
let final_field_type;
3183-
let field_type_hint;
3184-
31853184
let ident = tcx.adjust(field.name.node, variant.did, self.body_id).0;
3186-
if let Some(v_field) = remaining_fields.remove(&ident) {
3187-
final_field_type = self.field_ty(field.span, v_field, substs);
3188-
field_type_hint = self.field_ty(field.span, v_field, hint_substs);
3189-
3185+
let field_type = if let Some(v_field) = remaining_fields.remove(&ident) {
31903186
seen_fields.insert(field.name.node, field.span);
31913187

31923188
// we don't look at stability attributes on
@@ -3195,10 +3191,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
31953191
if adt_kind != ty::AdtKind::Enum {
31963192
tcx.check_stability(v_field.did, expr_id, field.span);
31973193
}
3194+
3195+
self.field_ty(field.span, v_field, substs)
31983196
} else {
31993197
error_happened = true;
3200-
final_field_type = tcx.types.err;
3201-
field_type_hint = tcx.types.err;
32023198
if let Some(_) = variant.find_field_named(field.name.node) {
32033199
let mut err = struct_span_err!(self.tcx.sess,
32043200
field.name.span,
@@ -3216,12 +3212,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
32163212
} else {
32173213
self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
32183214
}
3219-
}
3215+
3216+
tcx.types.err
3217+
};
32203218

32213219
// Make sure to give a type to the field even if there's
32223220
// an error, so we can continue typechecking
3223-
let ty = self.check_expr_with_hint(&field.expr, field_type_hint);
3224-
self.demand_coerce(&field.expr, ty, final_field_type);
3221+
self.check_expr_coercable_to_type(&field.expr, field_type);
32253222
}
32263223

32273224
// Make sure the programmer specified correct number of fields.

src/test/run-pass/issue-31260.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ pub struct Struct<K: 'static> {
1212
pub field: K,
1313
}
1414

15-
// Partial fix for #31260, doesn't work without {...}.
1615
static STRUCT: Struct<&'static [u8]> = Struct {
1716
field: {&[1]}
1817
};
1918

19+
static STRUCT2: Struct<&'static [u8]> = Struct {
20+
field: &[1]
21+
};
22+
2023
fn main() {}

src/test/ui/mismatched_types/abridged.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,25 @@ fn c() -> Result<Foo, Bar> {
3939
}
4040

4141
fn d() -> X<X<String, String>, String> {
42-
X {
42+
let x = X {
4343
x: X {
4444
x: "".to_string(),
4545
y: 2,
4646
},
4747
y: 3,
48-
}
48+
};
49+
x
4950
}
5051

5152
fn e() -> X<X<String, String>, String> {
52-
X {
53+
let x = X {
5354
x: X {
5455
x: "".to_string(),
5556
y: 2,
5657
},
5758
y: "".to_string(),
58-
}
59+
};
60+
x
5961
}
6062

6163
fn main() {}

src/test/ui/mismatched_types/abridged.stderr

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,31 +35,19 @@ error[E0308]: mismatched types
3535
found type `Foo`
3636

3737
error[E0308]: mismatched types
38-
--> $DIR/abridged.rs:42:5
38+
--> $DIR/abridged.rs:49:5
3939
|
40-
42 | / X {
41-
43 | | x: X {
42-
44 | | x: "".to_string(),
43-
45 | | y: 2,
44-
46 | | },
45-
47 | | y: 3,
46-
48 | | }
47-
| |_____^ expected struct `std::string::String`, found integral variable
40+
49 | x
41+
| ^ expected struct `std::string::String`, found integral variable
4842
|
4943
= note: expected type `X<X<_, std::string::String>, std::string::String>`
5044
found type `X<X<_, {integer}>, {integer}>`
5145

5246
error[E0308]: mismatched types
53-
--> $DIR/abridged.rs:52:5
47+
--> $DIR/abridged.rs:60:5
5448
|
55-
52 | / X {
56-
53 | | x: X {
57-
54 | | x: "".to_string(),
58-
55 | | y: 2,
59-
56 | | },
60-
57 | | y: "".to_string(),
61-
58 | | }
62-
| |_____^ expected struct `std::string::String`, found integral variable
49+
60 | x
50+
| ^ expected struct `std::string::String`, found integral variable
6351
|
6452
= note: expected type `X<X<_, std::string::String>, _>`
6553
found type `X<X<_, {integer}>, _>`

0 commit comments

Comments
 (0)