rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
96.98k stars 12.54k forks source link

(Modules) Tracking issue for `(use) crate_name::` paths without `extern crate` #53128

Closed Centril closed 5 years ago

Centril commented 6 years ago

This is a sub-tracking issue for the RFC "Clarify and streamline paths and visibility" (rust-lang/rfcs#2126) dealing with the deprecation of extern crate as well as having use crate_name::foo::bar and crate_name::foo::bar Just Work™.

Unresolved questions:

None

rfcbot commented 6 years ago

The final comment period, with a disposition to merge, as per the review above, is now complete.

sanmai-NL commented 6 years ago

@Centril: in the OP you mention macro_use. AFAIK this has been solved, one can use macros and https://github.com/rust-lang/rust/issues/53128#issuecomment-419210498 seems to confirm this issue has been solved. Could you update the OP for other readers?

spearman commented 5 years ago

Is there an opt-out for this?

Crates are not required to have the same name as their packages, so as far as I know there's really there's no way to know what's in scope by looking at either the source or Cargo.toml without looking at yet another Cargo.toml for the extern crate to see what [lib] is named. That sounds like a huge headache and a bad default. Correct me if I'm wrong.

At least by requiring 'extern crate' to appear before use you're required to declare the crate name somewhere in the source code. It seems much better than having to look outside of the source tree, much less having to go look at the Cargo.toml of a completely different project.

mark-i-m commented 5 years ago

I've been using this feature for a while now and haven't had any problems. My guess is that the vast majority of crates use the same name and crates.io name (at least all of the ones I use do).

On the contrary, this is one of the most noticable ergonomics improvements in rust 2018 IMHO, and that's saying a lot because there are many nice features.

mark-i-m commented 5 years ago

Are there any specific crates that have caused you particular headache?

spearman commented 5 years ago

The only one that I can think of right now is the fmod package, for which the library is named rfmod (and to confuse things more the repository is named rust-fmod).

In other languages it's a common requirement that imports are declared before use. Haskell and Python both have import statements, C and C++ have includes. I never have found this to be 'un-ergonomic'. In fact it's very useful to be able to look at the first 10 or so lines of a single-file main.rs and see exactly what is being used within it. What doesn't make sense to me with this change, and I think might be confusing for beginners, is why what seems like an expected part of the language (declaring external dependencies) is being pushed into the build system (cargo)?

sanmai-NL commented 5 years ago

@spearman: I see the issue, and I have suffered it too. IMO, the proper solution is for crates.io and more generally Cargo registry tooling to enforce that ‘crates’ (packages) are named the same as the root module.

rpjohnst commented 5 years ago

In other languages it's a common requirement that imports are declared before use.

This isn't changing. You still have use or fully-qualified paths; the only thing going away is the redundant extern crate some_name before the more-useful use some_name::actual_item.

joshtriplett commented 5 years ago

@spearman Because the build system has to know about it, and it shouldn't appear in two places.

Regarding fmod, and other crates that differ from their package names, I wonder if it might be worth going through those and working with their authors to transition to having the two match, for simplicity's sake alone?

@rpjohnst :+1:

sanmai-NL commented 5 years ago

@joshtriplett: Yes please! There’s also the difference in acceptance of - and _ in names. This causes needless friction. I do hope, once everyone is on board, the name rules are actually going to be enforced rather than remedied afterwards in the future.

spearman commented 5 years ago

@joshtriplett I'm arguing it should appear in both places because they do different things: extern crate in a root module declares an external dependency, and the dependency entry in the cargo manifest tells the build system where to find that dependency (whether it's on crates.io, is a git repository, or a local path, etc.)

sanmai-NL commented 5 years ago

@spearman The use statement also declares a dependency, at least it does now with the more explicit anchored paths as implemented in Rust 2018 (https://github.com/rust-lang/rust/issues/53130).

spearman commented 5 years ago

@sanmai-NL so does this become this? or this

sanmai-NL commented 5 years ago

The latter. It remains unambiguous though that rand is an external module. You can put the use statement on top at top level if you think that’s clearer.

Centril commented 5 years ago

@rust-lang/lang From what I can tell there's nothing left to do here? Shall we close this issue?

spearman commented 5 years ago

This generates a warning on nightly, not on stable:

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=e7ae48ec055a83fd451ead26301cef44

cramertj commented 5 years ago

@spearman It's correct to generate a warning for that code-- the use of rand::random() does not require use rand; in the 2018 edition.

spearman commented 5 years ago

Previously warn(unused_extern_crates) was a way to detect unused dependencies. How can I:

1) declare dependencies in the root module 2) be warned when those dependencies are not used

As it is now, cargo builds all dependencies and does not warn if they are unused.

cramertj commented 5 years ago

@spearman You cannot currently do what you describe.

mark-i-m commented 5 years ago

That seems unfortunate... perhaps its worth it's own issue?

alexreg commented 5 years ago

@mark-i-m Yeah, I'd create one. A PR to add a new lint for this probably wouldn't be too hard.

mark-i-m commented 5 years ago

Opened #57274

Centril commented 5 years ago

I believe this is done now so I'll close this out.

mark-i-m commented 5 years ago

@Centril Was this issue supposed to cover getting rid of extern crate altogether? Because we have not done that yet; you still need it for core, std, etc

cramertj commented 5 years ago

@mark-i-m Are you referring to how std-surfaced macro intrinsics aren't yet usable by their std paths? e.g. This code only works if you remove std:::

fn main() {
    println!("{}", std::format_args!("{}", 5));
}
error[E0433]: failed to resolve: could not find `format_args` in `std`
 --> src/main.rs:2:25
  |
2 |     println!("{}", std::format_args!("{}", 5));
  |                         ^^^^^^^^^^^ could not find `format_args` in `std`

error: aborting due to previous error
mark-i-m commented 5 years ago

@cramertj Not sure. It might be related. I was thinking more about how one must do things like extern crate core in no_std crates. You still have to do that for sysroot crates.

Centril commented 5 years ago

@mark-i-m Could you create targeted issues for the remaining work if there is any? That way it's easier to triage... :)

mark-i-m commented 5 years ago

I opened #57288.

@cramertj I don't fully understand the error you brought up. Is it the same one or different? Should I create a new tracking issue for it?

cramertj commented 5 years ago

@mark-i-m It is a different issue. Sure, if you would that would be great!

mark-i-m commented 5 years ago

Done. #57289 :)