Skip to content
Closed
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ pub struct SyntaxExtension {
/// Edition of the crate in which this macro is defined.
pub edition: Edition,
/// Built-in macros have a couple of special properties like availability
/// in `#[no_implicit_prelude]` modules, so we have to keep this flag.
/// in `#[no_prelude]` modules, so we have to keep this flag.
pub builtin_name: Option<Symbol>,
}

Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,9 @@ declare_features! (
/// Allows arbitrary expressions in key-value attributes at parse time.
(active, extended_key_value_attributes, "1.50.0", Some(78835), None),

/// Allow #![no_prelude] to disable prelude for current module
(active, no_prelude, "1.51.0", Some(20561), None),

/// `:pat2018` and `:pat2021` macro matchers.
(active, edition_macro_pats, "1.51.0", Some(54883), None),

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
ungated!(path, Normal, template!(NameValueStr: "file")),
ungated!(no_std, CrateLevel, template!(Word)),
ungated!(no_implicit_prelude, Normal, template!(Word)),
gated!(
no_prelude, Normal, template!(Word),
"experimental feature: replacement for #![no_implicit_prelude] that is not inherited by descendants"
),
ungated!(non_exhaustive, AssumedUsed, template!(Word)),

// Runtime
Expand Down
9 changes: 6 additions & 3 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,10 +761,13 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {

ItemKind::Mod(..) => {
let module_kind = ModuleKind::Def(DefKind::Mod, def_id, ident.name);
let inheritable_no_prelude = parent.pass_on_no_prelude
|| self.r.session.contains_name(&item.attrs, sym::no_implicit_prelude);
let local_no_prelude = inheritable_no_prelude
|| self.r.session.contains_name(&item.attrs, sym::no_prelude);
let module = self.r.arenas.alloc_module(ModuleData {
no_implicit_prelude: parent.no_implicit_prelude || {
self.r.session.contains_name(&item.attrs, sym::no_implicit_prelude)
},
pass_on_no_prelude: inheritable_no_prelude,
no_prelude: local_no_prelude,
..ModuleData::new(Some(parent), module_kind, def_id, expansion, item.span)
});
self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
// We can see through blocks
} else {
// Items from the prelude
if !module.no_implicit_prelude {
if !module.no_prelude {
let extern_prelude = self.r.extern_prelude.clone();
names.extend(extern_prelude.iter().flat_map(|(ident, _)| {
self.r.crate_loader.maybe_process_path_extern(ident.name).and_then(
Expand Down
25 changes: 18 additions & 7 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,12 @@ pub struct ModuleData<'a> {
unexpanded_invocations: RefCell<FxHashSet<ExpnId>>,

/// Whether `#[no_implicit_prelude]` is active.
no_implicit_prelude: bool,
/// And should therefore be active in decendant modules
pass_on_no_prelude: bool,

/// Whether `#[no_prelude]` or `#[no_implicit_prelude]` is active.
/// And therefore the current modul should use no prelude
no_prelude: bool,

glob_importers: RefCell<Vec<&'a Import<'a>>>,
globs: RefCell<Vec<&'a Import<'a>>>,
Expand Down Expand Up @@ -524,7 +529,8 @@ impl<'a> ModuleData<'a> {
lazy_resolutions: Default::default(),
populate_on_access: Cell::new(!nearest_parent_mod.is_local()),
unexpanded_invocations: Default::default(),
no_implicit_prelude: false,
pass_on_no_prelude: false,
no_prelude: false,
glob_importers: RefCell::new(Vec::new()),
globs: RefCell::new(Vec::new()),
traits: RefCell::new(None),
Expand Down Expand Up @@ -1207,13 +1213,18 @@ impl<'a> Resolver<'a> {
let root_local_def_id = LocalDefId { local_def_index: CRATE_DEF_INDEX };
let root_def_id = root_local_def_id.to_def_id();
let root_module_kind = ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty);
let inheritable_no_prelude = session.contains_name(&krate.attrs, sym::no_implicit_prelude);
let local_no_prelude =
inheritable_no_prelude || session.contains_name(&krate.attrs, sym::no_prelude);
let graph_root = arenas.alloc_module(ModuleData {
no_implicit_prelude: session.contains_name(&krate.attrs, sym::no_implicit_prelude),
pass_on_no_prelude: inheritable_no_prelude,
no_prelude: local_no_prelude,
..ModuleData::new(None, root_module_kind, root_def_id, ExpnId::root(), krate.span)
});
let empty_module_kind = ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty);
let empty_module = arenas.alloc_module(ModuleData {
no_implicit_prelude: true,
pass_on_no_prelude: true,
no_prelude: true,
..ModuleData::new(
Some(graph_root),
empty_module_kind,
Expand Down Expand Up @@ -1724,7 +1735,7 @@ impl<'a> Resolver<'a> {
MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
};
let mut ctxt = ctxt.normalize_to_macros_2_0();
let mut use_prelude = !module.no_implicit_prelude;
let mut use_prelude = !module.no_prelude;

loop {
let visit = match scope {
Expand Down Expand Up @@ -1795,7 +1806,7 @@ impl<'a> Resolver<'a> {
ValueNS | MacroNS => break,
},
Scope::Module(module) => {
use_prelude = !module.no_implicit_prelude;
use_prelude = !module.no_prelude;
match self.hygienic_lexical_parent(module, &mut ctxt) {
Some(parent_module) => Scope::Module(parent_module),
None => {
Expand Down Expand Up @@ -1967,7 +1978,7 @@ impl<'a> Resolver<'a> {
}
}

if !module.no_implicit_prelude {
if !module.no_prelude {
ident.span.adjust(ExpnId::root());
if ns == TypeNS {
if let Some(binding) = self.extern_prelude_get(ident, !record_used) {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,7 @@ symbols! {
no_main,
no_mangle,
no_niche,
no_prelude,
no_sanitize,
no_stack_check,
no_start,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
// for `ByRef`. The right answer was to consider the result ambiguous
// until more type information was available.

#![feature(lang_items)]
#![no_implicit_prelude]
#![feature(no_prelude, lang_items)]
#![no_prelude]

use std::marker::Sized;
use std::option::Option::{None, Some, self};
Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/associated-types/associated-types-issue-20346.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Test that we reliably check the value of the associated type.

#![crate_type = "lib"]
#![no_implicit_prelude]
#![feature(no_prelude)]
#![no_prelude]

use std::option::Option::{self, None, Some};
use std::vec::Vec;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0271]: type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
--> $DIR/associated-types-issue-20346.rs:34:5
--> $DIR/associated-types-issue-20346.rs:35:5
|
LL | fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
| ------ required by this bound in `is_iterator_of`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
// for `ByRef`. The right answer was to consider the result ambiguous
// until more type information was available.

#![feature(lang_items)]
#![no_implicit_prelude]
#![feature(no_prelude, lang_items)]
#![no_prelude]

use std::marker::Sized;
use std::option::Option::{None, Some, self};
Expand Down
63 changes: 63 additions & 0 deletions src/test/ui/attributes/no-prelude-nested.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#![feature(no_prelude)]

// Test that things from the prelude aren't in scope. Use many of them
// so that renaming some things won't magically make this test fail
// for the wrong reason (e.g. if `Add` changes to `Addition`, and
// `no_prelude` stops working, then the `impl Add` will still
// fail with the same error message).
//
// Unlike `no_implicit_prelude`, `no_prelude` doesn't cascade into nested
// modules, this makes the impl in foo::baz work.

#[no_prelude]
mod foo {
mod baz {
struct Test;
impl From<Test> for Test {
fn from(t: Test) {
Test
}
}
impl Clone for Test {
fn clone(&self) {
Test
}
}
impl Eq for Test {}

fn foo() {
drop(2)
}
}

struct Test;
impl From for Test {} //~ ERROR: cannot find trait
impl Clone for Test {} //~ ERROR: expected trait, found derive macro
impl Iterator for Test {} //~ ERROR: cannot find trait
impl ToString for Test {} //~ ERROR: cannot find trait
impl Eq for Test {} //~ ERROR: expected trait, found derive macro

fn foo() {
drop(2) //~ ERROR: cannot find function `drop`
}
}

fn qux() {
#[no_prelude]
mod qux_inner {
struct Test;
impl From for Test {} //~ ERROR: cannot find trait
impl Clone for Test {} //~ ERROR: expected trait, found derive macro
impl Iterator for Test {} //~ ERROR: cannot find trait
impl ToString for Test {} //~ ERROR: cannot find trait
impl Eq for Test {} //~ ERROR: expected trait, found derive macro
fn foo() {
drop(2) //~ ERROR: cannot find function `drop`
}
}
}

fn main() {
// these should work fine
drop(2)
}
136 changes: 136 additions & 0 deletions src/test/ui/attributes/no-prelude-nested.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
error[E0405]: cannot find trait `From` in this scope
--> $DIR/no-prelude-nested.rs:34:10
|
LL | impl From for Test {}
| ^^^^ not found in this scope
|
help: consider importing this trait
|
LL | use std::convert::From;
|

error[E0404]: expected trait, found derive macro `Clone`
--> $DIR/no-prelude-nested.rs:35:10
|
LL | impl Clone for Test {}
| ^^^^^ not a trait
|
help: consider importing this trait instead
|
LL | use std::clone::Clone;
|

error[E0405]: cannot find trait `Iterator` in this scope
--> $DIR/no-prelude-nested.rs:36:10
|
LL | impl Iterator for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing this trait
|
LL | use std::iter::Iterator;
|

error[E0405]: cannot find trait `ToString` in this scope
--> $DIR/no-prelude-nested.rs:37:10
|
LL | impl ToString for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing this trait
|
LL | use std::string::ToString;
|

error[E0404]: expected trait, found derive macro `Eq`
--> $DIR/no-prelude-nested.rs:38:10
|
LL | impl Eq for Test {}
| ^^ not a trait
|
help: consider importing this trait instead
|
LL | use std::cmp::Eq;
|

error[E0425]: cannot find function `drop` in this scope
--> $DIR/no-prelude-nested.rs:41:9
|
LL | drop(2)
| ^^^^ not found in this scope
|
help: consider importing this function
|
LL | use std::mem::drop;
|

error[E0405]: cannot find trait `From` in this scope
--> $DIR/no-prelude-nested.rs:49:14
|
LL | impl From for Test {}
| ^^^^ not found in this scope
|
help: consider importing this trait
|
LL | use std::convert::From;
|

error[E0404]: expected trait, found derive macro `Clone`
--> $DIR/no-prelude-nested.rs:50:14
|
LL | impl Clone for Test {}
| ^^^^^ not a trait
|
help: consider importing this trait instead
|
LL | use std::clone::Clone;
|

error[E0405]: cannot find trait `Iterator` in this scope
--> $DIR/no-prelude-nested.rs:51:14
|
LL | impl Iterator for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing this trait
|
LL | use std::iter::Iterator;
|

error[E0405]: cannot find trait `ToString` in this scope
--> $DIR/no-prelude-nested.rs:52:14
|
LL | impl ToString for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing this trait
|
LL | use std::string::ToString;
|

error[E0404]: expected trait, found derive macro `Eq`
--> $DIR/no-prelude-nested.rs:53:14
|
LL | impl Eq for Test {}
| ^^ not a trait
|
help: consider importing this trait instead
|
LL | use std::cmp::Eq;
|

error[E0425]: cannot find function `drop` in this scope
--> $DIR/no-prelude-nested.rs:55:13
|
LL | drop(2)
| ^^^^ not found in this scope
|
help: consider importing this function
|
LL | use std::mem::drop;
|

error: aborting due to 12 previous errors

Some errors have detailed explanations: E0404, E0405, E0425.
For more information about an error, try `rustc --explain E0404`.
19 changes: 19 additions & 0 deletions src/test/ui/attributes/no-prelude.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![feature(no_prelude)]
#![no_prelude]

// Test that things from the prelude aren't in scope. Use many of them
// so that renaming some things won't magically make this test fail
// for the wrong reason (e.g. if `Add` changes to `Addition`, and
// `no_prelude` stops working, then the `impl Add` will still
// fail with the same error message).

struct Test;
impl Add for Test {} //~ ERROR: cannot find trait
impl Clone for Test {} //~ ERROR: expected trait, found derive macro
impl Iterator for Test {} //~ ERROR: cannot find trait
impl ToString for Test {} //~ ERROR: cannot find trait
impl Writer for Test {} //~ ERROR: cannot find trait

fn main() {
drop(2) //~ ERROR: cannot find function `drop`
}
Loading