-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Explicitly export core and std macros #139493
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
base: master
Are you sure you want to change the base?
Explicitly export core and std macros #139493
Conversation
Currently all core and std macros are automatically added to the prelude via #[macro_use]. However a situation arose where we want to add a new macro `assert_matches` but don't want to pull it into the standard prelude for compatibility reasons. By explicitly exporting the macros found in the core and std crates we get to decide on a per macro basis and can later add them via the rust_20xx preludes.
r? @ChrisDenton rustbot has assigned @ChrisDenton. Use |
r? @Amanieu |
This comment has been minimized.
This comment has been minimized.
|
||
use super::*; | ||
// Explicit import to avoid macro namespace collision. | ||
use super::{arena, client, DecodeMut, Encode, fxhash, Mark, Marked, Reader, server, Unmark, Writer}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What collision is this? Is this something that user code is likely to encounter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is the error that I get when not making this change:
error[E0659]: `panic` is ambiguous
--> library/proc_macro/src/bridge/symbol.rs:41:17
|
41 | panic!("`{}` cannot be a raw identifier", string);
| ^^^^^ ambiguous name
|
= note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
note: `panic` could refer to the macro imported here
--> library/proc_macro/src/bridge/symbol.rs:19:5
|
19 | use super::*;
| ^^^^^^^^
= help: consider adding an explicit import of `panic` to disambiguate
= help: or use `self::panic` to refer to this macro unambiguously
note: `panic` could also refer to the macro defined here
--> /rust/library/std/src/prelude/mod.rs:157:13
|
157 | pub use super::v1::*;
| ^^^^^^^^^
My reasoning is a follows, this special proc macro is built together with std which gives access to std via super
, causing the import ambiguity. I don't think this is an issue for user code since normal crates can't access std via super
- I checked - and I assume normal proc macros can't either, but I'm no expert in that area.
This comment has been minimized.
This comment has been minimized.
@Amanieu the tidy issue highlights an annoying and unforeseen side-effect of this change. The fn xx(i: vec::IntoIter<i32>) {
let _ = i.as_slice();
}
fn main() {} that currently doesn't compile on stable would now compile. Initially I thought this would cause name collisions if users define their own |
There's an issue for this change - #53977. |
@Voultapher, avoiding the vec module re-export can be done like this: #[macro_export]
macro_rules! myvec {
() => {};
}
pub mod myvec {
pub struct Vec;
}
pub mod prelude {
// Bad: re-exports both macro and type namespace
// pub use crate::myvec;
mod vec_macro_only {
#[allow(hidden_glob_reexports)]
mod myvec {}
pub use crate::*;
}
pub use self::vec_macro_only::myvec;
}
fn main() {
prelude::myvec!();
let _: prelude::myvec::Vec; // error
} |
|
This comment has been minimized.
This comment has been minimized.
@Voultapher Based on the CI failure I think that a try build would fail now. |
Ok, I'll try to get the CI passing first. |
@petrochenkov I went through all macros and searched the docs and |
The job Click to see the possible cause of the failure (guessed by this bot)
|
@Amanieu this program previously worked: use std::*;
fn main() {
panic!("panic works")
} and now runs into:
I don't see how we can resolve that without changing language import rules and or special casing the prelude import. |
@petrochenkov Do you have any ideas about that? |
Could you add a test making sure that the modules |
The ambiguity wouldn't happen if it was the same panic in std root and in the stdlib prelude. Previously |
That's an interesting point. Correspondingly, today, this is an error: use core::*;
fn main() {
panic!(); //~ ERROR `panic` is ambiguous
} What are the obstacles to cc @m-ou-se |
I'd forgotten about |
These macros are actually not the same, at least when invoked from Rust ≤2018: use core::panic as c;
use std::panic as s;
fn main() {
// Different behavior in Rust ≤2018:
edition::rust_2018! {
c!(String::new()); // error
s!(String::new()); // ok
c!(&String::new()); // ok
s!(&String::new()); // error
}
// Identical behavior in Rust ≥2021:
edition::rust_2021! {
c!(String::new()); // error
s!(String::new()); // error
c!(&String::new()); // error
s!(&String::new()); // error
}
} |
I can change the std v1 prelude to handle it like
pub mod rust_2021 {
#[stable(feature = "prelude_2021", since = "1.55.0")]
#[doc(no_inline)]
pub use super::v1::*;
#[stable(feature = "prelude_2021", since = "1.55.0")]
#[doc(no_inline)]
pub use core::prelude::rust_2021::*;
} What we need is to import Option (A) could be easier done if we introduce an intermediate layer that is the core prelude minus panic, and then there is the real prelude that adds panic. But before I embark on that journey I'd like to get your feedback. |
Exporting the std panic explicitly |
Small update, while looking into and fixing the UI tests last week I noticed that there will have to be more compiler changes, at least one lint will need to be changed and possibly more code. I've not yet had the time to look into it in detail. |
Currently all core and std macros are automatically added to the prelude via #[macro_use]. However a situation arose where we want to add a new macro
assert_matches
but don't want to pull it into the standard prelude for compatibility reasons. By explicitly exporting the macros found in the core and std crates we get to decide on a per macro basis and can later add them via the rust_20xx preludes.Closes #53977
Unlocks #137487