Skip to content

use self::b has stopped consulting local non-pub use of b #13598

Closed
@pnkfelix

Description

@pnkfelix

I used to be able to do:

use a::b;
use D = self::b::C;

but now I cannot, at least not in all cases.

Here is a test case:

mod a {
    pub mod b {
        pub type C = uint;
    }
}

#[cfg(variant1)]
mod variant1 {
    use a::b;
    use D = self::b::C;

    pub fn main() {
        let d : D = 3;
        println!("d: {}", d);
    }
}

#[cfg(variant2)]
mod variant2 {
    use D = a::b::C;

    pub fn main() {
        let d : D = 3;
        println!("d: {}", d);
    }
}

#[cfg(variant1)]
pub fn main() {
    variant1::main();
}

#[cfg(variant2)]
pub fn main() {
    variant2::main();
}

Here is a transcript of how this used to work (on a rustc v0.11-pre circa 2014-04-07) versus breaking now (on a rustc v0.11-pre circa 2014-04018).

% rustc --version
/Users/fklock/opt/rust-dbg/bin/rustc 0.11-pre (0deb16a 2014-04-07 02:26:37 -0700)
host: x86_64-apple-darwin
% rustc --cfg variant1 /tmp/n.rs && ./n
d: 3
% rustc --cfg variant2 /tmp/n.rs && ./n
d: 3
% ./objdir-dbgopt/x86_64-apple-darwin/stage2/bin/rustc --version
./objdir-dbgopt/x86_64-apple-darwin/stage2/bin/rustc 0.11-pre (ce2bab6 2014-04-18 04:11:19 -0700)
host: x86_64-apple-darwin
% ./objdir-dbgopt/x86_64-apple-darwin/stage2/bin/rustc --cfg variant1 /tmp/n.rs && ./n
/tmp/n.rs:10:9: 10:24 error: unresolved import: could not find `b` in `variant1`.
/tmp/n.rs:10     use D = self::b::C;
                     ^~~~~~~~~~~~~~~
/tmp/n.rs:10:9: 10:24 error: failed to resolve import `self::b::C`
/tmp/n.rs:10     use D = self::b::C;
                     ^~~~~~~~~~~~~~~
error: aborting due to 2 previous errors
% ./objdir-dbgopt/x86_64-apple-darwin/stage2/bin/rustc --cfg variant2 /tmp/n.rs && ./n
d: 3
% 

Discussion with @alexcrichton leads me to think that this change may have been injected as part of PR #13409.

It may or may be a bug. Whether you see it as a bug may depend on your view of how privacy and use interact. (In particular, if you make a variant3 of variant1 where the use a::b is rewritten to pub use a::b, so that the b is now publicly exported from self, then things seem to work.)

My reasoning is that we should be able to do:

use a::b; // a non-pub import
use D = self::b::C;

because the way we resolve use self::b::C, we look for other non-pub things in self, such as a hypothetical non-pub mod b defined within self.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-resolveArea: Name/path resolution done by `rustc_resolve` specifically

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions