};
use rustc::hir::def::Namespace::*;
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
-use rustc::hir::{Upvar, UpvarMap, TraitCandidate, TraitMap, GlobMap};
+use rustc::hir::{TraitCandidate, TraitMap, GlobMap};
use rustc::ty::{self, DefIdTree};
use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
use rustc::{bug, span_bug};
function_kind: FnKind<'tcx>,
declaration: &'tcx FnDecl,
_: Span,
- node_id: NodeId)
+ _: NodeId)
{
debug!("(resolving function) entering function");
- let (rib_kind, asyncness) = match function_kind {
- FnKind::ItemFn(_, ref header, ..) =>
- (FnItemRibKind, &header.asyncness.node),
- FnKind::Method(_, ref sig, _, _) =>
- (AssocItemRibKind, &sig.header.asyncness.node),
- FnKind::Closure(_) =>
- // Async closures aren't resolved through `visit_fn`-- they're
- // processed separately
- (ClosureRibKind(node_id), &IsAsync::NotAsync),
+ let rib_kind = match function_kind {
+ FnKind::ItemFn(..) => FnItemRibKind,
+ FnKind::Method(..) => AssocItemRibKind,
+ FnKind::Closure(_) => NormalRibKind,
};
// Create a value rib for the function.
self.ribs[ValueNS].push(Rib::new(rib_kind));
// Create a label rib for the function.
- match rib_kind {
- ClosureRibKind(_) => {}
- _ => self.label_ribs.push(Rib::new(rib_kind)),
- }
+ self.label_ribs.push(Rib::new(rib_kind));
// Add each argument to the rib.
let mut bindings_list = FxHashMap::default();
- let mut add_argument = |argument: &ast::Arg| {
+ for argument in &declaration.inputs {
self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);
+
self.visit_ty(&argument.ty);
- debug!("(resolving function) recorded argument");
- };
- // Walk the generated async arguments if this is an `async fn`, otherwise walk the
- // normal arguments.
- if let IsAsync::Async { ref arguments, .. } = asyncness {
- for (i, a) in arguments.iter().enumerate() {
- if let Some(arg) = &a.arg {
- add_argument(&arg);
- } else {
- add_argument(&declaration.inputs[i]);
- }
- }
- } else {
- for a in &declaration.inputs { add_argument(a); }
+ debug!("(resolving function) recorded argument");
}
-
visit::walk_fn_ret_ty(self, &declaration.output);
// Resolve the function body, potentially inside the body of an async closure
- if let IsAsync::Async { closure_id, .. } = asyncness {
- let rib_kind = ClosureRibKind(*closure_id);
- self.ribs[ValueNS].push(Rib::new(rib_kind));
- }
-
match function_kind {
- FnKind::ItemFn(.., body) | FnKind::Method(.., body) => {
- if let IsAsync::Async { ref arguments, .. } = asyncness {
- let mut body = body.clone();
- // Insert the generated statements into the body before attempting to
- // resolve names.
- for a in arguments.iter().rev() {
- if let Some(pat_stmt) = a.pat_stmt.clone() {
- body.stmts.insert(0, pat_stmt);
- }
- body.stmts.insert(0, a.move_stmt.clone());
- }
- self.visit_block(&body);
- } else {
- self.visit_block(body);
- }
+ FnKind::ItemFn(.., body) |
+ FnKind::Method(.., body) => {
+ self.visit_block(body);
}
FnKind::Closure(body) => {
self.visit_expr(body);
}
};
- // Leave the body of the async closure
- if asyncness.is_async() {
- self.ribs[ValueNS].pop();
- }
-
debug!("(resolving function) leaving function");
- match rib_kind {
- ClosureRibKind(_) => {}
- _ => {
- self.label_ribs.pop();
- }
- }
+ self.label_ribs.pop();
self.ribs[ValueNS].pop();
}
RibKind<'a>),
}
-/// The rib kind controls the translation of local
-/// definitions (`Res::Local`) to upvars (`Res::Upvar`).
+/// The rib kind restricts certain accesses,
+/// e.g. to a `Res::Local` of an outer item.
#[derive(Copy, Clone, Debug)]
enum RibKind<'a> {
- /// No translation needs to be applied.
+ /// No restriction needs to be applied.
NormalRibKind,
- /// We passed through a closure scope at the given `NodeId`.
- /// Translate upvars as appropriate.
- ClosureRibKind(NodeId /* func id */),
-
/// We passed through an impl or trait and are now in one of its
/// methods or associated types. Allow references to ty params that impl or trait
/// binds. Disallow any other upvars (including other ty params that are
/// Resolutions for labels (node IDs of their corresponding blocks or loops).
label_res_map: NodeMap<NodeId>,
- pub upvars: UpvarMap,
pub export_map: ExportMap<NodeId>,
pub trait_map: TraitMap,
partial_res_map: Default::default(),
import_res_map: Default::default(),
label_res_map: Default::default(),
- upvars: Default::default(),
export_map: FxHashMap::default(),
trait_map: Default::default(),
module_map,
let orig_current_module = self.current_module;
match module {
ModuleOrUniformRoot::Module(module) => {
- ident.span = ident.span.modern();
- if let Some(def) = ident.span.adjust(module.expansion) {
+ if let Some(def) = ident.span.modernize_and_adjust(module.expansion) {
self.current_module = self.macro_def_scope(def);
}
}
ModuleOrUniformRoot::ExternPrelude => {
- ident.span = ident.span.modern();
- ident.span.adjust(Mark::root());
+ ident.span.modernize_and_adjust(Mark::root());
}
ModuleOrUniformRoot::CrateRootAndExternPrelude |
ModuleOrUniformRoot::CurrentScope => {
for rib in self.label_ribs.iter().rev() {
match rib.kind {
NormalRibKind => {}
- ClosureRibKind(_) => {
- span_bug!(ident.span, "rustc_resolve: `ClosureRibKind` in `label_ribs`");
- }
// If an invocation of this macro created `ident`, give up on `ident`
// and switch to `ident`'s source from the macro definition.
MacroDefinition(def) => {
diag);
}
- // Validate a local resolution (from ribs), potentially recording closure upvars.
+ // Validate a local resolution (from ribs).
fn validate_res_from_ribs(
&mut self,
ns: Namespace,
}
match res {
- Res::Local(var_id) => {
+ Res::Local(_) => {
use ResolutionError::*;
let mut res_err = None;
ForwardTyParamBanRibKind | TyParamAsConstParamTy => {
// Nothing to do. Continue.
}
- ClosureRibKind(function_id) => {
- if record_used {
- self.upvars.entry(function_id).or_default()
- .entry(var_id).or_insert(Upvar { span });
- }
- }
ItemRibKind | FnItemRibKind | AssocItemRibKind => {
// This was an attempt to access an upvar inside a
// named function item. This is not allowed, so we
Res::Def(DefKind::TyParam, _) | Res::SelfTy(..) => {
for rib in ribs {
match rib.kind {
- NormalRibKind | AssocItemRibKind | ClosureRibKind(..) |
+ NormalRibKind | AssocItemRibKind |
ModuleRibKind(..) | MacroDefinition(..) | ForwardTyParamBanRibKind |
ConstantItemRibKind | TyParamAsConstParamTy => {
// Nothing to do. Continue.
let add_module_candidates = |module: Module<'_>, names: &mut Vec<TypoSuggestion>| {
for (&(ident, _), resolution) in module.resolutions.borrow().iter() {
if let Some(binding) = resolution.borrow().binding {
- if !ident.is_gensymed() && filter_fn(binding.res()) {
+ if filter_fn(binding.res()) {
names.push(TypoSuggestion {
candidate: ident.name,
article: binding.res().article(),
for rib in self.ribs[ns].iter().rev() {
// Locals and type parameters
for (ident, &res) in &rib.bindings {
- if !ident.is_gensymed() && filter_fn(res) {
+ if filter_fn(res) {
names.push(TypoSuggestion {
candidate: ident.name,
article: res.article(),
},
);
- if !ident.is_gensymed() && filter_fn(crate_mod) {
+ if filter_fn(crate_mod) {
Some(TypoSuggestion {
candidate: ident.name,
article: "a",
// Add primitive types to the mix
if filter_fn(Res::PrimTy(Bool)) {
names.extend(
- self.primitive_type_table.primitive_types
- .iter()
- .map(|(name, _)| {
- TypoSuggestion {
- candidate: *name,
- article: "a",
- kind: "primitive type",
- }
- })
+ self.primitive_type_table.primitive_types.iter().map(|(name, _)| {
+ TypoSuggestion {
+ candidate: *name,
+ article: "a",
+ kind: "primitive type",
+ }
+ })
)
}
} else {
visit::walk_expr(self, expr);
self.current_type_ascription.pop();
}
- // Resolve the body of async exprs inside the async closure to which they desugar
- ExprKind::Async(_, async_closure_id, ref block) => {
- let rib_kind = ClosureRibKind(async_closure_id);
- self.ribs[ValueNS].push(Rib::new(rib_kind));
- self.visit_block(&block);
- self.ribs[ValueNS].pop();
- }
// `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
// resolve the arguments within the proper scopes so that usages of them inside the
// closure are detected as upvars rather than normal closure arg usages.
ExprKind::Closure(
- _, IsAsync::Async { closure_id: inner_closure_id, .. }, _,
+ _, IsAsync::Async { .. }, _,
ref fn_decl, ref body, _span,
) => {
- let rib_kind = ClosureRibKind(expr.id);
+ let rib_kind = NormalRibKind;
self.ribs[ValueNS].push(Rib::new(rib_kind));
// Resolve arguments:
let mut bindings_list = FxHashMap::default();
// Now resolve the inner closure
{
- let rib_kind = ClosureRibKind(inner_closure_id);
- self.ribs[ValueNS].push(Rib::new(rib_kind));
// No need to resolve arguments: the inner closure has none.
// Resolve the return type:
visit::walk_fn_ret_ty(self, &fn_decl.output);
// Resolve the body
self.visit_expr(body);
- self.ribs[ValueNS].pop();
}
self.ribs[ValueNS].pop();
}
let mut ident = ident;
if ident.span.glob_adjust(
module.expansion,
- binding.span.ctxt().modern(),
+ binding.span,
).is_none() {
continue
}