Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resolve: Scope visiting doesn't need an Ident #80782

Merged
merged 1 commit into from
Jan 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,8 @@ impl<'a> Resolver<'a> {
filter_fn: &impl Fn(Res) -> bool,
) -> Option<TypoSuggestion> {
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 {
Scope::DeriveHelpers(expn_id) => {
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
Expand Down
82 changes: 47 additions & 35 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,52 +262,60 @@ impl<'a> PathSource<'a> {

crate fn is_expected(self, res: Res) -> bool {
match self {
PathSource::Type => matches!(res, Res::Def(
PathSource::Type => matches!(
res,
Res::Def(
DefKind::Struct
| DefKind::Union
| DefKind::Enum
| DefKind::Trait
| DefKind::TraitAlias
| DefKind::TyAlias
| DefKind::AssocTy
| DefKind::TyParam
| DefKind::OpaqueTy
| DefKind::ForeignTy,
| DefKind::Union
| DefKind::Enum
| DefKind::Trait
| DefKind::TraitAlias
| DefKind::TyAlias
| DefKind::AssocTy
| DefKind::TyParam
| DefKind::OpaqueTy
| DefKind::ForeignTy,
_,
)
| Res::PrimTy(..)
| Res::SelfTy(..)),
) | Res::PrimTy(..)
| Res::SelfTy(..)
),
PathSource::Trait(AliasPossibility::No) => matches!(res, Res::Def(DefKind::Trait, _)),
PathSource::Trait(AliasPossibility::Maybe) => {
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::Const
| DefKind::Static
| DefKind::Fn
| DefKind::AssocFn
| DefKind::AssocConst
| DefKind::ConstParam,
| DefKind::Const
| DefKind::Static
| DefKind::Fn
| DefKind::AssocFn
| DefKind::AssocConst
| DefKind::ConstParam,
_,
)
| Res::Local(..)
| Res::SelfCtor(..)),
PathSource::Pat => matches!(res, Res::Def(
) | Res::Local(..)
| Res::SelfCtor(..)
),
PathSource::Pat => matches!(
res,
Res::Def(
DefKind::Ctor(_, CtorKind::Const) | DefKind::Const | DefKind::AssocConst,
_,
)
| Res::SelfCtor(..)),
) | Res::SelfCtor(..)
),
PathSource::TupleStruct(..) => res.expected_in_tuple_struct_pat(),
PathSource::Struct => matches!(res, Res::Def(
PathSource::Struct => matches!(
res,
Res::Def(
DefKind::Struct
| DefKind::Union
| DefKind::Variant
| DefKind::TyAlias
| DefKind::AssocTy,
| DefKind::Union
| DefKind::Variant
| DefKind::TyAlias
| DefKind::AssocTy,
_,
)
| Res::SelfTy(..)),
) | Res::SelfTy(..)
),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PathSource::TraitItem(ns) => match res {
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) if ns == ValueNS => true,
Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,
Expand Down Expand Up @@ -2397,8 +2405,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
&mut found_traits,
&self.parent_scope,
);
search_module =
unwrap_or!(self.r.hygienic_lexical_parent(search_module, &mut ident.span), break);
let mut span_data = ident.span.data();
search_module = unwrap_or!(
self.r.hygienic_lexical_parent(search_module, &mut span_data.ctxt),
break
);
ident.span = span_data.span();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will go away in #80765 which reuses visit_scopes for this logic.

}

if let Some(prelude) = self.r.prelude {
Expand Down
47 changes: 29 additions & 18 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ use rustc_middle::{bug, span_bug};
use rustc_session::lint;
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
use rustc_session::Session;
use rustc_span::edition::Edition;
use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
Expand Down Expand Up @@ -759,10 +760,13 @@ impl<'a> NameBinding<'a> {
}

fn is_variant(&self) -> bool {
matches!(self.kind, NameBindingKind::Res(
matches!(
self.kind,
NameBindingKind::Res(
Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), _),
_,
))
)
)
}

fn is_extern_crate(&self) -> bool {
Expand Down Expand Up @@ -1626,8 +1630,13 @@ impl<'a> Resolver<'a> {
&mut self,
scope_set: ScopeSet,
parent_scope: &ParentScope<'a>,
ident: Ident,
mut visitor: impl FnMut(&mut Self, Scope<'a>, /*use_prelude*/ bool, Ident) -> Option<T>,
ctxt: SyntaxContext,
mut visitor: impl FnMut(
&mut Self,
Scope<'a>,
/*use_prelude*/ bool,
SyntaxContext,
) -> Option<T>,
) -> Option<T> {
// General principles:
// 1. Not controlled (user-defined) names should have higher priority than controlled names
Expand Down Expand Up @@ -1670,7 +1679,7 @@ impl<'a> Resolver<'a> {
// 4c. Standard library prelude (de-facto 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 {
ScopeSet::All(ns, _) => (ns, None, false),
ScopeSet::AbsolutePath(ns) => (ns, None, true),
Expand All @@ -1683,7 +1692,7 @@ impl<'a> Resolver<'a> {
TypeNS | ValueNS => Scope::Module(module),
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;

loop {
Expand Down Expand Up @@ -1719,7 +1728,7 @@ impl<'a> Resolver<'a> {
};

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;
}
}
Expand Down Expand Up @@ -1749,17 +1758,17 @@ impl<'a> Resolver<'a> {
},
Scope::CrateRoot => match ns {
TypeNS => {
ident.span.adjust(ExpnId::root());
ctxt.adjust(ExpnId::root());
Scope::ExternPrelude
}
ValueNS | MacroNS => break,
},
Scope::Module(module) => {
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),
None => {
ident.span.adjust(ExpnId::root());
ctxt.adjust(ExpnId::root());
match ns {
TypeNS => Scope::ExternPrelude,
ValueNS => Scope::StdLibPrelude,
Expand Down Expand Up @@ -1882,16 +1891,18 @@ impl<'a> Resolver<'a> {
ident = normalized_ident;
let mut poisoned = None;
loop {
let mut span_data = ident.span.data();
let opt_module = if let Some(node_id) = record_used_id {
self.hygienic_lexical_parent_with_compatibility_fallback(
module,
&mut ident.span,
&mut span_data.ctxt,
node_id,
&mut poisoned,
)
} else {
self.hygienic_lexical_parent(module, &mut ident.span)
self.hygienic_lexical_parent(module, &mut span_data.ctxt)
};
ident.span = span_data.span();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is not yet refactored to use visit_scopes, but it should also go away eventually.

module = unwrap_or!(opt_module, break);
let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
let result = self.resolve_ident_in_module_unadjusted(
Expand Down Expand Up @@ -1965,10 +1976,10 @@ impl<'a> Resolver<'a> {
fn hygienic_lexical_parent(
&mut self,
module: Module<'a>,
span: &mut Span,
ctxt: &mut SyntaxContext,
) -> Option<Module<'a>> {
if !module.expansion.outer_expn_is_descendant_of(span.ctxt()) {
return Some(self.macro_def_scope(span.remove_mark()));
if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
return Some(self.macro_def_scope(ctxt.remove_mark()));
}

if let ModuleKind::Block(..) = module.kind {
Expand All @@ -1981,11 +1992,11 @@ impl<'a> Resolver<'a> {
fn hygienic_lexical_parent_with_compatibility_fallback(
&mut self,
module: Module<'a>,
span: &mut Span,
ctxt: &mut SyntaxContext,
node_id: NodeId,
poisoned: &mut Option<NodeId>,
) -> 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;
}

Expand All @@ -2010,7 +2021,7 @@ impl<'a> Resolver<'a> {
let ext = self.get_macro_by_def_id(def_id);
if !ext.is_builtin
&& 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);
return module.parent;
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,8 +618,9 @@ impl<'a> Resolver<'a> {
let break_result = self.visit_scopes(
scope_set,
parent_scope,
orig_ident,
|this, scope, use_prelude, ident| {
orig_ident.span.ctxt(),
|this, scope, use_prelude, ctxt| {
let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
let ok = |res, span, arenas| {
Ok((
(res, ty::Visibility::Public, span, ExpnId::root()).to_name_binding(arenas),
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_span/src/hygiene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,10 @@ impl SyntaxContext {
pub fn dollar_crate_name(self) -> Symbol {
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 {
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,10 @@ pub struct SpanData {
}

impl SpanData {
#[inline]
pub fn span(&self) -> Span {
Span::new(self.lo, self.hi, self.ctxt)
}
#[inline]
pub fn with_lo(&self, lo: BytePos) -> Span {
Span::new(lo, self.hi, self.ctxt)
Expand Down Expand Up @@ -468,7 +472,7 @@ impl Span {

/// Edition of the crate from which this span came.
pub fn edition(self) -> edition::Edition {
self.ctxt().outer_expn_data().edition
self.ctxt().edition()
}

#[inline]
Expand Down