Impls and impl items inherit lint levels of the corresponding traits and trait items
This commit is contained in:
parent
23d01cd241
commit
12474ce192
4 changed files with 110 additions and 0 deletions
|
|
@ -778,6 +778,15 @@ fn maybe_record_as_seed<'tcx>(
|
|||
match tcx.def_kind(parent) {
|
||||
DefKind::Impl { of_trait: false } | DefKind::Trait => {}
|
||||
DefKind::Impl { of_trait: true } => {
|
||||
if let Some(trait_item_def_id) =
|
||||
tcx.associated_item(owner_id.def_id).trait_item_def_id()
|
||||
&& let Some(trait_item_local_def_id) = trait_item_def_id.as_local()
|
||||
&& let Some(comes_from_allow) =
|
||||
has_allow_dead_code_or_lang_attr(tcx, trait_item_local_def_id)
|
||||
{
|
||||
worklist.push((owner_id.def_id, comes_from_allow));
|
||||
}
|
||||
|
||||
// We only care about associated items of traits,
|
||||
// because they cannot be visited directly,
|
||||
// so we later mark them as live if their corresponding traits
|
||||
|
|
@ -791,6 +800,14 @@ fn maybe_record_as_seed<'tcx>(
|
|||
}
|
||||
DefKind::Impl { of_trait: true } => {
|
||||
if allow_dead_code.is_none() {
|
||||
if let Some(trait_def_id) =
|
||||
tcx.impl_trait_ref(owner_id.def_id).skip_binder().def_id.as_local()
|
||||
&& let Some(comes_from_allow) =
|
||||
has_allow_dead_code_or_lang_attr(tcx, trait_def_id)
|
||||
{
|
||||
worklist.push((owner_id.def_id, comes_from_allow));
|
||||
}
|
||||
|
||||
unsolved_items.push(owner_id.def_id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
38
tests/ui/lint/dead-code/allow-trait-or-impl.rs
Normal file
38
tests/ui/lint/dead-code/allow-trait-or-impl.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#![deny(dead_code)]
|
||||
|
||||
pub mod a {
|
||||
pub trait Foo { }
|
||||
impl Foo for u32 { }
|
||||
|
||||
struct PrivateType; //~ ERROR struct `PrivateType` is never constructed
|
||||
impl Foo for PrivateType { } // <-- warns as dead, even though Foo is public
|
||||
|
||||
struct AnotherPrivateType; //~ ERROR struct `AnotherPrivateType` is never constructed
|
||||
impl Foo for AnotherPrivateType { } // <-- warns as dead, even though Foo is public
|
||||
}
|
||||
|
||||
pub mod b {
|
||||
#[allow(dead_code)]
|
||||
pub trait Foo { }
|
||||
impl Foo for u32 { }
|
||||
|
||||
struct PrivateType;
|
||||
impl Foo for PrivateType { } // <-- no warning, trait is "allowed"
|
||||
|
||||
struct AnotherPrivateType;
|
||||
impl Foo for AnotherPrivateType { } // <-- no warning, trait is "allowed"
|
||||
}
|
||||
|
||||
pub mod c {
|
||||
pub trait Foo { }
|
||||
impl Foo for u32 { }
|
||||
|
||||
struct PrivateType;
|
||||
#[allow(dead_code)]
|
||||
impl Foo for PrivateType { } // <-- no warning, impl is allowed
|
||||
|
||||
struct AnotherPrivateType; //~ ERROR struct `AnotherPrivateType` is never constructed
|
||||
impl Foo for AnotherPrivateType { } // <-- warns as dead, even though Foo is public
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
26
tests/ui/lint/dead-code/allow-trait-or-impl.stderr
Normal file
26
tests/ui/lint/dead-code/allow-trait-or-impl.stderr
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
error: struct `PrivateType` is never constructed
|
||||
--> $DIR/allow-trait-or-impl.rs:7:12
|
||||
|
|
||||
LL | struct PrivateType;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/allow-trait-or-impl.rs:1:9
|
||||
|
|
||||
LL | #![deny(dead_code)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: struct `AnotherPrivateType` is never constructed
|
||||
--> $DIR/allow-trait-or-impl.rs:10:12
|
||||
|
|
||||
LL | struct AnotherPrivateType;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: struct `AnotherPrivateType` is never constructed
|
||||
--> $DIR/allow-trait-or-impl.rs:34:12
|
||||
|
|
||||
LL | struct AnotherPrivateType;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
29
tests/ui/lint/dead-code/allow-unused-trait.rs
Normal file
29
tests/ui/lint/dead-code/allow-unused-trait.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
//@ check-pass
|
||||
|
||||
#![deny(dead_code)]
|
||||
|
||||
#[allow(dead_code)]
|
||||
trait Foo {
|
||||
const FOO: u32;
|
||||
type Baz;
|
||||
fn foobar();
|
||||
}
|
||||
|
||||
const fn bar(x: u32) -> u32 {
|
||||
x
|
||||
}
|
||||
|
||||
struct Qux;
|
||||
|
||||
struct FooBar;
|
||||
|
||||
impl Foo for u32 {
|
||||
const FOO: u32 = bar(0);
|
||||
type Baz = Qux;
|
||||
|
||||
fn foobar() {
|
||||
let _ = FooBar;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue