use syntax::ext::base::SyntaxExtension;
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
use syntax::ext::base::MacroKind;
+use syntax::feature_gate::{emit_feature_err, GateIssue};
use syntax::symbol::{Symbol, keywords};
use syntax::util::lev_distance::find_best_match_for_name;
self.label_ribs.push(Rib::new(rib_kind));
// Add each argument to the rib.
- let mut bindings_list = FxHashMap();
+ let mut bindings_list = FxHashMap::default();
for argument in &declaration.inputs {
self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);
impl<'a> Rib<'a> {
fn new(kind: RibKind<'a>) -> Rib<'a> {
Rib {
- bindings: FxHashMap(),
+ bindings: Default::default(),
kind,
}
}
parent,
kind,
normal_ancestor_id,
- resolutions: RefCell::new(FxHashMap()),
+ resolutions: Default::default(),
legacy_macro_resolutions: RefCell::new(Vec::new()),
macro_resolutions: RefCell::new(Vec::new()),
builtin_attrs: RefCell::new(Vec::new()),
- unresolved_invocations: RefCell::new(FxHashSet()),
+ unresolved_invocations: Default::default(),
no_implicit_prelude: false,
glob_importers: RefCell::new(Vec::new()),
globs: RefCell::new(Vec::new()),
match self.kind {
NameBindingKind::Import {
directive: &ImportDirective {
- subclass: ImportDirectiveSubclass::ExternCrate(_), ..
+ subclass: ImportDirectiveSubclass::ExternCrate { .. }, ..
}, ..
} => true,
_ => false,
}
}
- fn is_renamed_extern_crate(&self) -> bool {
- if let NameBindingKind::Import { directive, ..} = self.kind {
- if let ImportDirectiveSubclass::ExternCrate(Some(_)) = directive.subclass {
- return true;
- }
- }
- false
- }
-
fn is_glob_import(&self) -> bool {
match self.kind {
NameBindingKind::Import { directive, .. } => directive.is_glob(),
///
/// All other types are defined somewhere and possibly imported, but the primitive ones need
/// special handling, since they have no place of origin.
+#[derive(Default)]
struct PrimitiveTypeTable {
primitive_types: FxHashMap<Name, PrimTy>,
}
impl PrimitiveTypeTable {
fn new() -> PrimitiveTypeTable {
- let mut table = PrimitiveTypeTable { primitive_types: FxHashMap() };
+ let mut table = PrimitiveTypeTable::default();
table.intern("bool", Bool);
table.intern("char", Char);
}
}
+#[derive(Default, Clone)]
+pub struct ExternPreludeEntry<'a> {
+ extern_crate_item: Option<&'a NameBinding<'a>>,
+ pub introduced_by_item: bool,
+}
+
/// The main resolver class.
///
/// This is the visitor that walks the whole crate.
graph_root: Module<'a>,
prelude: Option<Module<'a>>,
- pub extern_prelude: FxHashSet<Name>,
+ pub extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'a>>,
/// n.b. This is used only for better diagnostics, not name resolution itself.
has_self: FxHashSet<DefId>,
}
/// Nothing really interesting here, it just provides memory for the rest of the crate.
+#[derive(Default)]
pub struct ResolverArenas<'a> {
modules: arena::TypedArena<ModuleData<'a>>,
local_modules: RefCell<Vec<Module<'a>>>,
*def = module.def().unwrap(),
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
*def = path_res.base_def(),
- PathResult::NonModule(..) => match self.resolve_path(
- None,
- &path,
- None,
- true,
- span,
- CrateLint::No,
- ) {
- PathResult::Failed(span, msg, _) => {
+ PathResult::NonModule(..) =>
+ if let PathResult::Failed(span, msg, _) = self.resolve_path(
+ None,
+ &path,
+ None,
+ true,
+ span,
+ CrateLint::No,
+ ) {
error_callback(self, span, ResolutionError::FailedToResolve(&msg));
- }
- _ => {}
- },
+ },
PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) |
PathResult::Indeterminate => unreachable!(),
PathResult::Failed(span, msg, _) => {
no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"),
..ModuleData::new(None, root_module_kind, root_def_id, Mark::root(), krate.span)
});
- let mut module_map = FxHashMap();
+ let mut module_map = FxHashMap::default();
module_map.insert(DefId::local(CRATE_DEF_INDEX), graph_root);
let mut definitions = Definitions::new();
DefCollector::new(&mut definitions, Mark::root())
.collect_root(crate_name, session.local_crate_disambiguator());
- let mut extern_prelude: FxHashSet<Name> =
- session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect();
+ let mut extern_prelude: FxHashMap<Ident, ExternPreludeEntry> =
+ session.opts.externs.iter().map(|kv| (Ident::from_str(kv.0), Default::default()))
+ .collect();
if !attr::contains_name(&krate.attrs, "no_core") {
- extern_prelude.insert(Symbol::intern("core"));
+ extern_prelude.insert(Ident::from_str("core"), Default::default());
if !attr::contains_name(&krate.attrs, "no_std") {
- extern_prelude.insert(Symbol::intern("std"));
+ extern_prelude.insert(Ident::from_str("std"), Default::default());
if session.rust_2018() {
- extern_prelude.insert(Symbol::intern("meta"));
+ extern_prelude.insert(Ident::from_str("meta"), Default::default());
}
}
}
- let mut invocations = FxHashMap();
+ let mut invocations = FxHashMap::default();
invocations.insert(Mark::root(),
arenas.alloc_invocation_data(InvocationData::root(graph_root)));
- let mut macro_defs = FxHashMap();
+ let mut macro_defs = FxHashMap::default();
macro_defs.insert(Mark::root(), root_def_id);
Resolver {
prelude: None,
extern_prelude,
- has_self: FxHashSet(),
- field_names: FxHashMap(),
+ has_self: FxHashSet::default(),
+ field_names: FxHashMap::default(),
determined_imports: Vec::new(),
indeterminate_imports: Vec::new(),
import_map: NodeMap(),
freevars: NodeMap(),
freevars_seen: NodeMap(),
- export_map: FxHashMap(),
+ export_map: FxHashMap::default(),
trait_map: NodeMap(),
module_map,
block_map: NodeMap(),
- extern_module_map: FxHashMap(),
- binding_parent_modules: FxHashMap(),
+ extern_module_map: FxHashMap::default(),
+ binding_parent_modules: FxHashMap::default(),
make_glob_map: make_glob_map == MakeGlobMap::Yes,
glob_map: NodeMap(),
- used_imports: FxHashSet(),
+ used_imports: FxHashSet::default(),
maybe_unused_trait_imports: NodeSet(),
maybe_unused_extern_crates: Vec::new(),
- unused_labels: FxHashMap(),
+ unused_labels: FxHashMap::default(),
privacy_errors: Vec::new(),
ambiguity_errors: Vec::new(),
}),
crate_loader,
- macro_names: FxHashSet(),
- builtin_macros: FxHashMap(),
- macro_use_prelude: FxHashMap(),
- all_macros: FxHashMap(),
- macro_map: FxHashMap(),
+ macro_names: FxHashSet::default(),
+ builtin_macros: FxHashMap::default(),
+ macro_use_prelude: FxHashMap::default(),
+ all_macros: FxHashMap::default(),
+ macro_map: FxHashMap::default(),
invocations,
macro_defs,
- local_macro_def_scopes: FxHashMap(),
- name_already_seen: FxHashMap(),
+ local_macro_def_scopes: FxHashMap::default(),
+ name_already_seen: FxHashMap::default(),
whitelisted_legacy_custom_derives: Vec::new(),
potentially_unused_imports: Vec::new(),
struct_constructors: DefIdMap(),
found_unresolved_macro: false,
- unused_macros: FxHashSet(),
+ unused_macros: FxHashSet::default(),
current_type_ascription: Vec::new(),
injected_crate: None,
}
}
pub fn arenas() -> ResolverArenas<'a> {
- ResolverArenas {
- modules: arena::TypedArena::new(),
- local_modules: RefCell::new(Vec::new()),
- name_bindings: arena::TypedArena::new(),
- import_directives: arena::TypedArena::new(),
- name_resolutions: arena::TypedArena::new(),
- invocation_data: arena::TypedArena::new(),
- legacy_bindings: arena::TypedArena::new(),
- }
+ Default::default()
}
/// Runs the function on each namespace.
}
if !module.no_implicit_prelude {
- // `record_used` means that we don't try to load crates during speculative resolution
- if record_used && ns == TypeNS && self.extern_prelude.contains(&ident.name) {
- let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
- let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
- self.populate_module_if_necessary(&crate_root);
-
- let binding = (crate_root, ty::Visibility::Public,
- ident.span, Mark::root()).to_name_binding(self.arenas);
- return Some(LexicalScopeBinding::Item(binding));
+ if ns == TypeNS {
+ if let Some(binding) = self.extern_prelude_get(ident, !record_used, false) {
+ return Some(LexicalScopeBinding::Item(binding));
+ }
}
if ns == TypeNS && is_known_tool(ident.name) {
let binding = (Def::ToolMod, ty::Visibility::Public,
span: prefix.span.to(use_tree.prefix.span),
};
- if items.len() == 0 {
+ if items.is_empty() {
// Resolve prefix of an import with empty braces (issue #28388).
self.smart_resolve_path_with_crate_lint(
id,
match type_parameters {
HasTypeParameters(generics, rib_kind) => {
let mut function_type_rib = Rib::new(rib_kind);
- let mut seen_bindings = FxHashMap();
+ let mut seen_bindings = FxHashMap::default();
for param in &generics.params {
match param.kind {
GenericParamKind::Lifetime { .. } => {}
walk_list!(self, visit_expr, &local.init);
// Resolve the pattern.
- self.resolve_pattern(&local.pat, PatternSource::Let, &mut FxHashMap());
+ self.resolve_pattern(&local.pat, PatternSource::Let, &mut FxHashMap::default());
}
// build a map from pattern identifiers to binding-info's.
// that expands into an or-pattern where one 'x' was from the
// user and one 'x' came from the macro.
fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
- let mut binding_map = FxHashMap();
+ let mut binding_map = FxHashMap::default();
pat.walk(&mut |pat| {
if let PatKind::Ident(binding_mode, ident, ref sub_pat) = pat.node {
return;
}
- let mut missing_vars = FxHashMap();
- let mut inconsistent_vars = FxHashMap();
+ let mut missing_vars = FxHashMap::default();
+ let mut inconsistent_vars = FxHashMap::default();
for (i, p) in pats.iter().enumerate() {
let map_i = self.binding_mode_map(&p);
let map_j = self.binding_mode_map(&q);
for (&key, &binding_i) in &map_i {
- if map_j.len() == 0 { // Account for missing bindings when
+ if map_j.is_empty() { // Account for missing bindings when
let binding_error = missing_vars // map_j has none.
.entry(key.name)
.or_insert(BindingError {
fn resolve_arm(&mut self, arm: &Arm) {
self.ribs[ValueNS].push(Rib::new(NormalRibKind));
- let mut bindings_list = FxHashMap();
+ let mut bindings_list = FxHashMap::default();
for pattern in &arm.pats {
self.resolve_pattern(&pattern, PatternSource::Match, &mut bindings_list);
}
// This has to happen *after* we determine which pat_idents are variants
self.check_consistent_bindings(&arm.pats);
- match arm.guard {
- Some(ast::Guard::If(ref expr)) => self.visit_expr(expr),
- _ => {}
+ if let Some(ast::Guard::If(ref expr)) = arm.guard {
+ self.visit_expr(expr)
}
self.visit_expr(&arm.body);
// Make the base error.
let expected = source.descr_expected();
let path_str = names_to_string(path);
- let item_str = path[path.len() - 1];
+ let item_str = path.last().unwrap();
let code = source.error_code(def.is_some());
let (base_msg, fallback_label, base_span) = if let Some(def) = def {
(format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
format!("not a {}", expected),
span)
} else {
- let item_span = path[path.len() - 1].span;
+ let item_span = path.last().unwrap().span;
let (mod_prefix, mod_str) = if path.len() == 1 {
(String::new(), "this scope".to_string())
} else if path.len() == 2 && path[0].name == keywords::CrateRoot.name() {
let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code);
// Emit help message for fake-self from other languages like `this`(javascript)
- let fake_self: Vec<Ident> = ["this", "my"].iter().map(
- |s| Ident::from_str(*s)
- ).collect();
- if fake_self.contains(&item_str)
+ if ["this", "my"].contains(&&*item_str.as_str())
&& this.self_value_is_available(path[0].span, span) {
err.span_suggestion_with_applicability(
span,
);
}
break;
- } else if snippet.trim().len() != 0 {
+ } else if !snippet.trim().is_empty() {
debug!("tried to find type ascription `:` token, couldn't find it");
break;
}
if let NameBindingKind::Import { directive: d, .. } = binding.kind {
// Careful: we still want to rewrite paths from
// renamed extern crates.
- if let ImportDirectiveSubclass::ExternCrate(None) = d.subclass {
+ if let ImportDirectiveSubclass::ExternCrate { source: None, .. } = d.subclass {
return
}
}
}
_ => {}
}
- return def;
+ def
}
fn lookup_assoc_candidate<FilterFn>(&mut self,
} else {
// Items from the prelude
if !module.no_implicit_prelude {
- names.extend(self.extern_prelude.iter().cloned());
+ names.extend(self.extern_prelude.iter().map(|(ident, _)| ident.name));
if let Some(prelude) = self.prelude {
add_module_candidates(prelude, &mut names);
}
self.visit_expr(subexpression);
self.ribs[ValueNS].push(Rib::new(NormalRibKind));
- let mut bindings_list = FxHashMap();
+ let mut bindings_list = FxHashMap::default();
for pat in pats {
self.resolve_pattern(pat, PatternSource::IfLet, &mut bindings_list);
}
self.with_resolved_label(label, expr.id, |this| {
this.visit_expr(subexpression);
this.ribs[ValueNS].push(Rib::new(NormalRibKind));
- let mut bindings_list = FxHashMap();
+ let mut bindings_list = FxHashMap::default();
for pat in pats {
this.resolve_pattern(pat, PatternSource::WhileLet, &mut bindings_list);
}
ExprKind::ForLoop(ref pattern, ref subexpression, ref block, label) => {
self.visit_expr(subexpression);
self.ribs[ValueNS].push(Rib::new(NormalRibKind));
- self.resolve_pattern(pattern, PatternSource::For, &mut FxHashMap());
+ self.resolve_pattern(pattern, PatternSource::For, &mut FxHashMap::default());
self.resolve_labeled_block(label, expr.id, block);
self.ribs[ValueNS].push(Rib::new(rib_kind));
self.label_ribs.push(Rib::new(rib_kind));
// Resolve arguments:
- let mut bindings_list = FxHashMap();
+ let mut bindings_list = FxHashMap::default();
for argument in &fn_decl.inputs {
self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);
self.visit_ty(&argument.ty);
where FilterFn: Fn(Def) -> bool
{
let mut candidates = Vec::new();
- let mut worklist = Vec::new();
- let mut seen_modules = FxHashSet();
+ let mut seen_modules = FxHashSet::default();
let not_local_module = crate_name != keywords::Crate.ident();
- worklist.push((start_module, Vec::<ast::PathSegment>::new(), not_local_module));
+ let mut worklist = vec![(start_module, Vec::<ast::PathSegment>::new(), not_local_module)];
while let Some((in_module,
path_segments,
-> Vec<ImportSuggestion>
where FilterFn: Fn(Def) -> bool
{
- let mut suggestions = vec![];
-
- suggestions.extend(
- self.lookup_import_candidates_from_module(
- lookup_name, namespace, self.graph_root, keywords::Crate.ident(), &filter_fn
- )
- );
+ let mut suggestions = self.lookup_import_candidates_from_module(
+ lookup_name, namespace, self.graph_root, keywords::Crate.ident(), &filter_fn);
if self.session.rust_2018() {
let extern_prelude_names = self.extern_prelude.clone();
- for &name in extern_prelude_names.iter() {
- let ident = Ident::with_empty_ctxt(name);
- match self.crate_loader.maybe_process_path_extern(name, ident.span) {
- Some(crate_id) => {
- let crate_root = self.get_module(DefId {
- krate: crate_id,
- index: CRATE_DEF_INDEX,
- });
- self.populate_module_if_necessary(&crate_root);
+ for (ident, _) in extern_prelude_names.into_iter() {
+ if let Some(crate_id) = self.crate_loader.maybe_process_path_extern(ident.name,
+ ident.span) {
+ let crate_root = self.get_module(DefId {
+ krate: crate_id,
+ index: CRATE_DEF_INDEX,
+ });
+ self.populate_module_if_necessary(&crate_root);
- suggestions.extend(
- self.lookup_import_candidates_from_module(
- lookup_name, namespace, crate_root, ident, &filter_fn
- )
- );
- }
- None => {}
+ suggestions.extend(self.lookup_import_candidates_from_module(
+ lookup_name, namespace, crate_root, ident, &filter_fn));
}
}
}
-> Option<(Module<'a>, ImportSuggestion)>
{
let mut result = None;
- let mut worklist = Vec::new();
- let mut seen_modules = FxHashSet();
- worklist.push((self.graph_root, Vec::new()));
+ let mut seen_modules = FxHashSet::default();
+ let mut worklist = vec![(self.graph_root, Vec::new())];
while let Some((in_module, path_segments)) = worklist.pop() {
// abort if the module is already found
fn report_errors(&mut self, krate: &Crate) {
self.report_with_use_injections(krate);
- let mut reported_spans = FxHashSet();
+ let mut reported_spans = FxHashSet::default();
for &(span_use, span_def) in &self.macro_expanded_macro_export_errors {
let msg = "macro-expanded `macro_export` macros from the current crate \
};
let cm = self.session.source_map();
- let rename_msg = "You can use `as` to change the binding name of the import";
-
- if let (Ok(snippet), false) = (cm.span_to_snippet(binding.span),
- binding.is_renamed_extern_crate()) {
+ let rename_msg = "you can use `as` to change the binding name of the import";
+
+ if let (
+ Ok(snippet),
+ NameBindingKind::Import { directive, ..},
+ _dummy @ false,
+ ) = (
+ cm.span_to_snippet(binding.span),
+ binding.kind.clone(),
+ binding.span.is_dummy(),
+ ) {
let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() {
format!("Other{}", name)
} else {
err.span_suggestion_with_applicability(
binding.span,
- rename_msg,
- if snippet.ends_with(';') {
- format!("{} as {};", &snippet[..snippet.len() - 1], suggested_name)
- } else {
- format!("{} as {}", snippet, suggested_name)
+ &rename_msg,
+ match (&directive.subclass, snippet.as_ref()) {
+ (ImportDirectiveSubclass::SingleImport { .. }, "self") =>
+ format!("self as {}", suggested_name),
+ (ImportDirectiveSubclass::SingleImport { source, .. }, _) =>
+ format!(
+ "{} as {}{}",
+ &snippet[..((source.span.hi().0 - binding.span.lo().0) as usize)],
+ suggested_name,
+ if snippet.ends_with(";") {
+ ";"
+ } else {
+ ""
+ }
+ ),
+ (ImportDirectiveSubclass::ExternCrate { source, target, .. }, _) =>
+ format!(
+ "extern crate {} as {};",
+ source.unwrap_or(target.name),
+ suggested_name,
+ ),
+ (_, _) => unreachable!(),
},
- Applicability::MachineApplicable,
+ Applicability::MaybeIncorrect,
);
} else {
err.span_label(binding.span, rename_msg);
err.emit();
self.name_already_seen.insert(name, span);
}
+
+ fn extern_prelude_get(&mut self, ident: Ident, speculative: bool, skip_feature_gate: bool)
+ -> Option<&'a NameBinding<'a>> {
+ self.extern_prelude.get(&ident.modern()).cloned().and_then(|entry| {
+ if let Some(binding) = entry.extern_crate_item {
+ if !speculative && !skip_feature_gate && entry.introduced_by_item &&
+ !self.session.features_untracked().extern_crate_item_prelude {
+ emit_feature_err(&self.session.parse_sess, "extern_crate_item_prelude",
+ ident.span, GateIssue::Language,
+ "use of extern prelude names introduced \
+ with `extern crate` items is unstable");
+ }
+ Some(binding)
+ } else {
+ let crate_id = if !speculative {
+ self.crate_loader.process_path_extern(ident.name, ident.span)
+ } else if let Some(crate_id) =
+ self.crate_loader.maybe_process_path_extern(ident.name, ident.span) {
+ crate_id
+ } else {
+ return None;
+ };
+ let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
+ self.populate_module_if_necessary(&crate_root);
+ Some((crate_root, ty::Visibility::Public, ident.span, Mark::root())
+ .to_name_binding(self.arenas))
+ }
+ })
+ }
}
fn is_self_type(path: &[Ident], namespace: Namespace) -> bool {