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

Nonconflicting Conflicting impl in trait object when trait and object impl same item name #45251

Closed
Havvy opened this issue Oct 13, 2017 · 5 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug.

Comments

@Havvy
Copy link
Contributor

Havvy commented Oct 13, 2017

Playpen

Source
trait Trait {
    fn test(&self) -> &'static str { "Default" }
}

struct NotSyncStruct(*const ());

impl NotSyncStruct {
    fn new() -> NotSyncStruct { NotSyncStruct(&() as *const ()) }
}

impl Trait {
    fn test(&self) -> &'static str { "Without Send and Sync" }
}

impl Trait + Send + Sync {
    fn test(&self) -> &'static str { "With Send and Sync" }
}

impl Trait for NotSyncStruct {}

fn main () {
    println!("{}", <Trait>::test(&NotSyncStruct::new()));
}

Error Message
   Compiling playground v0.0.1 (file:///playground)
error[E0034]: multiple applicable items in scope
  --> src/main.rs:22:20
   |
22 |     println!("{}", <Trait>::test(&NotSyncStruct::new()));
   |                    ^^^^^^^^^^^^^ multiple `test` found
   |
note: candidate #1 is defined in an impl for the type `Trait + 'static`
  --> src/main.rs:12:5
   |
12 |     fn test(&self) -> &'static str { "Without Send and Sync" }
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl for the type `Trait + std::marker::Sync + std::marker::Send + 'static`
  --> src/main.rs:16:5
   |
16 |     fn test(&self) -> &'static str { "With Send and Sync" }
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: candidate #3 is defined in the trait `Trait`
  --> src/main.rs:2:5
   |
2  |     fn test(&self) -> &'static str { "Default" }
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = help: to disambiguate the method call, write `Trait::test(...)` instead

error: aborting due to previous error

error: Could not compile `playground`.

To learn more, run the command again with --verbose.

The error message here suggests that there are three implementations that define the associated item when in reality, there can only be two. It's not possible to call the implementation on Trait + std::marker::Sync + std::marker::Send + 'static` because the type is not Sync. So the error message should not show that implementation.

At least, that is what I believe the error to be. For if you comment out either the default implementation on line 2 or the inherent implementation on line 12, then the program actually compiles.

@Havvy
Copy link
Contributor Author

Havvy commented Oct 13, 2017

Actually, I'm not even sure there should be a conflict here. Inherent methods are supposed to win out over all trait methods. And since the implementations don't seem to overlap, I can only presume that the conflicting implementation are false altogether.

@petrochenkov
Copy link
Contributor

petrochenkov commented Oct 13, 2017

@Havvy

Inherent methods are supposed to win out over all trait methods.

Trait objects are a special case, trait method and inherent method on a trait with the same name are supposed to conflict because someone (IIRC, @nrc) in the past thought it would prevent errors.
There's even test checking for this, but I can't find it without modifying the compiler.
I think this can be changed backward-compatibly though.

@Havvy
Copy link
Contributor Author

Havvy commented Oct 13, 2017

If that's the case, then the error should happen without having to call the function. I'd be okay with making it a hard error to have a trait object implement an item with the same name as its trait. Just make sure there's a specific error for this. Although with dyn Trait becoming a thing, I don't think there would be too much confusion, and could just be relegated to a lint (possibly even a Clippy lint?)

@Havvy Havvy changed the title Nonconflicting Conflicting implementation in trait object madness Nonconflicting Conflicting impl in trait object when trait and object impl same item name Oct 13, 2017
@Havvy
Copy link
Contributor Author

Havvy commented Dec 29, 2017

This still needs to be tagged. cc @kennytm

@kennytm kennytm added A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. labels Dec 29, 2017
@Havvy
Copy link
Contributor Author

Havvy commented Jun 9, 2018

Closing in favor of issue #51402

@Havvy Havvy closed this as completed Jun 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants