mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Don't consider regions in deref_into_dyn_supertrait lint
This commit is contained in:
parent
46ecc10c69
commit
63b34cf480
@ -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 },
|
||||
);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
@ -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`.
|
18
tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs
Normal file
18
tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs
Normal file
@ -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 was previously accepted by the compiler
|
||||
type Target = dyn Bar<'a>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -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 was previously accepted by the compiler but is being phased out; it will become a hard error 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
|
||||
|
@ -1,15 +1,13 @@
|
||||
#![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
|
||||
//~^ ERROR `dyn B` implements `Deref` with supertrait `A` as target
|
||||
//~| WARN this was previously accepted by the compiler but is being phased out;
|
||||
|
||||
type Target = dyn A;
|
||||
|
@ -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 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
Loading…
Reference in New Issue
Block a user