Skip to content

Coherence problem when a generic has a default value from an associated type #61400

New issue

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

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

Already on GitHub? # to your account

Closed
ohadravid opened this issue May 31, 2019 · 3 comments
Closed
Labels
C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team

Comments

@ohadravid
Copy link
Contributor

ohadravid commented May 31, 2019

I ran into a coherence problem where I think that the compiler is too strict, even though the code should be accepted according to the coherence rules (as far as I can tell).

For the code below, the compiler will report

 error[E0210]: type parameter `<MyString as somelib::ConvertTo>::Output` must be used as the type parameter for some local type ...`,

but passing O explicitly (for ItemOrConverted<MyString, String>) works.

The code:

/// In some other crate.
trait ConvertTo {
    type Output;
}


enum ItemOrConverted<T: ConvertTo, O = <T as ConvertTo>::Output> {
    Item(T),
    Converted(O),
}

/// In our crate.
struct MyString { }

impl ConvertTo for MyString {
    type Output = String;
}

impl PartialEq<MyString> for ItemOrConverted<MyString> {
    fn eq(&self, other: &MyString) -> bool {
        unimplemented!();
    }
}

I have a trait with an associated type (ConvertTo::Output, in the example below), and an enum which is generic over T: ConvertTo and generic over O with a default value for O based on the associated type from T's ConvertTo, all in one crate.

In another crate I have MyString, and I would like to implement PartialEq<MyString> for this enum over MyString, but without changing the default value for O. (Think impl PartialEq<MyString> for Cow<MyString>).

Is this really allowed "in theory" by the coherence rules or am I missing something?

(edit: Compiling with #![feature(re_rebalance_coherence)] works!)

Meta

rustc 1.37.0-nightly (37d001e 2019-05-29)
binary: rustc
commit-hash: 37d001e
commit-date: 2019-05-29
host: x86_64-pc-windows-msvc
release: 1.37.0-nightly
LLVM version: 8.0

@jonas-schievink jonas-schievink added C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team labels May 31, 2019
@jonas-schievink
Copy link
Contributor

(edit: Compiling with #![feature(re_rebalance_coherence)] works!)

In that case, maybe this should be closed in favor of #55437, which tracks the stabilization of that feature?

@ohadravid
Copy link
Contributor Author

Yeah, sounds good.
Maybe I'll add a test for this? the implementation PR of #55437 doesn't seem to have one.

@jonas-schievink
Copy link
Contributor

There's a few tests in #56145, but having a more diverse test set is always good, so feel free to add this!

Centril added a commit to Centril/rust that referenced this issue Jul 12, 2019
…-assiociated-type-re-rebalance-coherence, r=nikomatsakis

Coherence test when a generic type param has a default value from an associated type

A followup on rust-lang#61400.
Before `re_rebalance_coherence`, this fails to compile (even though it should be accepted).
`re_rebalance_coherence` had no direct test for this, and I wanted to (a) make sure it doesn't regress in the future and (b) get it on record that this is actually the intended behavior.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team
Projects
None yet
Development

No branches or pull requests

2 participants