1
Fork 0

resolve: Make bindings for derive helper attributes unique

instead of creating them every time such attribute is used
This commit is contained in:
Vadim Petrochenkov 2023-08-22 19:14:32 +08:00
parent 02640f9d59
commit 50bbe01de0
4 changed files with 25 additions and 28 deletions

View file

@ -1032,7 +1032,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
.get(&expn_id) .get(&expn_id)
.into_iter() .into_iter()
.flatten() .flatten()
.map(|ident| TypoSuggestion::typo_from_ident(*ident, res)), .map(|(ident, _)| TypoSuggestion::typo_from_ident(*ident, res)),
); );
} }
} }

View file

@ -421,26 +421,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
orig_ident.span.ctxt(), orig_ident.span.ctxt(),
|this, scope, use_prelude, ctxt| { |this, scope, use_prelude, ctxt| {
let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt)); let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
let ok = |res, span, arenas| {
Ok((
(res, Visibility::Public, span, LocalExpnId::ROOT).to_name_binding(arenas),
Flags::empty(),
))
};
let result = match scope { let result = match scope {
Scope::DeriveHelpers(expn_id) => { Scope::DeriveHelpers(expn_id) => {
if let Some(attr) = this if let Some(binding) = this.helper_attrs.get(&expn_id).and_then(|attrs| {
.helper_attrs attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, binding)| *binding)
.get(&expn_id) }) {
.and_then(|attrs| attrs.iter().rfind(|i| ident == **i))
{
let binding = (
Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
Visibility::Public,
attr.span,
expn_id,
)
.to_name_binding(this.arenas);
Ok((binding, Flags::empty())) Ok((binding, Flags::empty()))
} else { } else {
Err(Determinacy::Determined) Err(Determinacy::Determined)
@ -459,11 +444,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
) { ) {
Ok((Some(ext), _)) => { Ok((Some(ext), _)) => {
if ext.helper_attrs.contains(&ident.name) { if ext.helper_attrs.contains(&ident.name) {
result = ok( let binding = (
Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat), Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
Visibility::Public,
derive.span, derive.span,
this.arenas, LocalExpnId::ROOT,
); )
.to_name_binding(this.arenas);
result = Ok((binding, Flags::empty()));
break; break;
} }
} }

View file

@ -1047,7 +1047,7 @@ pub struct Resolver<'a, 'tcx> {
/// `macro_rules` scopes produced by `macro_rules` item definitions. /// `macro_rules` scopes produced by `macro_rules` item definitions.
macro_rules_scopes: FxHashMap<LocalDefId, MacroRulesScopeRef<'a>>, macro_rules_scopes: FxHashMap<LocalDefId, MacroRulesScopeRef<'a>>,
/// Helper attributes that are in scope for the given expansion. /// Helper attributes that are in scope for the given expansion.
helper_attrs: FxHashMap<LocalExpnId, Vec<Ident>>, helper_attrs: FxHashMap<LocalExpnId, Vec<(Ident, NameBinding<'a>)>>,
/// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute /// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute
/// with the given `ExpnId`. /// with the given `ExpnId`.
derive_data: FxHashMap<LocalExpnId, DeriveData>, derive_data: FxHashMap<LocalExpnId, DeriveData>,

View file

@ -7,7 +7,7 @@ use crate::errors::{
use crate::Namespace::*; use crate::Namespace::*;
use crate::{BuiltinMacroState, Determinacy}; use crate::{BuiltinMacroState, Determinacy};
use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet}; use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment}; use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
use rustc_ast::expand::StrippedCfgItem; use rustc_ast::expand::StrippedCfgItem;
use rustc_ast::{self as ast, attr, Crate, Inline, ItemKind, ModKind, NodeId}; use rustc_ast::{self as ast, attr, Crate, Inline, ItemKind, ModKind, NodeId};
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
@ -20,10 +20,10 @@ use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
use rustc_expand::compile_declarative_macro; use rustc_expand::compile_declarative_macro;
use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion}; use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion};
use rustc_hir::def::{self, DefKind, NonMacroAttrKind}; use rustc_hir::def::{self, DefKind, NonMacroAttrKind};
use rustc_hir::def_id::{CrateNum, LocalDefId}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
use rustc_middle::middle::stability; use rustc_middle::middle::stability;
use rustc_middle::ty::RegisteredTools; use rustc_middle::ty::RegisteredTools;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::{TyCtxt, Visibility};
use rustc_session::lint::builtin::{ use rustc_session::lint::builtin::{
LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE, UNKNOWN_DIAGNOSTIC_ATTRIBUTES, LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE, UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
}; };
@ -401,8 +401,17 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
} }
// Sort helpers in a stable way independent from the derive resolution order. // Sort helpers in a stable way independent from the derive resolution order.
entry.helper_attrs.sort_by_key(|(i, _)| *i); entry.helper_attrs.sort_by_key(|(i, _)| *i);
self.helper_attrs let helper_attrs = entry
.insert(expn_id, entry.helper_attrs.iter().map(|(_, ident)| *ident).collect()); .helper_attrs
.iter()
.map(|(_, ident)| {
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
let binding = (res, Visibility::<DefId>::Public, ident.span, expn_id)
.to_name_binding(self.arenas);
(*ident, binding)
})
.collect();
self.helper_attrs.insert(expn_id, helper_attrs);
// Mark this derive as having `Copy` either if it has `Copy` itself or if its parent derive // Mark this derive as having `Copy` either if it has `Copy` itself or if its parent derive
// has `Copy`, to support cases like `#[derive(Clone, Copy)] #[derive(Debug)]`. // has `Copy`, to support cases like `#[derive(Clone, Copy)] #[derive(Debug)]`.
if entry.has_derive_copy || self.has_derive_copy(parent_scope.expansion) { if entry.has_derive_copy || self.has_derive_copy(parent_scope.expansion) {