From 2e4a420db08a0bb5a43834227aef532a9de3b3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 14 Mar 2026 18:02:00 +0000 Subject: [PATCH] Explain that default field values aren't compatible with type parameters unless going through the type parameter ``` error[E0308]: mismatched types --> $DIR/struct-type-parameter-with-default.rs:5:12 | LL | struct Foo { | ---------- expected this type parameter LL | x: T = String::new(), | ^^^^^^^^^^^^^ expected type parameter `T`, found `String` | = note: expected type parameter `T` found struct `String` = note: the type of default fields referencing type parameters can't be assumed inside the struct defining them ``` --- compiler/rustc_hir_typeck/src/lib.rs | 18 ++++++++++++++++-- .../struct-type-parameter-with-default.rs | 11 +++++++++++ .../struct-type-parameter-with-default.stderr | 15 +++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 tests/ui/structs/default-field-values/struct-type-parameter-with-default.rs create mode 100644 tests/ui/structs/default-field-values/struct-type-parameter-with-default.stderr diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 200cef49f35d..734e5136f880 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -205,7 +205,7 @@ fn typeck_with_inspect<'tcx>( } fcx.check_expr_coercible_to_type_or_error(body.value, expected_type, None, |err, _| { - extend_err_with_const_context(err, tcx, node); + extend_err_with_const_context(err, tcx, node, expected_type); }); fcx.write_ty(id, expected_type); @@ -276,7 +276,12 @@ fn typeck_with_inspect<'tcx>( typeck_results } -fn extend_err_with_const_context(err: &mut Diag<'_>, tcx: TyCtxt<'_>, node: hir::Node<'_>) { +fn extend_err_with_const_context( + err: &mut Diag<'_>, + tcx: TyCtxt<'_>, + node: hir::Node<'_>, + expected_ty: Ty<'_>, +) { match node { hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(ty, _), .. }) | hir::Node::TraitItem(hir::TraitItem { @@ -378,6 +383,15 @@ fn extend_err_with_const_context(err: &mut Diag<'_>, tcx: TyCtxt<'_>, node: hir: // Point at `char` in `pattern_type!(char is 1..=1)`. err.span_label(ty.span, "the pattern must match the type"); } + hir::Node::AnonConst(anon) + if let hir::Node::Field(_) = tcx.parent_hir_node(anon.hir_id) + && let ty::Param(_) = expected_ty.kind() => + { + err.note( + "the type of default fields referencing type parameters can't be assumed inside \ + the struct defining them", + ); + } _ => {} } } diff --git a/tests/ui/structs/default-field-values/struct-type-parameter-with-default.rs b/tests/ui/structs/default-field-values/struct-type-parameter-with-default.rs new file mode 100644 index 000000000000..c9e5aa9afb41 --- /dev/null +++ b/tests/ui/structs/default-field-values/struct-type-parameter-with-default.rs @@ -0,0 +1,11 @@ +// Test for #147748, providing additional clarification that default field values aren't compatible +// with type parameters unless going through the type parameter. +#![feature(default_field_values)] +struct Foo { //~ NOTE: expected this type parameter + x: T = String::new(), + //~^ ERROR: mismatched types + //~| NOTE: expected type parameter + //~| NOTE: expected type parameter + //~| NOTE: the type of default fields referencing type parameters can't be assumed inside the struct defining them +} +fn main() {} diff --git a/tests/ui/structs/default-field-values/struct-type-parameter-with-default.stderr b/tests/ui/structs/default-field-values/struct-type-parameter-with-default.stderr new file mode 100644 index 000000000000..553b49023835 --- /dev/null +++ b/tests/ui/structs/default-field-values/struct-type-parameter-with-default.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/struct-type-parameter-with-default.rs:5:12 + | +LL | struct Foo { + | ---------- expected this type parameter +LL | x: T = String::new(), + | ^^^^^^^^^^^^^ expected type parameter `T`, found `String` + | + = note: expected type parameter `T` + found struct `String` + = note: the type of default fields referencing type parameters can't be assumed inside the struct defining them + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.