Rollup merge of #135971 - compiler-errors:self-projection, r=fmease
Properly report error when object type param default references self I accidentally broke this error for cases where a type parameter references `Self` via a projection (i.e. `trait Foo<Arg = Self::Bar> {}`). This PR fixes that, and also makes the error a bit easier to understand. Fixes #135918
This commit is contained in:
commit
9ffe558455
11 changed files with 71 additions and 21 deletions
|
@ -5,10 +5,8 @@ Erroneous code example:
|
||||||
```compile_fail,E0393
|
```compile_fail,E0393
|
||||||
trait A<T = Self> {}
|
trait A<T = Self> {}
|
||||||
|
|
||||||
fn together_we_will_rule_the_galaxy(son: &A) {}
|
fn together_we_will_rule_the_galaxy(son: &dyn A) {}
|
||||||
// error: the type parameter `T` must be explicitly specified in an
|
// error: the type parameter `T` must be explicitly specified
|
||||||
// object type because its default value `Self` references the
|
|
||||||
// type `Self`
|
|
||||||
```
|
```
|
||||||
|
|
||||||
A trait object is defined over a single, fully-defined trait. With a regular
|
A trait object is defined over a single, fully-defined trait. With a regular
|
||||||
|
@ -25,5 +23,5 @@ 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!
|
||||||
```
|
```
|
||||||
|
|
|
@ -353,7 +353,13 @@ hir_analysis_missing_type_params =
|
||||||
[one] reference
|
[one] reference
|
||||||
*[other] references
|
*[other] references
|
||||||
} to {$parameters}
|
} 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 =
|
hir_analysis_multiple_relaxed_default_bounds =
|
||||||
type parameter has more than one relaxed default bound, only one is supported
|
type parameter has more than one relaxed default bound, only one is supported
|
||||||
|
|
|
@ -237,16 +237,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
// Skip `Self`
|
// Skip `Self`
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.map(|(index, arg)| {
|
.map(|(index, arg)| {
|
||||||
if arg == dummy_self.into() {
|
if arg.walk().any(|arg| arg == dummy_self.into()) {
|
||||||
let param = &generics.own_params[index];
|
let param = &generics.own_params[index];
|
||||||
missing_type_params.push(param.name);
|
missing_type_params.push(param.name);
|
||||||
Ty::new_misc_error(tcx).into()
|
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 {
|
} else {
|
||||||
arg
|
arg
|
||||||
}
|
}
|
||||||
|
|
17
tests/ui/dyn-compatibility/default-param-self-projection.rs
Normal file
17
tests/ui/dyn-compatibility/default-param-self-projection.rs
Normal file
|
@ -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() {}
|
|
@ -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`.
|
|
@ -7,7 +7,7 @@ LL |
|
||||||
LL | fn together_we_will_rule_the_galaxy(son: &dyn A) {}
|
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
|
help: set the type parameter to the desired type
|
||||||
|
|
|
|
||||||
LL | fn together_we_will_rule_the_galaxy(son: &dyn A<T>) {}
|
LL | fn together_we_will_rule_the_galaxy(son: &dyn A<T>) {}
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL |
|
||||||
LL | fn f(a: &dyn A) {}
|
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
|
help: set the type parameter to the desired type
|
||||||
|
|
|
|
||||||
LL | fn f(a: &dyn A<T>) {}
|
LL | fn f(a: &dyn A<T>) {}
|
||||||
|
|
|
@ -10,6 +10,7 @@ fn w<'a, T: 'a, F: Fn(&'a T)>() {
|
||||||
let b: &dyn FromResidual = &();
|
let b: &dyn FromResidual = &();
|
||||||
//~^ ERROR: the trait `FromResidual` is not dyn compatible
|
//~^ ERROR: the trait `FromResidual` is not dyn compatible
|
||||||
//~| 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() {}
|
fn main() {}
|
||||||
|
|
|
@ -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
|
error[E0038]: the trait `FromResidual` is not dyn compatible
|
||||||
--> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:32
|
--> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:32
|
||||||
|
|
|
|
||||||
|
@ -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;
|
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`.
|
||||||
|
|
|
@ -97,7 +97,7 @@ LL | pub trait Bar<X=usize, A=Self> {
|
||||||
LL | let e = Bar::<usize>::lol();
|
LL | let e = Bar::<usize>::lol();
|
||||||
| ^^^^^^^^^^^^ missing reference to `A`
|
| ^^^^^^^^^^^^ 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
|
error: aborting due to 5 previous errors; 5 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | trait Foo<T=Self> {
|
||||||
LL | fn foo(x: &dyn Foo) { }
|
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
|
help: set the type parameter to the desired type
|
||||||
|
|
|
|
||||||
LL | fn foo(x: &dyn Foo<T>) { }
|
LL | fn foo(x: &dyn Foo<T>) { }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue