Implement lint for definition site item shadowing too
This commit is contained in:
parent
2189908170
commit
72b4df3772
15 changed files with 296 additions and 25 deletions
|
@ -506,6 +506,12 @@ hir_analysis_specialization_trait = implementing `rustc_specialization_trait` tr
|
||||||
|
|
||||||
hir_analysis_static_specialize = cannot specialize on `'static` lifetime
|
hir_analysis_static_specialize = cannot specialize on `'static` lifetime
|
||||||
|
|
||||||
|
hir_analysis_supertrait_item_multiple_shadowee = items from several supertraits are shadowed: {$traits}
|
||||||
|
|
||||||
|
hir_analysis_supertrait_item_shadowee = item from `{$supertrait}` is shadowed by a subtrait item
|
||||||
|
|
||||||
|
hir_analysis_supertrait_item_shadowing = trait item `{$item}` from `{$subtrait}` shadows identically named item from supertrait
|
||||||
|
|
||||||
hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature
|
hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature
|
||||||
.note = this item must mention the opaque type in its signature in order to be able to register hidden types
|
.note = this item must mention the opaque type in its signature in order to be able to register hidden types
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::{AmbigArg, ItemKind};
|
use rustc_hir::{AmbigArg, ItemKind};
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
|
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
|
||||||
|
use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION;
|
||||||
use rustc_macros::LintDiagnostic;
|
use rustc_macros::LintDiagnostic;
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
|
@ -388,7 +389,12 @@ fn check_trait_item<'tcx>(
|
||||||
hir::TraitItemKind::Type(_bounds, Some(ty)) => (None, ty.span),
|
hir::TraitItemKind::Type(_bounds, Some(ty)) => (None, ty.span),
|
||||||
_ => (None, trait_item.span),
|
_ => (None, trait_item.span),
|
||||||
};
|
};
|
||||||
|
|
||||||
check_dyn_incompatible_self_trait_by_name(tcx, trait_item);
|
check_dyn_incompatible_self_trait_by_name(tcx, trait_item);
|
||||||
|
|
||||||
|
// Check that an item definition in a subtrait is shadowing a supertrait item.
|
||||||
|
lint_item_shadowing_supertrait_item(tcx, def_id);
|
||||||
|
|
||||||
let mut res = check_associated_item(tcx, def_id, span, method_sig);
|
let mut res = check_associated_item(tcx, def_id, span, method_sig);
|
||||||
|
|
||||||
if matches!(trait_item.kind, hir::TraitItemKind::Fn(..)) {
|
if matches!(trait_item.kind, hir::TraitItemKind::Fn(..)) {
|
||||||
|
@ -898,6 +904,45 @@ fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lint_item_shadowing_supertrait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_def_id: LocalDefId) {
|
||||||
|
let item_name = tcx.item_name(trait_item_def_id.to_def_id());
|
||||||
|
let trait_def_id = tcx.local_parent(trait_item_def_id);
|
||||||
|
|
||||||
|
let shadowed: Vec<_> = traits::supertrait_def_ids(tcx, trait_def_id.to_def_id())
|
||||||
|
.skip(1)
|
||||||
|
.flat_map(|supertrait_def_id| {
|
||||||
|
tcx.associated_items(supertrait_def_id).filter_by_name_unhygienic(item_name)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
if !shadowed.is_empty() {
|
||||||
|
let shadowee = if let [shadowed] = shadowed[..] {
|
||||||
|
errors::SupertraitItemShadowee::Labeled {
|
||||||
|
span: tcx.def_span(shadowed.def_id),
|
||||||
|
supertrait: tcx.item_name(shadowed.trait_container(tcx).unwrap()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let (traits, spans): (Vec<_>, Vec<_>) = shadowed
|
||||||
|
.iter()
|
||||||
|
.map(|item| {
|
||||||
|
(tcx.item_name(item.trait_container(tcx).unwrap()), tcx.def_span(item.def_id))
|
||||||
|
})
|
||||||
|
.unzip();
|
||||||
|
errors::SupertraitItemShadowee::Several { traits: traits.into(), spans: spans.into() }
|
||||||
|
};
|
||||||
|
|
||||||
|
tcx.emit_node_span_lint(
|
||||||
|
SUPERTRAIT_ITEM_SHADOWING_DEFINITION,
|
||||||
|
tcx.local_def_id_to_hir_id(trait_item_def_id),
|
||||||
|
tcx.def_span(trait_item_def_id),
|
||||||
|
errors::SupertraitItemShadowing {
|
||||||
|
item: item_name,
|
||||||
|
subtrait: tcx.item_name(trait_def_id.to_def_id()),
|
||||||
|
shadowee,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn check_impl_item<'tcx>(
|
fn check_impl_item<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl_item: &'tcx hir::ImplItem<'tcx>,
|
impl_item: &'tcx hir::ImplItem<'tcx>,
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
use rustc_abi::ExternAbi;
|
use rustc_abi::ExternAbi;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan,
|
Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level,
|
||||||
|
MultiSpan,
|
||||||
};
|
};
|
||||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
|
@ -1733,3 +1734,28 @@ pub(crate) struct RegisterTypeUnstable<'a> {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub ty: Ty<'a>,
|
pub ty: Ty<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(hir_analysis_supertrait_item_shadowing)]
|
||||||
|
pub(crate) struct SupertraitItemShadowing {
|
||||||
|
pub item: Symbol,
|
||||||
|
pub subtrait: Symbol,
|
||||||
|
#[subdiagnostic]
|
||||||
|
pub shadowee: SupertraitItemShadowee,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
pub(crate) enum SupertraitItemShadowee {
|
||||||
|
#[note(hir_analysis_supertrait_item_shadowee)]
|
||||||
|
Labeled {
|
||||||
|
#[primary_span]
|
||||||
|
span: Span,
|
||||||
|
supertrait: Symbol,
|
||||||
|
},
|
||||||
|
#[note(hir_analysis_supertrait_item_multiple_shadowee)]
|
||||||
|
Several {
|
||||||
|
#[primary_span]
|
||||||
|
spans: MultiSpan,
|
||||||
|
traits: DiagSymbolList,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
@ -143,9 +143,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
let method_sig = ty::Binder::dummy(method_sig);
|
let method_sig = ty::Binder::dummy(method_sig);
|
||||||
|
|
||||||
// Make sure nobody calls `drop()` explicitly.
|
// Make sure nobody calls `drop()` explicitly.
|
||||||
self.enforce_illegal_method_limitations(pick);
|
self.check_for_illegal_method_calls(pick);
|
||||||
|
|
||||||
self.enforce_shadowed_supertrait_items(pick, segment);
|
// Lint when an item is shadowing a supertrait item.
|
||||||
|
self.lint_shadowed_supertrait_items(pick, segment);
|
||||||
|
|
||||||
// Add any trait/regions obligations specified on the method's type parameters.
|
// Add any trait/regions obligations specified on the method's type parameters.
|
||||||
// We won't add these if we encountered an illegal sized bound, so that we can use
|
// We won't add these if we encountered an illegal sized bound, so that we can use
|
||||||
|
@ -660,7 +661,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>) {
|
fn check_for_illegal_method_calls(&self, pick: &probe::Pick<'_>) {
|
||||||
// Disallow calls to the method `drop` defined in the `Drop` trait.
|
// Disallow calls to the method `drop` defined in the `Drop` trait.
|
||||||
if let Some(trait_def_id) = pick.item.trait_container(self.tcx) {
|
if let Some(trait_def_id) = pick.item.trait_container(self.tcx) {
|
||||||
if let Err(e) = callee::check_legal_trait_for_method_call(
|
if let Err(e) = callee::check_legal_trait_for_method_call(
|
||||||
|
@ -676,7 +677,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enforce_shadowed_supertrait_items(
|
fn lint_shadowed_supertrait_items(
|
||||||
&self,
|
&self,
|
||||||
pick: &probe::Pick<'_>,
|
pick: &probe::Pick<'_>,
|
||||||
segment: &hir::PathSegment<'tcx>,
|
segment: &hir::PathSegment<'tcx>,
|
||||||
|
|
|
@ -101,6 +101,7 @@ declare_lint_pass! {
|
||||||
SINGLE_USE_LIFETIMES,
|
SINGLE_USE_LIFETIMES,
|
||||||
SOFT_UNSTABLE,
|
SOFT_UNSTABLE,
|
||||||
STABLE_FEATURES,
|
STABLE_FEATURES,
|
||||||
|
SUPERTRAIT_ITEM_SHADOWING_DEFINITION,
|
||||||
SUPERTRAIT_ITEM_SHADOWING_USAGE,
|
SUPERTRAIT_ITEM_SHADOWING_USAGE,
|
||||||
TAIL_EXPR_DROP_ORDER,
|
TAIL_EXPR_DROP_ORDER,
|
||||||
TEST_UNSTABLE_LINT,
|
TEST_UNSTABLE_LINT,
|
||||||
|
@ -4924,7 +4925,7 @@ declare_lint! {
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust,compile_fail
|
||||||
/// #![feature(supertrait_item_shadowing)]
|
/// #![feature(supertrait_item_shadowing)]
|
||||||
/// #![deny(supertrait_item_shadowing_usage)]
|
/// #![deny(supertrait_item_shadowing_usage)]
|
||||||
///
|
///
|
||||||
|
@ -4959,6 +4960,45 @@ declare_lint! {
|
||||||
@feature_gate = supertrait_item_shadowing;
|
@feature_gate = supertrait_item_shadowing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `supertrait_item_shadowing_definition` lint detects when the
|
||||||
|
/// definition of an item that is provided by both a subtrait and
|
||||||
|
/// supertrait is shadowed, preferring the subtrait.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust,compile_fail
|
||||||
|
/// #![feature(supertrait_item_shadowing)]
|
||||||
|
/// #![deny(supertrait_item_shadowing_definition)]
|
||||||
|
///
|
||||||
|
/// trait Upstream {
|
||||||
|
/// fn hello(&self) {}
|
||||||
|
/// }
|
||||||
|
/// impl<T> Upstream for T {}
|
||||||
|
///
|
||||||
|
/// trait Downstream: Upstream {
|
||||||
|
/// fn hello(&self) {}
|
||||||
|
/// }
|
||||||
|
/// impl<T> Downstream for T {}
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// {{produces}}
|
||||||
|
///
|
||||||
|
/// ### Explanation
|
||||||
|
///
|
||||||
|
/// RFC 3624 specified a heuristic in which a supertrait item would be
|
||||||
|
/// shadowed by a subtrait item when ambiguity occurs during item
|
||||||
|
/// selection. In order to mitigate side-effects of this happening
|
||||||
|
/// silently, this lint detects these cases when users want to deny them
|
||||||
|
/// or fix their trait definitions.
|
||||||
|
pub SUPERTRAIT_ITEM_SHADOWING_DEFINITION,
|
||||||
|
// FIXME(supertrait_item_shadowing): It is not decided if this should
|
||||||
|
// warn by default at the usage site.
|
||||||
|
Allow,
|
||||||
|
"detects when a supertrait item is shadowed by a subtrait item",
|
||||||
|
@feature_gate = supertrait_item_shadowing;
|
||||||
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `ptr_to_integer_transmute_in_consts` lint detects pointer to integer
|
/// The `ptr_to_integer_transmute_in_consts` lint detects pointer to integer
|
||||||
/// transmute in const functions and associated constants.
|
/// transmute in const functions and associated constants.
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#![feature(supertrait_item_shadowing)]
|
#![feature(supertrait_item_shadowing)]
|
||||||
#![warn(supertrait_item_shadowing_usage)]
|
#![warn(supertrait_item_shadowing_usage)]
|
||||||
|
#![warn(supertrait_item_shadowing_definition)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
trait A {
|
trait A {
|
||||||
|
@ -21,6 +22,7 @@ impl<T> B for T {}
|
||||||
|
|
||||||
trait C: A + B {
|
trait C: A + B {
|
||||||
fn hello(&self) {
|
fn hello(&self) {
|
||||||
|
//~^ WARN trait item `hello` from `C` shadows identically named item
|
||||||
println!("C");
|
println!("C");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,36 @@
|
||||||
warning: trait item `hello` from `C` shadows identically named item from supertrait
|
warning: trait item `hello` from `C` shadows identically named item from supertrait
|
||||||
--> $DIR/common-ancestor-2.rs:30:8
|
--> $DIR/common-ancestor-2.rs:24:5
|
||||||
|
|
|
||||||
|
LL | fn hello(&self) {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: items from several supertraits are shadowed: `B` and `A`
|
||||||
|
--> $DIR/common-ancestor-2.rs:10:5
|
||||||
|
|
|
||||||
|
LL | fn hello(&self) {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | fn hello(&self) {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/common-ancestor-2.rs:6:9
|
||||||
|
|
|
||||||
|
LL | #![warn(supertrait_item_shadowing_definition)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
warning: trait item `hello` from `C` shadows identically named item from supertrait
|
||||||
|
--> $DIR/common-ancestor-2.rs:32:8
|
||||||
|
|
|
|
||||||
LL | ().hello();
|
LL | ().hello();
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
note: item from `C` shadows a supertrait item
|
note: item from `C` shadows a supertrait item
|
||||||
--> $DIR/common-ancestor-2.rs:23:5
|
--> $DIR/common-ancestor-2.rs:24:5
|
||||||
|
|
|
|
||||||
LL | fn hello(&self) {
|
LL | fn hello(&self) {
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
note: items from several supertraits are shadowed: `A` and `B`
|
note: items from several supertraits are shadowed: `A` and `B`
|
||||||
--> $DIR/common-ancestor-2.rs:9:5
|
--> $DIR/common-ancestor-2.rs:10:5
|
||||||
|
|
|
|
||||||
LL | fn hello(&self) {
|
LL | fn hello(&self) {
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
@ -23,5 +43,5 @@ note: the lint level is defined here
|
||||||
LL | #![warn(supertrait_item_shadowing_usage)]
|
LL | #![warn(supertrait_item_shadowing_usage)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: 1 warning emitted
|
warning: 2 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#![feature(supertrait_item_shadowing)]
|
#![feature(supertrait_item_shadowing)]
|
||||||
#![warn(supertrait_item_shadowing_usage)]
|
#![warn(supertrait_item_shadowing_usage)]
|
||||||
|
#![warn(supertrait_item_shadowing_definition)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
trait A {
|
trait A {
|
||||||
|
@ -21,6 +22,7 @@ impl<T> B for T {}
|
||||||
|
|
||||||
trait C: A + B {
|
trait C: A + B {
|
||||||
fn hello(&self) {
|
fn hello(&self) {
|
||||||
|
//~^ WARN trait item `hello` from `C` shadows identically named item
|
||||||
println!("C");
|
println!("C");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +32,7 @@ impl<T> C for T {}
|
||||||
|
|
||||||
trait D: C {
|
trait D: C {
|
||||||
fn hello(&self) {
|
fn hello(&self) {
|
||||||
|
//~^ WARN trait item `hello` from `D` shadows identically named item
|
||||||
println!("D");
|
println!("D");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,54 @@
|
||||||
|
warning: trait item `hello` from `C` shadows identically named item from supertrait
|
||||||
|
--> $DIR/common-ancestor-3.rs:24:5
|
||||||
|
|
|
||||||
|
LL | fn hello(&self) {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: items from several supertraits are shadowed: `B` and `A`
|
||||||
|
--> $DIR/common-ancestor-3.rs:10:5
|
||||||
|
|
|
||||||
|
LL | fn hello(&self) {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | fn hello(&self) {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/common-ancestor-3.rs:6:9
|
||||||
|
|
|
||||||
|
LL | #![warn(supertrait_item_shadowing_definition)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: trait item `hello` from `D` shadows identically named item from supertrait
|
warning: trait item `hello` from `D` shadows identically named item from supertrait
|
||||||
--> $DIR/common-ancestor-3.rs:39:8
|
--> $DIR/common-ancestor-3.rs:34:5
|
||||||
|
|
|
||||||
|
LL | fn hello(&self) {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: items from several supertraits are shadowed: `C`, `B`, and `A`
|
||||||
|
--> $DIR/common-ancestor-3.rs:10:5
|
||||||
|
|
|
||||||
|
LL | fn hello(&self) {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | fn hello(&self) {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | fn hello(&self) {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
warning: trait item `hello` from `D` shadows identically named item from supertrait
|
||||||
|
--> $DIR/common-ancestor-3.rs:42:8
|
||||||
|
|
|
|
||||||
LL | ().hello();
|
LL | ().hello();
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
note: item from `D` shadows a supertrait item
|
note: item from `D` shadows a supertrait item
|
||||||
--> $DIR/common-ancestor-3.rs:32:5
|
--> $DIR/common-ancestor-3.rs:34:5
|
||||||
|
|
|
|
||||||
LL | fn hello(&self) {
|
LL | fn hello(&self) {
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
note: items from several supertraits are shadowed: `A`, `B`, and `C`
|
note: items from several supertraits are shadowed: `A`, `B`, and `C`
|
||||||
--> $DIR/common-ancestor-3.rs:9:5
|
--> $DIR/common-ancestor-3.rs:10:5
|
||||||
|
|
|
|
||||||
LL | fn hello(&self) {
|
LL | fn hello(&self) {
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
@ -26,5 +64,5 @@ note: the lint level is defined here
|
||||||
LL | #![warn(supertrait_item_shadowing_usage)]
|
LL | #![warn(supertrait_item_shadowing_usage)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: 1 warning emitted
|
warning: 3 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#![feature(supertrait_item_shadowing)]
|
#![feature(supertrait_item_shadowing)]
|
||||||
#![warn(supertrait_item_shadowing_usage)]
|
#![warn(supertrait_item_shadowing_usage)]
|
||||||
|
#![warn(supertrait_item_shadowing_definition)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
trait A {
|
trait A {
|
||||||
|
@ -14,6 +15,7 @@ impl<T> A for T {}
|
||||||
|
|
||||||
trait B: A {
|
trait B: A {
|
||||||
fn hello(&self) {
|
fn hello(&self) {
|
||||||
|
//~^ WARN trait item `hello` from `B` shadows identically named item
|
||||||
println!("B");
|
println!("B");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,33 @@
|
||||||
warning: trait item `hello` from `B` shadows identically named item from supertrait
|
warning: trait item `hello` from `B` shadows identically named item from supertrait
|
||||||
--> $DIR/common-ancestor.rs:23:8
|
--> $DIR/common-ancestor.rs:17:5
|
||||||
|
|
|
||||||
|
LL | fn hello(&self) {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: item from `A` is shadowed by a subtrait item
|
||||||
|
--> $DIR/common-ancestor.rs:10:5
|
||||||
|
|
|
||||||
|
LL | fn hello(&self) {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/common-ancestor.rs:6:9
|
||||||
|
|
|
||||||
|
LL | #![warn(supertrait_item_shadowing_definition)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
warning: trait item `hello` from `B` shadows identically named item from supertrait
|
||||||
|
--> $DIR/common-ancestor.rs:25:8
|
||||||
|
|
|
|
||||||
LL | ().hello();
|
LL | ().hello();
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
note: item from `B` shadows a supertrait item
|
note: item from `B` shadows a supertrait item
|
||||||
--> $DIR/common-ancestor.rs:16:5
|
--> $DIR/common-ancestor.rs:17:5
|
||||||
|
|
|
|
||||||
LL | fn hello(&self) {
|
LL | fn hello(&self) {
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
note: item from `A` is shadowed by a subtrait item
|
note: item from `A` is shadowed by a subtrait item
|
||||||
--> $DIR/common-ancestor.rs:9:5
|
--> $DIR/common-ancestor.rs:10:5
|
||||||
|
|
|
|
||||||
LL | fn hello(&self) {
|
LL | fn hello(&self) {
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
@ -20,5 +37,5 @@ note: the lint level is defined here
|
||||||
LL | #![warn(supertrait_item_shadowing_usage)]
|
LL | #![warn(supertrait_item_shadowing_usage)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: 1 warning emitted
|
warning: 2 warnings emitted
|
||||||
|
|
||||||
|
|
18
tests/ui/methods/supertrait-shadowing/definition-site.rs
Normal file
18
tests/ui/methods/supertrait-shadowing/definition-site.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#![feature(supertrait_item_shadowing)]
|
||||||
|
#![deny(supertrait_item_shadowing_definition)]
|
||||||
|
|
||||||
|
trait SuperSuper {
|
||||||
|
fn method();
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Super: SuperSuper {
|
||||||
|
fn method();
|
||||||
|
//~^ ERROR trait item `method` from `Super` shadows identically named item
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Sub: Super {
|
||||||
|
fn method();
|
||||||
|
//~^ ERROR trait item `method` from `Sub` shadows identically named item
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
34
tests/ui/methods/supertrait-shadowing/definition-site.stderr
Normal file
34
tests/ui/methods/supertrait-shadowing/definition-site.stderr
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
error: trait item `method` from `Super` shadows identically named item from supertrait
|
||||||
|
--> $DIR/definition-site.rs:9:5
|
||||||
|
|
|
||||||
|
LL | fn method();
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: item from `SuperSuper` is shadowed by a subtrait item
|
||||||
|
--> $DIR/definition-site.rs:5:5
|
||||||
|
|
|
||||||
|
LL | fn method();
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/definition-site.rs:2:9
|
||||||
|
|
|
||||||
|
LL | #![deny(supertrait_item_shadowing_definition)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: trait item `method` from `Sub` shadows identically named item from supertrait
|
||||||
|
--> $DIR/definition-site.rs:14:5
|
||||||
|
|
|
||||||
|
LL | fn method();
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: items from several supertraits are shadowed: `Super` and `SuperSuper`
|
||||||
|
--> $DIR/definition-site.rs:5:5
|
||||||
|
|
|
||||||
|
LL | fn method();
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | fn method();
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#![feature(supertrait_item_shadowing)]
|
#![feature(supertrait_item_shadowing)]
|
||||||
#![warn(supertrait_item_shadowing_usage)]
|
#![warn(supertrait_item_shadowing_usage)]
|
||||||
|
#![warn(supertrait_item_shadowing_definition)]
|
||||||
|
|
||||||
struct W<T>(T);
|
struct W<T>(T);
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ impl<T> Upstream for T {}
|
||||||
|
|
||||||
trait Downstream: Upstream {
|
trait Downstream: Upstream {
|
||||||
fn hello(&self) {}
|
fn hello(&self) {}
|
||||||
|
//~^ WARN trait item `hello` from `Downstream` shadows identically named item
|
||||||
}
|
}
|
||||||
impl<T> Downstream for W<T> where T: Foo {}
|
impl<T> Downstream for W<T> where T: Foo {}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,33 @@
|
||||||
warning: trait item `hello` from `Downstream` shadows identically named item from supertrait
|
warning: trait item `hello` from `Downstream` shadows identically named item from supertrait
|
||||||
--> $DIR/false-subtrait-after-inference.rs:20:7
|
--> $DIR/false-subtrait-after-inference.rs:13:5
|
||||||
|
|
|
||||||
|
LL | fn hello(&self) {}
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: item from `Upstream` is shadowed by a subtrait item
|
||||||
|
--> $DIR/false-subtrait-after-inference.rs:8:5
|
||||||
|
|
|
||||||
|
LL | fn hello(&self) {}
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/false-subtrait-after-inference.rs:3:9
|
||||||
|
|
|
||||||
|
LL | #![warn(supertrait_item_shadowing_definition)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
warning: trait item `hello` from `Downstream` shadows identically named item from supertrait
|
||||||
|
--> $DIR/false-subtrait-after-inference.rs:22:7
|
||||||
|
|
|
|
||||||
LL | x.hello();
|
LL | x.hello();
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
note: item from `Downstream` shadows a supertrait item
|
note: item from `Downstream` shadows a supertrait item
|
||||||
--> $DIR/false-subtrait-after-inference.rs:12:5
|
--> $DIR/false-subtrait-after-inference.rs:13:5
|
||||||
|
|
|
|
||||||
LL | fn hello(&self) {}
|
LL | fn hello(&self) {}
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
note: item from `Upstream` is shadowed by a subtrait item
|
note: item from `Upstream` is shadowed by a subtrait item
|
||||||
--> $DIR/false-subtrait-after-inference.rs:7:5
|
--> $DIR/false-subtrait-after-inference.rs:8:5
|
||||||
|
|
|
|
||||||
LL | fn hello(&self) {}
|
LL | fn hello(&self) {}
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
@ -21,22 +38,22 @@ LL | #![warn(supertrait_item_shadowing_usage)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0277]: the trait bound `i32: Foo` is not satisfied
|
error[E0277]: the trait bound `i32: Foo` is not satisfied
|
||||||
--> $DIR/false-subtrait-after-inference.rs:20:7
|
--> $DIR/false-subtrait-after-inference.rs:22:7
|
||||||
|
|
|
|
||||||
LL | x.hello();
|
LL | x.hello();
|
||||||
| ^^^^^ the trait `Foo` is not implemented for `i32`
|
| ^^^^^ the trait `Foo` is not implemented for `i32`
|
||||||
|
|
|
|
||||||
help: this trait has no implementations, consider adding one
|
help: this trait has no implementations, consider adding one
|
||||||
--> $DIR/false-subtrait-after-inference.rs:16:1
|
--> $DIR/false-subtrait-after-inference.rs:18:1
|
||||||
|
|
|
|
||||||
LL | trait Foo {}
|
LL | trait Foo {}
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
note: required for `W<i32>` to implement `Downstream`
|
note: required for `W<i32>` to implement `Downstream`
|
||||||
--> $DIR/false-subtrait-after-inference.rs:14:9
|
--> $DIR/false-subtrait-after-inference.rs:16:9
|
||||||
|
|
|
|
||||||
LL | impl<T> Downstream for W<T> where T: Foo {}
|
LL | impl<T> Downstream for W<T> where T: Foo {}
|
||||||
| ^^^^^^^^^^ ^^^^ --- unsatisfied trait bound introduced here
|
| ^^^^^^^^^^ ^^^^ --- unsatisfied trait bound introduced here
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error: aborting due to 1 previous error; 2 warnings emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue