Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lint: convert incoherent_fundamental_impls into hard error #49799

Merged
merged 1 commit into from
May 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/doc/rustc/src/lints/groups.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
41 changes: 0 additions & 41 deletions src/doc/rustc/src/lints/listing/deny-by-default.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
```
7 changes: 0 additions & 7 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
43 changes: 24 additions & 19 deletions src/librustc/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,29 +321,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) {
Expand Down
7 changes: 2 additions & 5 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>",
Expand Down Expand Up @@ -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>) {
Expand Down
38 changes: 4 additions & 34 deletions src/librustc_typeck/coherence/inherent_impls_overlap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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(),
Expand All @@ -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,
Expand All @@ -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,
),
|| (),
);
}
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/test/ui/issues/issue-43355.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
6 changes: 2 additions & 4 deletions src/test/ui/issues/issue-43355.stderr
Original file line number Diff line number Diff line change
@@ -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> {
Expand All @@ -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`.