resolve: Integrate inert attributes registererd by legacy plugins into macro resolution
This commit is contained in:
parent
b8bea5a0a6
commit
dd6347a6b9
|
@ -36,6 +36,8 @@ pub enum NonMacroAttrKind {
|
||||||
Tool,
|
Tool,
|
||||||
/// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
|
/// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
|
||||||
DeriveHelper,
|
DeriveHelper,
|
||||||
|
/// Single-segment custom attriubte registered by a legacy plugin (`register_attribute`).
|
||||||
|
LegacyPluginHelper,
|
||||||
/// Single-segment custom attribute not registered in any way (`#[my_attr]`).
|
/// Single-segment custom attribute not registered in any way (`#[my_attr]`).
|
||||||
Custom,
|
Custom,
|
||||||
}
|
}
|
||||||
|
@ -259,6 +261,7 @@ impl NonMacroAttrKind {
|
||||||
NonMacroAttrKind::Builtin => "built-in attribute",
|
NonMacroAttrKind::Builtin => "built-in attribute",
|
||||||
NonMacroAttrKind::Tool => "tool attribute",
|
NonMacroAttrKind::Tool => "tool attribute",
|
||||||
NonMacroAttrKind::DeriveHelper => "derive helper attribute",
|
NonMacroAttrKind::DeriveHelper => "derive helper attribute",
|
||||||
|
NonMacroAttrKind::LegacyPluginHelper => "legacy plugin helper attribute",
|
||||||
NonMacroAttrKind::Custom => "custom attribute",
|
NonMacroAttrKind::Custom => "custom attribute",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1012,6 +1012,7 @@ impl_stable_hash_for!(enum hir::def::NonMacroAttrKind {
|
||||||
Builtin,
|
Builtin,
|
||||||
Tool,
|
Tool,
|
||||||
DeriveHelper,
|
DeriveHelper,
|
||||||
|
LegacyPluginHelper,
|
||||||
Custom,
|
Custom,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -248,11 +248,6 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
|
||||||
for i in 0..attrs.len() {
|
for i in 0..attrs.len() {
|
||||||
let name = attrs[i].name();
|
let name = attrs[i].name();
|
||||||
|
|
||||||
if self.session.plugin_attributes.borrow().iter()
|
|
||||||
.any(|&(ref attr_nm, _)| name == &**attr_nm) {
|
|
||||||
attr::mark_known(&attrs[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.builtin_macros.get(&name).cloned() {
|
match self.builtin_macros.get(&name).cloned() {
|
||||||
Some(binding) => match *binding.get_macro(self) {
|
Some(binding) => match *binding.get_macro(self) {
|
||||||
MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => {
|
MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => {
|
||||||
|
@ -591,6 +586,15 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
// 2b. Standard library prelude is currently implemented as `macro-use` (closed, controlled)
|
// 2b. Standard library prelude is currently implemented as `macro-use` (closed, controlled)
|
||||||
// 3. Language prelude: builtin macros (closed, controlled, except for legacy plugins).
|
// 3. Language prelude: builtin macros (closed, controlled, except for legacy plugins).
|
||||||
// 4. Language prelude: builtin attributes (closed, controlled).
|
// 4. Language prelude: builtin attributes (closed, controlled).
|
||||||
|
// N (unordered). Derive helpers (open, not controlled). All ambiguities with other names
|
||||||
|
// are currently reported as errors. They should be higher in priority than preludes
|
||||||
|
// and maybe even names in modules according to the "general principles" above. They
|
||||||
|
// also should be subject to restricted shadowing because are effectively produced by
|
||||||
|
// derives (you need to resolve the derive first to add helpers into scope), but they
|
||||||
|
// should be available before the derive is expanded for compatibility.
|
||||||
|
// It's mess in general, so we are being conservative for now.
|
||||||
|
// N (unordered). Legacy plugin helpers (open, not controlled). Similar to derive helpers,
|
||||||
|
// but introduced by legacy plugins using `register_attribute`.
|
||||||
|
|
||||||
assert!(ns == TypeNS || ns == MacroNS);
|
assert!(ns == TypeNS || ns == MacroNS);
|
||||||
assert!(force || !record_used); // `record_used` implies `force`
|
assert!(force || !record_used); // `record_used` implies `force`
|
||||||
|
@ -615,6 +619,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
BuiltinMacros,
|
BuiltinMacros,
|
||||||
BuiltinAttrs,
|
BuiltinAttrs,
|
||||||
DeriveHelpers,
|
DeriveHelpers,
|
||||||
|
LegacyPluginHelpers,
|
||||||
ExternPrelude,
|
ExternPrelude,
|
||||||
ToolPrelude,
|
ToolPrelude,
|
||||||
StdLibPrelude,
|
StdLibPrelude,
|
||||||
|
@ -681,6 +686,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
WhereToResolve::LegacyPluginHelpers => {
|
||||||
|
if self.session.plugin_attributes.borrow().iter()
|
||||||
|
.any(|(name, _)| ident.name == &**name) {
|
||||||
|
let binding = (Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper),
|
||||||
|
ty::Visibility::Public, ident.span, Mark::root())
|
||||||
|
.to_name_binding(self.arenas);
|
||||||
|
Ok((binding, FromPrelude(false)))
|
||||||
|
} else {
|
||||||
|
Err(Determinacy::Determined)
|
||||||
|
}
|
||||||
|
}
|
||||||
WhereToResolve::ExternPrelude => {
|
WhereToResolve::ExternPrelude => {
|
||||||
if use_prelude && self.session.extern_prelude.contains(&ident.name) {
|
if use_prelude && self.session.extern_prelude.contains(&ident.name) {
|
||||||
let crate_id =
|
let crate_id =
|
||||||
|
@ -752,8 +768,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
}
|
}
|
||||||
WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros,
|
WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros,
|
||||||
WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs,
|
WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs,
|
||||||
WhereToResolve::BuiltinAttrs => break, // nowhere else to search
|
WhereToResolve::BuiltinAttrs => WhereToResolve::DeriveHelpers,
|
||||||
WhereToResolve::DeriveHelpers => WhereToResolve::Module(parent_scope.module),
|
WhereToResolve::DeriveHelpers => WhereToResolve::LegacyPluginHelpers,
|
||||||
|
WhereToResolve::LegacyPluginHelpers => break, // nowhere else to search
|
||||||
WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude,
|
WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude,
|
||||||
WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude,
|
WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude,
|
||||||
WhereToResolve::StdLibPrelude => WhereToResolve::BuiltinTypes,
|
WhereToResolve::StdLibPrelude => WhereToResolve::BuiltinTypes,
|
||||||
|
@ -775,12 +792,15 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
|
|
||||||
if let Some(innermost_result) = innermost_result {
|
if let Some(innermost_result) = innermost_result {
|
||||||
// Found another solution, if the first one was "weak", report an error.
|
// Found another solution, if the first one was "weak", report an error.
|
||||||
let (def, innermost_def) = (result.0.def(), innermost_result.0.def());
|
let prohibit_ambiguities = |def| {
|
||||||
if def != innermost_def &&
|
def == Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper) ||
|
||||||
|
def == Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper)
|
||||||
|
};
|
||||||
|
if result.0.def() != innermost_result.0.def() &&
|
||||||
(innermost_result.0.is_glob_import() ||
|
(innermost_result.0.is_glob_import() ||
|
||||||
innermost_result.0.may_appear_after(parent_scope.expansion, result.0) ||
|
innermost_result.0.may_appear_after(parent_scope.expansion, result.0) ||
|
||||||
innermost_def == Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper) ||
|
prohibit_ambiguities(innermost_result.0.def()) ||
|
||||||
def == Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper)) {
|
prohibit_ambiguities(result.0.def())) {
|
||||||
self.ambiguity_errors.push(AmbiguityError {
|
self.ambiguity_errors.push(AmbiguityError {
|
||||||
ident,
|
ident,
|
||||||
b1: innermost_result.0,
|
b1: innermost_result.0,
|
||||||
|
|
Loading…
Reference in New Issue