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

Tracking issue for `incoherent_fundamental_impls` compatibility lint #46205

Open
arielb1 opened this Issue Nov 23, 2017 · 4 comments

Comments

Projects
None yet
5 participants
@arielb1
Contributor

arielb1 commented Nov 23, 2017

This is the summary issue for the incoherent_fundamental_impls
future-compatibility warning and other related errors. The goal of
this page is describe why this change was made and how you can fix
code that is affected by it. It also provides a place to ask questions
or register a complaint if you feel the change should not be made. For
more information on the policy around future-compatibility warnings,
see our breaking change policy guidelines.

What is the warning for?

Some trait impls that could cause coherence conflicts were incorrectly allowed because of #43355. TBD: write understandable version.

When will this warning become a hard error?

At the beginning of each 6-week release cycle, the Rust compiler team
will review the set of outstanding future compatibility warnings and
nominate some of them for Final Comment Period. Toward the end of
the cycle, we will review any comments and make a final determination
whether to convert the warning into a hard error or remove it
entirely.

@nikomatsakis

This comment has been minimized.

Contributor

nikomatsakis commented Apr 6, 2018

This is a "forwards compatibility" lint. We used to accept potentially overlapping impls due to a bug. We fixed the bug but only gave warnings so people had time to adapt. As we move forward on overhauling the trait system, though, I predict this is going to be an annoyance -- I think we should close this bug.

In order to do that, we need to prepare a PR that removes this lint and just makes the situation a hard error. You can find the code related to this lint by ripgrep'ing the code for INCOHERENT_FUNDAMENTAL_IMPLS (or use github search). Mostly it's here:

let mut err = if used_to_be_allowed && node_id.is_some() {
self.tcx.struct_span_lint_node(
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
node_id.unwrap(),
self.tcx.span_of_impl(item1).unwrap(),
&format!("duplicate definitions with name `{}` (E0592)", name)
)
} else {
struct_span_err!(self.tcx.sess,
self.tcx.span_of_impl(item1).unwrap(),
E0592,
"duplicate definitions with name `{}`",
name)
};

and here:

let mut err = if used_to_be_allowed {
tcx.struct_span_lint_node(
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
tcx.hir.as_local_node_id(impl_def_id).unwrap(),
impl_span,
&msg)
} else {
struct_span_err!(tcx.sess,
impl_span,
E0119,
"{}",
msg)
};

We would remove the used_to_be_allowed_flag, which should allow us to simplify some of the code around it. We would also remove the code that declares the lint:

declare_lint! {
pub INCOHERENT_FUNDAMENTAL_IMPLS,
Warn,
"potentially-conflicting impls were erroneously allowed"
}

And add a call to register_removed, sorta like this one:

store.register_removed("resolve_trait_on_defaulted_unit",
"converted into hard error, see https://github.com/rust-lang/rust/issues/48950");

cc @rust-lang/wg-traits -- good trait-related cleanup!

@hdhoang

This comment has been minimized.

Contributor

hdhoang commented Apr 7, 2018

I would like to tackle this, thanks for the instructions! AIUI, I can start with addressing these usages:

src/librustc_lint/lib.rs
268:            id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS),

src/librustc_typeck/coherence/inherent_impls_overlap.rs
52:                            lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,

src/librustc/lint/builtin.rs
303:            INCOHERENT_FUNDAMENTAL_IMPLS,

src/test/compile-fail/issue-43355.rs
11:#![deny(incoherent_fundamental_impls)]

src/librustc/traits/specialize/mod.rs
351:                        lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,

That could start out with replacing usage of used_to_be_allowed_flag with false, then trim down the resulting branches, then removing used_to_be_allowed_flag itself.

Then I will remove the lint declaration, and add the removal notification with link to this issue, and the run-pass compile test.

bors pushed a commit that referenced this issue Apr 10, 2018

bors added a commit that referenced this issue Apr 10, 2018

Auto merge of #49799 - hdhoang:46205_deny_incoherent_fundamental_impl…
…s, r=<try>

lint: convert incoherent_fundamental_impls into hard error

implement #46205

r? @nikomatsakis
@nikomatsakis

This comment has been minimized.

Contributor

nikomatsakis commented Apr 10, 2018

@hdhoang thanks!

@RReverser

This comment has been minimized.

Contributor

RReverser commented Oct 30, 2018

This new lint makes it very inconvenient to create generic wrappers.

For example, on one hand, I can't do

struct CustomWrapper<T>(T);

impl<T> From<CustomWrapper<T>> for T {
    fn from(w: CustomWrapper<T>) -> T { w.0 }
}

because that violates

error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)

 --> <source>:3:1

  |

3 | impl<T> From<CustomWrapper<T>> for T {

  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type

  |

  = note: only traits defined in the current crate can be implemented for a type parameter

and, on the other hand, I now can't do more restricted version either

struct CustomWrapper<T>(T);

impl<T> Into<T> for CustomWrapper<T> {
    fn into(self) -> T { self.0 }
}

because of

rror[E0119]: conflicting implementations of trait `std::convert::Into<_>` for type `CustomWrapper<_>`:

 --> <source>:3:1

  |

3 | impl<T> Into<T> for CustomWrapper<T> {

  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  |

  = note: conflicting implementation in crate `core`:

          - impl<T, U> std::convert::Into<U> for T

            where U: std::convert::From<T>;

Is now the only way to define custom method each time I want to provide conversion? It doesn't feel very idiomatic if so, given the existence of specialised traits for that...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment