item_like_imports: Can "ambiguity error" items be reexported?
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
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.Vadim Petrochenkov at 2016-09-29 21:02:37
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 resolvepub use ambig::*;next, then the resolution ofAinmergeis determined to bety2::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
Ainmergewasty2::Ain the above case, I don't think we'd be able to make enough progress to support a lot of existing code.Jeffrey Seyfried at 2016-09-29 21:24:13
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. }Jeffrey Seyfried at 2016-09-29 21:51:05
Cross-crate encoding for reexported ambiguities was implemented in https://github.com/rust-lang/rust/pull/114682 but not merged.
Issue "Tracking Issue for
ambiguous_glob_importslint" is also relevant here because cross-crate reexports for ambiguities that are usable for backward compatibility are a part of that warning.Vadim Petrochenkov at 2024-08-21 15:03:05