Skip to content

trait permitting extra members #54665

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

Closed
nikomatsakis opened this issue Sep 29, 2018 · 12 comments
Closed

trait permitting extra members #54665

nikomatsakis opened this issue Sep 29, 2018 · 12 comments
Assignees
Labels
A-trait-system Area: Trait system P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@nikomatsakis
Copy link
Contributor

I've been tinkering locally with a crate called salsa. Along the way, I noticed that my impl permits me to add extra members. e.g., I have this trait:

pub trait QueryContext: QueryContextStorageTypes {
    fn salsa_runtime(&self) -> &runtime::Runtime<Self>;
}

But in my cargo example I can use this impl:

impl salsa::QueryContext for QueryContextImpl {
    fn extra(&self) -> u32 {
        0
    }

    fn salsa_runtime(&self) -> &salsa::runtime::Runtime<QueryContextImpl> {
        &self.runtime
    }
}

What the heck is going on here? I couldn't easily reproduce this in a smaller example, so I saved the commit. It did reproduce cleanly after rm -rf target and cargo clean, so I guess it's (probably?) not an incremental bug.

To reproduce:

Marking as T-compiler and P-high. P-high because this could be a very dangerous bug in terms of backwards compat risk! But I'm hoping it's something more bizarre (e.g., not rebuilding when I think it is). I did validate though that adding other weird stuff (e.g., invalid tokens) causes compilation to fail. Assigning to myself to investigate on Monday.

@nikomatsakis nikomatsakis added A-trait-system Area: Trait system P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 29, 2018
@nikomatsakis nikomatsakis self-assigned this Sep 29, 2018
@GabrielMajeri
Copy link
Contributor

@nikomatsakis Hi, while playing around with that example I found something interesting:

If I add an

extern crate salsa;

at the top it does error correctly:

error[E0407]: method `extra` is not a member of trait `salsa::QueryContext`                                                                              
  --> examples/storage_varieties/implementation.rs:30:5                                                                                                  
   |                                                                                                                                                     
30 | /     fn extra(&self) -> u32 {                                                                                                                      
31 | |         0                                                                                                                                         
32 | |     }                                                                                                                                             
   | |_____^ not a member of trait `salsa::QueryContext`                                                                                                 
                                                     

So at least this seems to be an issue with the new Rust 2018 module system?

@GabrielMajeri
Copy link
Contributor

GabrielMajeri commented Sep 29, 2018

I think I've got a minimal repro (repro.tar.gz). Considering a Rust 2018 crate with a library and a binary:

lib.rs:

pub trait Foo {
    fn foo();
}

main.rs:

// Uncomment to make error work:
//extern crate repro;

pub struct Bar;

impl repro::Foo for Bar {
    fn foo() {}

    // This compiles!
    fn extra() {}
}

fn main() {}

I can also work around the bug by adding a use repro::Foo;

@ishitatsuyuki ishitatsuyuki changed the title trait permtting exta members trait permtting extra members Sep 29, 2018
@csmoe csmoe changed the title trait permtting extra members trait permitting extra members Sep 29, 2018
@nikomatsakis
Copy link
Contributor Author

@GabrielMajeri awesome, thanks!

@nikomatsakis
Copy link
Contributor Author

cc @petrochenkov — any ideas? I'm looking into the code a bit

@nikomatsakis
Copy link
Contributor Author

The immediate cause of the problem is that current_trait_ref is None here:

if let Some((module, _)) = self.current_trait_ref {

@nikomatsakis
Copy link
Contributor Author

We seem to enter this block of code with a successful resolution in def:

new_id = Some(def.def_id());
let span = trait_ref.path.span;
if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
self.resolve_path(
None,
&path,
None,
false,
span,
CrateLint::SimplePath(trait_ref.ref_id),
)
{
new_val = Some((module, trait_ref.clone()));
}

But something goes wrong after that.

@nikomatsakis
Copy link
Contributor Author

It seems like the problem is that resolve_path returns "Indeterminate"

@nikomatsakis
Copy link
Contributor Author

Here is the output from some logs I added, showing the value of def and also the result of the call to resolve_path:

DEBUG 2018-10-04T16:36:34Z: rustc_resolve: with_optional_trait_ref: def=Trait(DefId(9/0:3))
DEBUG 2018-10-04T16:36:34Z: rustc_resolve: resolve_path(path=[repro#0, Foo#0], opt_ns=None, record_used=false, path_span=Span { lo: BytePos(42), hi: BytePos(52), ctxt: #0 }, crate_lint=SimplePath(NodeId(9)))
DEBUG 2018-10-04T16:36:34Z: rustc_resolve: resolve_path ident 0 repro#0
DEBUG 2018-10-04T16:36:34Z: rustc_resolve: with_optional_trait_ref: path_resolution=Indeterminate

@nikomatsakis
Copy link
Contributor Author

cc @eddyb also — maybe you or @petrochenkov has some clue what's happening here based on the above output.

@nikomatsakis nikomatsakis added this to the Edition 2018 RC 2 milestone Oct 4, 2018
@petrochenkov petrochenkov self-assigned this Oct 5, 2018
@petrochenkov
Copy link
Contributor

I'll look at this once I'm back from vacation next week (unless it's resolved before that).

@pnkfelix
Copy link
Member

visited for triage. Leaving on RC2 milestone, and thus, leaving at P-high.

@petrochenkov
Copy link
Contributor

Fixed in #55102

kennytm added a commit to kennytm/rust that referenced this issue Oct 18, 2018
resolve: Do not skip extern prelude during speculative resolution

Fixes rust-lang#54665
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-trait-system Area: Trait system P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants