Skip to content

Properly report error when object type param default references self #135971

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions compiler/rustc_error_codes/src/error_codes/E0393.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ A type parameter which references `Self` in its default value was not specified.
Erroneous code example:

```compile_fail,E0393
trait A<T=Self> {}
trait A<T = Self> {}

fn together_we_will_rule_the_galaxy(son: &A) {}
// error: the type parameter `T` must be explicitly specified in an
// object type because its default value `Self` references the
// type `Self`
fn together_we_will_rule_the_galaxy(son: &dyn A) {}
// error: the type parameter `T` must be explicitly specified
```

A trait object is defined over a single, fully-defined trait. With a regular
Expand All @@ -23,7 +21,7 @@ disallowed. Making the trait concrete by explicitly specifying the value of the
defaulted parameter will fix this issue. Fixed example:

```
trait A<T=Self> {}
trait A<T = Self> {}

fn together_we_will_rule_the_galaxy(son: &A<i32>) {} // Ok!
fn together_we_will_rule_the_galaxy(son: &dyn A<i32>) {} // Ok!
```
8 changes: 7 additions & 1 deletion compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,13 @@ hir_analysis_missing_type_params =
[one] reference
*[other] references
} to {$parameters}
.note = because of the default `Self` reference, type parameters must be specified on object types
.note = because the parameter {$parameterCount ->
[one] default references
*[other] defaults reference
} `Self`, the {$parameterCount ->
[one] parameter
*[other] parameters
} must be specified on the object type

hir_analysis_multiple_relaxed_default_bounds =
type parameter has more than one relaxed default bound, only one is supported
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,16 +237,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// Skip `Self`
.skip(1)
.map(|(index, arg)| {
if arg == dummy_self.into() {
if arg.walk().any(|arg| arg == dummy_self.into()) {
let param = &generics.own_params[index];
missing_type_params.push(param.name);
Ty::new_misc_error(tcx).into()
} else if arg.walk().any(|arg| arg == dummy_self.into()) {
let guar = self.dcx().span_delayed_bug(
span,
"trait object trait bounds reference `Self`",
);
replace_dummy_self_with_error(tcx, arg, guar)
} else {
arg
}
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/dyn-compatibility/default-param-self-projection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
trait A<C = <Self as D>::E> {}

trait D {
type E;
}

impl A<()> for () {}
impl D for () {
type E = ();
}

fn f() {
let B: &dyn A = &();
//~^ ERROR the type parameter `C` must be explicitly specified
}

fn main() {}
18 changes: 18 additions & 0 deletions tests/ui/dyn-compatibility/default-param-self-projection.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
error[E0393]: the type parameter `C` must be explicitly specified
--> $DIR/default-param-self-projection.rs:13:17
|
LL | trait A<C = <Self as D>::E> {}
| --------------------------- type parameter `C` must be specified for this
...
LL | let B: &dyn A = &();
| ^
|
= note: because the parameter default references `Self`, the parameter must be specified on the object type
help: set the type parameter to the desired type
|
LL | let B: &dyn A<C> = &();
| +++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0393`.
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0393.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL |
LL | fn together_we_will_rule_the_galaxy(son: &dyn A) {}
| ^
|
= note: because of the default `Self` reference, type parameters must be specified on object types
= note: because the parameter default references `Self`, the parameter must be specified on the object type
help: set the type parameter to the desired type
|
LL | fn together_we_will_rule_the_galaxy(son: &dyn A<T>) {}
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/issues/issue-22370.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL |
LL | fn f(a: &dyn A) {}
| ^
|
= note: because of the default `Self` reference, type parameters must be specified on object types
= note: because the parameter default references `Self`, the parameter must be specified on the object type
help: set the type parameter to the desired type
|
LL | fn f(a: &dyn A<T>) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ fn w<'a, T: 'a, F: Fn(&'a T)>() {
let b: &dyn FromResidual = &();
//~^ ERROR: the trait `FromResidual` is not dyn compatible
//~| ERROR: the trait `FromResidual` is not dyn compatible
//~| ERROR the type parameter `R` must be explicitly specified
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
error[E0393]: the type parameter `R` must be explicitly specified
--> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:17
|
LL | trait FromResidual<R = <Self as Try>::Residual> {
| ----------------------------------------------- type parameter `R` must be specified for this
...
LL | let b: &dyn FromResidual = &();
| ^^^^^^^^^^^^
|
= note: because the parameter default references `Self`, the parameter must be specified on the object type
help: set the type parameter to the desired type
|
LL | let b: &dyn FromResidual<R> = &();
| +++

error[E0038]: the trait `FromResidual` is not dyn compatible
--> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:32
|
Expand Down Expand Up @@ -45,6 +60,7 @@ help: alternatively, consider constraining `from_residual` so it does not apply
LL | fn from_residual(residual: R) -> Self where Self: Sized;
| +++++++++++++++++

error: aborting due to 2 previous errors
error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0038`.
Some errors have detailed explanations: E0038, E0393.
For more information about an error, try `rustc --explain E0038`.
2 changes: 1 addition & 1 deletion tests/ui/traits/unspecified-self-in-trait-ref.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ LL | pub trait Bar<X=usize, A=Self> {
LL | let e = Bar::<usize>::lol();
| ^^^^^^^^^^^^ missing reference to `A`
|
= note: because of the default `Self` reference, type parameters must be specified on object types
= note: because the parameter default references `Self`, the parameter must be specified on the object type

error: aborting due to 5 previous errors; 5 warnings emitted

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL | trait Foo<T=Self> {
LL | fn foo(x: &dyn Foo) { }
| ^^^
|
= note: because of the default `Self` reference, type parameters must be specified on object types
= note: because the parameter default references `Self`, the parameter must be specified on the object type
help: set the type parameter to the desired type
|
LL | fn foo(x: &dyn Foo<T>) { }
Expand Down
Loading