Skip to content

Commit 41ff8aa

Browse files
authored
Unrolled build for rust-lang#118026
Rollup merge of rust-lang#118026 - compiler-errors:deref-into-dyn-regions, r=lcnr Don't consider regions in `deref_into_dyn_supertrait` lint I actually wonder if we should just warn on *any* deref impl with a target type that matches a supertrait by *def-id*. cc rust-lang#89460 r? types
2 parents 8534923 + e6ca8e1 commit 41ff8aa

7 files changed

+107
-14
lines changed

Diff for: compiler/rustc_lint/src/deref_into_dyn_supertrait.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ declare_lint! {
5050
Warn,
5151
"`Deref` implementation usage with a supertrait trait object for output might be shadowed in the future",
5252
@future_incompatible = FutureIncompatibleInfo {
53-
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
53+
reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange,
5454
reference: "issue #89460 <https://github.com/rust-lang/rust/issues/89460>",
5555
};
5656
}
@@ -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,36 @@
1+
#![deny(deref_into_dyn_supertrait)]
2+
#![feature(trait_upcasting)] // remove this and the test compiles
3+
4+
use std::ops::Deref;
5+
6+
trait Bar<T> {}
7+
impl<T, U> Bar<U> for T {}
8+
9+
trait Foo: Bar<i32> {
10+
fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar<u32> + 'a);
11+
}
12+
13+
impl Foo for () {
14+
fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar<u32> + 'a) {
15+
self
16+
}
17+
}
18+
19+
impl<'a> Deref for dyn Foo + 'a {
20+
type Target = dyn Bar<u32> + 'a;
21+
22+
fn deref(&self) -> &Self::Target {
23+
self.as_dyn_bar_u32()
24+
}
25+
}
26+
27+
fn take_dyn<T>(x: &dyn Bar<T>) -> T {
28+
todo!()
29+
}
30+
31+
fn main() {
32+
let x: &dyn Foo = &();
33+
let y = take_dyn(x);
34+
let z: u32 = y;
35+
//~^ ERROR mismatched types
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/inference-behavior-change-deref.rs:34:18
3+
|
4+
LL | let z: u32 = y;
5+
| --- ^ expected `u32`, found `i32`
6+
| |
7+
| expected due to this
8+
|
9+
help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit
10+
|
11+
LL | let z: u32 = y.try_into().unwrap();
12+
| ++++++++++++++++++++
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0308`.
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 will change its meaning in a future release!
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 will change its meaning 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+

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

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
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
13-
//~| WARN this was previously accepted by the compiler but is being phased out;
10+
//~^ ERROR `dyn B` implements `Deref` with supertrait `A` as target
11+
//~| WARN this will change its meaning in a future release!
1412

1513
type Target = dyn A;
1614
fn deref(&self) -> &Self::Target {

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
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
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
...
77
LL | type Target = dyn A;
88
| -------------------- target type is set here
99
|
10-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
10+
= warning: this will change its meaning in a future release!
1111
= note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460>
1212
note: the lint level is defined here
1313
--> $DIR/migrate-lint-deny.rs:1:9

0 commit comments

Comments
 (0)