Skip to content

Commit bea815b

Browse files
Don't consider regions in deref_into_dyn_supertrait lint
1 parent 069a4af commit bea815b

File tree

5 files changed

+52
-11
lines changed

5 files changed

+52
-11
lines changed

compiler/rustc_lint/src/deref_into_dyn_supertrait.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,13 @@ declare_lint_pass!(DerefIntoDynSupertrait => [DEREF_INTO_DYN_SUPERTRAIT]);
5959

6060
impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
6161
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
62+
let tcx = cx.tcx;
6263
// `Deref` is being implemented for `t`
6364
if let hir::ItemKind::Impl(impl_) = item.kind
6465
&& let Some(trait_) = &impl_.of_trait
65-
&& let t = cx.tcx.type_of(item.owner_id).instantiate_identity()
66+
&& let t = tcx.type_of(item.owner_id).instantiate_identity()
6667
&& let opt_did @ Some(did) = trait_.trait_def_id()
67-
&& opt_did == cx.tcx.lang_items().deref_trait()
68+
&& opt_did == tcx.lang_items().deref_trait()
6869
// `t` is `dyn t_principal`
6970
&& let ty::Dynamic(data, _, ty::Dyn) = t.kind()
7071
&& let Some(t_principal) = data.principal()
@@ -73,17 +74,22 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
7374
&& let ty::Dynamic(data, _, ty::Dyn) = target.kind()
7475
&& let Some(target_principal) = data.principal()
7576
// `target_principal` is a supertrait of `t_principal`
76-
&& supertraits(cx.tcx, t_principal.with_self_ty(cx.tcx, cx.tcx.types.trait_object_dummy_self))
77-
.any(|sup| sup.map_bound(|x| ty::ExistentialTraitRef::erase_self_ty(cx.tcx, x)) == target_principal)
77+
&& supertraits(tcx, t_principal.with_self_ty(tcx, tcx.types.trait_object_dummy_self))
78+
.any(|sup| {
79+
tcx.erase_regions(
80+
sup.map_bound(|x| ty::ExistentialTraitRef::erase_self_ty(tcx, x)),
81+
) == tcx.erase_regions(target_principal)
82+
})
7883
{
84+
let t = tcx.erase_regions(t);
7985
let label = impl_
8086
.items
8187
.iter()
8288
.find_map(|i| (i.ident.name == sym::Target).then_some(i.span))
8389
.map(|label| SupertraitAsDerefTargetLabel { label });
8490
cx.emit_spanned_lint(
8591
DEREF_INTO_DYN_SUPERTRAIT,
86-
cx.tcx.def_span(item.owner_id.def_id),
92+
tcx.def_span(item.owner_id.def_id),
8793
SupertraitAsDerefTarget { t, target_principal, label },
8894
);
8995
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![deny(deref_into_dyn_supertrait)]
2+
3+
use std::ops::Deref;
4+
5+
trait Bar<'a> {}
6+
trait Foo<'a>: Bar<'a> {}
7+
8+
impl<'a> Deref for dyn Foo<'a> {
9+
//~^ ERROR dyn Foo<'_>` implements `Deref` with supertrait `Bar<'_>` as target
10+
//~| WARN this was previously accepted by the compiler
11+
type Target = dyn Bar<'a>;
12+
13+
fn deref(&self) -> &Self::Target {
14+
todo!()
15+
}
16+
}
17+
18+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error: `dyn Foo<'_>` implements `Deref` with supertrait `Bar<'_>` as target
2+
--> $DIR/migrate-lint-deny-regions.rs:8:1
3+
|
4+
LL | impl<'a> Deref for dyn Foo<'a> {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
...
7+
LL | type Target = dyn Bar<'a>;
8+
| -------------------------- target type is set here
9+
|
10+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
11+
= note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460>
12+
note: the lint level is defined here
13+
--> $DIR/migrate-lint-deny-regions.rs:1:9
14+
|
15+
LL | #![deny(deref_into_dyn_supertrait)]
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
17+
18+
error: aborting due to previous error
19+

tests/ui/traits/trait-upcasting/migrate-lint-deny.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
#![deny(deref_into_dyn_supertrait)]
22

3-
extern crate core;
4-
5-
use core::ops::Deref;
3+
use std::ops::Deref;
64

75
// issue 89190
86
trait A {}
97
trait B: A {}
108

119
impl<'a> Deref for dyn 'a + B {
12-
//~^ ERROR `(dyn B + 'a)` implements `Deref` with supertrait `A` as target
10+
//~^ ERROR `dyn B` implements `Deref` with supertrait `A` as target
1311
//~| WARN this was previously accepted by the compiler but is being phased out;
1412

1513
type Target = dyn A;

tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
error: `(dyn B + 'a)` implements `Deref` with supertrait `A` as target
2-
--> $DIR/migrate-lint-deny.rs:11:1
1+
error: `dyn B` implements `Deref` with supertrait `A` as target
2+
--> $DIR/migrate-lint-deny.rs:9:1
33
|
44
LL | impl<'a> Deref for dyn 'a + B {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)