Skip to content

Rust stable 1.30 allows use of extern crates without declaration #55478

Closed
@jrobsonchase

Description

@jrobsonchase

Example crate(s): https://github.com/jrobsonchase/cloud_to_butt

It appears that rust stable 1.30 allows the use of absolute paths to items from other crates without the extern crate declaration. This works in code, but not in use statements.

I originally thought it was just a proc-macro crate problem since that's where I noticed it first, but it shows up in both. See https://github.com/jrobsonchase/cloud_to_butt/blob/master/src/lib.rs#L28 and https://github.com/jrobsonchase/cloud_to_butt/blob/master/cloud/src/main.rs#L10. Both contain full paths to syn/proc_macro2 items that shouldn't be available since there's been no extern crate for either.

my rustc version:

rustc 1.30.0 (da5f414c2 2018-10-24)

Activity

changed the title [-]Rust stable 1.30 proc-macro crates allow use of extern crates without declaration[/-] [+]Rust stable 1.30 allows use of extern crates without declaration[/+] on Oct 29, 2018
petrochenkov

petrochenkov commented on Oct 29, 2018

@petrochenkov
Contributor

This is by design, crate names passed with --extern are put into prelude and available from the whole crate without imports for compatibility with 2018 edition, but also for convenience.

This is what the "Module system improvements" section in the announce blog post attempted to convey.

jrobsonchase

jrobsonchase commented on Oct 29, 2018

@jrobsonchase
Author
petrochenkov

petrochenkov commented on Oct 29, 2018

@petrochenkov
Contributor

@jrobsonchase
Yes, use on 2015 edition still uses paths relative to the crate root, so for use my_crate::foo; to work my_crate must be somehow defined in the crate root, usually via extern crate my_crate;.
On 2018 edition imports will be able to work without extern crate my_crate; items too, making extern crate nearly obsolete.

So, on 2015, I think, there's now a choice between two guidelines on how to use extern crate items:

  1. Add extern crate items only if necessary for imports, and
  2. Add extern crate for all used crates for consistency (or to support older versions of rustc).
jrobsonchase

jrobsonchase commented on Oct 29, 2018

@jrobsonchase
Author
petrochenkov

petrochenkov commented on Oct 29, 2018

@petrochenkov
Contributor

it's intended behavior to be able to use things from
dependency crates without extern crate as long as you use the full path

Yes, "full path" -> "relative path starting with a crate name" to be precise.

but as soon as you want to refactor and bring things into local scope with
use, then you need extern crate as well

Correct.

If so, I find that to be an
extremely unintuitive intermediate step between 2015's "you must always
have extern crate declarations" and 2018's "you almost never need extern crate."

In this case you may want to follow the guideline 2. and use extern crate for everything.

petrochenkov

petrochenkov commented on Oct 29, 2018

@petrochenkov
Contributor

FWIW, unresolved imports still explicitly recommend adding an extern crate item:

error[E0432]: unresolved import `my_crate`
 --> src/main.rs:1:5
  |
1 | use my_crate::foo;
  |     ^^^^^^^^ Maybe a missing `extern crate my_crate;`?

so it's clear what to do when a person unfamiliar with the rules encounters this error.

jrobsonchase

jrobsonchase commented on Oct 29, 2018

@jrobsonchase
Author
petrochenkov

petrochenkov commented on Oct 29, 2018

@petrochenkov
Contributor

Because some_crate::do_something() and use some_crate::do_something are resolved very differently (relative paths vs absolute paths).
(That was always a source of confusion, and the whole 2018 module system overhaul started from the desire to remove this distinction.)

(By the way, other prelude names behave very similarly, i.e. you can write Vec::new(), but not use Vec;, println!(...), but not use println;).

petrochenkov

petrochenkov commented on Dec 18, 2018

@petrochenkov
Contributor

My plan so far is to implement fallback from crate-relative names (crate::foo) to extern crates (extern::foo) in imports (use foo::bar) on 2015 edition and make crater experiment.
If everything is good, we'll be able to support use my_crate::bar imports on Rust 2015 as well as on Rust 2018.

self-assigned this
on Dec 18, 2018
added a commit that references this issue on Jan 18, 2019

Auto merge of #57745 - petrochenkov:uni2015, r=<try>

petrochenkov

petrochenkov commented on Jan 18, 2019

@petrochenkov
Contributor

My plan so far is to implement fallback from crate-relative names (crate::foo) to extern crates (extern::foo) in imports (use foo::bar) on 2015 edition and make crater experiment.

#57745 is implementation of that plan.

added
A-resolveArea: Name/path resolution done by `rustc_resolve` specifically
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Jan 27, 2019
petrochenkov

petrochenkov commented on Mar 21, 2019

@petrochenkov
Contributor

There was not enough interest in addressing this issue in #57745, closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-resolveArea: Name/path resolution done by `rustc_resolve` specificallyT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @jrobsonchase@jonas-schievink@petrochenkov

      Issue actions

        Rust stable 1.30 allows use of extern crates without declaration · Issue #55478 · rust-lang/rust