Skip to content

Consistent no_prelude attribute #80427

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

Closed
wants to merge 12 commits into from
Closed
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
@@ -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>,
}

3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
@@ -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),

4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
@@ -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
9 changes: 6 additions & 3 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
@@ -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));
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -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(
25 changes: 18 additions & 7 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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>>>,
@@ -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),
@@ -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,
@@ -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 {
@@ -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 => {
@@ -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) {
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -753,6 +753,7 @@ symbols! {
no_main,
no_mangle,
no_niche,
no_prelude,
no_sanitize,
no_stack_check,
no_start,
Original file line number Diff line number Diff line change
@@ -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};
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;
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`
Original file line number Diff line number Diff line change
@@ -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};
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`
}
65 changes: 65 additions & 0 deletions src/test/ui/attributes/no-prelude.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
error[E0405]: cannot find trait `Add` in this scope
--> $DIR/no-prelude.rs:11:6
|
LL | impl Add for Test {}
| ^^^ not found in this scope
|
help: consider importing this trait
|
LL | use std::ops::Add;
|

error[E0404]: expected trait, found derive macro `Clone`
--> $DIR/no-prelude.rs:12:6
|
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.rs:13:6
|
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.rs:14:6
|
LL | impl ToString for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing this trait
|
LL | use std::string::ToString;
|

error[E0405]: cannot find trait `Writer` in this scope
--> $DIR/no-prelude.rs:15:6
|
LL | impl Writer for Test {}
| ^^^^^^ not found in this scope

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

error: aborting due to 6 previous errors

Some errors have detailed explanations: E0404, E0405, E0425.
For more information about an error, try `rustc --explain E0404`.
3 changes: 2 additions & 1 deletion src/test/ui/attributes/register-attr-tool-prelude.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,8 @@
#![register_attr(attr)]
#![register_tool(tool)]

#[no_implicit_prelude]
#![feature(no_prelude)]
#[no_prelude]
mod m {
#[attr] //~ ERROR cannot find attribute `attr` in this scope
#[tool::attr] //~ ERROR failed to resolve: use of undeclared crate or module `tool`
4 changes: 2 additions & 2 deletions src/test/ui/attributes/register-attr-tool-prelude.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0433]: failed to resolve: use of undeclared crate or module `tool`
--> $DIR/register-attr-tool-prelude.rs:10:7
--> $DIR/register-attr-tool-prelude.rs:11:7
|
LL | #[tool::attr]
| ^^^^ use of undeclared crate or module `tool`

error: cannot find attribute `attr` in this scope
--> $DIR/register-attr-tool-prelude.rs:9:7
--> $DIR/register-attr-tool-prelude.rs:10:7
|
LL | #[attr]
| ^^^^
4 changes: 4 additions & 0 deletions src/test/ui/feature-gates/feature-gate-no_prelude.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#![no_prelude] //~ ERROR: experimental feature: replacement for #![no_implicit_prelude]
//~^ HELP: feature(no_prelude)

fn main(){}
12 changes: 12 additions & 0 deletions src/test/ui/feature-gates/feature-gate-no_prelude.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0658]: experimental feature: replacement for #![no_implicit_prelude] that is not inherited by descendants
--> $DIR/feature-gate-no_prelude.rs:1:1
|
LL | #![no_prelude]
| ^^^^^^^^^^^^^^
|
= note: see issue #20561 <https://github.com/rust-lang/rust/issues/20561> for more information
= help: add `#![feature(no_prelude)]` to the crate attributes to enable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.
3 changes: 2 additions & 1 deletion src/test/ui/issues/issue-21363.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// check-pass
// pretty-expanded FIXME #23616

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

trait Iterator {
type Item;
3 changes: 2 additions & 1 deletion src/test/ui/macros/issue-78333.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// build-pass

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

fn main() {
::std::panic!();
12 changes: 12 additions & 0 deletions src/test/ui/unused/unused-no_prelude.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![no_implicit_prelude]
#![feature(no_prelude)]
#![deny(unused_attributes)]
#![no_prelude]
//~^ ERROR: unused attribute

mod unused {
#![no_prelude]
//~^ ERROR: unused attribute
}

fn main() {}
20 changes: 20 additions & 0 deletions src/test/ui/unused/unused-no_prelude.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: unused attribute
--> $DIR/unused-no_prelude.rs:8:5
|
LL | #![no_prelude]
| ^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/unused-no_prelude.rs:3:9
|
LL | #![deny(unused_attributes)]
| ^^^^^^^^^^^^^^^^^

error: unused attribute
--> $DIR/unused-no_prelude.rs:4:1
|
LL | #![no_prelude]
| ^^^^^^^^^^^^^^

error: aborting due to 2 previous errors