diff options
| author | Waffle Lapkin <waffle.lapkin@gmail.com> | 2025-02-06 21:57:50 +0100 |
|---|---|---|
| committer | Waffle Lapkin <waffle.lapkin@gmail.com> | 2025-02-06 23:44:24 +0100 |
| commit | 491599569c081985d6cc3eb4ab55d692e380e938 (patch) | |
| tree | adfe56b57b4dbc0c622d5c95c7c32d3728f78862 | |
| parent | bc1d68e389d000730084b8e3bfc3ba23b9450dd8 (diff) | |
| download | rust-491599569c081985d6cc3eb4ab55d692e380e938.tar.gz rust-491599569c081985d6cc3eb4ab55d692e380e938.zip | |
allow+update `deref_into_dyn_supertrait`
this commit makes `deref_into_dyn_supertrait` lint allow-by-default, removes future incompatibility (we finally live in a broken world), and changes the wording in the documentation. previously documentation erroneously said that it lints against *usage* of the deref impl, while it actually (since 104742) lints on the impl itself (oooops, my oversight, should have updated it 2+ years ago...)
9 files changed, 63 insertions, 75 deletions
diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index 07f46aba05b..181f44fb4de 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -1,6 +1,5 @@ use rustc_hir::{self as hir, LangItem}; use rustc_middle::ty; -use rustc_session::lint::FutureIncompatibilityReason; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::sym; use rustc_trait_selection::traits::supertraits; @@ -9,12 +8,12 @@ use crate::lints::{SupertraitAsDerefTarget, SupertraitAsDerefTargetLabel}; use crate::{LateContext, LateLintPass, LintContext}; declare_lint! { - /// The `deref_into_dyn_supertrait` lint is output whenever there is a use of the - /// `Deref` implementation with a `dyn SuperTrait` type as `Output`. + /// The `deref_into_dyn_supertrait` lint is emitted whenever there is a `Deref` implementation + /// for `dyn SubTrait` with a `dyn SuperTrait` type as the `Output` type. /// - /// These implementations are shadowed by the `trait_upcasting` feature (stabilized since + /// These implementations are "shadowed" by trait upcasting (stabilized since /// CURRENT_RUSTC_VERSION). The `deref` functions is no longer called implicitly, which might - /// be behavior change compared to previous rustc versions. + /// change behavior compared to previous rustc versions. /// /// ### Example /// @@ -44,15 +43,14 @@ declare_lint! { /// /// ### Explanation /// - /// The dyn upcasting coercion feature added a new coercion rules, taking priority - /// over certain other coercion rules, which caused some behavior change. + /// The trait upcasting coercion added a new coercion rule, taking priority over certain other + /// coercion rules, which causes some behavior change compared to older `rustc` versions. + /// + /// `deref` can be still called explicitly, it just isn't called as part of a deref coercion + /// (since trait upcasting coercion takes priority). pub DEREF_INTO_DYN_SUPERTRAIT, - Warn, - "`Deref` implementation usage with a supertrait trait object for output is shadowed by trait upcasting", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange, - reference: "issue #89460 <https://github.com/rust-lang/rust/issues/89460>", - }; + Allow, + "`Deref` implementation with a supertrait trait object for output is shadowed by trait upcasting", } declare_lint_pass!(DerefIntoDynSupertrait => [DEREF_INTO_DYN_SUPERTRAIT]); diff --git a/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.rs b/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.rs new file mode 100644 index 00000000000..ab84527edcf --- /dev/null +++ b/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.rs @@ -0,0 +1,17 @@ +//@ check-pass +#![warn(deref_into_dyn_supertrait)] +use std::ops::Deref; + +trait Bar<T> {} +trait Foo: Bar<i32> {} + +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 { + todo!() + } +} + +fn main() {} diff --git a/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.stderr b/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.stderr new file mode 100644 index 00000000000..0d7f957a50e --- /dev/null +++ b/tests/ui/traits/trait-upcasting/deref-upcast-shadowing-lint.stderr @@ -0,0 +1,17 @@ +warning: this `Deref` implementation is covered by an implicit supertrait coercion + --> $DIR/deref-upcast-shadowing-lint.rs:8: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` + | +note: the lint level is defined here + --> $DIR/deref-upcast-shadowing-lint.rs:2:9 + | +LL | #![warn(deref_into_dyn_supertrait)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs index da1a9cc2775..d33d3bfd5dc 100644 --- a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs +++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs @@ -1,4 +1,5 @@ -#![deny(deref_into_dyn_supertrait)] +//@ check-pass +#![warn(deref_into_dyn_supertrait)] use std::ops::Deref; @@ -6,8 +7,7 @@ trait Bar<'a> {} trait Foo<'a>: Bar<'a> {} impl<'a> Deref for dyn Foo<'a> { - //~^ ERROR this `Deref` implementation is covered by an implicit supertrait coercion - //~| WARN this will change its meaning in a future release! + //~^ warn: this `Deref` implementation is covered by an implicit supertrait coercion type Target = dyn Bar<'a>; fn deref(&self) -> &Self::Target { diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr index a5f3660d4bc..806c57e44a2 100644 --- a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr +++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr @@ -1,19 +1,17 @@ -error: this `Deref` implementation is covered by an implicit supertrait coercion - --> $DIR/migrate-lint-deny-regions.rs:8:1 +warning: this `Deref` implementation is covered by an implicit supertrait coercion + --> $DIR/migrate-lint-deny-regions.rs:9: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<'_>` | - = warning: this will change its meaning in a future release! - = note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460> note: the lint level is defined here - --> $DIR/migrate-lint-deny-regions.rs:1:9 + --> $DIR/migrate-lint-deny-regions.rs:2:9 | -LL | #![deny(deref_into_dyn_supertrait)] +LL | #![warn(deref_into_dyn_supertrait)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +warning: 1 warning emitted diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs b/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs deleted file mode 100644 index 926b3649e01..00000000000 --- a/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![deny(deref_into_dyn_supertrait)] - -use std::ops::Deref; - -// issue 89190 -trait A {} -trait B: A {} - -impl<'a> Deref for dyn 'a + B { - //~^ ERROR this `Deref` implementation is covered by an implicit supertrait coercion - //~| WARN this will change its meaning in a future release! - - type Target = dyn A; - fn deref(&self) -> &Self::Target { - todo!() - } -} - -fn take_a(_: &dyn A) {} - -fn whoops(b: &dyn B) { - take_a(b) -} - -fn main() {} diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr deleted file mode 100644 index 29997a9b3d9..00000000000 --- a/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: this `Deref` implementation is covered by an implicit supertrait coercion - --> $DIR/migrate-lint-deny.rs:9:1 - | -LL | impl<'a> Deref for dyn 'a + B { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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` - | - = warning: this will change its meaning in a future release! - = note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460> -note: the lint level is defined here - --> $DIR/migrate-lint-deny.rs:1:9 - | -LL | #![deny(deref_into_dyn_supertrait)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.rs b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.rs index 8e62c4b95b0..20806f22886 100644 --- a/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.rs +++ b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.rs @@ -1,4 +1,5 @@ //@ check-pass +#![warn(deref_into_dyn_supertrait)] use std::ops::Deref; @@ -9,8 +10,7 @@ trait Foo: Bar<i32> { } impl<'a> Deref for dyn Foo + 'a { - //~^ WARN this `Deref` implementation is covered by an implicit supertrait coercion - //~| WARN this will change its meaning in a future release! + //~^ warn: this `Deref` implementation is covered by an implicit supertrait coercion type Target = dyn Bar<u32> + 'a; fn deref(&self) -> &Self::Target { diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr index 6245da5a176..86cff5233ff 100644 --- a/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr +++ b/tests/ui/traits/trait-upcasting/migrate-lint-different-substs.stderr @@ -1,15 +1,17 @@ warning: this `Deref` implementation is covered by an implicit supertrait coercion - --> $DIR/migrate-lint-different-substs.rs:11:1 + --> $DIR/migrate-lint-different-substs.rs:12: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` | - = warning: this will change its meaning in a future release! - = note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460> - = note: `#[warn(deref_into_dyn_supertrait)]` on by default +note: the lint level is defined here + --> $DIR/migrate-lint-different-substs.rs:2:9 + | +LL | #![warn(deref_into_dyn_supertrait)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted |
