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

strange scoping issue when trying to use alloc::vec![] #61699

Closed
alex opened this issue Jun 9, 2019 · 4 comments · Fixed by #61629
Closed

strange scoping issue when trying to use alloc::vec![] #61699

alex opened this issue Jun 9, 2019 · 4 comments · Fixed by #61629
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-resolve Area: Path resolution C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@alex
Copy link
Member

alex commented Jun 9, 2019

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

#![no_std]

extern crate alloc;

use alloc::vec::Vec;

pub fn f() -> Vec<u8> {
    let x = alloc::vec![
        0,
    ].into_boxed_slice();
    return x.to_vec();
}
   Compiling playground v0.0.1 (/playground)
error: cannot find macro `vec!` in this scope
  --> src/lib.rs:8:13
   |
8  |       let x = alloc::vec![
   |  _____________^
9  | |         0,
10 | |     ].into_boxed_slice();
   | |_____^
   |
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error: aborting due to previous error

error: Could not compile `playground`.

If I change the invocation to alloc::vec![] it has no trouble finding the invocation. I have no idea what to make of this.

@jonas-schievink jonas-schievink added A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-resolve Area: Path resolution T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Jun 9, 2019
@petrochenkov
Copy link
Contributor

Fixed in #61629

@alex
Copy link
Member Author

alex commented Jun 9, 2019

Thanks!

@jonas-schievink jonas-schievink added the C-bug Category: This is a bug. label Jun 9, 2019
@petrochenkov
Copy link
Contributor

petrochenkov commented Jun 9, 2019

The workaround is to remove the trailing comma after 0 inside vec![], then vec won't call itself recursively (which is causing the error).

@alex
Copy link
Member Author

alex commented Jun 9, 2019

Yup, now that you've pointed it out it's completely clear what was happening :-/

Centril added a commit to Centril/rust that referenced this issue Jun 12, 2019
Hygienize macros in the standard library

Same as rust-lang#55597, but for all macros in the standard library.
Nested macro calls will now call what they are intended to call rather than whatever is in the closest scope at call site.
Technically this is a breaking change, so crater run would probably be useful.

---

One exception that is not hygienized is calls to `panic!(...)`.
Macros defined in libcore do not want to call `core::panic`.
What they really want to call is either `std::panic` or `core::panic` depending on `no_std` settings.
EDIT: After some thought, recursive calls to `panic` from `panic` itself probably do want to use `$crate` (UPDATE: done).

Calling `std::panic` from macros defined in std and "whatever `panic` is in scope" from macros defined in libcore is probably even worse than always calling "whatever `panic` is in scope", so I kept the existing code.

The only way to do the std/core switch correctly that I'm aware of is to define a built-in panic macro that would dispatch to `std::panic` or `core::panic` using compiler magic.
Then standard library macros could delegate to this built-in macro.
The macro could be named `panic` too, that would fix rust-lang#61567.
(This PR doesn't do that.)

---
cc rust-lang#56389
cc rust-lang#61567
Fixes rust-lang#61699
r? @alexcrichton
Centril added a commit to Centril/rust that referenced this issue Jun 12, 2019
Hygienize macros in the standard library

Same as rust-lang#55597, but for all macros in the standard library.
Nested macro calls will now call what they are intended to call rather than whatever is in the closest scope at call site.
Technically this is a breaking change, so crater run would probably be useful.

---

One exception that is not hygienized is calls to `panic!(...)`.
Macros defined in libcore do not want to call `core::panic`.
What they really want to call is either `std::panic` or `core::panic` depending on `no_std` settings.
EDIT: After some thought, recursive calls to `panic` from `panic` itself probably do want to use `$crate` (UPDATE: done).

Calling `std::panic` from macros defined in std and "whatever `panic` is in scope" from macros defined in libcore is probably even worse than always calling "whatever `panic` is in scope", so I kept the existing code.

The only way to do the std/core switch correctly that I'm aware of is to define a built-in panic macro that would dispatch to `std::panic` or `core::panic` using compiler magic.
Then standard library macros could delegate to this built-in macro.
The macro could be named `panic` too, that would fix rust-lang#61567.
(This PR doesn't do that.)

---
cc rust-lang#56389
cc rust-lang#61567
Fixes rust-lang#61699
r? @alexcrichton
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-resolve Area: Path resolution C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants