Rollup merge of #55630 - petrochenkov:noprelude, r=Centril
resolve: Filter away macro prelude in modules with `#[no_implicit_prelude]` on 2018 edition This is a tiny thing. For historical reasons macro prelude (macros from `#[macro_use] extern crate ...`, including `extern crate std`) is still available in modules with `#[no_implicit_prelude]`. This PR provides proper isolation and removes those names from scope. `#[no_implicit_prelude]` modules still have built-in types (`u8`), built-in attributes (`#[inline]`) and built-in macros (`env!("PATH")`) in scope. We can introduce some `#[no_implicit_prelude_at_all]` to remove those as well, but that's a separate issue. The change is done only on 2018 edition for backward compatibility. I'm pretty sure this can be done on 2015 as well because `#[no_implicit_prelude]` is rarely used, but I don't want to go through the crater/deprecation process right now, maybe later. cc https://github.com/rust-lang/rust/issues/53977 r? @ghost
This commit is contained in:
commit
75e920f847
@ -963,6 +963,10 @@ impl Session {
|
||||
self.opts.debugging_opts.teach && self.diagnostic().must_teach(code)
|
||||
}
|
||||
|
||||
pub fn rust_2015(&self) -> bool {
|
||||
self.opts.edition == Edition::Edition2015
|
||||
}
|
||||
|
||||
/// Are we allowed to use features from the Rust 2018 edition?
|
||||
pub fn rust_2018(&self) -> bool {
|
||||
self.opts.edition >= Edition::Edition2018
|
||||
|
@ -663,10 +663,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||
binding.map(|binding| (binding, Flags::MODULE, Flags::empty()))
|
||||
}
|
||||
WhereToResolve::MacroUsePrelude => {
|
||||
match self.macro_use_prelude.get(&ident.name).cloned() {
|
||||
Some(binding) => Ok((binding, Flags::PRELUDE, Flags::empty())),
|
||||
None => Err(Determinacy::Determined),
|
||||
let mut result = Err(Determinacy::Determined);
|
||||
if use_prelude || self.session.rust_2015() {
|
||||
if let Some(binding) = self.macro_use_prelude.get(&ident.name).cloned() {
|
||||
result = Ok((binding, Flags::PRELUDE, Flags::empty()));
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
WhereToResolve::BuiltinMacros => {
|
||||
match self.builtin_macros.get(&ident.name).cloned() {
|
||||
@ -685,7 +688,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||
}
|
||||
}
|
||||
WhereToResolve::LegacyPluginHelpers => {
|
||||
if self.session.plugin_attributes.borrow().iter()
|
||||
if (use_prelude || self.session.rust_2015()) &&
|
||||
self.session.plugin_attributes.borrow().iter()
|
||||
.any(|(name, _)| ident.name == &**name) {
|
||||
let binding = (Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper),
|
||||
ty::Visibility::Public, ident.span, Mark::root())
|
||||
|
11
src/test/ui/hygiene/no_implicit_prelude-2018.rs
Normal file
11
src/test/ui/hygiene/no_implicit_prelude-2018.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// edition:2018
|
||||
|
||||
#[no_implicit_prelude]
|
||||
mod bar {
|
||||
fn f() {
|
||||
::std::print!(""); // OK
|
||||
print!(); //~ ERROR cannot find macro `print!` in this scope
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
10
src/test/ui/hygiene/no_implicit_prelude-2018.stderr
Normal file
10
src/test/ui/hygiene/no_implicit_prelude-2018.stderr
Normal file
@ -0,0 +1,10 @@
|
||||
error: cannot find macro `print!` in this scope
|
||||
--> $DIR/no_implicit_prelude-2018.rs:7:9
|
||||
|
|
||||
LL | print!(); //~ ERROR cannot find macro `print!` in this scope
|
||||
| ^^^^^
|
||||
|
|
||||
= help: have you added the `#[macro_use]` on the module/import?
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -21,7 +21,10 @@ mod bar {
|
||||
Vec::new(); //~ ERROR failed to resolve
|
||||
().clone() //~ ERROR no method named `clone` found
|
||||
}
|
||||
fn f() { ::foo::m!(); }
|
||||
fn f() {
|
||||
::foo::m!();
|
||||
println!(); // OK on 2015 edition (at least for now)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user