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...)
This commit is contained in:
parent
bc1d68e389
commit
491599569c
9 changed files with 63 additions and 75 deletions
|
@ -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]);
|
||||
|
|
|
@ -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() {}
|
|
@ -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
|
||||
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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() {}
|
|
@ -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
|
||||
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue