resolve: Scope visiting doesn't need an Ident
This commit is contained in:
parent
bf5f30684a
commit
3ff866ed7c
6 changed files with 90 additions and 57 deletions
|
@ -595,7 +595,8 @@ impl<'a> Resolver<'a> {
|
||||||
filter_fn: &impl Fn(Res) -> bool,
|
filter_fn: &impl Fn(Res) -> bool,
|
||||||
) -> Option<TypoSuggestion> {
|
) -> Option<TypoSuggestion> {
|
||||||
let mut suggestions = Vec::new();
|
let mut suggestions = Vec::new();
|
||||||
self.visit_scopes(scope_set, parent_scope, ident, |this, scope, use_prelude, _| {
|
let ctxt = ident.span.ctxt();
|
||||||
|
self.visit_scopes(scope_set, parent_scope, ctxt, |this, scope, use_prelude, _| {
|
||||||
match scope {
|
match scope {
|
||||||
Scope::DeriveHelpers(expn_id) => {
|
Scope::DeriveHelpers(expn_id) => {
|
||||||
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
|
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
|
||||||
|
|
|
@ -262,52 +262,60 @@ impl<'a> PathSource<'a> {
|
||||||
|
|
||||||
crate fn is_expected(self, res: Res) -> bool {
|
crate fn is_expected(self, res: Res) -> bool {
|
||||||
match self {
|
match self {
|
||||||
PathSource::Type => matches!(res, Res::Def(
|
PathSource::Type => matches!(
|
||||||
|
res,
|
||||||
|
Res::Def(
|
||||||
DefKind::Struct
|
DefKind::Struct
|
||||||
| DefKind::Union
|
| DefKind::Union
|
||||||
| DefKind::Enum
|
| DefKind::Enum
|
||||||
| DefKind::Trait
|
| DefKind::Trait
|
||||||
| DefKind::TraitAlias
|
| DefKind::TraitAlias
|
||||||
| DefKind::TyAlias
|
| DefKind::TyAlias
|
||||||
| DefKind::AssocTy
|
| DefKind::AssocTy
|
||||||
| DefKind::TyParam
|
| DefKind::TyParam
|
||||||
| DefKind::OpaqueTy
|
| DefKind::OpaqueTy
|
||||||
| DefKind::ForeignTy,
|
| DefKind::ForeignTy,
|
||||||
_,
|
_,
|
||||||
)
|
) | Res::PrimTy(..)
|
||||||
| Res::PrimTy(..)
|
| Res::SelfTy(..)
|
||||||
| Res::SelfTy(..)),
|
),
|
||||||
PathSource::Trait(AliasPossibility::No) => matches!(res, Res::Def(DefKind::Trait, _)),
|
PathSource::Trait(AliasPossibility::No) => matches!(res, Res::Def(DefKind::Trait, _)),
|
||||||
PathSource::Trait(AliasPossibility::Maybe) => {
|
PathSource::Trait(AliasPossibility::Maybe) => {
|
||||||
matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))
|
matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))
|
||||||
}
|
}
|
||||||
PathSource::Expr(..) => matches!(res, Res::Def(
|
PathSource::Expr(..) => matches!(
|
||||||
|
res,
|
||||||
|
Res::Def(
|
||||||
DefKind::Ctor(_, CtorKind::Const | CtorKind::Fn)
|
DefKind::Ctor(_, CtorKind::Const | CtorKind::Fn)
|
||||||
| DefKind::Const
|
| DefKind::Const
|
||||||
| DefKind::Static
|
| DefKind::Static
|
||||||
| DefKind::Fn
|
| DefKind::Fn
|
||||||
| DefKind::AssocFn
|
| DefKind::AssocFn
|
||||||
| DefKind::AssocConst
|
| DefKind::AssocConst
|
||||||
| DefKind::ConstParam,
|
| DefKind::ConstParam,
|
||||||
_,
|
_,
|
||||||
)
|
) | Res::Local(..)
|
||||||
| Res::Local(..)
|
| Res::SelfCtor(..)
|
||||||
| Res::SelfCtor(..)),
|
),
|
||||||
PathSource::Pat => matches!(res, Res::Def(
|
PathSource::Pat => matches!(
|
||||||
|
res,
|
||||||
|
Res::Def(
|
||||||
DefKind::Ctor(_, CtorKind::Const) | DefKind::Const | DefKind::AssocConst,
|
DefKind::Ctor(_, CtorKind::Const) | DefKind::Const | DefKind::AssocConst,
|
||||||
_,
|
_,
|
||||||
)
|
) | Res::SelfCtor(..)
|
||||||
| Res::SelfCtor(..)),
|
),
|
||||||
PathSource::TupleStruct(..) => res.expected_in_tuple_struct_pat(),
|
PathSource::TupleStruct(..) => res.expected_in_tuple_struct_pat(),
|
||||||
PathSource::Struct => matches!(res, Res::Def(
|
PathSource::Struct => matches!(
|
||||||
|
res,
|
||||||
|
Res::Def(
|
||||||
DefKind::Struct
|
DefKind::Struct
|
||||||
| DefKind::Union
|
| DefKind::Union
|
||||||
| DefKind::Variant
|
| DefKind::Variant
|
||||||
| DefKind::TyAlias
|
| DefKind::TyAlias
|
||||||
| DefKind::AssocTy,
|
| DefKind::AssocTy,
|
||||||
_,
|
_,
|
||||||
)
|
) | Res::SelfTy(..)
|
||||||
| Res::SelfTy(..)),
|
),
|
||||||
PathSource::TraitItem(ns) => match res {
|
PathSource::TraitItem(ns) => match res {
|
||||||
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) if ns == ValueNS => true,
|
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) if ns == ValueNS => true,
|
||||||
Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,
|
Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,
|
||||||
|
@ -2397,8 +2405,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
&mut found_traits,
|
&mut found_traits,
|
||||||
&self.parent_scope,
|
&self.parent_scope,
|
||||||
);
|
);
|
||||||
search_module =
|
let mut span_data = ident.span.data();
|
||||||
unwrap_or!(self.r.hygienic_lexical_parent(search_module, &mut ident.span), break);
|
search_module = unwrap_or!(
|
||||||
|
self.r.hygienic_lexical_parent(search_module, &mut span_data.ctxt),
|
||||||
|
break
|
||||||
|
);
|
||||||
|
ident.span = span_data.span();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(prelude) = self.r.prelude {
|
if let Some(prelude) = self.r.prelude {
|
||||||
|
|
|
@ -50,6 +50,7 @@ use rustc_middle::{bug, span_bug};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency};
|
use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency};
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
|
@ -759,10 +760,13 @@ impl<'a> NameBinding<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_variant(&self) -> bool {
|
fn is_variant(&self) -> bool {
|
||||||
matches!(self.kind, NameBindingKind::Res(
|
matches!(
|
||||||
|
self.kind,
|
||||||
|
NameBindingKind::Res(
|
||||||
Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), _),
|
Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), _),
|
||||||
_,
|
_,
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_extern_crate(&self) -> bool {
|
fn is_extern_crate(&self) -> bool {
|
||||||
|
@ -1626,8 +1630,13 @@ impl<'a> Resolver<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
scope_set: ScopeSet,
|
scope_set: ScopeSet,
|
||||||
parent_scope: &ParentScope<'a>,
|
parent_scope: &ParentScope<'a>,
|
||||||
ident: Ident,
|
ctxt: SyntaxContext,
|
||||||
mut visitor: impl FnMut(&mut Self, Scope<'a>, /*use_prelude*/ bool, Ident) -> Option<T>,
|
mut visitor: impl FnMut(
|
||||||
|
&mut Self,
|
||||||
|
Scope<'a>,
|
||||||
|
/*use_prelude*/ bool,
|
||||||
|
SyntaxContext,
|
||||||
|
) -> Option<T>,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
// General principles:
|
// General principles:
|
||||||
// 1. Not controlled (user-defined) names should have higher priority than controlled names
|
// 1. Not controlled (user-defined) names should have higher priority than controlled names
|
||||||
|
@ -1670,7 +1679,7 @@ impl<'a> Resolver<'a> {
|
||||||
// 4c. Standard library prelude (de-facto closed, controlled).
|
// 4c. Standard library prelude (de-facto closed, controlled).
|
||||||
// 6. Language prelude: builtin attributes (closed, controlled).
|
// 6. Language prelude: builtin attributes (closed, controlled).
|
||||||
|
|
||||||
let rust_2015 = ident.span.rust_2015();
|
let rust_2015 = ctxt.edition() == Edition::Edition2015;
|
||||||
let (ns, macro_kind, is_absolute_path) = match scope_set {
|
let (ns, macro_kind, is_absolute_path) = match scope_set {
|
||||||
ScopeSet::All(ns, _) => (ns, None, false),
|
ScopeSet::All(ns, _) => (ns, None, false),
|
||||||
ScopeSet::AbsolutePath(ns) => (ns, None, true),
|
ScopeSet::AbsolutePath(ns) => (ns, None, true),
|
||||||
|
@ -1683,7 +1692,7 @@ impl<'a> Resolver<'a> {
|
||||||
TypeNS | ValueNS => Scope::Module(module),
|
TypeNS | ValueNS => Scope::Module(module),
|
||||||
MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
|
MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
|
||||||
};
|
};
|
||||||
let mut ident = ident.normalize_to_macros_2_0();
|
let mut ctxt = ctxt.normalize_to_macros_2_0();
|
||||||
let mut use_prelude = !module.no_implicit_prelude;
|
let mut use_prelude = !module.no_implicit_prelude;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -1719,7 +1728,7 @@ impl<'a> Resolver<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if visit {
|
if visit {
|
||||||
if let break_result @ Some(..) = visitor(self, scope, use_prelude, ident) {
|
if let break_result @ Some(..) = visitor(self, scope, use_prelude, ctxt) {
|
||||||
return break_result;
|
return break_result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1749,17 +1758,17 @@ impl<'a> Resolver<'a> {
|
||||||
},
|
},
|
||||||
Scope::CrateRoot => match ns {
|
Scope::CrateRoot => match ns {
|
||||||
TypeNS => {
|
TypeNS => {
|
||||||
ident.span.adjust(ExpnId::root());
|
ctxt.adjust(ExpnId::root());
|
||||||
Scope::ExternPrelude
|
Scope::ExternPrelude
|
||||||
}
|
}
|
||||||
ValueNS | MacroNS => break,
|
ValueNS | MacroNS => break,
|
||||||
},
|
},
|
||||||
Scope::Module(module) => {
|
Scope::Module(module) => {
|
||||||
use_prelude = !module.no_implicit_prelude;
|
use_prelude = !module.no_implicit_prelude;
|
||||||
match self.hygienic_lexical_parent(module, &mut ident.span) {
|
match self.hygienic_lexical_parent(module, &mut ctxt) {
|
||||||
Some(parent_module) => Scope::Module(parent_module),
|
Some(parent_module) => Scope::Module(parent_module),
|
||||||
None => {
|
None => {
|
||||||
ident.span.adjust(ExpnId::root());
|
ctxt.adjust(ExpnId::root());
|
||||||
match ns {
|
match ns {
|
||||||
TypeNS => Scope::ExternPrelude,
|
TypeNS => Scope::ExternPrelude,
|
||||||
ValueNS => Scope::StdLibPrelude,
|
ValueNS => Scope::StdLibPrelude,
|
||||||
|
@ -1882,16 +1891,18 @@ impl<'a> Resolver<'a> {
|
||||||
ident = normalized_ident;
|
ident = normalized_ident;
|
||||||
let mut poisoned = None;
|
let mut poisoned = None;
|
||||||
loop {
|
loop {
|
||||||
|
let mut span_data = ident.span.data();
|
||||||
let opt_module = if let Some(node_id) = record_used_id {
|
let opt_module = if let Some(node_id) = record_used_id {
|
||||||
self.hygienic_lexical_parent_with_compatibility_fallback(
|
self.hygienic_lexical_parent_with_compatibility_fallback(
|
||||||
module,
|
module,
|
||||||
&mut ident.span,
|
&mut span_data.ctxt,
|
||||||
node_id,
|
node_id,
|
||||||
&mut poisoned,
|
&mut poisoned,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
self.hygienic_lexical_parent(module, &mut ident.span)
|
self.hygienic_lexical_parent(module, &mut span_data.ctxt)
|
||||||
};
|
};
|
||||||
|
ident.span = span_data.span();
|
||||||
module = unwrap_or!(opt_module, break);
|
module = unwrap_or!(opt_module, break);
|
||||||
let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
|
let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
|
||||||
let result = self.resolve_ident_in_module_unadjusted(
|
let result = self.resolve_ident_in_module_unadjusted(
|
||||||
|
@ -1965,10 +1976,10 @@ impl<'a> Resolver<'a> {
|
||||||
fn hygienic_lexical_parent(
|
fn hygienic_lexical_parent(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: Module<'a>,
|
module: Module<'a>,
|
||||||
span: &mut Span,
|
ctxt: &mut SyntaxContext,
|
||||||
) -> Option<Module<'a>> {
|
) -> Option<Module<'a>> {
|
||||||
if !module.expansion.outer_expn_is_descendant_of(span.ctxt()) {
|
if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
|
||||||
return Some(self.macro_def_scope(span.remove_mark()));
|
return Some(self.macro_def_scope(ctxt.remove_mark()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ModuleKind::Block(..) = module.kind {
|
if let ModuleKind::Block(..) = module.kind {
|
||||||
|
@ -1981,11 +1992,11 @@ impl<'a> Resolver<'a> {
|
||||||
fn hygienic_lexical_parent_with_compatibility_fallback(
|
fn hygienic_lexical_parent_with_compatibility_fallback(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: Module<'a>,
|
module: Module<'a>,
|
||||||
span: &mut Span,
|
ctxt: &mut SyntaxContext,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
poisoned: &mut Option<NodeId>,
|
poisoned: &mut Option<NodeId>,
|
||||||
) -> Option<Module<'a>> {
|
) -> Option<Module<'a>> {
|
||||||
if let module @ Some(..) = self.hygienic_lexical_parent(module, span) {
|
if let module @ Some(..) = self.hygienic_lexical_parent(module, ctxt) {
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2010,7 +2021,7 @@ impl<'a> Resolver<'a> {
|
||||||
let ext = self.get_macro_by_def_id(def_id);
|
let ext = self.get_macro_by_def_id(def_id);
|
||||||
if !ext.is_builtin
|
if !ext.is_builtin
|
||||||
&& ext.macro_kind() == MacroKind::Derive
|
&& ext.macro_kind() == MacroKind::Derive
|
||||||
&& parent.expansion.outer_expn_is_descendant_of(span.ctxt())
|
&& parent.expansion.outer_expn_is_descendant_of(*ctxt)
|
||||||
{
|
{
|
||||||
*poisoned = Some(node_id);
|
*poisoned = Some(node_id);
|
||||||
return module.parent;
|
return module.parent;
|
||||||
|
|
|
@ -618,8 +618,9 @@ impl<'a> Resolver<'a> {
|
||||||
let break_result = self.visit_scopes(
|
let break_result = self.visit_scopes(
|
||||||
scope_set,
|
scope_set,
|
||||||
parent_scope,
|
parent_scope,
|
||||||
orig_ident,
|
orig_ident.span.ctxt(),
|
||||||
|this, scope, use_prelude, ident| {
|
|this, scope, use_prelude, ctxt| {
|
||||||
|
let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
|
||||||
let ok = |res, span, arenas| {
|
let ok = |res, span, arenas| {
|
||||||
Ok((
|
Ok((
|
||||||
(res, ty::Visibility::Public, span, ExpnId::root()).to_name_binding(arenas),
|
(res, ty::Visibility::Public, span, ExpnId::root()).to_name_binding(arenas),
|
||||||
|
|
|
@ -622,6 +622,10 @@ impl SyntaxContext {
|
||||||
pub fn dollar_crate_name(self) -> Symbol {
|
pub fn dollar_crate_name(self) -> Symbol {
|
||||||
HygieneData::with(|data| data.syntax_context_data[self.0 as usize].dollar_crate_name)
|
HygieneData::with(|data| data.syntax_context_data[self.0 as usize].dollar_crate_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn edition(self) -> Edition {
|
||||||
|
self.outer_expn_data().edition
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for SyntaxContext {
|
impl fmt::Debug for SyntaxContext {
|
||||||
|
|
|
@ -300,6 +300,10 @@ pub struct SpanData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpanData {
|
impl SpanData {
|
||||||
|
#[inline]
|
||||||
|
pub fn span(&self) -> Span {
|
||||||
|
Span::new(self.lo, self.hi, self.ctxt)
|
||||||
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_lo(&self, lo: BytePos) -> Span {
|
pub fn with_lo(&self, lo: BytePos) -> Span {
|
||||||
Span::new(lo, self.hi, self.ctxt)
|
Span::new(lo, self.hi, self.ctxt)
|
||||||
|
@ -468,7 +472,7 @@ impl Span {
|
||||||
|
|
||||||
/// Edition of the crate from which this span came.
|
/// Edition of the crate from which this span came.
|
||||||
pub fn edition(self) -> edition::Edition {
|
pub fn edition(self) -> edition::Edition {
|
||||||
self.ctxt().outer_expn_data().edition
|
self.ctxt().edition()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue