about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc_driver/driver.rs7
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs11
-rw-r--r--src/librustc_resolve/lib.rs32
-rw-r--r--src/librustc_resolve/resolve_imports.rs2
-rw-r--r--src/libsyntax/std_inject.rs172
5 files changed, 79 insertions, 145 deletions
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index b28d203ed8d..41afa43fe28 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -601,7 +601,8 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
     })?;
 
     krate = time(time_passes, "crate injection", || {
-        syntax::std_inject::maybe_inject_crates_ref(krate, sess.opts.alt_std_name.clone())
+        let alt_std_name = sess.opts.alt_std_name.clone();
+        syntax::std_inject::maybe_inject_crates_ref(&sess.parse_sess, krate, alt_std_name)
     });
 
     let macros = time(time_passes,
@@ -720,10 +721,6 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
                                          sess.diagnostic())
     });
 
-    krate = time(time_passes,
-                 "prelude injection",
-                 || syntax::std_inject::maybe_inject_prelude(&sess.parse_sess, krate));
-
     time(time_passes,
          "checking for inline asm in case the target doesn't support it",
          || no_asm::check_crate(sess, &krate));
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index c7b113689fd..775c24b6d4a 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -27,7 +27,7 @@ use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
 use rustc::ty::{self, VariantKind};
 
 use syntax::ast::Name;
-use syntax::attr::AttrMetaMethods;
+use syntax::attr;
 use syntax::parse::token;
 use syntax::codemap::{Span, DUMMY_SP};
 
@@ -57,6 +57,9 @@ impl<'a> ToNameBinding<'a> for (Def, Span, ty::Visibility) {
 impl<'b> Resolver<'b> {
     /// Constructs the reduced graph for the entire crate.
     pub fn build_reduced_graph(&mut self, krate: &Crate) {
+        let no_implicit_prelude = attr::contains_name(&krate.attrs, "no_implicit_prelude");
+        self.graph_root.no_implicit_prelude.set(no_implicit_prelude);
+
         let mut visitor = BuildReducedGraphVisitor {
             parent: self.graph_root,
             resolver: self,
@@ -128,7 +131,7 @@ impl<'b> Resolver<'b> {
                 };
 
                 // Build up the import directives.
-                let is_prelude = item.attrs.iter().any(|attr| attr.name() == "prelude_import");
+                let is_prelude = attr::contains_name(&item.attrs, "prelude_import");
 
                 match view_path.node {
                     ViewPathSimple(binding, ref full_path) => {
@@ -221,6 +224,10 @@ impl<'b> Resolver<'b> {
                 let parent_link = ModuleParentLink(parent, name);
                 let def = Def::Mod(self.definitions.local_def_id(item.id));
                 let module = self.new_module(parent_link, Some(def), false);
+                module.no_implicit_prelude.set({
+                    parent.no_implicit_prelude.get() ||
+                        attr::contains_name(&item.attrs, "no_implicit_prelude")
+                });
                 self.define(parent, name, TypeNS, (module, sp, vis));
                 self.module_map.insert(item.id, module);
                 *parent_ref = module;
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 78aa0a75dcc..0fab12c230c 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -788,7 +788,7 @@ pub struct ModuleS<'a> {
     resolutions: RefCell<HashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
     unresolved_imports: RefCell<Vec<&'a ImportDirective<'a>>>,
 
-    prelude: RefCell<Option<Module<'a>>>,
+    no_implicit_prelude: Cell<bool>,
 
     glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective<'a>)>>,
     globs: RefCell<Vec<&'a ImportDirective<'a>>>,
@@ -817,7 +817,7 @@ impl<'a> ModuleS<'a> {
             extern_crate_id: None,
             resolutions: RefCell::new(HashMap::new()),
             unresolved_imports: RefCell::new(Vec::new()),
-            prelude: RefCell::new(None),
+            no_implicit_prelude: Cell::new(false),
             glob_importers: RefCell::new(Vec::new()),
             globs: RefCell::new((Vec::new())),
             traits: RefCell::new(None),
@@ -981,6 +981,8 @@ pub struct Resolver<'a> {
 
     graph_root: Module<'a>,
 
+    prelude: Option<Module<'a>>,
+
     trait_item_map: FnvHashMap<(Name, DefId), bool /* is static method? */>,
 
     structs: FnvHashMap<DefId, Vec<Name>>,
@@ -1170,6 +1172,7 @@ impl<'a> Resolver<'a> {
             // The outermost module has def ID 0; this is not reflected in the
             // AST.
             graph_root: graph_root,
+            prelude: None,
 
             trait_item_map: FnvHashMap(),
             structs: FnvHashMap(),
@@ -1453,10 +1456,13 @@ impl<'a> Resolver<'a> {
 
                 // We can only see through anonymous modules
                 if module.def.is_some() {
-                    return module.prelude.borrow().and_then(|module| {
-                        module.resolve_name(name, ns, false)
-                              .success().map(LexicalScopeBinding::Item)
-                    });
+                    return match self.prelude {
+                        Some(prelude) if !module.no_implicit_prelude.get() => {
+                            prelude.resolve_name(name, ns, false).success()
+                                   .map(LexicalScopeBinding::Item)
+                        }
+                        _ => None,
+                    };
                 }
             }
         }
@@ -3261,7 +3267,7 @@ impl<'a> Resolver<'a> {
         let mut search_module = self.current_module;
         loop {
             // Look for trait children.
-            let mut search_in_module = |module: Module<'a>| {
+            let mut search_in_module = |this: &mut Self, module: Module<'a>| {
                 let mut traits = module.traits.borrow_mut();
                 if traits.is_none() {
                     let mut collected_traits = Vec::new();
@@ -3276,23 +3282,25 @@ impl<'a> Resolver<'a> {
 
                 for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
                     let trait_def_id = binding.def().unwrap().def_id();
-                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
+                    if this.trait_item_map.contains_key(&(name, trait_def_id)) {
                         let mut import_id = None;
                         if let NameBindingKind::Import { directive, .. } = binding.kind {
                             let id = directive.id;
-                            self.maybe_unused_trait_imports.insert(id);
+                            this.maybe_unused_trait_imports.insert(id);
                             import_id = Some(id);
                         }
                         add_trait_info(&mut found_traits, trait_def_id, import_id, name);
-                        self.record_use(trait_name, binding);
+                        this.record_use(trait_name, binding);
                     }
                 }
             };
-            search_in_module(search_module);
+            search_in_module(self, search_module);
 
             match search_module.parent_link {
                 NoParentLink | ModuleParentLink(..) => {
-                    search_module.prelude.borrow().map(search_in_module);
+                    if !search_module.no_implicit_prelude.get() {
+                        self.prelude.map(|prelude| search_in_module(self, prelude));
+                    }
                     break;
                 }
                 BlockParentLink(parent_module, _) => {
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index f4c38e76123..629b687d8f7 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -624,7 +624,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
         self.resolver.populate_module_if_necessary(target_module);
 
         if let GlobImport { is_prelude: true } = directive.subclass {
-            *module_.prelude.borrow_mut() = Some(target_module);
+            self.resolver.prelude = Some(target_module);
             return Success(());
         }
 
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index 84a7b144848..8834c026067 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -12,12 +12,9 @@ use ast;
 use attr;
 use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
 use codemap;
-use fold::Folder;
-use fold;
 use parse::token::{intern, InternedString, keywords};
 use parse::{token, ParseSess};
 use ptr::P;
-use util::small_vector::SmallVector;
 
 /// Craft a span that will be ignored by the stability lint's
 /// call to codemap's is_internal check.
@@ -37,33 +34,6 @@ fn ignored_span(sess: &ParseSess, sp: Span) -> Span {
     return sp;
 }
 
-pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>)
-                               -> ast::Crate {
-    if no_core(&krate) {
-        krate
-    } else {
-        let name = if no_std(&krate) {"core"} else {"std"};
-        let mut fold = CrateInjector {
-            item_name: token::str_to_ident(name),
-            crate_name: token::intern(&alt_std_name.unwrap_or(name.to_string())),
-        };
-        fold.fold_crate(krate)
-    }
-}
-
-pub fn maybe_inject_prelude(sess: &ParseSess, krate: ast::Crate) -> ast::Crate {
-    if no_core(&krate) {
-        krate
-    } else {
-        let name = if no_std(&krate) {"core"} else {"std"};
-        let mut fold = PreludeInjector {
-            span: ignored_span(sess, DUMMY_SP),
-            crate_identifier: token::str_to_ident(name),
-        };
-        fold.fold_crate(krate)
-    }
-}
-
 pub fn no_core(krate: &ast::Crate) -> bool {
     attr::contains_name(&krate.attrs, "no_core")
 }
@@ -72,102 +42,54 @@ pub fn no_std(krate: &ast::Crate) -> bool {
     attr::contains_name(&krate.attrs, "no_std") || no_core(krate)
 }
 
-fn no_prelude(attrs: &[ast::Attribute]) -> bool {
-    attr::contains_name(attrs, "no_implicit_prelude")
-}
-
-struct CrateInjector {
-    item_name: ast::Ident,
-    crate_name: ast::Name,
-}
-
-impl fold::Folder for CrateInjector {
-    fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
-        krate.module.items.insert(0, P(ast::Item {
-            id: ast::DUMMY_NODE_ID,
-            ident: self.item_name,
-            attrs: vec!(
-                attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
-                        InternedString::new("macro_use")))),
-            node: ast::ItemKind::ExternCrate(Some(self.crate_name)),
-            vis: ast::Visibility::Inherited,
-            span: DUMMY_SP
-        }));
-
-        krate
-    }
-}
-
-struct PreludeInjector {
-    span: Span,
-    crate_identifier: ast::Ident,
-}
-
-impl fold::Folder for PreludeInjector {
-    fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
-        // only add `use std::prelude::*;` if there wasn't a
-        // `#![no_implicit_prelude]` at the crate level.
-        // fold_mod() will insert glob path.
-        if !no_prelude(&krate.attrs) {
-            krate.module = self.fold_mod(krate.module);
-        }
-        krate
-    }
-
-    fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
-        if !no_prelude(&item.attrs) {
-            // only recur if there wasn't `#![no_implicit_prelude]`
-            // on this item, i.e. this means that the prelude is not
-            // implicitly imported though the whole subtree
-            fold::noop_fold_item(item, self)
-        } else {
-            SmallVector::one(item)
-        }
+pub fn maybe_inject_crates_ref(sess: &ParseSess,
+                               mut krate: ast::Crate,
+                               alt_std_name: Option<String>)
+                               -> ast::Crate {
+    if no_core(&krate) {
+        return krate;
     }
 
-    fn fold_mod(&mut self, mut mod_: ast::Mod) -> ast::Mod {
-        let prelude_path = ast::Path {
-            span: self.span,
+    let name = if no_std(&krate) { "core" } else { "std" };
+    let crate_name = token::intern(&alt_std_name.unwrap_or(name.to_string()));
+
+    krate.module.items.insert(0, P(ast::Item {
+        attrs: vec![attr::mk_attr_outer(attr::mk_attr_id(),
+                                        attr::mk_word_item(InternedString::new("macro_use")))],
+        vis: ast::Visibility::Inherited,
+        node: ast::ItemKind::ExternCrate(Some(crate_name)),
+        ident: token::str_to_ident(name),
+        id: ast::DUMMY_NODE_ID,
+        span: DUMMY_SP,
+    }));
+
+    let span = ignored_span(sess, DUMMY_SP);
+    krate.module.items.insert(0, P(ast::Item {
+        attrs: vec![ast::Attribute {
+            node: ast::Attribute_ {
+                style: ast::AttrStyle::Outer,
+                value: P(ast::MetaItem {
+                    node: ast::MetaItemKind::Word(token::intern_and_get_ident("prelude_import")),
+                    span: span,
+                }),
+                id: attr::mk_attr_id(),
+                is_sugared_doc: false,
+            },
+            span: span,
+        }],
+        vis: ast::Visibility::Inherited,
+        node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path {
             global: false,
-            segments: vec![
-                ast::PathSegment {
-                    identifier: self.crate_identifier,
-                    parameters: ast::PathParameters::none(),
-                },
-                ast::PathSegment {
-                    identifier: token::str_to_ident("prelude"),
-                    parameters: ast::PathParameters::none(),
-                },
-                ast::PathSegment {
-                    identifier: token::str_to_ident("v1"),
-                    parameters: ast::PathParameters::none(),
-                },
-            ],
-        };
-
-        let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path)));
-        mod_.items.insert(0, P(ast::Item {
-            id: ast::DUMMY_NODE_ID,
-            ident: keywords::Invalid.ident(),
-            node: ast::ItemKind::Use(vp),
-            attrs: vec![ast::Attribute {
-                span: self.span,
-                node: ast::Attribute_ {
-                    id: attr::mk_attr_id(),
-                    style: ast::AttrStyle::Outer,
-                    value: P(ast::MetaItem {
-                        span: self.span,
-                        node: ast::MetaItemKind::Word(
-                            token::intern_and_get_ident("prelude_import")
-                        ),
-                    }),
-                    is_sugared_doc: false,
-                },
-            }],
-            vis: ast::Visibility::Inherited,
-            span: self.span,
-        }));
-
-        fold::noop_fold_mod(mod_, self)
-    }
+            segments: vec![name, "prelude", "v1"].into_iter().map(|name| ast::PathSegment {
+                identifier: token::str_to_ident(name),
+                parameters: ast::PathParameters::none(),
+            }).collect(),
+            span: span,
+        })))),
+        id: ast::DUMMY_NODE_ID,
+        ident: keywords::Invalid.ident(),
+        span: span,
+    }));
+
+    krate
 }