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

item_like_imports: Can "ambiguity error" items be reexported? #36837

Open
petrochenkov opened this Issue Sep 29, 2016 · 3 comments

Comments

Projects
None yet
4 participants
@petrochenkov
Copy link
Contributor

petrochenkov commented Sep 29, 2016

Is the next code well formed or not?

#![feature(item_like_imports)]

mod ty1 {
    pub type A = u8;
}
mod ty2 {
    pub type A = u8;
}
mod ambig {
    // Create an ambiguity item in type namespace.
    pub use ty1::*;
    pub use ty2::*;
}
mod merge {
    pub use ambig::*; // <- reexports an ambiguity error, or reexports nothing?
    pub use ty1::*; // <- does this contribute to the ambiguity error or create a valid name?
}

fn main() {
    let _: merge::A; // <- Valid or an ambiguity error?
}

Currently the behavior of this code depends on whether the "merge" step is done in the same crate or in some other crate.
In a single crate scenario the snippet above fails to compile with A is ambiguous error.
If merge is moved to another crate, then all erroneous resolutions are filtered away and are not represented in metadata, pub use ambig::* becomes an empty import and merge::A unambiguously means ty1::A.
Supposedly, local and cross-crate behavior should be the same.

cc @jseyfried @nrc

@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented Sep 29, 2016

My opinion so far is that reexported Def::Errs (ambiguity and others) should never affect resolution results, but may affect diagnostics and give better error messages, i.e. the code above is valid.

@jseyfried

This comment has been minimized.

Copy link
Contributor

jseyfried commented Sep 29, 2016

I agree that ideally your example would be valid, but I don't think that's possible to implement, at least not without introducing a lot of ambiguous imports ("deadlocking") in code that compiles today.

For example, if we resolve pub use ty2::*; first and resolve pub use ambig::*; next, then the resolution of A in merge is determined to be ty2::A, so it could be re-exported in other places or used in other imports' module paths (if it were a module instead of a type alias).

If we couldn't assume that the resolution of A in merge was ty2::A in the above case, I don't think we'd be able to make enough progress to support a lot of existing code.

@jseyfried

This comment has been minimized.

Copy link
Contributor

jseyfried commented Sep 29, 2016

More specifically, if we wanted to support that example then we wouldn't be able to glob-import a name unless we knew that the name would never become ambiguous in the glob-imported module.

Thus, we wouldn't be able to support the following, which compiles today:

mod foo {
    pub mod quux {}
}
mod bar {
    pub use foo::*;
    pub use baz::quux::*; // We need to resolve this to deduce that `bar::quux` isn't ambiguous,
}
mod baz {
    pub use bar::*; // but that requires importing `quux` here, which we wouldn't be able to do until we have deduced that `quux` isn't ambiguous.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.