Skip to content

Commit 060de10

Browse files
committed
auto merge of #7844 : huonw/rust/no-implicit-prelude, r=alexcrichton
It disables the insertion of `use std::prelude::*;` into the top of all the modules below the item on which it is placed (including that item itself). (Similar to GHC's `-XNoImplicitPrelude`.)
2 parents 9c1e530 + 040e470 commit 060de10

File tree

3 files changed

+116
-1
lines changed

3 files changed

+116
-1
lines changed

src/librustc/front/std_inject.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::crate)
3232
fn use_std(crate: &ast::crate) -> bool {
3333
!attr::attrs_contains_name(crate.node.attrs, "no_std")
3434
}
35+
fn no_prelude(attrs: &[ast::attribute]) -> bool {
36+
attr::attrs_contains_name(attrs, "no_implicit_prelude")
37+
}
3538

3639
fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate {
3740
fn spanned<T:Copy>(x: T) -> codemap::spanned<T> {
@@ -63,7 +66,12 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate {
6366
view_items: vis,
6467
../*bad*/copy crate.module
6568
};
66-
new_module = fld.fold_mod(&new_module);
69+
70+
if !no_prelude(crate.attrs) {
71+
// only add `use std::prelude::*;` if there wasn't a
72+
// `#[no_implicit_prelude];` at the crate level.
73+
new_module = fld.fold_mod(&new_module);
74+
}
6775

6876
// FIXME #2543: Bad copy.
6977
let new_crate = ast::crate_ {
@@ -72,6 +80,16 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate {
7280
};
7381
(new_crate, span)
7482
},
83+
fold_item: |item, fld| {
84+
if !no_prelude(item.attrs) {
85+
// only recur if there wasn't `#[no_implicit_prelude];`
86+
// on this item, i.e. this means that the prelude is not
87+
// implicitly imported though the whole subtree
88+
fold::noop_fold_item(item, fld)
89+
} else {
90+
Some(item)
91+
}
92+
},
7593
fold_mod: |module, fld| {
7694
let n2 = sess.next_node_id();
7795

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that things from the prelude aren't in scope. Use many of them
12+
// so that renaming some things won't magically make this test fail
13+
// for the wrong reason (e.g. if `Add` changes to `Addition`, and
14+
// `no_implicit_prelude` stops working, then the `impl Add` will still
15+
// fail with the same error message).
16+
17+
#[no_implicit_prelude]
18+
mod foo {
19+
mod baz {
20+
struct Test;
21+
impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
22+
impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
23+
impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
24+
impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
25+
impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
26+
27+
fn foo() {
28+
print("foo"); //~ ERROR: unresolved name
29+
println("bar"); //~ ERROR: unresolved name
30+
}
31+
}
32+
33+
struct Test;
34+
impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
35+
impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
36+
impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
37+
impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
38+
impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
39+
40+
fn foo() {
41+
print("foo"); //~ ERROR: unresolved name
42+
println("bar"); //~ ERROR: unresolved name
43+
}
44+
}
45+
46+
fn qux() {
47+
#[no_implicit_prelude]
48+
mod qux_inner {
49+
struct Test;
50+
impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
51+
impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
52+
impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
53+
impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
54+
impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
55+
56+
fn foo() {
57+
print("foo"); //~ ERROR: unresolved name
58+
println("bar"); //~ ERROR: unresolved name
59+
}
60+
}
61+
}
62+
63+
64+
fn main() {
65+
// these should work fine
66+
print("foo");
67+
println("bar");
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#[no_implicit_prelude];
12+
13+
// Test that things from the prelude aren't in scope. Use many of them
14+
// so that renaming some things won't magically make this test fail
15+
// for the wrong reason (e.g. if `Add` changes to `Addition`, and
16+
// `no_implicit_prelude` stops working, then the `impl Add` will still
17+
// fail with the same error message).
18+
19+
struct Test;
20+
impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
21+
impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
22+
impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
23+
impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
24+
impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
25+
26+
fn main() {
27+
print("foo"); //~ ERROR: unresolved name
28+
println("bar"); //~ ERROR: unresolved name
29+
}

0 commit comments

Comments
 (0)