1
Fork 0

Rollup merge of #118146 - compiler-errors:deref-into-dyn-regions, r=lcnr

Rework supertrait lint once again

I accidentally pushed the wrong commits because I totally didn't check I was on the right computer when updating #118026.
Sorry, this should address all the nits in #118026.

r? lcnr
This commit is contained in:
Matthias Krüger 2023-11-23 07:06:30 +01:00 committed by GitHub
commit add423bcf7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 125 additions and 25 deletions

View file

@ -2,7 +2,7 @@ warning: this `Deref` implementation is covered by an implicit supertrait coerci
--> $DIR/deref-lint-regions.rs:8:1
|
LL | impl<'a> Deref for dyn Foo<'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo<'_>` implements `Deref<Target = dyn Bar<'_>>` which conflicts with supertrait `Bar<'_>`
LL |
LL | type Target = dyn Bar<'a>;
| -------------------------- target type is a supertrait of `dyn Foo<'_>`

View file

@ -8,6 +8,7 @@ trait B: A {}
impl<'a> Deref for dyn 'a + B {
//~^ WARN this `Deref` implementation is covered by an implicit supertrait coercion
type Target = dyn A;
fn deref(&self) -> &Self::Target {
todo!()

View file

@ -2,8 +2,8 @@ warning: this `Deref` implementation is covered by an implicit supertrait coerci
--> $DIR/deref-lint.rs:9:1
|
LL | impl<'a> Deref for dyn 'a + B {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn B` implements `Deref<Target = dyn A>` which conflicts with supertrait `A`
...
LL | type Target = dyn A;
| -------------------- target type is a supertrait of `dyn B`
|

View file

@ -0,0 +1,34 @@
#![deny(deref_into_dyn_supertrait)]
use std::ops::Deref;
trait Bar<T> {}
impl<T, U> Bar<U> for T {}
trait Foo: Bar<i32> {
fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar<u32> + 'a);
}
impl Foo for () {
fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar<u32> + 'a) {
self
}
}
impl<'a> Deref for dyn Foo + 'a {
type Target = dyn Bar<u32> + 'a;
fn deref(&self) -> &Self::Target {
self.as_dyn_bar_u32()
}
}
fn take_dyn<T>(x: &dyn Bar<T>) -> T {
todo!()
}
fn main() {
let x: &dyn Foo = &();
let y = take_dyn(x);
let z: u32 = y;
//~^ ERROR mismatched types
}

View file

@ -0,0 +1,16 @@
error[E0308]: mismatched types
--> $DIR/deref-upcast-behavioral-change.rs:32:18
|
LL | let z: u32 = y;
| --- ^ expected `u32`, found `i32`
| |
| expected due to this
|
help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit
|
LL | let z: u32 = y.try_into().unwrap();
| ++++++++++++++++++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -0,0 +1,20 @@
// check-pass
use std::ops::Deref;
trait Bar<T> {}
trait Foo: Bar<i32> {
fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar<u32> + 'a);
}
impl<'a> Deref for dyn Foo + 'a {
//~^ WARN this `Deref` implementation is covered by an implicit supertrait coercion
type Target = dyn Bar<u32> + 'a;
fn deref(&self) -> &Self::Target {
self.as_dyn_bar_u32()
}
}
fn main() {}

View file

@ -0,0 +1,14 @@
warning: this `Deref` implementation is covered by an implicit supertrait coercion
--> $DIR/migrate-lint-different-substs.rs:11:1
|
LL | impl<'a> Deref for dyn Foo + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref<Target = dyn Bar<u32>>` which conflicts with supertrait `Bar<i32>`
LL |
LL | type Target = dyn Bar<u32> + 'a;
| -------------------------------- target type is a supertrait of `dyn Foo`
|
= help: consider removing this implementation or replacing it with a method instead
= note: `#[warn(deref_into_dyn_supertrait)]` on by default
warning: 1 warning emitted