Auto merge of #49799 - hdhoang:46205_deny_incoherent_fundamental_impls, r=nikomatsakis
lint: convert incoherent_fundamental_impls into hard error *Summary for affected authors:* If your crate depends on one of the following crates, please upgrade to a newer version: - gtk-rs: upgrade to at least 0.4 - rusqlite: upgrade to at least 0.14 - nalgebra: upgrade to at least 0.15, or the last patch version of 0.14 - spade: upgrade or refresh the Cargo.lock file to use version 1.7 - imageproc: upgrade to at least 0.16 (newer versions no longer use nalgebra) implement #46205 r? @nikomatsakis
This commit is contained in:
commit
a614cee22e
8 changed files with 34 additions and 113 deletions
|
@ -21,9 +21,9 @@ Here's a list of each lint group, and the lints that they are made up of:
|
||||||
| edition-2018 | Lints that will be turned into errors in Rust 2018 | tyvar-behind-raw-pointer |
|
| edition-2018 | Lints that will be turned into errors in Rust 2018 | tyvar-behind-raw-pointer |
|
||||||
| rust-2018-idioms | Lints to nudge you toward idiomatic features of Rust 2018 | bare-trait-object, unreachable-pub |
|
| rust-2018-idioms | Lints to nudge you toward idiomatic features of Rust 2018 | bare-trait-object, unreachable-pub |
|
||||||
| unused | These lints detect things being declared but not used | unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-allocation, unused-doc-comment, unused-extern-crates, unused-features, unused-parens |
|
| unused | These lints detect things being declared but not used | unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-allocation, unused-doc-comment, unused-extern-crates, unused-features, unused-parens |
|
||||||
| future-incompatible | Lints that detect code that has future-compatibility problems | private-in-public, pub-use-of-private-extern-crate, patterns-in-fns-without-body, safe-extern-statics, invalid-type-param-default, legacy-directory-ownership, legacy-imports, legacy-constructor-visibility, missing-fragment-specifier, illegal-floating-point-literal-pattern, anonymous-parameters, parenthesized-params-in-types-and-modules, late-bound-lifetime-arguments, safe-packed-borrows, incoherent-fundamental-impls, tyvar-behind-raw-pointer, unstable-name-collision |
|
| future-incompatible | Lints that detect code that has future-compatibility problems | private-in-public, pub-use-of-private-extern-crate, patterns-in-fns-without-body, safe-extern-statics, invalid-type-param-default, legacy-directory-ownership, legacy-imports, legacy-constructor-visibility, missing-fragment-specifier, illegal-floating-point-literal-pattern, anonymous-parameters, parenthesized-params-in-types-and-modules, late-bound-lifetime-arguments, safe-packed-borrows, tyvar-behind-raw-pointer, unstable-name-collision |
|
||||||
|
|
||||||
Additionally, there's a `bad-style` lint group that's a deprecated alias for `nonstandard-style`.
|
Additionally, there's a `bad-style` lint group that's a deprecated alias for `nonstandard-style`.
|
||||||
|
|
||||||
Finally, you can also see the table above by invoking `rustc -W help`. This will give you the exact values for the specific
|
Finally, you can also see the table above by invoking `rustc -W help`. This will give you the exact values for the specific
|
||||||
compiler you have installed.
|
compiler you have installed.
|
||||||
|
|
|
@ -222,44 +222,3 @@ error: invalid `crate_type` value
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## incoherent-fundamental-impls
|
|
||||||
|
|
||||||
This lint detects potentially-conflicting impls that were erroneously allowed. Some
|
|
||||||
example code that triggers this lint:
|
|
||||||
|
|
||||||
```rust,ignore
|
|
||||||
pub trait Trait1<X> {
|
|
||||||
type Output;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Trait2<X> {}
|
|
||||||
|
|
||||||
pub struct A;
|
|
||||||
|
|
||||||
impl<X, T> Trait1<X> for T where T: Trait2<X> {
|
|
||||||
type Output = ();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<X> Trait1<Box<X>> for A {
|
|
||||||
type Output = i32;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This will produce:
|
|
||||||
|
|
||||||
```text
|
|
||||||
error: conflicting implementations of trait `Trait1<std::boxed::Box<_>>` for type `A`: (E0119)
|
|
||||||
--> src/main.rs:13:1
|
|
||||||
|
|
|
||||||
9 | impl<X, T> Trait1<X> for T where T: Trait2<X> {
|
|
||||||
| --------------------------------------------- first implementation here
|
|
||||||
...
|
|
||||||
13 | impl<X> Trait1<Box<X>> for A {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A`
|
|
||||||
|
|
|
||||||
= note: #[deny(incoherent_fundamental_impls)] on by default
|
|
||||||
= 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 #46205 <https://github.com/rust-lang/rust/issues/46205>
|
|
||||||
= note: downstream crates may implement trait `Trait2<std::boxed::Box<_>>` for type `A`
|
|
||||||
```
|
|
||||||
|
|
|
@ -198,12 +198,6 @@ declare_lint! {
|
||||||
"detects generic lifetime arguments in path segments with late bound lifetime parameters"
|
"detects generic lifetime arguments in path segments with late bound lifetime parameters"
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
|
||||||
pub INCOHERENT_FUNDAMENTAL_IMPLS,
|
|
||||||
Deny,
|
|
||||||
"potentially-conflicting impls were erroneously allowed"
|
|
||||||
}
|
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub ORDER_DEPENDENT_TRAIT_OBJECTS,
|
pub ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||||
Deny,
|
Deny,
|
||||||
|
@ -428,7 +422,6 @@ declare_lint_pass! {
|
||||||
MISSING_FRAGMENT_SPECIFIER,
|
MISSING_FRAGMENT_SPECIFIER,
|
||||||
PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
|
PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
|
||||||
LATE_BOUND_LIFETIME_ARGUMENTS,
|
LATE_BOUND_LIFETIME_ARGUMENTS,
|
||||||
INCOHERENT_FUNDAMENTAL_IMPLS,
|
|
||||||
ORDER_DEPENDENT_TRAIT_OBJECTS,
|
ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||||
DEPRECATED,
|
DEPRECATED,
|
||||||
UNUSED_UNSAFE,
|
UNUSED_UNSAFE,
|
||||||
|
|
|
@ -319,29 +319,34 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(
|
||||||
String::new(), |ty| {
|
String::new(), |ty| {
|
||||||
format!(" for type `{}`", ty)
|
format!(" for type `{}`", ty)
|
||||||
}),
|
}),
|
||||||
if used_to_be_allowed.is_some() { " (E0119)" } else { "" }
|
match used_to_be_allowed {
|
||||||
|
Some(FutureCompatOverlapErrorKind::Issue33140) => " (E0119)",
|
||||||
|
_ => "",
|
||||||
|
}
|
||||||
);
|
);
|
||||||
let impl_span = tcx.sess.source_map().def_span(
|
let impl_span = tcx.sess.source_map().def_span(
|
||||||
tcx.span_of_impl(impl_def_id).unwrap()
|
tcx.span_of_impl(impl_def_id).unwrap()
|
||||||
);
|
);
|
||||||
let mut err = if let Some(kind) = used_to_be_allowed {
|
let mut err = match used_to_be_allowed {
|
||||||
let lint = match kind {
|
Some(FutureCompatOverlapErrorKind::Issue43355) | None =>
|
||||||
FutureCompatOverlapErrorKind::Issue43355 =>
|
struct_span_err!(tcx.sess,
|
||||||
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
|
impl_span,
|
||||||
FutureCompatOverlapErrorKind::Issue33140 =>
|
E0119,
|
||||||
lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS,
|
"{}",
|
||||||
};
|
msg),
|
||||||
tcx.struct_span_lint_hir(
|
Some(kind) => {
|
||||||
lint,
|
let lint = match kind {
|
||||||
tcx.hir().as_local_hir_id(impl_def_id).unwrap(),
|
FutureCompatOverlapErrorKind::Issue43355 =>
|
||||||
impl_span,
|
unreachable!("converted to hard error above"),
|
||||||
&msg)
|
FutureCompatOverlapErrorKind::Issue33140 =>
|
||||||
} else {
|
lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||||
struct_span_err!(tcx.sess,
|
};
|
||||||
impl_span,
|
tcx.struct_span_lint_hir(
|
||||||
E0119,
|
lint,
|
||||||
"{}",
|
tcx.hir().as_local_hir_id(impl_def_id).unwrap(),
|
||||||
msg)
|
impl_span,
|
||||||
|
&msg)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match tcx.span_of_impl(overlap.with_impl) {
|
match tcx.span_of_impl(overlap.with_impl) {
|
||||||
|
|
|
@ -371,11 +371,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||||
reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
|
reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
|
||||||
edition: None,
|
edition: None,
|
||||||
},
|
},
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS),
|
|
||||||
reference: "issue #46205 <https://github.com/rust-lang/rust/issues/46205>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
FutureIncompatibleInfo {
|
||||||
id: LintId::of(ORDER_DEPENDENT_TRAIT_OBJECTS),
|
id: LintId::of(ORDER_DEPENDENT_TRAIT_OBJECTS),
|
||||||
reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>",
|
reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>",
|
||||||
|
@ -491,6 +486,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||||
"replaced with a generic attribute input check");
|
"replaced with a generic attribute input check");
|
||||||
store.register_removed("duplicate_matcher_binding_name",
|
store.register_removed("duplicate_matcher_binding_name",
|
||||||
"converted into hard error, see https://github.com/rust-lang/rust/issues/57742");
|
"converted into hard error, see https://github.com/rust-lang/rust/issues/57742");
|
||||||
|
store.register_removed("incoherent_fundamental_impls",
|
||||||
|
"converted into hard error, see https://github.com/rust-lang/rust/issues/46205");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) {
|
pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||||
|
|
|
@ -5,8 +5,6 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
||||||
use rustc::traits::{self, IntercrateMode};
|
use rustc::traits::{self, IntercrateMode};
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
|
|
||||||
use crate::lint;
|
|
||||||
|
|
||||||
pub fn crate_inherent_impls_overlap_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
pub fn crate_inherent_impls_overlap_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
crate_num: CrateNum) {
|
crate_num: CrateNum) {
|
||||||
assert_eq!(crate_num, LOCAL_CRATE);
|
assert_eq!(crate_num, LOCAL_CRATE);
|
||||||
|
@ -20,8 +18,7 @@ struct InherentOverlapChecker<'a, 'tcx: 'a> {
|
||||||
|
|
||||||
impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
|
impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
|
||||||
fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId,
|
fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId,
|
||||||
overlap: traits::OverlapResult<'_>,
|
overlap: traits::OverlapResult<'_>) {
|
||||||
used_to_be_allowed: bool) {
|
|
||||||
|
|
||||||
let name_and_namespace = |def_id| {
|
let name_and_namespace = |def_id| {
|
||||||
let item = self.tcx.associated_item(def_id);
|
let item = self.tcx.associated_item(def_id);
|
||||||
|
@ -36,22 +33,12 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
|
||||||
|
|
||||||
for &item2 in &impl_items2[..] {
|
for &item2 in &impl_items2[..] {
|
||||||
if (name, namespace) == name_and_namespace(item2) {
|
if (name, namespace) == name_and_namespace(item2) {
|
||||||
let hir_id = self.tcx.hir().as_local_hir_id(impl1);
|
let mut err =
|
||||||
let mut err = if used_to_be_allowed && hir_id.is_some() {
|
|
||||||
self.tcx.struct_span_lint_hir(
|
|
||||||
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
|
|
||||||
hir_id.unwrap(),
|
|
||||||
self.tcx.span_of_impl(item1).unwrap(),
|
|
||||||
&format!("duplicate definitions with name `{}` (E0592)", name)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
struct_span_err!(self.tcx.sess,
|
struct_span_err!(self.tcx.sess,
|
||||||
self.tcx.span_of_impl(item1).unwrap(),
|
self.tcx.span_of_impl(item1).unwrap(),
|
||||||
E0592,
|
E0592,
|
||||||
"duplicate definitions with name `{}`",
|
"duplicate definitions with name `{}`",
|
||||||
name)
|
name);
|
||||||
};
|
|
||||||
|
|
||||||
err.span_label(self.tcx.span_of_impl(item1).unwrap(),
|
err.span_label(self.tcx.span_of_impl(item1).unwrap(),
|
||||||
format!("duplicate definitions for `{}`", name));
|
format!("duplicate definitions for `{}`", name));
|
||||||
err.span_label(self.tcx.span_of_impl(item2).unwrap(),
|
err.span_label(self.tcx.span_of_impl(item2).unwrap(),
|
||||||
|
@ -76,7 +63,7 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
|
||||||
|
|
||||||
for (i, &impl1_def_id) in impls.iter().enumerate() {
|
for (i, &impl1_def_id) in impls.iter().enumerate() {
|
||||||
for &impl2_def_id in &impls[(i + 1)..] {
|
for &impl2_def_id in &impls[(i + 1)..] {
|
||||||
let used_to_be_allowed = traits::overlapping_impls(
|
traits::overlapping_impls(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
impl1_def_id,
|
impl1_def_id,
|
||||||
impl2_def_id,
|
impl2_def_id,
|
||||||
|
@ -86,28 +73,11 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
|
||||||
impl1_def_id,
|
impl1_def_id,
|
||||||
impl2_def_id,
|
impl2_def_id,
|
||||||
overlap,
|
overlap,
|
||||||
false,
|
|
||||||
);
|
);
|
||||||
false
|
false
|
||||||
},
|
},
|
||||||
|| true,
|
|| true,
|
||||||
);
|
);
|
||||||
|
|
||||||
if used_to_be_allowed {
|
|
||||||
traits::overlapping_impls(
|
|
||||||
self.tcx,
|
|
||||||
impl1_def_id,
|
|
||||||
impl2_def_id,
|
|
||||||
IntercrateMode::Fixed,
|
|
||||||
|overlap| self.check_for_common_items_in_impls(
|
|
||||||
impl1_def_id,
|
|
||||||
impl2_def_id,
|
|
||||||
overlap,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
|| (),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ impl<X, T> Trait1<X> for T where T: Trait2<X> {
|
||||||
|
|
||||||
impl<X> Trait1<Box<X>> for A {
|
impl<X> Trait1<Box<X>> for A {
|
||||||
//~^ ERROR conflicting implementations of trait
|
//~^ ERROR conflicting implementations of trait
|
||||||
//~| hard error
|
|
||||||
//~| downstream crates may implement trait `Trait2<std::boxed::Box<_>>` for type `A`
|
//~| downstream crates may implement trait `Trait2<std::boxed::Box<_>>` for type `A`
|
||||||
type Output = i32;
|
type Output = i32;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: conflicting implementations of trait `Trait1<std::boxed::Box<_>>` for type `A`: (E0119)
|
error[E0119]: conflicting implementations of trait `Trait1<std::boxed::Box<_>>` for type `A`:
|
||||||
--> $DIR/issue-43355.rs:13:1
|
--> $DIR/issue-43355.rs:13:1
|
||||||
|
|
|
|
||||||
LL | impl<X, T> Trait1<X> for T where T: Trait2<X> {
|
LL | impl<X, T> Trait1<X> for T where T: Trait2<X> {
|
||||||
|
@ -7,10 +7,8 @@ LL | impl<X, T> Trait1<X> for T where T: Trait2<X> {
|
||||||
LL | impl<X> Trait1<Box<X>> for A {
|
LL | impl<X> Trait1<Box<X>> for A {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A`
|
||||||
|
|
|
|
||||||
= note: #[deny(incoherent_fundamental_impls)] on by default
|
|
||||||
= 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 #46205 <https://github.com/rust-lang/rust/issues/46205>
|
|
||||||
= note: downstream crates may implement trait `Trait2<std::boxed::Box<_>>` for type `A`
|
= note: downstream crates may implement trait `Trait2<std::boxed::Box<_>>` for type `A`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0119`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue