Relative paths and Rust 2018 `use` statements


provide custom prelude with module reexports, then:


I’d be very surprised if that doesn’t keep working, since it works today. Why would that not keep working?

(That said, the proposal needs to account for it explicitly. It’s easy to forget that use SomeEnum::Variant is a thing.)


That does not work today. You need to write use self::Enum::Variant today?


You can always rename the dependency foo rather than shadowing.

Fair enough; I hadn’t considered that possibility. Still, I don’t think we want to go there any time soon.

I am not sure I understand the thought here exactly, but I think we don’t need to go anywhere? You already can rename dependencies in Cargo.


We shouldn’t break that. And I don’t see any reason why we’d need to. This proposal can easily preserve that.

(Or perhaps we’re using “today” differently. Are you talking about the 2018 edition preview, rather than current stable Rust? If we’ve broken that in the 2018 edition preview, all the more reason to fix it before we ship.)


I think it’s pretty unfortunate that we can’t make use inscopename::foo work, because I find @josh’s mental model here very appealing.


That happens to work in the root module, but not other modules. We are already breaking that in Rust 2018 anyhow, where you must write use crate::Foo instead (or use self::Foo). =)


So… I’m sorry to be the one to say this but…

2018-08-02: Edition preview 2
2018-09-13: Edition release candidate (RC)
2018-10-25: Edition release

Changes discussed here sound nice to me, but don’t forget about the time pressure we’re under. :slight_smile:

I’d like to hear from @nikomatsakis about the time this will take and impending deadlines…


Overall, I really like this idea!

I am a bit worried by the enum problem: the proposal increases uniformity in the common case, but it also creates more special cases.

For locality, I think we can use code style to gain it back!

I think most people, myself included, write extern crate, use and mods in this order:

extern crate foo;

use bar::baz;

mod quux;

and then struggle with putting use self::quux::Spam either with other uses, or with mod quux; Just today I’ve found out that there’s in fact an alternative style of putting mods before usees:

extern crate foo;

mod quux;

use bar::baz;
use self::quux::Spam;

I personally find this style much better (although I’ve been using the opposite one for several years!), and, with this proposal, it’ll actually provide locality as well because, typically, you’ll only need to scan a small mod section before uses.


I see.

Given the proposal under discussion here, which specifically changes name resolution in use to start from the local module, it’d be consistent to make enum Enum { ... } use Enum::*; work no matter what module you’re in. Is there some obvious reason we can’t do that?


One day I hope to fix that by no longer having to write mod quux; at all, but I have no intention of mixing that with this proposal. :slight_smile:


I don’t think it’s any harder to support enums than it is to support modules (I have concerns about path that I cited here). I just thought you explicitly didn’t want that, since @aturon wrote:

Note the “not any other declaration” part.


Indeed, the idea of making any changes here makes me very nervous. I think it’s better to think about this as a “post edition” sort of change.

Concerned about Rust 2018 stability

This exploration is coming from feedback from people attempting to use the preview, so I think the process is working ok. There is, of course, a very high bar to making changes at this point.

As a daily user of the preview, I messed up use EnumType::* 100% of the time at first until the compiler reminded me to insert the self::* so that’s one data point.

The overall big improvement to unify the semantics of the two kinds of paths makes it easier to forget about the remaining differences, in my experience so far.


I think that’s purely because it’s easy to forget about use Enum::*; as a thing. Neither of us talked about that at all when we were formulating this proposal.


Note: several of the discussion participants ended up talking in high bandwidth on the Discord, and I’m now working on writing up a revised proposal. Once that’s ready, I’m going to close this thread and open a new one (to keep things manageable).


Sounds like the conservative route should bear some consideration. Would @gbutler’s idea work here?

With 1 tweak: leave use self::<rest of path> in. This would cause all paths in 2018 to be explicit, until it can be determined which root (or roots) should support elision.


I have no strong thoughts on this, other than to point out that python originally had imports that worked as described here, and decided to switch to something like the current 2018 edition plan. Before going down this route, it would make sense to consider the reasons that python decided to move away from what is being proposed here.


Rationale from the PEP:

As Python’s library expands, more and more existing package internal modules suddenly shadow standard library modules by accident.

It’s a particularly difficult problem inside packages because there’s no way to specify which module is meant.

The second problem doesn’t apply at all; the first problem feels a lot different in Rust, since std isn’t growing and the conflicts would be with library names (which also require an explicit addition to Cargo.toml).

My feeling is that, as long as we have ergonomic unambiguous syntax, these conflicts shouldn’t be an issue.


When you say, “described here” do you mean the 2018 Current vs new possible proposal or do you mean the alternative with explicit absolute path indicators everywhere that absolute paths are desired?

Which route are you referring to when you say, “this route”?

Which proposal are you saying Python moved away from?

Sorry, I’m just not sure I understand which proposal is which in what you said and how Python’s previous proposals vs current situation relate to the 3 different alternatives discussed in this thread.