about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_lint/src/deref_into_dyn_supertrait.rs18
-rw-r--r--tests/ui/traits/trait-upcasting/inference-behavior-change-deref.rs36
-rw-r--r--tests/ui/traits/trait-upcasting/inference-behavior-change-deref.stderr16
-rw-r--r--tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs18
-rw-r--r--tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr19
-rw-r--r--tests/ui/traits/trait-upcasting/migrate-lint-deny.rs8
-rw-r--r--tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr6
7 files changed, 107 insertions, 14 deletions
diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
index d2d99bc0da8..d3e2d5c7646 100644
--- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
+++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
@@ -50,7 +50,7 @@ declare_lint! {
     Warn,
     "`Deref` implementation usage with a supertrait trait object for output might be shadowed in the future",
     @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
+        reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange,
         reference: "issue #89460 <https://github.com/rust-lang/rust/issues/89460>",
     };
 }
@@ -59,12 +59,13 @@ declare_lint_pass!(DerefIntoDynSupertrait => [DEREF_INTO_DYN_SUPERTRAIT]);
 
 impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
+        let tcx = cx.tcx;
         // `Deref` is being implemented for `t`
         if let hir::ItemKind::Impl(impl_) = item.kind
             && let Some(trait_) = &impl_.of_trait
-            && let t = cx.tcx.type_of(item.owner_id).instantiate_identity()
+            && let t = tcx.type_of(item.owner_id).instantiate_identity()
             && let opt_did @ Some(did) = trait_.trait_def_id()
-            && opt_did == cx.tcx.lang_items().deref_trait()
+            && opt_did == tcx.lang_items().deref_trait()
             // `t` is `dyn t_principal`
             && let ty::Dynamic(data, _, ty::Dyn) = t.kind()
             && let Some(t_principal) = data.principal()
@@ -73,9 +74,14 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
             && let ty::Dynamic(data, _, ty::Dyn) = target.kind()
             && let Some(target_principal) = data.principal()
             // `target_principal` is a supertrait of `t_principal`
-            && supertraits(cx.tcx, t_principal.with_self_ty(cx.tcx, cx.tcx.types.trait_object_dummy_self))
-                .any(|sup| sup.map_bound(|x| ty::ExistentialTraitRef::erase_self_ty(cx.tcx, x)) == target_principal)
+            && supertraits(tcx, t_principal.with_self_ty(tcx, tcx.types.trait_object_dummy_self))
+                .any(|sup| {
+                    tcx.erase_regions(
+                        sup.map_bound(|x| ty::ExistentialTraitRef::erase_self_ty(tcx, x)),
+                    ) == tcx.erase_regions(target_principal)
+                })
         {
+            let t = tcx.erase_regions(t);
             let label = impl_
                 .items
                 .iter()
@@ -83,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
                 .map(|label| SupertraitAsDerefTargetLabel { label });
             cx.emit_spanned_lint(
                 DEREF_INTO_DYN_SUPERTRAIT,
-                cx.tcx.def_span(item.owner_id.def_id),
+                tcx.def_span(item.owner_id.def_id),
                 SupertraitAsDerefTarget { t, target_principal, label },
             );
         }
diff --git a/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.rs b/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.rs
new file mode 100644
index 00000000000..79fb643eacd
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.rs
@@ -0,0 +1,36 @@
+#![deny(deref_into_dyn_supertrait)]
+#![feature(trait_upcasting)] // remove this and the test compiles
+
+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
+}
diff --git a/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.stderr b/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.stderr
new file mode 100644
index 00000000000..cfd6f7f175f
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/inference-behavior-change-deref.rs:34: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`.
diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs
new file mode 100644
index 00000000000..b3f14a5f256
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs
@@ -0,0 +1,18 @@
+#![deny(deref_into_dyn_supertrait)]
+
+use std::ops::Deref;
+
+trait Bar<'a> {}
+trait Foo<'a>: Bar<'a> {}
+
+impl<'a> Deref for dyn Foo<'a> {
+    //~^ ERROR dyn Foo<'_>` implements `Deref` with supertrait `Bar<'_>` as target
+    //~| WARN this will change its meaning in a future release!
+    type Target = dyn Bar<'a>;
+
+    fn deref(&self) -> &Self::Target {
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr
new file mode 100644
index 00000000000..250bcabc698
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr
@@ -0,0 +1,19 @@
+error: `dyn Foo<'_>` implements `Deref` with supertrait `Bar<'_>` as target
+  --> $DIR/migrate-lint-deny-regions.rs:8:1
+   |
+LL | impl<'a> Deref for dyn Foo<'a> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |     type Target = dyn Bar<'a>;
+   |     -------------------------- target type is set here
+   |
+   = 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
+   |
+LL | #![deny(deref_into_dyn_supertrait)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs b/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs
index d624187561e..114d2c249da 100644
--- a/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs
+++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs
@@ -1,16 +1,14 @@
 #![deny(deref_into_dyn_supertrait)]
 
-extern crate core;
-
-use core::ops::Deref;
+use std::ops::Deref;
 
 // issue 89190
 trait A {}
 trait B: A {}
 
 impl<'a> Deref for dyn 'a + B {
-    //~^ ERROR `(dyn B + 'a)` implements `Deref` with supertrait `A` as target
-    //~| WARN this was previously accepted by the compiler but is being phased out;
+    //~^ ERROR `dyn B` implements `Deref` with supertrait `A` as target
+    //~| WARN this will change its meaning in a future release!
 
     type Target = dyn A;
     fn deref(&self) -> &Self::Target {
diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr
index 4533b116342..c8b683c23c1 100644
--- a/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr
+++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr
@@ -1,5 +1,5 @@
-error: `(dyn B + 'a)` implements `Deref` with supertrait `A` as target
-  --> $DIR/migrate-lint-deny.rs:11:1
+error: `dyn B` implements `Deref` with supertrait `A` as target
+  --> $DIR/migrate-lint-deny.rs:9:1
    |
 LL | impl<'a> Deref for dyn 'a + B {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | impl<'a> Deref for dyn 'a + B {
 LL |     type Target = dyn A;
    |     -------------------- target type is set here
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = 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