Skip to content

Commit 970102f

Browse files
committed
Auto merge of #52589 - petrochenkov:derlint, r=alexcrichton
Attach deprecation lint `proc_macro_derive_resolution_fallback` to a specific node id So it can be `allow`-ed from inside the derive. cc #51952
2 parents 2e6fc3e + 79b5ebf commit 970102f

File tree

3 files changed

+49
-17
lines changed

3 files changed

+49
-17
lines changed

src/librustc_resolve/lib.rs

+33-17
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
717717
}
718718
TyKind::ImplicitSelf => {
719719
let self_ty = keywords::SelfType.ident();
720-
let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, true, ty.span)
720+
let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span)
721721
.map_or(Def::Err, |d| d.def());
722722
self.record_def(ty.id, PathResolution::new(def));
723723
}
@@ -1839,9 +1839,10 @@ impl<'a> Resolver<'a> {
18391839
fn resolve_ident_in_lexical_scope(&mut self,
18401840
mut ident: Ident,
18411841
ns: Namespace,
1842-
record_used: bool,
1842+
record_used_id: Option<NodeId>,
18431843
path_span: Span)
18441844
-> Option<LexicalScopeBinding<'a>> {
1845+
let record_used = record_used_id.is_some();
18451846
if ns == TypeNS {
18461847
ident.span = if ident.name == keywords::SelfType.name() {
18471848
// FIXME(jseyfried) improve `Self` hygiene
@@ -1890,10 +1891,11 @@ impl<'a> Resolver<'a> {
18901891

18911892
ident.span = ident.span.modern();
18921893
loop {
1893-
let (opt_module, poisoned) = if record_used {
1894-
self.hygienic_lexical_parent_with_compatibility_fallback(module, &mut ident.span)
1894+
let (opt_module, poisoned) = if let Some(node_id) = record_used_id {
1895+
self.hygienic_lexical_parent_with_compatibility_fallback(module, &mut ident.span,
1896+
node_id)
18951897
} else {
1896-
(self.hygienic_lexical_parent(module, &mut ident.span), false)
1898+
(self.hygienic_lexical_parent(module, &mut ident.span), None)
18971899
};
18981900
module = unwrap_or!(opt_module, break);
18991901
let orig_current_module = self.current_module;
@@ -1905,18 +1907,18 @@ impl<'a> Resolver<'a> {
19051907

19061908
match result {
19071909
Ok(binding) => {
1908-
if poisoned {
1910+
if let Some(node_id) = poisoned {
19091911
self.session.buffer_lint_with_diagnostic(
19101912
lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
1911-
CRATE_NODE_ID, ident.span,
1913+
node_id, ident.span,
19121914
&format!("cannot find {} `{}` in this scope", ns.descr(), ident),
19131915
lint::builtin::BuiltinLintDiagnostics::
19141916
ProcMacroDeriveResolutionFallback(ident.span),
19151917
);
19161918
}
19171919
return Some(LexicalScopeBinding::Item(binding))
19181920
}
1919-
_ if poisoned => break,
1921+
_ if poisoned.is_some() => break,
19201922
Err(Undetermined) => return None,
19211923
Err(Determined) => {}
19221924
}
@@ -1965,10 +1967,11 @@ impl<'a> Resolver<'a> {
19651967
}
19661968

19671969
fn hygienic_lexical_parent_with_compatibility_fallback(
1968-
&mut self, module: Module<'a>, span: &mut Span) -> (Option<Module<'a>>, /* poisoned */ bool
1969-
) {
1970+
&mut self, module: Module<'a>, span: &mut Span, node_id: NodeId
1971+
) -> (Option<Module<'a>>, /* poisoned */ Option<NodeId>)
1972+
{
19701973
if let module @ Some(..) = self.hygienic_lexical_parent(module, span) {
1971-
return (module, false);
1974+
return (module, None);
19721975
}
19731976

19741977
// We need to support the next case under a deprecation warning
@@ -1989,13 +1992,13 @@ impl<'a> Resolver<'a> {
19891992
// The macro is a proc macro derive
19901993
if module.expansion.looks_like_proc_macro_derive() {
19911994
if parent.expansion.is_descendant_of(span.ctxt().outer()) {
1992-
return (module.parent, true);
1995+
return (module.parent, Some(node_id));
19931996
}
19941997
}
19951998
}
19961999
}
19972000

1998-
(None, false)
2001+
(None, None)
19992002
}
20002003

20012004
fn resolve_ident_in_module(&mut self,
@@ -2760,7 +2763,7 @@ impl<'a> Resolver<'a> {
27602763
// First try to resolve the identifier as some existing
27612764
// entity, then fall back to a fresh binding.
27622765
let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS,
2763-
false, pat.span)
2766+
None, pat.span)
27642767
.and_then(LexicalScopeBinding::item);
27652768
let resolution = binding.map(NameBinding::def).and_then(|def| {
27662769
let is_syntactic_ambiguity = opt_pat.is_none() &&
@@ -3191,13 +3194,13 @@ impl<'a> Resolver<'a> {
31913194

31923195
fn self_type_is_available(&mut self, span: Span) -> bool {
31933196
let binding = self.resolve_ident_in_lexical_scope(keywords::SelfType.ident(),
3194-
TypeNS, false, span);
3197+
TypeNS, None, span);
31953198
if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
31963199
}
31973200

31983201
fn self_value_is_available(&mut self, self_span: Span, path_span: Span) -> bool {
31993202
let ident = Ident::new(keywords::SelfValue.name(), self_span);
3200-
let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, false, path_span);
3203+
let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, path_span);
32013204
if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
32023205
}
32033206

@@ -3474,7 +3477,9 @@ impl<'a> Resolver<'a> {
34743477
self.resolve_lexical_macro_path_segment(ident, ns, record_used, path_span)
34753478
.map(MacroBinding::binding)
34763479
} else {
3477-
match self.resolve_ident_in_lexical_scope(ident, ns, record_used, path_span) {
3480+
let record_used_id =
3481+
if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };
3482+
match self.resolve_ident_in_lexical_scope(ident, ns, record_used_id, path_span) {
34783483
// we found a locally-imported or available item/module
34793484
Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
34803485
// we found a local variable or type param
@@ -4694,4 +4699,15 @@ enum CrateLint {
46944699
QPathTrait { qpath_id: NodeId, qpath_span: Span },
46954700
}
46964701

4702+
impl CrateLint {
4703+
fn node_id(&self) -> Option<NodeId> {
4704+
match *self {
4705+
CrateLint::No => None,
4706+
CrateLint::SimplePath(id) |
4707+
CrateLint::UsePath { root_id: id, .. } |
4708+
CrateLint::QPathTrait { qpath_id: id, .. } => Some(id),
4709+
}
4710+
}
4711+
}
4712+
46974713
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }

src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs

+13
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,16 @@ pub fn check_derive(_: TokenStream) -> TokenStream {
5252
}
5353
".parse().unwrap()
5454
}
55+
56+
#[proc_macro_derive(CheckDeriveLint)]
57+
pub fn check_derive_lint(_: TokenStream) -> TokenStream {
58+
"
59+
type AliasDeriveLint = FromOutside; // OK
60+
struct OuterDeriveLint;
61+
#[allow(proc_macro_derive_resolution_fallback)]
62+
mod inner_derive_lint {
63+
type Alias = FromOutside; // `FromOutside` shouldn't be available from here
64+
type Inner = OuterDeriveLint; // `OuterDeriveLint` shouldn't be available from here
65+
}
66+
".parse().unwrap()
67+
}

src/test/ui-fulldeps/proc-macro/generate-mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,7 @@ struct S;
3131
//~| WARN this was previously accepted
3232
struct Z;
3333

34+
#[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
35+
struct W;
36+
3437
fn main() {}

0 commit comments

Comments
 (0)