Auto merge of #82868 - petrochenkov:bto, r=estebank
Report missing cases of `bare_trait_objects` Fixes https://github.com/rust-lang/rust/issues/65371
This commit is contained in:
commit
2aafe452b8
39 changed files with 192 additions and 93 deletions
|
|
@ -1477,7 +1477,7 @@ impl Clean<Type> for hir::Ty<'_> {
|
|||
}
|
||||
}
|
||||
TyKind::Path(_) => clean_qpath(&self, cx),
|
||||
TyKind::TraitObject(ref bounds, ref lifetime) => {
|
||||
TyKind::TraitObject(ref bounds, ref lifetime, _) => {
|
||||
match bounds[0].clean(cx).trait_ {
|
||||
ResolvedPath { path, param_names: None, did, is_generic } => {
|
||||
let mut bounds: Vec<self::GenericBound> = bounds[1..]
|
||||
|
|
|
|||
18
src/test/ui/lint/bare-trait-objects-path.rs
Normal file
18
src/test/ui/lint/bare-trait-objects-path.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#![feature(associated_type_defaults)]
|
||||
|
||||
trait Assoc {
|
||||
fn func() {}
|
||||
const CONST: u8 = 0;
|
||||
type Ty = u8;
|
||||
}
|
||||
|
||||
trait Dyn {}
|
||||
|
||||
impl Assoc for dyn Dyn {}
|
||||
|
||||
fn main() {
|
||||
Dyn::func(); //~ WARN trait objects without an explicit `dyn` are deprecated
|
||||
::Dyn::func(); //~ WARN trait objects without an explicit `dyn` are deprecated
|
||||
Dyn::CONST; //~ WARN trait objects without an explicit `dyn` are deprecated
|
||||
let _: Dyn::Ty; //~ ERROR ambiguous associated type
|
||||
}
|
||||
29
src/test/ui/lint/bare-trait-objects-path.stderr
Normal file
29
src/test/ui/lint/bare-trait-objects-path.stderr
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
error[E0223]: ambiguous associated type
|
||||
--> $DIR/bare-trait-objects-path.rs:17:12
|
||||
|
|
||||
LL | let _: Dyn::Ty;
|
||||
| ^^^^^^^ help: use fully-qualified syntax: `<dyn Dyn as Trait>::Ty`
|
||||
|
||||
warning: trait objects without an explicit `dyn` are deprecated
|
||||
--> $DIR/bare-trait-objects-path.rs:14:5
|
||||
|
|
||||
LL | Dyn::func();
|
||||
| ^^^ help: use `dyn`: `<dyn Dyn>`
|
||||
|
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
|
||||
warning: trait objects without an explicit `dyn` are deprecated
|
||||
--> $DIR/bare-trait-objects-path.rs:15:5
|
||||
|
|
||||
LL | ::Dyn::func();
|
||||
| ^^^^^ help: use `dyn`: `<dyn (::Dyn)>`
|
||||
|
||||
warning: trait objects without an explicit `dyn` are deprecated
|
||||
--> $DIR/bare-trait-objects-path.rs:16:5
|
||||
|
|
||||
LL | Dyn::CONST;
|
||||
| ^^^ help: use `dyn`: `<dyn Dyn>`
|
||||
|
||||
error: aborting due to previous error; 3 warnings emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0223`.
|
||||
|
|
@ -30,8 +30,8 @@ fn main() {
|
|||
let x: &dyn T = &42;
|
||||
|
||||
x.foo();
|
||||
T::foo(x);
|
||||
T::bar();
|
||||
<dyn T>::foo(x);
|
||||
<dyn T>::bar();
|
||||
|
||||
unsafe { assert_eq!(COUNT, 12); }
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ fn with_trait<C:CompareToInts>(c: &C) -> bool {
|
|||
}
|
||||
|
||||
fn with_ufcs1<C:CompareToInts>(c: &C) -> bool {
|
||||
CompareToInts::same_as(c, 22) //~ ERROR `dyn CompareToInts: CompareTo<i32>` is not satisfied
|
||||
<dyn CompareToInts>::same_as(c, 22) //~ ERROR `dyn CompareToInts: CompareTo<i32>` is not satisfi
|
||||
}
|
||||
|
||||
fn with_ufcs2<C:CompareToInts>(c: &C) -> bool {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ error[E0277]: the trait bound `dyn CompareToInts: CompareTo<i32>` is not satisfi
|
|||
LL | fn same_as(&self, t: T) -> bool;
|
||||
| -------------------------------- required by `CompareTo::same_as`
|
||||
...
|
||||
LL | CompareToInts::same_as(c, 22)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `dyn CompareToInts`
|
||||
LL | <dyn CompareToInts>::same_as(c, 22)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `dyn CompareToInts`
|
||||
|
||||
error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied
|
||||
--> $DIR/repeated-supertrait-ambig.rs:38:5
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ fn with_trait<C:CompareToInts>(c: &C) -> bool {
|
|||
}
|
||||
|
||||
fn with_ufcs1<C:CompareToInts>(c: &C) -> bool {
|
||||
CompareToInts::same_as(c, 22_i64) && CompareToInts::same_as(c, 22_u64)
|
||||
<dyn CompareToInts>::same_as(c, 22_i64) && <dyn CompareToInts>::same_as(c, 22_u64)
|
||||
}
|
||||
|
||||
fn with_ufcs2<C:CompareToInts>(c: &C) -> bool {
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ fn check_method() {
|
|||
//~^ ERROR no function or associated item named `b` found
|
||||
S::c(&S); // OK
|
||||
// a, b, c are resolved as inherent items, their traits don't need to be in scope
|
||||
C::a(&S); //~ ERROR associated function `a` is private
|
||||
C::b(&S); // OK
|
||||
<dyn C>::a(&S); //~ ERROR associated function `a` is private
|
||||
<dyn C>::b(&S); // OK
|
||||
C::c(&S); // OK
|
||||
}
|
||||
|
||||
|
|
@ -98,9 +98,9 @@ fn check_assoc_const() {
|
|||
S::B; //~ ERROR no associated item named `B` found
|
||||
S::C; // OK
|
||||
// A, B, C are resolved as inherent items, their traits don't need to be in scope
|
||||
C::A; //~ ERROR associated constant `A` is private
|
||||
//~^ ERROR the trait `assoc_const::C` cannot be made into an object
|
||||
C::B; // ERROR the trait `assoc_const::C` cannot be made into an object
|
||||
<dyn C>::A; //~ ERROR associated constant `A` is private
|
||||
//~^ ERROR the trait `assoc_const::C` cannot be made into an object
|
||||
<dyn C>::B; // ERROR the trait `assoc_const::C` cannot be made into an object
|
||||
C::C; // OK
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,10 +67,10 @@ LL | use method::B;
|
|||
|
|
||||
|
||||
error[E0624]: associated function `a` is private
|
||||
--> $DIR/item-privacy.rs:84:8
|
||||
--> $DIR/item-privacy.rs:84:14
|
||||
|
|
||||
LL | C::a(&S);
|
||||
| ^ private associated function
|
||||
LL | <dyn C>::a(&S);
|
||||
| ^ private associated function
|
||||
|
||||
error[E0599]: no associated item named `A` found for struct `S` in the current scope
|
||||
--> $DIR/item-privacy.rs:97:8
|
||||
|
|
@ -104,16 +104,16 @@ LL | use assoc_const::B;
|
|||
|
|
||||
|
||||
error[E0624]: associated constant `A` is private
|
||||
--> $DIR/item-privacy.rs:101:8
|
||||
--> $DIR/item-privacy.rs:101:14
|
||||
|
|
||||
LL | C::A;
|
||||
| ^ private associated constant
|
||||
LL | <dyn C>::A;
|
||||
| ^ private associated constant
|
||||
|
||||
error[E0038]: the trait `assoc_const::C` cannot be made into an object
|
||||
--> $DIR/item-privacy.rs:101:5
|
||||
--> $DIR/item-privacy.rs:101:6
|
||||
|
|
||||
LL | C::A;
|
||||
| ^ `assoc_const::C` cannot be made into an object
|
||||
LL | <dyn C>::A;
|
||||
| ^^^^^ `assoc_const::C` cannot be made into an object
|
||||
|
|
||||
= help: consider moving `C` to another trait
|
||||
= help: consider moving `B` to another trait
|
||||
|
|
|
|||
|
|
@ -387,7 +387,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
|
|||
self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());
|
||||
return;
|
||||
},
|
||||
TyKind::TraitObject(bounds, ref lt) => {
|
||||
TyKind::TraitObject(bounds, ref lt, _) => {
|
||||
if !lt.is_elided() {
|
||||
self.unelided_trait_object_lifetime = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
|
|||
// Originally reported as the issue #3128.
|
||||
let inner_snippet = snippet(cx, inner.span, "..");
|
||||
let suggestion = match &inner.kind {
|
||||
TyKind::TraitObject(bounds, lt_bound) if bounds.len() > 1 || !lt_bound.is_elided() => {
|
||||
TyKind::TraitObject(bounds, lt_bound, _) if bounds.len() > 1 || !lt_bound.is_elided() => {
|
||||
format!("&{}({})", ltopt, &inner_snippet)
|
||||
},
|
||||
TyKind::Path(qpath)
|
||||
|
|
@ -86,7 +86,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
|
|||
// Returns true if given type is `Any` trait.
|
||||
fn is_any_trait(t: &hir::Ty<'_>) -> bool {
|
||||
if_chain! {
|
||||
if let TyKind::TraitObject(ref traits, _) = t.kind;
|
||||
if let TyKind::TraitObject(ref traits, ..) = t.kind;
|
||||
if !traits.is_empty();
|
||||
// Only Send/Sync can be used as additional traits, so it is enough to
|
||||
// check only the first trait.
|
||||
|
|
|
|||
|
|
@ -911,7 +911,7 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
|
|||
// function types bring a lot of overhead
|
||||
TyKind::BareFn(ref bare) if bare.abi == Abi::Rust => (50 * self.nest, 1),
|
||||
|
||||
TyKind::TraitObject(ref param_bounds, _) => {
|
||||
TyKind::TraitObject(ref param_bounds, ..) => {
|
||||
let has_lifetime_parameters = param_bounds.iter().any(|bound| {
|
||||
bound
|
||||
.bound_generic_params
|
||||
|
|
|
|||
|
|
@ -892,7 +892,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
TyKind::OpaqueDef(_, arg_list) => {
|
||||
self.hash_generic_args(arg_list);
|
||||
},
|
||||
TyKind::TraitObject(_, lifetime) => {
|
||||
TyKind::TraitObject(_, lifetime, _) => {
|
||||
self.hash_lifetime(lifetime);
|
||||
},
|
||||
TyKind::Typeof(anon_const) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue