Change:
fails to type check, while succeeds.
This coercion is important when using byte string literals.
The tuple struct case is actually the function call "expected type" propagation, which would have to be adapted to struct literals as well.
Yes.
Coercion already happens in non-generic struct literals:
Yes, but the field types are taken from the struct and not combined with the overall expected type for the struct literal.
I just discovered this bug/unexpected behavior today (). I would like to see some movement on it because it's surprising that these two don't work the same way. Here's a workaround I found; it's ugly as hell but I'm using it in a generated file that no human would want to look through anyway: I tried type ascription but it seems to not cue coercion, it just moves the type error: It seems that forcing a concrete type on the struct literal works as well (I didn't expect this syntax to work, honestly): Unfortunately this won't work for me because I'm using too and I can't add this extra syntax myself.
Any news on this?
Is anyone working on it?
It seems like implemented a partial fix in but suggests that there are backwards incompatibility issues to be considered that preventing him from going further. I'm not quite sure what he had in mind there, perhaps he can elaborate.
Making sure we remember to look at this.
What I did is I computed a "light hint" (which becomes "strong hint", i.e. forcing coercion, if it reaches a block, and it's enough to help integer inference for ). This is a common problem with coercion hints, in that unless there's enough type information to prevent them from triggering, they will trigger early even if that breaks later on. The thing to try here is to replace with the simpler: doesn't even need to be computed if that works, since is at least as specific - AFAICT, we already have that "specificity" with function calls, but since it hasn't been used with struct literals before, crater/cargobomb might reveal regressions.
ok, I was mostly wondering if you encountered actual regressions in practice, or just theorize that this might lead to problems.
I don't think I got the chance to do a crater run and then I lost track of it.
will open a PR and we can try a crater run at least.
There is still a similar problem with the type inference of temporaries when you have an array that should be interpreted as a slice buried in a tuple inside an outer slice.

Discussion:
let adt_ty_hint = self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty]) <del> .get(0).cloned().unwrap_or(adt_ty); </del> <ins> .get(0).cloned().unwrap_or(adt_ty); // re-link the regions that EIfEO can erase. self.demand_eqtype(span, adt_ty_hint, adt_ty); </ins> <del> 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()) </del> <ins> let (substs, adt_kind, kind_name) = match &adt_ty.sty{ &ty::TyAdt(adt, substs) => { (substs, adt.adt_kind(), adt.variant_descr()) </ins> } _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields") };

// Typecheck each field. for field in ast_fields { <del> let final_field_type; let field_type_hint; </del> let ident = tcx.adjust(field.name.node, variant.did, self.body_id).0; <del> 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); </del> <ins> let field_type = if let Some(v_field) = remaining_fields.remove(&ident) { </ins> seen_fields.insert(field.name.node, field.span); // we don't look at stability attributes on

if adt_kind != ty::AdtKind::Enum { tcx.check_stability(v_field.did, expr_id, field.span); } <ins> self.field_ty(field.span, v_field, substs) </ins> } else { error_happened = true; <del> final_field_type = tcx.types.err; field_type_hint = tcx.types.err; </del> if let Some(_) = variant.find_field_named(field.name.node) { let mut err = struct_span_err!(self.tcx.sess, field.name.span,

} else { self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name); } <del> } </del> <ins> tcx.types.err }; </ins> // Make sure to give a type to the field even if there's // an error, so we can continue typechecking <del> let ty = self.check_expr_with_hint(&field.expr, field_type_hint); self.demand_coerce(&field.expr, ty, final_field_type); </del> <ins> self.check_expr_coercable_to_type(&field.expr, field_type); </ins> } // Make sure the programmer specified correct number of fields.

pub field: K, } <del> // Partial fix for #31260, doesn't work without {...}. </del> static STRUCT: Struct<&'static [u8]> = Struct { field: {&[1]} }; <ins> static STRUCT2: Struct<&'static [u8]> = Struct { field: &[1] }; </ins> fn main() {}

} fn d() -> X<X<String, String>, String> { <del> X { </del> <ins> let x = X { </ins> x: X { x: "".to_string(), y: 2, }, y: 3, <del> } </del> <ins> }; x </ins> } fn e() -> X<X<String, String>, String> { <del> X { </del> <ins> let x = X { </ins> x: X { x: "".to_string(), y: 2, }, y: "".to_string(), <del> } </del> <ins> }; x </ins> } fn main() {}

found type `Foo` error[E0308]: mismatched types <del> --> $DIR/abridged.rs:42:5 </del> <ins> --> $DIR/abridged.rs:49:5 </ins> | <del> 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 </del> <ins> 49 |     x |     ^ expected struct `std::string::String`, found integral variable </ins> | = note: expected type `X<X<_, std::string::String>, std::string::String>` found type `X<X<_, {integer}>, {integer}>` error[E0308]: mismatched types <del> --> $DIR/abridged.rs:52:5 </del> <ins> --> $DIR/abridged.rs:60:5 </ins> | <del> 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 </del> <ins> 60 |     x |     ^ expected struct `std::string::String`, found integral variable </ins> | = note: expected type `X<X<_, std::string::String>, _>` found type `X<X<_, {integer}>, _>`