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<T = String> {
   |            ---------- 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
```
This commit is contained in:
Esteban Küber
2026-03-14 18:02:00 +00:00
parent 87d8f5885b
commit 2e4a420db0
3 changed files with 42 additions and 2 deletions
+16 -2
View File
@@ -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",
);
}
_ => {}
}
}
@@ -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<T = String> { //~ 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() {}
@@ -0,0 +1,15 @@
error[E0308]: mismatched types
--> $DIR/struct-type-parameter-with-default.rs:5:12
|
LL | struct Foo<T = String> {
| ---------- 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`.