Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use proc_macro regressed from nightly-2018-09-14 to nightly 2018-09-15 in edition 2018 #54418

Closed
LukasKalbertodt opened this issue Sep 21, 2018 · 11 comments

Comments

@LukasKalbertodt
Copy link
Member

LukasKalbertodt commented Sep 21, 2018

Use statements for proc_macro that worked in nightly-(2ab3eba 2018-09-14) don't work in (e4ba1d4 2018-09-15) (including all newer nightlies up to at least (3bc2ca7 2018-09-20) and the RC1 beta) anymore.

I tried this code:

src/lib.rs

use proc_macro::TokenStream;

#[proc_macro]
pub fn foo(input: TokenStream) -> TokenStream {
    input
}

Cargo.toml

[package]
name = "proc-fail"
version = "0.1.0"
authors = ["me"]
edition = "2018"

[lib]
proc-macro = true

[dependencies]

As said, compiling with (2ab3eba 2018-09-14), everything works. But compiling with (e4ba1d4 2018-09-15) results in:

Error (1)

error[E0432]: unresolved import `proc_macro`
 --> src/lib.rs:3:5
  |
3 | use proc_macro::TokenStream;
  |     ^^^^^^^^^^ Could not find `proc_macro` in `{{root}}`

I tried different configurations with the two different nightly versions. The error in edition = "2015" without the extern crate is expected, of course (or is it? I'm confused now).

With nightly-(2ab3eba 2018-09-14):

edition = "2015" edition = "2018"
with extern crate proc_macro works works
without extern crate proc_macro fails (3) works

With nightly- (e4ba1d4 2018-09-15):

edition = "2015" edition = "2018"
with extern crate proc_macro works fails (2)
without extern crate proc_macro fails (3) fails (1) (the case described above)

Error (2)

error[E0432]: unresolved import `proc_macro`
 --> src/lib.rs:3:5
  |
3 | use proc_macro::TokenStream;
  |     ^^^^^^^^^^ Did you mean `self::proc_macro`?

Error (3)

error[E0432]: unresolved import `proc_macro`
 --> src/lib.rs:3:5
  |
3 | use proc_macro::TokenStream;
  |     ^^^^^^^^^^ Did you mean `registrar::proc_macro`?

I couldn't really find any information about this. So the only way to make it work right now is to either use edition 2015 with extern crate or edition 2018 with extern crate and use self::proc_macro.

Is this intended or an unwanted regression?

@petrochenkov
Copy link
Contributor

@LukasKalbertodt

Is this intended or an unwanted regression?

Intended, #54116 is the relevant PR.

@LukasKalbertodt
Copy link
Member Author

@petrochenkov Thanks!

So what's the intended solution for Rust 2018 now? extern crate proc_macro; use self::proc_macro? That seems wrong :/
As I understand it, meta is only a placeholder and not yet usable.

@petrochenkov
Copy link
Contributor

petrochenkov commented Sep 21, 2018

Yes, for now extern crate proc_macro; is the solution on stable, until --extern crate_name is stabilized in some form.

@LukasKalbertodt
Copy link
Member Author

@petrochenkov But just adding extern crate proc_macro; doesn't solve the problem. Here as a full example again:

src/lib.rs

extern crate proc_macro;

use proc_macro::TokenStream;


#[proc_macro]
pub fn foo(input: TokenStream) -> TokenStream {
    input
}

Cargo.toml

[package]
name = "proc-fail"
version = "0.1.0"
authors = ["me"]
edition = "2018"

[lib]
proc-macro = true

[dependencies]

Executing cargo +nightly-2018-09-16 build results in (note nightly-2018-09-16 is (e4ba1d41e 2018-09-15)):

error[E0432]: unresolved import `proc_macro`
 --> src/lib.rs:3:5
  |
3 | use proc_macro::TokenStream;
  |     ^^^^^^^^^^ Did you mean `self::proc_macro`?

Is this also intended?

@petrochenkov
Copy link
Contributor

@LukasKalbertodt
No, this is not intended.

Minimal reproduction:

// --edition 2018
extern crate proc_macro;
use proc_macro::TokenStream; // ERROR unresolved import `proc_macro`

fn main() {}

cc @eddyb

@petrochenkov
Copy link
Contributor

petrochenkov commented Sep 21, 2018

Workaround:

// --edition 2018
extern crate proc_macro;
use crate::proc_macro::TokenStream; // OK

fn main() {}

@eddyb
Copy link
Member

eddyb commented Sep 21, 2018

We can't make extern crate extend the extern prelude, can we? I haven't seen a plan for doing so, or how it would be sound wrt fixpoint searches.

@petrochenkov
Copy link
Contributor

@eddyb
The question is why use proc_macro::... doesn't resolve to proc_macro from the current module (self::proc_macro) introduced by the extern crate item.

@petrochenkov
Copy link
Contributor

Oh, crap.
feature(uniform_path) is still not enabled by default.

@petrochenkov
Copy link
Contributor

So, yes, with "anchored path" model (#53130) this works as intended, even if it looks pretty bad.

@LukasKalbertodt
Copy link
Member Author

@petrochenkov Ahhh ok, now I get it. That makes sense, even if it's a bit unfortunate. So I will just use self::proc_macro for now.

bors added a commit that referenced this issue Oct 24, 2018
Add `extern crate` items to extern prelude

With this patch each `extern crate orig_name as name` item adds name `name` into the extern prelude, as if it was passed with `--extern`.

What changes this causes in practice?
Almost none! After all, `--extern` passed from Cargo was supposed to replace `extern crate` items in source, so if some code has `extern crate` item (or had it on 2015 edition), then it most likely uses `--extern` as well...

... with exception of a few important cases.

- Crates using `proc_macro`. `proc_macro` is not passed with `--extern` right now and is therefore not in extern prelude.
Together with 2018 edition import behavior this causes problems like #54418, e.g.
    ```rust
    extern crate proc_macro;
    use proc_macro::TokenStream;
    ```
    doesn't work.
It starts working after this patch.

- `#[no_std]` crates using `std` conditionally, like @aturon described in #53166 (comment), and still wanting to write `std` instead of `crate::std`. This PR covers that case as well.
This allows us to revert placing `std` into the extern prelude unconditionally, which was, I think, a [bad idea](#53166 (comment)).

- Later `extern crate` syntax can be extended to support adding an alias to some local path to extern prelude, as it may be required for resolving #54647.

Notes:
- Only `extern crate` items from the root module added to the prelude, mostly because this behavior for items from inner modules would look very strange, rather than for technical reasons.
This means you can opt out from the prelude additions with something like
    ```rust
    mod inner {
        pub(crate) extern crate foo;
    }
    use inner::foo;
    ```
- I haven't updated logic for 2018 import canaries to work fully correctly with this. The cases where it matters are pretty exotic (the `extern crate` item must be "sufficiently macro expanded") and I'd rather spend the time on eliminating the canaries entirely.
bors added a commit that referenced this issue Oct 24, 2018
Add `extern crate` items to extern prelude

With this patch each `extern crate orig_name as name` item adds name `name` into the extern prelude, as if it was passed with `--extern`.

What changes this causes in practice?
Almost none! After all, `--extern` passed from Cargo was supposed to replace `extern crate` items in source, so if some code has `extern crate` item (or had it on 2015 edition), then it most likely uses `--extern` as well...

... with exception of a few important cases.

- Crates using `proc_macro`. `proc_macro` is not passed with `--extern` right now and is therefore not in extern prelude.
Together with 2018 edition import behavior this causes problems like #54418, e.g.
    ```rust
    extern crate proc_macro;
    use proc_macro::TokenStream;
    ```
    doesn't work.
It starts working after this patch.

- `#[no_std]` crates using `std` conditionally, like @aturon described in #53166 (comment), and still wanting to write `std` instead of `crate::std`. This PR covers that case as well.
This allows us to revert placing `std` into the extern prelude unconditionally, which was, I think, a [bad idea](#53166 (comment)).

- Later `extern crate` syntax can be extended to support adding an alias to some local path to extern prelude, as it may be required for resolving #54647.

Notes:
- Only `extern crate` items from the root module added to the prelude, mostly because this behavior for items from inner modules would look very strange, rather than for technical reasons.
This means you can opt out from the prelude additions with something like
    ```rust
    mod inner {
        pub(crate) extern crate foo;
    }
    use inner::foo;
    ```
- I haven't updated logic for 2018 import canaries to work fully correctly with this. The cases where it matters are pretty exotic (the `extern crate` item must be "sufficiently macro expanded") and I'd rather spend the time on eliminating the canaries entirely.
bors added a commit that referenced this issue Oct 25, 2018
Add `extern crate` items to extern prelude

With this patch each `extern crate orig_name as name` item adds name `name` into the extern prelude, as if it was passed with `--extern`.

What changes this causes in practice?
Almost none! After all, `--extern` passed from Cargo was supposed to replace `extern crate` items in source, so if some code has `extern crate` item (or had it on 2015 edition), then it most likely uses `--extern` as well...

... with exception of a few important cases.

- Crates using `proc_macro`. `proc_macro` is not passed with `--extern` right now and is therefore not in extern prelude.
Together with 2018 edition import behavior this causes problems like #54418, e.g.
    ```rust
    extern crate proc_macro;
    use proc_macro::TokenStream;
    ```
    doesn't work.
It starts working after this patch.

- `#[no_std]` crates using `std` conditionally, like @aturon described in #53166 (comment), and still wanting to write `std` instead of `crate::std`. This PR covers that case as well.
This allows us to revert placing `std` into the extern prelude unconditionally, which was, I think, a [bad idea](#53166 (comment)).

- Later `extern crate` syntax can be extended to support adding an alias to some local path to extern prelude, as it may be required for resolving #54647.

Notes:
- Only `extern crate` items from the root module added to the prelude, mostly because this behavior for items from inner modules would look very strange, rather than for technical reasons.
This means you can opt out from the prelude additions with something like
    ```rust
    mod inner {
        pub(crate) extern crate foo;
    }
    use inner::foo;
    ```
- I haven't updated logic for 2018 import canaries to work fully correctly with this. The cases where it matters are pretty exotic (the `extern crate` item must be "sufficiently macro expanded") and I'd rather spend the time on eliminating the canaries entirely.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants