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

Weird use issue #66

Closed
timsueberkrueb opened this issue Dec 18, 2018 · 11 comments
Closed

Weird use issue #66

timsueberkrueb opened this issue Dec 18, 2018 · 11 comments
Labels
bug Something isn't working

Comments

@timsueberkrueb
Copy link

Hey, I ran into this compiler error which I don't understand. Minimal example:

use logos::Logos;

#[derive(Logos)]
enum Token {
    #[error]
    Error,
    #[end]
    End,
}

mod example {
    use super::Token;

    fn test() {
        let t = Token::End;
    }
}

I get the following compiler error:

error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
  --> src/main.rs:12:9
   |
12 |     use super::Token;
   |         ^^^^^^^^^^^^
   |
   = note: #[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)] on by default
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #52234 <https://github.com/rust-lang/rust/issues/52234>
note: the macro is defined here
  --> src/main.rs:3:10
   |
3  | #[derive(Logos)]
   |          ^^^^^

Interestingly, I cannot reproduce this error with a dummy proc_macro derive I just wrote trying to debug this.
This is on 1.31 stable and I'm using Logos 0.9. Am I missing something? Thanks a lot in advance :)

@maciejhirsz
Copy link
Owner

This is quite peculiar. #[derive(Logos)] on top of deriving the Logos trait, also creates a helper macro with the same name as the enum, so if your enum is named Token it will also create a Token! macro that is then being used internally in the lookup! macro.

I figured this is a pretty safe abstraction since importing Token will import both the enum and the macro in one go. Ideally when const_let gets stabilized I won't have to do hacks like this. Anyway, will see if I can reproduce this.

@eira-fransham
Copy link

If you need a local helper macro you can use the private variant pattern for macros (I don't know if that fits your use case but it might be something to look at). It looks like this:

macro_rules! foo {
    // ...
    (@myprivatevariant $whatever:tt) => {
    }
}

@maciejhirsz
Copy link
Owner

It wouldn't work unfortunately, since the macros are in different places (one is defined in the logos crate, the other is generated from the derive).

@maciejhirsz maciejhirsz added the bug Something isn't working label Dec 20, 2018
@maciejhirsz
Copy link
Owner

Was talking to @Vurich who provided me with a better hack to make lookup! work using just const fn without const_let (and by all that is sacred, is it both magnificent and ugly).

@eira-fransham
Copy link

eira-fransham commented Dec 20, 2018

For the sake of future archaeologists, this is the hack: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=59da2fac8e7a17ea287337f7cf5730a5

We need this to emulate this:

static TABLE: [Garbage; Token::SIZE] = {
    let table = [some_default; Token::SIZE];

    table[Token::Foo as usize] = foo_value;
    table[Token::Bar as usize] = bar_value;

    table
}; 

without const_let.

@CAD97
Copy link
Contributor

CAD97 commented Feb 23, 2019

This is still an issue that I just ran into with a token at the root of my crate.

error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
 --> pegcel\meta\src\generated.rs:7:5
  |
7 |     crate::Token,
  |     ^^^^^^^^^^^^
  |
  = note: #[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)] on by default
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #52234 <https://github.com/rust-lang/rust/issues/52234>
note: the macro is defined here
 --> pegcel\meta\src\lib.rs:6:10
  |
6 | #[derive(Logos)]
  |          ^^^^^

What's the clientside workaround currently, and what needs to happen to remove the unneeded export?

@CAD97
Copy link
Contributor

CAD97 commented Feb 24, 2019

Side note: this might be a bug in rustc. If I'm reading the linked PR correctly, it's supposed to prevent use from the path to the declaration, but the #[macro_export] path at the root directory should remain accessable. Or I could have it backwards. But here they're both the same path, and I'm pretty sure one of them is supposed to work.

@maciejhirsz
Copy link
Owner

I kinda got stuck on this one, the solution I thought would work doesn't really (I either restrict myself to Copy types only or am forced to use macros at levels at which I don't have access to literals).

The problem is definitely having two different macro definitions with #[macro_export] in the same crate, even though they are in different modules. You should be able to import them with use without name conflicts, but, alas you can't even compile it. If that got solved in rustc that would be great, but then const let would solve the issue in a much more elegant way to begin with.

@maciejhirsz
Copy link
Owner

Well, const let just landed, so I'll scrap the whole macro :D

@maciejhirsz
Copy link
Owner

Released v0.10.0-rc2 with a fix to this.

@CAD97
Copy link
Contributor

CAD97 commented Apr 25, 2019

Since I ended up doing some digging that led back to this: rust-lang/rust#53270 is the reason for the error. The macro just wasn't imported from non-crate-root locations and is gated from being imported from crate-root location, so because it had the same name as the type, it made the type unimportable from crate-root location.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants