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:
bors 2019-05-17 23:06:51 +00:00
commit a614cee22e
8 changed files with 34 additions and 113 deletions

View File

@ -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 |
| 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 |
| 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`.
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.

View File

@ -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`
```

View File

@ -198,12 +198,6 @@ declare_lint! {
"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! {
pub ORDER_DEPENDENT_TRAIT_OBJECTS,
Deny,
@ -428,7 +422,6 @@ declare_lint_pass! {
MISSING_FRAGMENT_SPECIFIER,
PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
LATE_BOUND_LIFETIME_ARGUMENTS,
INCOHERENT_FUNDAMENTAL_IMPLS,
ORDER_DEPENDENT_TRAIT_OBJECTS,
DEPRECATED,
UNUSED_UNSAFE,

View File

@ -319,29 +319,34 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(
String::new(), |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(
tcx.span_of_impl(impl_def_id).unwrap()
);
let mut err = if let Some(kind) = used_to_be_allowed {
let lint = match kind {
FutureCompatOverlapErrorKind::Issue43355 =>
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
FutureCompatOverlapErrorKind::Issue33140 =>
lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS,
};
tcx.struct_span_lint_hir(
lint,
tcx.hir().as_local_hir_id(impl_def_id).unwrap(),
impl_span,
&msg)
} else {
struct_span_err!(tcx.sess,
impl_span,
E0119,
"{}",
msg)
let mut err = match used_to_be_allowed {
Some(FutureCompatOverlapErrorKind::Issue43355) | None =>
struct_span_err!(tcx.sess,
impl_span,
E0119,
"{}",
msg),
Some(kind) => {
let lint = match kind {
FutureCompatOverlapErrorKind::Issue43355 =>
unreachable!("converted to hard error above"),
FutureCompatOverlapErrorKind::Issue33140 =>
lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS,
};
tcx.struct_span_lint_hir(
lint,
tcx.hir().as_local_hir_id(impl_def_id).unwrap(),
impl_span,
&msg)
}
};
match tcx.span_of_impl(overlap.with_impl) {

View File

@ -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>",
edition: None,
},
FutureIncompatibleInfo {
id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS),
reference: "issue #46205 <https://github.com/rust-lang/rust/issues/46205>",
edition: None,
},
FutureIncompatibleInfo {
id: LintId::of(ORDER_DEPENDENT_TRAIT_OBJECTS),
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");
store.register_removed("duplicate_matcher_binding_name",
"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>) {

View File

@ -5,8 +5,6 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::traits::{self, IntercrateMode};
use rustc::ty::TyCtxt;
use crate::lint;
pub fn crate_inherent_impls_overlap_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
crate_num: CrateNum) {
assert_eq!(crate_num, LOCAL_CRATE);
@ -20,8 +18,7 @@ struct InherentOverlapChecker<'a, 'tcx: 'a> {
impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId,
overlap: traits::OverlapResult<'_>,
used_to_be_allowed: bool) {
overlap: traits::OverlapResult<'_>) {
let name_and_namespace = |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[..] {
if (name, namespace) == name_and_namespace(item2) {
let hir_id = self.tcx.hir().as_local_hir_id(impl1);
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 {
let mut err =
struct_span_err!(self.tcx.sess,
self.tcx.span_of_impl(item1).unwrap(),
E0592,
"duplicate definitions with name `{}`",
name)
};
name);
err.span_label(self.tcx.span_of_impl(item1).unwrap(),
format!("duplicate definitions for `{}`", name));
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 &impl2_def_id in &impls[(i + 1)..] {
let used_to_be_allowed = traits::overlapping_impls(
traits::overlapping_impls(
self.tcx,
impl1_def_id,
impl2_def_id,
@ -86,28 +73,11 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
impl1_def_id,
impl2_def_id,
overlap,
false,
);
false
},
|| 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,
),
|| (),
);
}
}
}
}

View File

@ -12,7 +12,6 @@ impl<X, T> Trait1<X> for T where T: Trait2<X> {
impl<X> Trait1<Box<X>> for A {
//~^ ERROR conflicting implementations of trait
//~| hard error
//~| downstream crates may implement trait `Trait2<std::boxed::Box<_>>` for type `A`
type Output = i32;
}

View File

@ -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
|
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 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0119`.