Auto merge of #34108 - jseyfried:refactor_prelude_injection, r=nrc
Refactor away the prelude injection fold Instead, just inject `#[prelude_import] use [core|std]::prelude::v1::*;` at the crate root while injecting `extern crate [core|std];` and process `#[no_implicit_prelude]` attributes in `resolve`. r? @nrc
This commit is contained in:
@@ -601,7 +601,8 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
krate = time(time_passes, "crate injection", || {
|
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 mut addl_plugins = Some(addl_plugins);
|
let mut addl_plugins = Some(addl_plugins);
|
||||||
@@ -729,10 +730,6 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
|
|||||||
sess.diagnostic())
|
sess.diagnostic())
|
||||||
});
|
});
|
||||||
|
|
||||||
krate = time(time_passes,
|
|
||||||
"prelude injection",
|
|
||||||
|| syntax::std_inject::maybe_inject_prelude(&sess.parse_sess, krate));
|
|
||||||
|
|
||||||
time(time_passes,
|
time(time_passes,
|
||||||
"checking for inline asm in case the target doesn't support it",
|
"checking for inline asm in case the target doesn't support it",
|
||||||
|| no_asm::check_crate(sess, &krate));
|
|| no_asm::check_crate(sess, &krate));
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
|
|||||||
use rustc::ty::{self, VariantKind};
|
use rustc::ty::{self, VariantKind};
|
||||||
|
|
||||||
use syntax::ast::Name;
|
use syntax::ast::Name;
|
||||||
use syntax::attr::AttrMetaMethods;
|
use syntax::attr;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::codemap::{Span, DUMMY_SP};
|
use syntax::codemap::{Span, DUMMY_SP};
|
||||||
|
|
||||||
@@ -57,6 +57,9 @@ impl<'a> ToNameBinding<'a> for (Def, Span, ty::Visibility) {
|
|||||||
impl<'b> Resolver<'b> {
|
impl<'b> Resolver<'b> {
|
||||||
/// Constructs the reduced graph for the entire crate.
|
/// Constructs the reduced graph for the entire crate.
|
||||||
pub fn build_reduced_graph(&mut self, krate: &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 {
|
let mut visitor = BuildReducedGraphVisitor {
|
||||||
parent: self.graph_root,
|
parent: self.graph_root,
|
||||||
resolver: self,
|
resolver: self,
|
||||||
@@ -128,7 +131,7 @@ impl<'b> Resolver<'b> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Build up the import directives.
|
// 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 {
|
match view_path.node {
|
||||||
ViewPathSimple(binding, ref full_path) => {
|
ViewPathSimple(binding, ref full_path) => {
|
||||||
@@ -221,6 +224,10 @@ impl<'b> Resolver<'b> {
|
|||||||
let parent_link = ModuleParentLink(parent, name);
|
let parent_link = ModuleParentLink(parent, name);
|
||||||
let def = Def::Mod(self.definitions.local_def_id(item.id));
|
let def = Def::Mod(self.definitions.local_def_id(item.id));
|
||||||
let module = self.new_module(parent_link, Some(def), false);
|
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.define(parent, name, TypeNS, (module, sp, vis));
|
||||||
self.module_map.insert(item.id, module);
|
self.module_map.insert(item.id, module);
|
||||||
*parent_ref = module;
|
*parent_ref = module;
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ enum ResolutionError<'a> {
|
|||||||
/// error E0413: cannot be named the same as an enum variant or unit-like struct in scope
|
/// error E0413: cannot be named the same as an enum variant or unit-like struct in scope
|
||||||
DeclarationShadowsEnumVariantOrUnitLikeStruct(Name),
|
DeclarationShadowsEnumVariantOrUnitLikeStruct(Name),
|
||||||
/// error E0414: only irrefutable patterns allowed here
|
/// error E0414: only irrefutable patterns allowed here
|
||||||
ConstantForIrrefutableBinding(Name),
|
ConstantForIrrefutableBinding(Name, &'a NameBinding<'a>),
|
||||||
/// error E0415: identifier is bound more than once in this parameter list
|
/// error E0415: identifier is bound more than once in this parameter list
|
||||||
IdentifierBoundMoreThanOnceInParameterList(&'a str),
|
IdentifierBoundMoreThanOnceInParameterList(&'a str),
|
||||||
/// error E0416: identifier is bound more than once in the same pattern
|
/// error E0416: identifier is bound more than once in the same pattern
|
||||||
@@ -317,19 +317,15 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
|
|||||||
&format!("has same name as enum variant or unit-like struct"));
|
&format!("has same name as enum variant or unit-like struct"));
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
ResolutionError::ConstantForIrrefutableBinding(name) => {
|
ResolutionError::ConstantForIrrefutableBinding(name, binding) => {
|
||||||
let mut err = struct_span_err!(resolver.session,
|
let mut err = struct_span_err!(resolver.session,
|
||||||
span,
|
span,
|
||||||
E0414,
|
E0414,
|
||||||
"let variables cannot be named the same as const variables");
|
"let variables cannot be named the same as const variables");
|
||||||
err.span_label(span,
|
err.span_label(span,
|
||||||
&format!("cannot be named the same as a const variable"));
|
&format!("cannot be named the same as a const variable"));
|
||||||
if let Some(binding) = resolver.current_module
|
let participle = if binding.is_import() { "imported" } else { "defined" };
|
||||||
.resolve_name_in_lexical_scope(name, ValueNS) {
|
err.span_label(binding.span, &format!("a constant `{}` is {} here", name, participle));
|
||||||
let participle = if binding.is_import() { "imported" } else { "defined" };
|
|
||||||
err.span_label(binding.span, &format!("a constant `{}` is {} here",
|
|
||||||
name, participle));
|
|
||||||
}
|
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
|
ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
|
||||||
@@ -714,9 +710,9 @@ enum AssocItemResolveResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
enum BareIdentifierPatternResolution {
|
enum BareIdentifierPatternResolution<'a> {
|
||||||
FoundStructOrEnumVariant(Def),
|
FoundStructOrEnumVariant(Def),
|
||||||
FoundConst(Def, Name),
|
FoundConst(&'a NameBinding<'a>, Name),
|
||||||
BareIdentifierPatternUnresolved,
|
BareIdentifierPatternUnresolved,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -792,7 +788,7 @@ pub struct ModuleS<'a> {
|
|||||||
resolutions: RefCell<HashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
|
resolutions: RefCell<HashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
|
||||||
unresolved_imports: RefCell<Vec<&'a ImportDirective<'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>)>>,
|
glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective<'a>)>>,
|
||||||
globs: RefCell<Vec<&'a ImportDirective<'a>>>,
|
globs: RefCell<Vec<&'a ImportDirective<'a>>>,
|
||||||
@@ -821,7 +817,7 @@ impl<'a> ModuleS<'a> {
|
|||||||
extern_crate_id: None,
|
extern_crate_id: None,
|
||||||
resolutions: RefCell::new(HashMap::new()),
|
resolutions: RefCell::new(HashMap::new()),
|
||||||
unresolved_imports: RefCell::new(Vec::new()),
|
unresolved_imports: RefCell::new(Vec::new()),
|
||||||
prelude: RefCell::new(None),
|
no_implicit_prelude: Cell::new(false),
|
||||||
glob_importers: RefCell::new(Vec::new()),
|
glob_importers: RefCell::new(Vec::new()),
|
||||||
globs: RefCell::new((Vec::new())),
|
globs: RefCell::new((Vec::new())),
|
||||||
traits: RefCell::new(None),
|
traits: RefCell::new(None),
|
||||||
@@ -985,6 +981,8 @@ pub struct Resolver<'a> {
|
|||||||
|
|
||||||
graph_root: Module<'a>,
|
graph_root: Module<'a>,
|
||||||
|
|
||||||
|
prelude: Option<Module<'a>>,
|
||||||
|
|
||||||
trait_item_map: FnvHashMap<(Name, DefId), bool /* is static method? */>,
|
trait_item_map: FnvHashMap<(Name, DefId), bool /* is static method? */>,
|
||||||
|
|
||||||
structs: FnvHashMap<DefId, Vec<Name>>,
|
structs: FnvHashMap<DefId, Vec<Name>>,
|
||||||
@@ -1174,6 +1172,7 @@ impl<'a> Resolver<'a> {
|
|||||||
// The outermost module has def ID 0; this is not reflected in the
|
// The outermost module has def ID 0; this is not reflected in the
|
||||||
// AST.
|
// AST.
|
||||||
graph_root: graph_root,
|
graph_root: graph_root,
|
||||||
|
prelude: None,
|
||||||
|
|
||||||
trait_item_map: FnvHashMap(),
|
trait_item_map: FnvHashMap(),
|
||||||
structs: FnvHashMap(),
|
structs: FnvHashMap(),
|
||||||
@@ -1456,7 +1455,15 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We can only see through anonymous modules
|
// We can only see through anonymous modules
|
||||||
if module.def.is_some() { return None; }
|
if module.def.is_some() {
|
||||||
|
return match self.prelude {
|
||||||
|
Some(prelude) if !module.no_implicit_prelude.get() => {
|
||||||
|
prelude.resolve_name(name, ns, false).success()
|
||||||
|
.map(LexicalScopeBinding::Item)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1543,11 +1550,7 @@ impl<'a> Resolver<'a> {
|
|||||||
debug!("(resolving name in module) resolving `{}` in `{}`", name, module_to_string(module));
|
debug!("(resolving name in module) resolving `{}` in `{}`", name, module_to_string(module));
|
||||||
|
|
||||||
self.populate_module_if_necessary(module);
|
self.populate_module_if_necessary(module);
|
||||||
match use_lexical_scope {
|
module.resolve_name(name, namespace, use_lexical_scope).and_then(|binding| {
|
||||||
true => module.resolve_name_in_lexical_scope(name, namespace)
|
|
||||||
.map(Success).unwrap_or(Failed(None)),
|
|
||||||
false => module.resolve_name(name, namespace, false),
|
|
||||||
}.and_then(|binding| {
|
|
||||||
if record_used {
|
if record_used {
|
||||||
if let NameBindingKind::Import { directive, .. } = binding.kind {
|
if let NameBindingKind::Import { directive, .. } = binding.kind {
|
||||||
self.used_imports.insert((directive.id, namespace));
|
self.used_imports.insert((directive.id, namespace));
|
||||||
@@ -2289,21 +2292,21 @@ impl<'a> Resolver<'a> {
|
|||||||
);
|
);
|
||||||
self.record_def(pattern.id, err_path_resolution());
|
self.record_def(pattern.id, err_path_resolution());
|
||||||
}
|
}
|
||||||
FoundConst(def, _) if const_ok => {
|
FoundConst(binding, _) if const_ok => {
|
||||||
debug!("(resolving pattern) resolving `{}` to constant", renamed);
|
debug!("(resolving pattern) resolving `{}` to constant", renamed);
|
||||||
|
|
||||||
self.enforce_default_binding_mode(pattern, binding_mode, "a constant");
|
self.enforce_default_binding_mode(pattern, binding_mode, "a constant");
|
||||||
self.record_def(pattern.id,
|
self.record_def(pattern.id,
|
||||||
PathResolution {
|
PathResolution {
|
||||||
base_def: def,
|
base_def: binding.def().unwrap(),
|
||||||
depth: 0,
|
depth: 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
FoundConst(_, name) => {
|
FoundConst(binding, name) => {
|
||||||
resolve_error(
|
resolve_error(
|
||||||
self,
|
self,
|
||||||
pattern.span,
|
pattern.span,
|
||||||
ResolutionError::ConstantForIrrefutableBinding(name)
|
ResolutionError::ConstantForIrrefutableBinding(name, binding)
|
||||||
);
|
);
|
||||||
self.record_def(pattern.id, err_path_resolution());
|
self.record_def(pattern.id, err_path_resolution());
|
||||||
}
|
}
|
||||||
@@ -2526,7 +2529,7 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_bare_identifier_pattern(&mut self, ident: ast::Ident, span: Span)
|
fn resolve_bare_identifier_pattern(&mut self, ident: ast::Ident, span: Span)
|
||||||
-> BareIdentifierPatternResolution {
|
-> BareIdentifierPatternResolution<'a> {
|
||||||
let binding = match self.resolve_ident_in_lexical_scope(ident, ValueNS, true) {
|
let binding = match self.resolve_ident_in_lexical_scope(ident, ValueNS, true) {
|
||||||
Some(LexicalScopeBinding::Item(binding)) => binding,
|
Some(LexicalScopeBinding::Item(binding)) => binding,
|
||||||
_ => return BareIdentifierPatternUnresolved,
|
_ => return BareIdentifierPatternUnresolved,
|
||||||
@@ -2535,7 +2538,7 @@ impl<'a> Resolver<'a> {
|
|||||||
|
|
||||||
match def {
|
match def {
|
||||||
Def::Variant(..) | Def::Struct(..) => FoundStructOrEnumVariant(def),
|
Def::Variant(..) | Def::Struct(..) => FoundStructOrEnumVariant(def),
|
||||||
Def::Const(..) | Def::AssociatedConst(..) => FoundConst(def, ident.name),
|
Def::Const(..) | Def::AssociatedConst(..) => FoundConst(binding, ident.name),
|
||||||
Def::Static(..) => {
|
Def::Static(..) => {
|
||||||
let error = ResolutionError::StaticVariableReference(binding);
|
let error = ResolutionError::StaticVariableReference(binding);
|
||||||
resolve_error(self, span, error);
|
resolve_error(self, span, error);
|
||||||
@@ -3264,7 +3267,7 @@ impl<'a> Resolver<'a> {
|
|||||||
let mut search_module = self.current_module;
|
let mut search_module = self.current_module;
|
||||||
loop {
|
loop {
|
||||||
// Look for trait children.
|
// 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();
|
let mut traits = module.traits.borrow_mut();
|
||||||
if traits.is_none() {
|
if traits.is_none() {
|
||||||
let mut collected_traits = Vec::new();
|
let mut collected_traits = Vec::new();
|
||||||
@@ -3279,23 +3282,25 @@ impl<'a> Resolver<'a> {
|
|||||||
|
|
||||||
for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
|
for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
|
||||||
let trait_def_id = binding.def().unwrap().def_id();
|
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;
|
let mut import_id = None;
|
||||||
if let NameBindingKind::Import { directive, .. } = binding.kind {
|
if let NameBindingKind::Import { directive, .. } = binding.kind {
|
||||||
let id = directive.id;
|
let id = directive.id;
|
||||||
self.maybe_unused_trait_imports.insert(id);
|
this.maybe_unused_trait_imports.insert(id);
|
||||||
import_id = Some(id);
|
import_id = Some(id);
|
||||||
}
|
}
|
||||||
add_trait_info(&mut found_traits, trait_def_id, import_id, name);
|
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 {
|
match search_module.parent_link {
|
||||||
NoParentLink | ModuleParentLink(..) => {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
BlockParentLink(parent_module, _) => {
|
BlockParentLink(parent_module, _) => {
|
||||||
|
|||||||
@@ -257,15 +257,6 @@ impl<'a> ::ModuleS<'a> {
|
|||||||
Failed(None)
|
Failed(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invariant: this may not be called until import resolution is complete.
|
|
||||||
pub fn resolve_name_in_lexical_scope(&self, name: Name, ns: Namespace)
|
|
||||||
-> Option<&'a NameBinding<'a>> {
|
|
||||||
self.resolution(name, ns).borrow().binding
|
|
||||||
.or_else(|| self.prelude.borrow().and_then(|prelude| {
|
|
||||||
prelude.resolve_name(name, ns, false).success()
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define the name or return the existing binding if there is a collision.
|
// Define the name or return the existing binding if there is a collision.
|
||||||
pub fn try_define_child(&self, name: Name, ns: Namespace, binding: NameBinding<'a>)
|
pub fn try_define_child(&self, name: Name, ns: Namespace, binding: NameBinding<'a>)
|
||||||
-> Result<(), &'a NameBinding<'a>> {
|
-> Result<(), &'a NameBinding<'a>> {
|
||||||
@@ -633,7 +624,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
|||||||
self.resolver.populate_module_if_necessary(target_module);
|
self.resolver.populate_module_if_necessary(target_module);
|
||||||
|
|
||||||
if let GlobImport { is_prelude: true } = directive.subclass {
|
if let GlobImport { is_prelude: true } = directive.subclass {
|
||||||
*module_.prelude.borrow_mut() = Some(target_module);
|
self.resolver.prelude = Some(target_module);
|
||||||
return Success(());
|
return Success(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1820,7 +1820,10 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(w, "</table>")
|
if curty.is_some() {
|
||||||
|
write!(w, "</table>")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<String> {
|
fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<String> {
|
||||||
|
|||||||
@@ -12,12 +12,9 @@ use ast;
|
|||||||
use attr;
|
use attr;
|
||||||
use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
|
use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
|
||||||
use codemap;
|
use codemap;
|
||||||
use fold::Folder;
|
|
||||||
use fold;
|
|
||||||
use parse::token::{intern, InternedString, keywords};
|
use parse::token::{intern, InternedString, keywords};
|
||||||
use parse::{token, ParseSess};
|
use parse::{token, ParseSess};
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
use util::small_vector::SmallVector;
|
|
||||||
|
|
||||||
/// Craft a span that will be ignored by the stability lint's
|
/// Craft a span that will be ignored by the stability lint's
|
||||||
/// call to codemap's is_internal check.
|
/// call to codemap's is_internal check.
|
||||||
@@ -37,33 +34,6 @@ fn ignored_span(sess: &ParseSess, sp: Span) -> Span {
|
|||||||
return sp;
|
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 {
|
pub fn no_core(krate: &ast::Crate) -> bool {
|
||||||
attr::contains_name(&krate.attrs, "no_core")
|
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)
|
attr::contains_name(&krate.attrs, "no_std") || no_core(krate)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn no_prelude(attrs: &[ast::Attribute]) -> bool {
|
pub fn maybe_inject_crates_ref(sess: &ParseSess,
|
||||||
attr::contains_name(attrs, "no_implicit_prelude")
|
mut krate: ast::Crate,
|
||||||
}
|
alt_std_name: Option<String>)
|
||||||
|
-> ast::Crate {
|
||||||
struct CrateInjector {
|
if no_core(&krate) {
|
||||||
item_name: ast::Ident,
|
return krate;
|
||||||
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>> {
|
let name = if no_std(&krate) { "core" } else { "std" };
|
||||||
if !no_prelude(&item.attrs) {
|
let crate_name = token::intern(&alt_std_name.unwrap_or(name.to_string()));
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold_mod(&mut self, mut mod_: ast::Mod) -> ast::Mod {
|
krate.module.items.insert(0, P(ast::Item {
|
||||||
let prelude_path = ast::Path {
|
attrs: vec![attr::mk_attr_outer(attr::mk_attr_id(),
|
||||||
span: self.span,
|
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,
|
global: false,
|
||||||
segments: vec![
|
segments: vec![name, "prelude", "v1"].into_iter().map(|name| ast::PathSegment {
|
||||||
ast::PathSegment {
|
identifier: token::str_to_ident(name),
|
||||||
identifier: self.crate_identifier,
|
parameters: ast::PathParameters::none(),
|
||||||
parameters: ast::PathParameters::none(),
|
}).collect(),
|
||||||
},
|
span: span,
|
||||||
ast::PathSegment {
|
})))),
|
||||||
identifier: token::str_to_ident("prelude"),
|
id: ast::DUMMY_NODE_ID,
|
||||||
parameters: ast::PathParameters::none(),
|
ident: keywords::Invalid.ident(),
|
||||||
},
|
span: span,
|
||||||
ast::PathSegment {
|
}));
|
||||||
identifier: token::str_to_ident("v1"),
|
|
||||||
parameters: ast::PathParameters::none(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path)));
|
krate
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user