提交 79b5ebf5 编写于 作者: V Vadim Petrochenkov

Attach deprecation lint `proc_macro_derive_resolution_fallback` to a specific node id

上级 942b384d
......@@ -717,7 +717,7 @@ fn visit_ty(&mut self, ty: &'tcx Ty) {
}
TyKind::ImplicitSelf => {
let self_ty = keywords::SelfType.ident();
let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, true, ty.span)
let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span)
.map_or(Def::Err, |d| d.def());
self.record_def(ty.id, PathResolution::new(def));
}
......@@ -1839,9 +1839,10 @@ fn add_to_glob_map(&mut self, id: NodeId, ident: Ident) {
fn resolve_ident_in_lexical_scope(&mut self,
mut ident: Ident,
ns: Namespace,
record_used: bool,
record_used_id: Option<NodeId>,
path_span: Span)
-> Option<LexicalScopeBinding<'a>> {
let record_used = record_used_id.is_some();
if ns == TypeNS {
ident.span = if ident.name == keywords::SelfType.name() {
// FIXME(jseyfried) improve `Self` hygiene
......@@ -1890,10 +1891,11 @@ fn resolve_ident_in_lexical_scope(&mut self,
ident.span = ident.span.modern();
loop {
let (opt_module, poisoned) = if record_used {
self.hygienic_lexical_parent_with_compatibility_fallback(module, &mut ident.span)
let (opt_module, poisoned) = if let Some(node_id) = record_used_id {
self.hygienic_lexical_parent_with_compatibility_fallback(module, &mut ident.span,
node_id)
} else {
(self.hygienic_lexical_parent(module, &mut ident.span), false)
(self.hygienic_lexical_parent(module, &mut ident.span), None)
};
module = unwrap_or!(opt_module, break);
let orig_current_module = self.current_module;
......@@ -1905,10 +1907,10 @@ fn resolve_ident_in_lexical_scope(&mut self,
match result {
Ok(binding) => {
if poisoned {
if let Some(node_id) = poisoned {
self.session.buffer_lint_with_diagnostic(
lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
CRATE_NODE_ID, ident.span,
node_id, ident.span,
&format!("cannot find {} `{}` in this scope", ns.descr(), ident),
lint::builtin::BuiltinLintDiagnostics::
ProcMacroDeriveResolutionFallback(ident.span),
......@@ -1916,7 +1918,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
}
return Some(LexicalScopeBinding::Item(binding))
}
_ if poisoned => break,
_ if poisoned.is_some() => break,
Err(Undetermined) => return None,
Err(Determined) => {}
}
......@@ -1965,10 +1967,11 @@ fn hygienic_lexical_parent(&mut self, module: Module<'a>, span: &mut Span)
}
fn hygienic_lexical_parent_with_compatibility_fallback(
&mut self, module: Module<'a>, span: &mut Span) -> (Option<Module<'a>>, /* poisoned */ bool
) {
&mut self, module: Module<'a>, span: &mut Span, node_id: NodeId
) -> (Option<Module<'a>>, /* poisoned */ Option<NodeId>)
{
if let module @ Some(..) = self.hygienic_lexical_parent(module, span) {
return (module, false);
return (module, None);
}
// We need to support the next case under a deprecation warning
......@@ -1989,13 +1992,13 @@ fn hygienic_lexical_parent_with_compatibility_fallback(
// The macro is a proc macro derive
if module.expansion.looks_like_proc_macro_derive() {
if parent.expansion.is_descendant_of(span.ctxt().outer()) {
return (module.parent, true);
return (module.parent, Some(node_id));
}
}
}
}
(None, false)
(None, None)
}
fn resolve_ident_in_module(&mut self,
......@@ -2758,7 +2761,7 @@ fn resolve_pattern(&mut self,
// First try to resolve the identifier as some existing
// entity, then fall back to a fresh binding.
let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS,
false, pat.span)
None, pat.span)
.and_then(LexicalScopeBinding::item);
let resolution = binding.map(NameBinding::def).and_then(|def| {
let is_syntactic_ambiguity = opt_pat.is_none() &&
......@@ -3189,13 +3192,13 @@ fn type_ascription_suggestion(&self,
fn self_type_is_available(&mut self, span: Span) -> bool {
let binding = self.resolve_ident_in_lexical_scope(keywords::SelfType.ident(),
TypeNS, false, span);
TypeNS, None, span);
if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
}
fn self_value_is_available(&mut self, self_span: Span, path_span: Span) -> bool {
let ident = Ident::new(keywords::SelfValue.name(), self_span);
let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, false, path_span);
let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, path_span);
if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
}
......@@ -3472,7 +3475,9 @@ fn resolve_path(
self.resolve_lexical_macro_path_segment(ident, ns, record_used, path_span)
.map(MacroBinding::binding)
} else {
match self.resolve_ident_in_lexical_scope(ident, ns, record_used, path_span) {
let record_used_id =
if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };
match self.resolve_ident_in_lexical_scope(ident, ns, record_used_id, path_span) {
// we found a locally-imported or available item/module
Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
// we found a local variable or type param
......@@ -4692,4 +4697,15 @@ enum CrateLint {
QPathTrait { qpath_id: NodeId, qpath_span: Span },
}
impl CrateLint {
fn node_id(&self) -> Option<NodeId> {
match *self {
CrateLint::No => None,
CrateLint::SimplePath(id) |
CrateLint::UsePath { root_id: id, .. } |
CrateLint::QPathTrait { qpath_id: id, .. } => Some(id),
}
}
}
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }
......@@ -52,3 +52,16 @@ mod inner_derive {
}
".parse().unwrap()
}
#[proc_macro_derive(CheckDeriveLint)]
pub fn check_derive_lint(_: TokenStream) -> TokenStream {
"
type AliasDeriveLint = FromOutside; // OK
struct OuterDeriveLint;
#[allow(proc_macro_derive_resolution_fallback)]
mod inner_derive_lint {
type Alias = FromOutside; // `FromOutside` shouldn't be available from here
type Inner = OuterDeriveLint; // `OuterDeriveLint` shouldn't be available from here
}
".parse().unwrap()
}
......@@ -31,4 +31,7 @@
//~| WARN this was previously accepted
struct Z;
#[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
struct W;
fn main() {}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册