Skip to main content

rustc_resolve/
macros.rs

1//! A bunch of methods and structures more or less related to resolving macros and
2//! interface provided by `Resolver` to macro expander.
3
4use std::mem;
5use std::sync::Arc;
6
7use rustc_ast::{self as ast, Crate, DelegationSuffixes, NodeId};
8use rustc_ast_pretty::pprust;
9use rustc_attr_parsing::AttributeParser;
10use rustc_errors::{Applicability, DiagCtxtHandle, StashKey};
11use rustc_expand::base::{
12    Annotatable, DeriveResolution, Indeterminate, ResolverExpand, SyntaxExtension,
13    SyntaxExtensionKind,
14};
15use rustc_expand::compile_declarative_macro;
16use rustc_expand::expand::{
17    AstFragment, AstFragmentKind, Invocation, InvocationKind, SupportsMacroExpansion,
18};
19use rustc_hir::attrs::{AttributeKind, CfgEntry, StrippedCfgItem};
20use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind};
21use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
22use rustc_hir::{Attribute, StabilityLevel};
23use rustc_middle::middle::stability;
24use rustc_middle::ty::{RegisteredTools, TyCtxt};
25use rustc_session::Session;
26use rustc_session::errors::feature_err;
27use rustc_session::lint::builtin::{
28    LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
29    UNUSED_MACRO_RULES, UNUSED_MACROS,
30};
31use rustc_span::edit_distance::find_best_match_for_name;
32use rustc_span::edition::Edition;
33use rustc_span::hygiene::{self, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
34use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
35
36use crate::Namespace::*;
37use crate::def_collector::collect_definitions;
38use crate::errors::{
39    self, AddAsNonDerive, CannotDetermineMacroResolution, CannotFindIdentInThisScope,
40    MacroExpectedFound, RemoveSurroundingDerive,
41};
42use crate::hygiene::Macros20NormalizedSyntaxContext;
43use crate::imports::Import;
44use crate::{
45    BindingKey, CacheCell, CmResolver, Decl, DeclKind, DeriveData, Determinacy, Finalize, IdentKey,
46    InvocationParent, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, Res,
47    ResolutionError, Resolver, ScopeSet, Segment, Used,
48};
49
50/// Name declaration produced by a `macro_rules` item definition.
51/// Not modularized, can shadow previous `macro_rules` definitions, etc.
52#[derive(#[automatically_derived]
impl<'ra> ::core::fmt::Debug for MacroRulesDecl<'ra> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f,
            "MacroRulesDecl", "decl", &self.decl, "parent_macro_rules_scope",
            &self.parent_macro_rules_scope, "ident", &self.ident,
            "orig_ident_span", &&self.orig_ident_span)
    }
}Debug)]
53pub(crate) struct MacroRulesDecl<'ra> {
54    pub(crate) decl: Decl<'ra>,
55    /// `macro_rules` scope into which the `macro_rules` item was planted.
56    pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'ra>,
57    pub(crate) ident: IdentKey,
58    pub(crate) orig_ident_span: Span,
59}
60
61/// The scope introduced by a `macro_rules!` macro.
62/// This starts at the macro's definition and ends at the end of the macro's parent
63/// module (named or unnamed), or even further if it escapes with `#[macro_use]`.
64/// Some macro invocations need to introduce `macro_rules` scopes too because they
65/// can potentially expand into macro definitions.
66#[derive(#[automatically_derived]
impl<'ra> ::core::marker::Copy for MacroRulesScope<'ra> { }Copy, #[automatically_derived]
impl<'ra> ::core::clone::Clone for MacroRulesScope<'ra> {
    #[inline]
    fn clone(&self) -> MacroRulesScope<'ra> {
        let _: ::core::clone::AssertParamIsClone<&'ra MacroRulesDecl<'ra>>;
        let _: ::core::clone::AssertParamIsClone<LocalExpnId>;
        *self
    }
}Clone, #[automatically_derived]
impl<'ra> ::core::fmt::Debug for MacroRulesScope<'ra> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            MacroRulesScope::Empty =>
                ::core::fmt::Formatter::write_str(f, "Empty"),
            MacroRulesScope::Def(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Def",
                    &__self_0),
            MacroRulesScope::Invocation(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Invocation", &__self_0),
        }
    }
}Debug)]
67pub(crate) enum MacroRulesScope<'ra> {
68    /// Empty "root" scope at the crate start containing no names.
69    Empty,
70    /// The scope introduced by a `macro_rules!` macro definition.
71    Def(&'ra MacroRulesDecl<'ra>),
72    /// The scope introduced by a macro invocation that can potentially
73    /// create a `macro_rules!` macro definition.
74    Invocation(LocalExpnId),
75}
76
77/// `macro_rules!` scopes are always kept by reference and inside a cell.
78/// The reason is that we update scopes with value `MacroRulesScope::Invocation(invoc_id)`
79/// in-place after `invoc_id` gets expanded.
80/// This helps to avoid uncontrollable growth of `macro_rules!` scope chains,
81/// which usually grow linearly with the number of macro invocations
82/// in a module (including derives) and hurt performance.
83pub(crate) type MacroRulesScopeRef<'ra> = &'ra CacheCell<MacroRulesScope<'ra>>;
84
85/// Macro namespace is separated into two sub-namespaces, one for bang macros and
86/// one for attribute-like macros (attributes, derives).
87/// We ignore resolutions from one sub-namespace when searching names in scope for another.
88pub(crate) fn sub_namespace_match(
89    candidate: Option<MacroKinds>,
90    requirement: Option<MacroKind>,
91) -> bool {
92    // "No specific sub-namespace" means "matches anything" for both requirements and candidates.
93    let (Some(candidate), Some(requirement)) = (candidate, requirement) else {
94        return true;
95    };
96    match requirement {
97        MacroKind::Bang => candidate.contains(MacroKinds::BANG),
98        MacroKind::Attr | MacroKind::Derive => {
99            candidate.intersects(MacroKinds::ATTR | MacroKinds::DERIVE)
100        }
101    }
102}
103
104// We don't want to format a path using pretty-printing,
105// `format!("{}", path)`, because that tries to insert
106// line-breaks and is slow.
107fn fast_print_path(path: &ast::Path) -> Symbol {
108    if let [segment] = path.segments.as_slice() {
109        segment.ident.name
110    } else {
111        let mut path_str = String::with_capacity(64);
112        for (i, segment) in path.segments.iter().enumerate() {
113            if i != 0 {
114                path_str.push_str("::");
115            }
116            if segment.ident.name != kw::PathRoot {
117                path_str.push_str(segment.ident.as_str())
118            }
119        }
120        Symbol::intern(&path_str)
121    }
122}
123
124pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools {
125    let (_, pre_configured_attrs) = &*tcx.crate_for_resolver(()).borrow();
126    registered_tools_ast(tcx.dcx(), pre_configured_attrs, tcx.sess)
127}
128
129pub fn registered_tools_ast(
130    dcx: DiagCtxtHandle<'_>,
131    pre_configured_attrs: &[ast::Attribute],
132    sess: &Session,
133) -> RegisteredTools {
134    let mut registered_tools = RegisteredTools::default();
135
136    if let Some(Attribute::Parsed(AttributeKind::RegisterTool(tools))) =
137        AttributeParser::parse_limited(sess, pre_configured_attrs, &[sym::register_tool])
138    {
139        for tool in tools {
140            if let Some(old_tool) = registered_tools.replace(tool) {
141                dcx.emit_err(errors::ToolWasAlreadyRegistered {
142                    span: tool.span,
143                    tool,
144                    old_ident_span: old_tool.span,
145                });
146            }
147        }
148    }
149
150    // We implicitly add `rustfmt`, `clippy`, `diagnostic`, `miri` and `rust_analyzer` to known
151    // tools, but it's not an error to register them explicitly.
152    let predefined_tools =
153        [sym::clippy, sym::rustfmt, sym::diagnostic, sym::miri, sym::rust_analyzer];
154    registered_tools.extend(predefined_tools.iter().cloned().map(Ident::with_dummy_span));
155    registered_tools
156}
157
158impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
159    fn next_node_id(&mut self) -> NodeId {
160        self.next_node_id()
161    }
162
163    fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId {
164        self.invocation_parents[&id].parent_def
165    }
166
167    fn mark_scope_with_compile_error(&mut self, id: NodeId) {
168        if let Some(id) = self.owners.get(&id).map(|i| i.def_id)
169            && self.tcx.def_kind(id).is_module_like()
170        {
171            self.mods_with_parse_errors.insert(id.to_def_id());
172        }
173    }
174
175    fn resolve_dollar_crates(&self) {
176        hygiene::update_dollar_crate_names(|ctxt| {
177            let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt));
178            self.resolve_crate_root(ident).name().unwrap_or(kw::Crate)
179        });
180    }
181
182    fn visit_ast_fragment_with_placeholders(
183        &mut self,
184        expansion: LocalExpnId,
185        fragment: &AstFragment,
186    ) {
187        // Integrate the new AST fragment into all the definition and module structures.
188        // We are inside the `expansion` now, but other parent scope components are still the same.
189        let parent_scope = ParentScope { expansion, ..self.invocation_parent_scopes[&expansion] };
190        let output_macro_rules_scope = collect_definitions(self, fragment, parent_scope);
191        self.output_macro_rules_scopes.insert(expansion, output_macro_rules_scope);
192
193        let module = parent_scope.module.expect_local();
194        module.unexpanded_invocations.borrow_mut(self).remove(&expansion);
195        if let Some(unexpanded_invocations) =
196            self.impl_unexpanded_invocations.get_mut(&self.invocation_parent(expansion))
197        {
198            unexpanded_invocations.remove(&expansion);
199        }
200    }
201
202    fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind) {
203        if self.builtin_macros.insert(name, ext).is_some() {
204            self.dcx().bug(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("built-in macro `{0}` was already registered",
                name))
    })format!("built-in macro `{name}` was already registered"));
205        }
206    }
207
208    // Create a new Expansion with a definition site of the provided module, or
209    // a fake empty `#[no_implicit_prelude]` module if no module is provided.
210    fn expansion_for_ast_pass(
211        &mut self,
212        call_site: Span,
213        pass: AstPass,
214        features: &[Symbol],
215        parent_module_id: Option<NodeId>,
216    ) -> LocalExpnId {
217        let parent_module =
218            parent_module_id.map(|module_id| self.owner_def_id(module_id).to_def_id());
219        let expn_id = self.tcx.with_stable_hashing_context(|hcx| {
220            LocalExpnId::fresh(
221                ExpnData::allow_unstable(
222                    ExpnKind::AstPass(pass),
223                    call_site,
224                    self.tcx.sess.edition(),
225                    features.into(),
226                    None,
227                    parent_module,
228                ),
229                hcx,
230            )
231        });
232
233        let parent_scope = parent_module
234            .map_or(self.empty_module, |def_id| self.expect_module(def_id).expect_local());
235        self.ast_transform_scopes.insert(expn_id, parent_scope);
236
237        expn_id
238    }
239
240    fn resolve_imports(&mut self) {
241        self.resolve_imports()
242    }
243
244    fn resolve_macro_invocation(
245        &mut self,
246        invoc: &Invocation,
247        eager_expansion_root: LocalExpnId,
248        force: bool,
249    ) -> Result<Arc<SyntaxExtension>, Indeterminate> {
250        let invoc_id = invoc.expansion_data.id;
251        let parent_scope = match self.invocation_parent_scopes.get(&invoc_id) {
252            Some(parent_scope) => *parent_scope,
253            None => {
254                // If there's no entry in the table, then we are resolving an eagerly expanded
255                // macro, which should inherit its parent scope from its eager expansion root -
256                // the macro that requested this eager expansion.
257                let parent_scope = *self
258                    .invocation_parent_scopes
259                    .get(&eager_expansion_root)
260                    .expect("non-eager expansion without a parent scope");
261                self.invocation_parent_scopes.insert(invoc_id, parent_scope);
262                parent_scope
263            }
264        };
265
266        let (mut derives, mut inner_attr, mut deleg_impl) = (&[][..], false, None);
267        let (path, kind) = match invoc.kind {
268            InvocationKind::Attr { ref attr, derives: ref attr_derives, .. } => {
269                derives = self.arenas.alloc_ast_paths(attr_derives);
270                inner_attr = attr.style == ast::AttrStyle::Inner;
271                (&attr.get_normal_item().path, MacroKind::Attr)
272            }
273            InvocationKind::Bang { ref mac, .. } => (&mac.path, MacroKind::Bang),
274            InvocationKind::Derive { ref path, .. } => (path, MacroKind::Derive),
275            InvocationKind::GlobDelegation { ref item, .. } => {
276                let ast::AssocItemKind::DelegationMac(deleg) = &item.kind else { ::core::panicking::panic("internal error: entered unreachable code")unreachable!() };
277                let DelegationSuffixes::Glob(star_span) = deleg.suffixes else { ::core::panicking::panic("internal error: entered unreachable code")unreachable!() };
278                deleg_impl = Some((self.invocation_parent(invoc_id), star_span));
279                // It is sufficient to consider glob delegation a bang macro for now.
280                (&deleg.prefix, MacroKind::Bang)
281            }
282        };
283
284        // Derives are not included when `invocations` are collected, so we have to add them here.
285        let parent_scope = &ParentScope { derives, ..parent_scope };
286        let supports_macro_expansion = invoc.fragment_kind.supports_macro_expansion();
287        let node_id = invoc.expansion_data.lint_node_id;
288        // This is a heuristic, but it's good enough for the lint.
289        let looks_like_invoc_in_mod_inert_attr = self
290            .invocation_parents
291            .get(&invoc_id)
292            .or_else(|| self.invocation_parents.get(&eager_expansion_root))
293            .filter(|&&InvocationParent { parent_def: mod_def_id, in_attr, .. }| {
294                in_attr
295                    && invoc.fragment_kind == AstFragmentKind::Expr
296                    && self.tcx.def_kind(mod_def_id) == DefKind::Mod
297            })
298            .map(|&InvocationParent { parent_def: mod_def_id, .. }| mod_def_id);
299        let sugg_span = match &invoc.kind {
300            InvocationKind::Attr { item: Annotatable::Item(item), .. }
301                if !item.span.from_expansion() =>
302            {
303                Some(item.span.shrink_to_lo())
304            }
305            _ => None,
306        };
307        let (ext, res) = self.smart_resolve_macro_path(
308            path,
309            kind,
310            supports_macro_expansion,
311            inner_attr,
312            parent_scope,
313            node_id,
314            force,
315            deleg_impl,
316            looks_like_invoc_in_mod_inert_attr,
317            sugg_span,
318        )?;
319
320        let span = invoc.span();
321        let def_id = if deleg_impl.is_some() { None } else { res.opt_def_id() };
322        self.tcx.with_stable_hashing_context(|hcx| {
323            invoc_id.set_expn_data(
324                ext.expn_data(
325                    parent_scope.expansion,
326                    span,
327                    fast_print_path(path),
328                    kind,
329                    def_id,
330                    def_id.map(|def_id| self.macro_def_scope(def_id).nearest_parent_mod()),
331                ),
332                hcx,
333            )
334        });
335
336        Ok(Arc::clone(ext))
337    }
338
339    fn record_macro_rule_usage(&mut self, id: NodeId, rule_i: usize) {
340        if let Some((_, rules)) = self.unused_macro_rules.get_mut(&id) {
341            rules.remove(rule_i);
342        }
343    }
344
345    fn check_unused_macros(&mut self) {
346        for (_, &(node_id, ident)) in self.unused_macros.iter() {
347            self.lint_buffer.buffer_lint(
348                UNUSED_MACROS,
349                node_id,
350                ident.span,
351                errors::UnusedMacroDefinition { name: ident.name },
352            );
353            // Do not report unused individual rules if the entire macro is unused
354            self.unused_macro_rules.swap_remove(&node_id);
355        }
356
357        for (&node_id, (def_id, unused_arms)) in self.unused_macro_rules.iter() {
358            if unused_arms.is_empty() {
359                continue;
360            }
361            let ext = self.local_macro_map[&def_id];
362            let SyntaxExtensionKind::MacroRules(ref m) = ext.kind else {
363                continue;
364            };
365            for arm_i in unused_arms.iter() {
366                if let Some((ident, rule_span)) = m.get_unused_rule(arm_i) {
367                    self.lint_buffer.buffer_lint(
368                        UNUSED_MACRO_RULES,
369                        node_id,
370                        rule_span,
371                        errors::MacroRuleNeverUsed { n: arm_i + 1, name: ident.name },
372                    );
373                }
374            }
375        }
376    }
377
378    fn has_derive_copy(&self, expn_id: LocalExpnId) -> bool {
379        self.containers_deriving_copy.contains(&expn_id)
380    }
381
382    fn resolve_derives(
383        &mut self,
384        expn_id: LocalExpnId,
385        force: bool,
386        derive_paths: &dyn Fn() -> Vec<DeriveResolution>,
387    ) -> Result<(), Indeterminate> {
388        // Block expansion of the container until we resolve all derives in it.
389        // This is required for two reasons:
390        // - Derive helper attributes are in scope for the item to which the `#[derive]`
391        //   is applied, so they have to be produced by the container's expansion rather
392        //   than by individual derives.
393        // - Derives in the container need to know whether one of them is a built-in `Copy`.
394        //   (But see the comment mentioning #124794 below.)
395        // Temporarily take the data to avoid borrow checker conflicts.
396        let mut derive_data = mem::take(&mut self.derive_data);
397        let entry = derive_data.entry(expn_id).or_insert_with(|| DeriveData {
398            resolutions: derive_paths(),
399            helper_attrs: Vec::new(),
400            has_derive_copy: false,
401        });
402        let parent_scope = self.invocation_parent_scopes[&expn_id];
403        for (i, resolution) in entry.resolutions.iter_mut().enumerate() {
404            if resolution.exts.is_none() {
405                resolution.exts = Some(Arc::clone(
406                    match self.cm().resolve_derive_macro_path(
407                        &resolution.path,
408                        &parent_scope,
409                        force,
410                        None,
411                    ) {
412                        Ok((Some(ext), _)) => {
413                            if !ext.helper_attrs.is_empty() {
414                                let span = resolution.path.segments.last().unwrap().ident.span;
415                                let ctxt = Macros20NormalizedSyntaxContext::new(span.ctxt());
416                                entry.helper_attrs.extend(
417                                    ext.helper_attrs
418                                        .iter()
419                                        .map(|&name| (i, IdentKey { name, ctxt }, span)),
420                                );
421                            }
422                            entry.has_derive_copy |= ext.builtin_name == Some(sym::Copy);
423                            ext
424                        }
425                        Ok(_) | Err(Determinacy::Determined) => self.dummy_ext(MacroKind::Derive),
426                        Err(Determinacy::Undetermined) => {
427                            if !self.derive_data.is_empty() {
    ::core::panicking::panic("assertion failed: self.derive_data.is_empty()")
};assert!(self.derive_data.is_empty());
428                            self.derive_data = derive_data;
429                            return Err(Indeterminate);
430                        }
431                    },
432                ));
433            }
434        }
435        // Sort helpers in a stable way independent from the derive resolution order.
436        entry.helper_attrs.sort_by_key(|(i, ..)| *i);
437        let helper_attrs = entry
438            .helper_attrs
439            .iter()
440            .map(|&(_, ident, orig_ident_span)| {
441                let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
442                let decl = self.arenas.new_pub_def_decl(res, orig_ident_span, expn_id);
443                (ident, orig_ident_span, decl)
444            })
445            .collect();
446        self.helper_attrs.insert(expn_id, helper_attrs);
447        // Mark this derive as having `Copy` either if it has `Copy` itself or if its parent derive
448        // has `Copy`, to support `#[derive(Copy, Clone)]`, `#[derive(Clone, Copy)]`, or
449        // `#[derive(Copy)] #[derive(Clone)]`. We do this because the code generated for
450        // `derive(Clone)` changes if `derive(Copy)` is also present.
451        //
452        // FIXME(#124794): unfortunately this doesn't work with `#[derive(Clone)] #[derive(Copy)]`.
453        // When the `Clone` impl is generated the `#[derive(Copy)]` hasn't been processed and
454        // `has_derive_copy` hasn't been set yet.
455        if entry.has_derive_copy || self.has_derive_copy(parent_scope.expansion) {
456            self.containers_deriving_copy.insert(expn_id);
457        }
458        if !self.derive_data.is_empty() {
    ::core::panicking::panic("assertion failed: self.derive_data.is_empty()")
};assert!(self.derive_data.is_empty());
459        self.derive_data = derive_data;
460        Ok(())
461    }
462
463    fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<Vec<DeriveResolution>> {
464        self.derive_data.remove(&expn_id).map(|data| data.resolutions)
465    }
466
467    // The function that implements the resolution logic of `#[cfg_accessible(path)]`.
468    // Returns true if the path can certainly be resolved in one of three namespaces,
469    // returns false if the path certainly cannot be resolved in any of the three namespaces.
470    // Returns `Indeterminate` if we cannot give a certain answer yet.
471    fn cfg_accessible(
472        &mut self,
473        expn_id: LocalExpnId,
474        path: &ast::Path,
475    ) -> Result<bool, Indeterminate> {
476        self.path_accessible(expn_id, path, &[TypeNS, ValueNS, MacroNS])
477    }
478
479    fn macro_accessible(
480        &mut self,
481        expn_id: LocalExpnId,
482        path: &ast::Path,
483    ) -> Result<bool, Indeterminate> {
484        self.path_accessible(expn_id, path, &[MacroNS])
485    }
486
487    fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span {
488        self.cstore().get_proc_macro_quoted_span_untracked(self.tcx, krate, id)
489    }
490
491    fn declare_proc_macro(&mut self, id: NodeId) {
492        self.proc_macros.push(self.owner_def_id(id))
493    }
494
495    fn append_stripped_cfg_item(
496        &mut self,
497        parent_node: NodeId,
498        ident: Ident,
499        cfg: CfgEntry,
500        cfg_span: Span,
501    ) {
502        self.stripped_cfg_items.push(StrippedCfgItem {
503            parent_scope: parent_node,
504            ident,
505            cfg: (cfg, cfg_span),
506        });
507    }
508
509    fn registered_tools(&self) -> &RegisteredTools {
510        self.registered_tools
511    }
512
513    fn register_glob_delegation(&mut self, invoc_id: LocalExpnId) {
514        self.glob_delegation_invoc_ids.insert(invoc_id);
515    }
516
517    fn glob_delegation_suffixes(
518        &self,
519        trait_def_id: DefId,
520        impl_def_id: LocalDefId,
521        star_span: Span,
522    ) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate> {
523        let target_trait = self.expect_module(trait_def_id);
524        if target_trait.has_unexpanded_invocations() {
525            return Err(Indeterminate);
526        }
527        // FIXME: Instead of waiting try generating all trait methods, and pruning
528        // the shadowed ones a bit later, e.g. when all macro expansion completes.
529        // Pros: expansion will be stuck less (but only in exotic cases), the implementation may be
530        // less hacky.
531        // Cons: More code is generated just to be deleted later, deleting already created `DefId`s
532        // may be nontrivial.
533        if let Some(unexpanded_invocations) = self.impl_unexpanded_invocations.get(&impl_def_id)
534            && !unexpanded_invocations.is_empty()
535        {
536            return Err(Indeterminate);
537        }
538
539        let mut idents = Vec::new();
540        target_trait.for_each_child(self, |this, ident, orig_ident_span, ns, _binding| {
541            if let Some(overriding_keys) = this.impl_binding_keys.get(&impl_def_id)
542                && overriding_keys.contains(&BindingKey::new(ident, ns))
543            {
544                // The name is overridden, do not produce it from the glob delegation.
545            } else {
546                // FIXME: Adjust hygiene for idents from globs, like for glob imports.
547                idents.push((ident.orig(star_span.with_ctxt(orig_ident_span.ctxt())), None));
548            }
549        });
550        Ok(idents)
551    }
552
553    fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol) {
554        self.impl_trait_names.insert(id, name);
555    }
556}
557
558impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
559    /// Resolve macro path with error reporting and recovery.
560    /// Uses dummy syntax extensions for unresolved macros or macros with unexpected resolutions
561    /// for better error recovery.
562    fn smart_resolve_macro_path(
563        &mut self,
564        path: &ast::Path,
565        kind: MacroKind,
566        supports_macro_expansion: SupportsMacroExpansion,
567        inner_attr: bool,
568        parent_scope: &ParentScope<'ra>,
569        node_id: NodeId,
570        force: bool,
571        deleg_impl: Option<(LocalDefId, Span)>,
572        invoc_in_mod_inert_attr: Option<LocalDefId>,
573        suggestion_span: Option<Span>,
574    ) -> Result<(&'ra Arc<SyntaxExtension>, Res), Indeterminate> {
575        let (ext, res) = match self.cm().resolve_macro_or_delegation_path(
576            path,
577            kind,
578            parent_scope,
579            force,
580            deleg_impl,
581            invoc_in_mod_inert_attr.map(|def_id| (def_id, node_id)),
582            None,
583            suggestion_span,
584        ) {
585            Ok((Some(ext), res)) => (ext, res),
586            Ok((None, res)) => (self.dummy_ext(kind), res),
587            Err(Determinacy::Determined) => (self.dummy_ext(kind), Res::Err),
588            Err(Determinacy::Undetermined) => return Err(Indeterminate),
589        };
590
591        // Everything below is irrelevant to glob delegation, take a shortcut.
592        if deleg_impl.is_some() {
593            if !#[allow(non_exhaustive_omitted_patterns)] match res {
    Res::Err | Res::Def(DefKind::Trait, _) => true,
    _ => false,
}matches!(res, Res::Err | Res::Def(DefKind::Trait, _)) {
594                self.dcx().emit_err(MacroExpectedFound {
595                    span: path.span,
596                    expected: "trait",
597                    article: "a",
598                    found: res.descr(),
599                    macro_path: &pprust::path_to_string(path),
600                    remove_surrounding_derive: None,
601                    add_as_non_derive: None,
602                });
603                return Ok((self.dummy_ext(kind), Res::Err));
604            }
605
606            return Ok((ext, res));
607        }
608
609        // Report errors for the resolved macro.
610        for (idx, segment) in path.segments.iter().enumerate() {
611            if let Some(args) = &segment.args {
612                self.dcx().emit_err(errors::GenericArgumentsInMacroPath { span: args.span() });
613            }
614            if kind == MacroKind::Attr && segment.ident.as_str().starts_with("rustc") {
615                if idx == 0 {
616                    self.dcx().emit_err(errors::AttributesStartingWithRustcAreReserved {
617                        span: segment.ident.span,
618                    });
619                } else {
620                    self.dcx().emit_err(errors::AttributesContainingRustcAreReserved {
621                        span: segment.ident.span,
622                    });
623                }
624            }
625        }
626
627        match res {
628            Res::Def(DefKind::Macro(_), def_id) => {
629                if let Some(def_id) = def_id.as_local() {
630                    self.unused_macros.swap_remove(&def_id);
631                    if self.proc_macro_stubs.contains(&def_id) {
632                        self.dcx().emit_err(errors::ProcMacroSameCrate {
633                            span: path.span,
634                            is_test: self.tcx.sess.is_test_crate(),
635                        });
636                    }
637                }
638            }
639            Res::NonMacroAttr(..) | Res::Err => {}
640            _ => {
    ::core::panicking::panic_fmt(format_args!("expected `DefKind::Macro` or `Res::NonMacroAttr`"));
}panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"),
641        };
642
643        self.check_stability_and_deprecation(&ext, path, node_id);
644
645        let unexpected_res = if !ext.macro_kinds().contains(kind.into()) {
646            Some((kind.article(), kind.descr_expected()))
647        } else if #[allow(non_exhaustive_omitted_patterns)] match res {
    Res::Def(..) => true,
    _ => false,
}matches!(res, Res::Def(..)) {
648            match supports_macro_expansion {
649                SupportsMacroExpansion::No => Some(("a", "non-macro attribute")),
650                SupportsMacroExpansion::Yes { supports_inner_attrs } => {
651                    if inner_attr && !supports_inner_attrs {
652                        Some(("a", "non-macro inner attribute"))
653                    } else {
654                        None
655                    }
656                }
657            }
658        } else {
659            None
660        };
661        if let Some((article, expected)) = unexpected_res {
662            let path_str = pprust::path_to_string(path);
663
664            let mut err = MacroExpectedFound {
665                span: path.span,
666                expected,
667                article,
668                found: res.descr(),
669                macro_path: &path_str,
670                remove_surrounding_derive: None,
671                add_as_non_derive: None,
672            };
673
674            // Suggest moving the macro out of the derive() if the macro isn't Derive
675            if !path.span.from_expansion()
676                && kind == MacroKind::Derive
677                && !ext.macro_kinds().contains(MacroKinds::DERIVE)
678                && ext.macro_kinds().contains(MacroKinds::ATTR)
679            {
680                err.remove_surrounding_derive = Some(RemoveSurroundingDerive { span: path.span });
681                err.add_as_non_derive = Some(AddAsNonDerive { macro_path: &path_str });
682            }
683
684            self.dcx().emit_err(err);
685
686            return Ok((self.dummy_ext(kind), Res::Err));
687        }
688
689        // We are trying to avoid reporting this error if other related errors were reported.
690        if res != Res::Err && inner_attr && !self.tcx.features().custom_inner_attributes() {
691            let is_macro = match res {
692                Res::Def(..) => true,
693                Res::NonMacroAttr(..) => false,
694                _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
695            };
696            let msg = if is_macro {
697                "inner macro attributes are unstable"
698            } else {
699                "custom inner attributes are unstable"
700            };
701            feature_err(&self.tcx.sess, sym::custom_inner_attributes, path.span, msg).emit();
702        }
703
704        const DIAGNOSTIC_ATTRIBUTES: &[(Symbol, Option<Symbol>)] = &[
705            (sym::on_unimplemented, None),
706            (sym::do_not_recommend, None),
707            (sym::on_move, Some(sym::diagnostic_on_move)),
708            (sym::on_const, Some(sym::diagnostic_on_const)),
709            (sym::on_unknown, Some(sym::diagnostic_on_unknown)),
710            (sym::on_unmatch_args, Some(sym::diagnostic_on_unmatch_args)),
711        ];
712
713        if res == Res::NonMacroAttr(NonMacroAttrKind::Tool)
714            && let [namespace, attribute, ..] = &*path.segments
715            && namespace.ident.name == sym::diagnostic
716            && !DIAGNOSTIC_ATTRIBUTES.iter().any(|(attr, feature)| {
717                attribute.ident.name == *attr
718                    && feature.is_none_or(|f| self.tcx.features().enabled(f))
719            })
720        {
721            let name = attribute.ident.name;
722            let span = attribute.span();
723
724            let help = 'help: {
725                if self.tcx.sess.is_nightly_build() {
726                    for (attr, feature) in DIAGNOSTIC_ATTRIBUTES {
727                        if let Some(feature) = *feature
728                            && *attr == name
729                        {
730                            break 'help Some(errors::UnknownDiagnosticAttributeHelp::UseFeature {
731                                feature,
732                            });
733                        }
734                    }
735                }
736
737                let candidates = DIAGNOSTIC_ATTRIBUTES
738                    .iter()
739                    .filter_map(|(attr, feature)| {
740                        feature.is_none_or(|f| self.tcx.features().enabled(f)).then_some(*attr)
741                    })
742                    .collect::<Vec<_>>();
743
744                find_best_match_for_name(&candidates, name, None).map(|typo_name| {
745                    errors::UnknownDiagnosticAttributeHelp::Typo { span, typo_name }
746                })
747            };
748
749            self.tcx.sess.psess.buffer_lint(
750                UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
751                span,
752                node_id,
753                errors::UnknownDiagnosticAttribute { help },
754            );
755        }
756
757        Ok((ext, res))
758    }
759
760    pub(crate) fn resolve_derive_macro_path<'r>(
761        self: CmResolver<'r, 'ra, 'tcx>,
762        path: &ast::Path,
763        parent_scope: &ParentScope<'ra>,
764        force: bool,
765        ignore_import: Option<Import<'ra>>,
766    ) -> Result<(Option<&'r Arc<SyntaxExtension>>, Res), Determinacy> {
767        self.resolve_macro_or_delegation_path(
768            path,
769            MacroKind::Derive,
770            parent_scope,
771            force,
772            None,
773            None,
774            ignore_import,
775            None,
776        )
777    }
778
779    fn resolve_macro_or_delegation_path<'r>(
780        mut self: CmResolver<'r, 'ra, 'tcx>,
781        ast_path: &ast::Path,
782        kind: MacroKind,
783        parent_scope: &ParentScope<'ra>,
784        force: bool,
785        deleg_impl: Option<(LocalDefId, Span)>,
786        invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
787        ignore_import: Option<Import<'ra>>,
788        suggestion_span: Option<Span>,
789    ) -> Result<(Option<&'ra Arc<SyntaxExtension>>, Res), Determinacy> {
790        let path_span = ast_path.span;
791        let mut path = Segment::from_path(ast_path);
792
793        // Possibly apply the macro helper hack
794        if deleg_impl.is_none()
795            && kind == MacroKind::Bang
796            && let [segment] = path.as_slice()
797            && segment.ident.span.ctxt().outer_expn_data().local_inner_macros
798        {
799            let root = Ident::new(kw::DollarCrate, segment.ident.span);
800            path.insert(0, Segment::from_ident(root));
801        }
802
803        let res = if deleg_impl.is_some() || path.len() > 1 {
804            let ns = if deleg_impl.is_some() { TypeNS } else { MacroNS };
805            let res = match self.reborrow().maybe_resolve_path(
806                &path,
807                Some(ns),
808                parent_scope,
809                ignore_import,
810            ) {
811                PathResult::NonModule(path_res) if let Some(res) = path_res.full_res() => Ok(res),
812                PathResult::Indeterminate if !force => return Err(Determinacy::Undetermined),
813                PathResult::NonModule(..)
814                | PathResult::Indeterminate
815                | PathResult::Failed { .. } => Err(Determinacy::Determined),
816                PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
817                    Ok(module.res().unwrap())
818                }
819                PathResult::Module(..) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
820            };
821
822            self.multi_segment_macro_resolutions.borrow_mut(&self).push((
823                path,
824                path_span,
825                kind,
826                *parent_scope,
827                res.ok(),
828                ns,
829            ));
830
831            self.prohibit_imported_non_macro_attrs(None, res.ok(), path_span);
832            res
833        } else {
834            let binding = self.reborrow().resolve_ident_in_scope_set(
835                path[0].ident,
836                ScopeSet::Macro(kind),
837                parent_scope,
838                None,
839                None,
840                None,
841            );
842            let binding = binding.map_err(|determinacy| {
843                Determinacy::determined(determinacy == Determinacy::Determined || force)
844            });
845            if let Err(Determinacy::Undetermined) = binding {
846                return Err(Determinacy::Undetermined);
847            }
848
849            self.single_segment_macro_resolutions.borrow_mut(&self).push((
850                path[0].ident,
851                kind,
852                *parent_scope,
853                binding.ok(),
854                suggestion_span,
855            ));
856
857            let res = binding.map(|binding| binding.res());
858            self.prohibit_imported_non_macro_attrs(binding.ok(), res.ok(), path_span);
859            self.reborrow().report_out_of_scope_macro_calls(
860                ast_path,
861                parent_scope,
862                invoc_in_mod_inert_attr,
863                binding.ok(),
864            );
865            res
866        };
867
868        let res = res?;
869        let ext = match deleg_impl {
870            Some((impl_def_id, star_span)) => match res {
871                Res::Def(DefKind::Trait, def_id) => {
872                    let edition = self.tcx.sess.edition();
873                    Some(self.arenas.alloc_macro(SyntaxExtension::glob_delegation(
874                        def_id,
875                        impl_def_id,
876                        star_span,
877                        edition,
878                    )))
879                }
880                _ => None,
881            },
882            None => self.get_macro(res),
883        };
884        Ok((ext, res))
885    }
886
887    pub(crate) fn finalize_macro_resolutions(&mut self, krate: &Crate) {
888        let check_consistency = |this: &Self,
889                                 path: &[Segment],
890                                 span,
891                                 kind: MacroKind,
892                                 initial_res: Option<Res>,
893                                 res: Res| {
894            if let Some(initial_res) = initial_res {
895                if res != initial_res {
896                    if this.ambiguity_errors.is_empty() {
897                        // Make sure compilation does not succeed if preferred macro resolution
898                        // has changed after the macro had been expanded. In theory all such
899                        // situations should be reported as errors, so this is a bug.
900                        this.dcx().span_delayed_bug(span, "inconsistent resolution for a macro");
901                    }
902                }
903            } else if this.tcx.dcx().has_errors().is_none() && this.privacy_errors.is_empty() {
904                // It's possible that the macro was unresolved (indeterminate) and silently
905                // expanded into a dummy fragment for recovery during expansion.
906                // Now, post-expansion, the resolution may succeed, but we can't change the
907                // past and need to report an error.
908                // However, non-speculative `resolve_path` can successfully return private items
909                // even if speculative `resolve_path` returned nothing previously, so we skip this
910                // less informative error if no other error is reported elsewhere.
911
912                let err = this.dcx().create_err(CannotDetermineMacroResolution {
913                    span,
914                    kind: kind.descr(),
915                    path: Segment::names_to_string(path),
916                });
917                err.stash(span, StashKey::UndeterminedMacroResolution);
918            }
919        };
920
921        let macro_resolutions = self.multi_segment_macro_resolutions.take(self);
922        for (mut path, path_span, kind, parent_scope, initial_res, ns) in macro_resolutions {
923            // FIXME: Path resolution will ICE if segment IDs present.
924            for seg in &mut path {
925                seg.id = None;
926            }
927            match self.cm().resolve_path(
928                &path,
929                Some(ns),
930                &parent_scope,
931                Some(Finalize::new(ast::CRATE_NODE_ID, path_span)),
932                None,
933                None,
934            ) {
935                PathResult::NonModule(path_res) if let Some(res) = path_res.full_res() => {
936                    check_consistency(self, &path, path_span, kind, initial_res, res)
937                }
938                // This may be a trait for glob delegation expansions.
939                PathResult::Module(ModuleOrUniformRoot::Module(module)) => check_consistency(
940                    self,
941                    &path,
942                    path_span,
943                    kind,
944                    initial_res,
945                    module.res().unwrap(),
946                ),
947                path_res @ (PathResult::NonModule(..) | PathResult::Failed { .. }) => {
948                    let mut suggestion = None;
949                    let (span, message, label, module, segment) = match path_res {
950                        PathResult::Failed {
951                            span, label, module, segment_name, message, ..
952                        } => {
953                            // try to suggest if it's not a macro, maybe a function
954                            if let PathResult::NonModule(partial_res) = self
955                                .cm()
956                                .maybe_resolve_path(&path, Some(ValueNS), &parent_scope, None)
957                                && partial_res.unresolved_segments() == 0
958                            {
959                                let sm = self.tcx.sess.source_map();
960                                let exclamation_span = sm.next_point(span);
961                                suggestion = Some((
962                                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(exclamation_span, "".to_string())]))vec![(exclamation_span, "".to_string())],
963                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} is not a macro, but a {1}, try to remove `!`",
                Segment::names_to_string(&path),
                partial_res.base_res().descr()))
    })format!(
964                                        "{} is not a macro, but a {}, try to remove `!`",
965                                        Segment::names_to_string(&path),
966                                        partial_res.base_res().descr()
967                                    ),
968                                    Applicability::MaybeIncorrect,
969                                ));
970                            }
971                            (span, message, label, module, segment_name)
972                        }
973                        PathResult::NonModule(partial_res) => {
974                            let found_an = partial_res.base_res().article();
975                            let found_descr = partial_res.base_res().descr();
976                            let scope = match &path[..partial_res.unresolved_segments()] {
977                                [.., prev] => {
978                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{1} `{0}`", prev.ident,
                found_descr))
    })format!("{found_descr} `{}`", prev.ident)
979                                }
980                                _ => found_descr.to_string(),
981                            };
982                            let expected_an = kind.article();
983                            let expected_descr = kind.descr();
984                            let expected_name = path[partial_res.unresolved_segments()].ident;
985
986                            (
987                                path_span,
988                                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("cannot find {0} `{1}` in {2}",
                expected_descr, expected_name, scope))
    })format!(
989                                    "cannot find {expected_descr} `{expected_name}` in {scope}"
990                                ),
991                                match partial_res.base_res() {
992                                    Res::Def(
993                                        DefKind::Mod | DefKind::Macro(..) | DefKind::ExternCrate,
994                                        _,
995                                    ) => ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("partially resolved path in {0} {1}",
                expected_an, expected_descr))
    })format!(
996                                        "partially resolved path in {expected_an} {expected_descr}",
997                                    ),
998                                    _ => ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} {1} can\'t exist within {2} {3}",
                expected_an, expected_descr, found_an, found_descr))
    })format!(
999                                        "{expected_an} {expected_descr} can't exist within \
1000                                         {found_an} {found_descr}"
1001                                    ),
1002                                },
1003                                None,
1004                                path.last().map(|segment| segment.ident.name).unwrap(),
1005                            )
1006                        }
1007                        _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1008                    };
1009                    self.report_error(
1010                        span,
1011                        ResolutionError::FailedToResolve {
1012                            segment,
1013                            label,
1014                            suggestion,
1015                            module,
1016                            message,
1017                        },
1018                    );
1019                }
1020                PathResult::Module(..) | PathResult::Indeterminate => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1021            }
1022        }
1023
1024        let macro_resolutions = self.single_segment_macro_resolutions.take(self);
1025        for (ident, kind, parent_scope, initial_binding, sugg_span) in macro_resolutions {
1026            match self.cm().resolve_ident_in_scope_set(
1027                ident,
1028                ScopeSet::Macro(kind),
1029                &parent_scope,
1030                Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)),
1031                None,
1032                None,
1033            ) {
1034                Ok(binding) => {
1035                    let initial_res = initial_binding.map(|initial_binding| {
1036                        self.record_use(ident, initial_binding, Used::Other);
1037                        initial_binding.res()
1038                    });
1039                    let res = binding.res();
1040                    let seg = Segment::from_ident(ident);
1041                    check_consistency(self, &[seg], ident.span, kind, initial_res, res);
1042                    if res == Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat) {
1043                        let node_id = self
1044                            .invocation_parents
1045                            .get(&parent_scope.expansion)
1046                            .map_or(ast::CRATE_NODE_ID, |parent| {
1047                                self.def_id_to_node_id(parent.parent_def)
1048                            });
1049                        self.lint_buffer.buffer_lint(
1050                            LEGACY_DERIVE_HELPERS,
1051                            node_id,
1052                            ident.span,
1053                            errors::LegacyDeriveHelpers { span: binding.span },
1054                        );
1055                    }
1056                }
1057                Err(..) => {
1058                    let expected = kind.descr_expected();
1059
1060                    let mut err = self.dcx().create_err(CannotFindIdentInThisScope {
1061                        span: ident.span,
1062                        expected,
1063                        ident,
1064                    });
1065                    self.unresolved_macro_suggestions(
1066                        &mut err,
1067                        kind,
1068                        &parent_scope,
1069                        ident,
1070                        krate,
1071                        sugg_span,
1072                    );
1073                    err.emit();
1074                }
1075            }
1076        }
1077
1078        let builtin_attrs = mem::take(&mut self.builtin_attrs);
1079        for (ident, parent_scope) in builtin_attrs {
1080            let _ = self.cm().resolve_ident_in_scope_set(
1081                ident,
1082                ScopeSet::Macro(MacroKind::Attr),
1083                &parent_scope,
1084                Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)),
1085                None,
1086                None,
1087            );
1088        }
1089    }
1090
1091    fn check_stability_and_deprecation(
1092        &mut self,
1093        ext: &SyntaxExtension,
1094        path: &ast::Path,
1095        node_id: NodeId,
1096    ) {
1097        let span = path.span;
1098        if let Some(stability) = &ext.stability
1099            && let StabilityLevel::Unstable { reason, issue, implied_by, .. } = stability.level
1100        {
1101            let feature = stability.feature;
1102
1103            let is_allowed =
1104                |feature| self.tcx.features().enabled(feature) || span.allows_unstable(feature);
1105            let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature));
1106            if !is_allowed(feature) && !allowed_by_implication {
1107                stability::report_unstable(
1108                    self.tcx.sess,
1109                    feature,
1110                    reason.to_opt_reason(),
1111                    issue,
1112                    None,
1113                    span,
1114                    stability::UnstableKind::Regular,
1115                );
1116            }
1117        }
1118        if let Some(depr) = &ext.deprecation {
1119            let path = pprust::path_to_string(path);
1120            stability::early_report_macro_deprecation(
1121                &mut self.lint_buffer,
1122                depr,
1123                span,
1124                node_id,
1125                path,
1126            );
1127        }
1128    }
1129
1130    fn prohibit_imported_non_macro_attrs(
1131        &self,
1132        decl: Option<Decl<'ra>>,
1133        res: Option<Res>,
1134        span: Span,
1135    ) {
1136        if let Some(Res::NonMacroAttr(kind)) = res {
1137            if kind != NonMacroAttrKind::Tool && decl.is_none_or(|b| b.is_import()) {
1138                self.dcx().emit_err(errors::CannotUseThroughAnImport {
1139                    span,
1140                    article: kind.article(),
1141                    descr: kind.descr(),
1142                    binding_span: decl.map(|d| d.span),
1143                });
1144            }
1145        }
1146    }
1147
1148    fn report_out_of_scope_macro_calls<'r>(
1149        mut self: CmResolver<'r, 'ra, 'tcx>,
1150        path: &ast::Path,
1151        parent_scope: &ParentScope<'ra>,
1152        invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
1153        decl: Option<Decl<'ra>>,
1154    ) {
1155        if let Some((mod_def_id, node_id)) = invoc_in_mod_inert_attr
1156            && let Some(decl) = decl
1157            // This is a `macro_rules` itself, not some import.
1158            && let DeclKind::Def(res) = decl.kind
1159            && let Res::Def(DefKind::Macro(kinds), def_id) = res
1160            && kinds.contains(MacroKinds::BANG)
1161            // And the `macro_rules` is defined inside the attribute's module,
1162            // so it cannot be in scope unless imported.
1163            && self.tcx.is_descendant_of(def_id, mod_def_id.to_def_id())
1164        {
1165            // Try to resolve our ident ignoring `macro_rules` scopes.
1166            // If such resolution is successful and gives the same result
1167            // (e.g. if the macro is re-imported), then silence the lint.
1168            let no_macro_rules = self.arenas.alloc_macro_rules_scope(MacroRulesScope::Empty);
1169            let ident = path.segments[0].ident;
1170            let fallback_binding = self.reborrow().resolve_ident_in_scope_set(
1171                ident,
1172                ScopeSet::Macro(MacroKind::Bang),
1173                &ParentScope { macro_rules: no_macro_rules, ..*parent_scope },
1174                None,
1175                None,
1176                None,
1177            );
1178            if let Ok(fallback_binding) = fallback_binding
1179                && fallback_binding.res().opt_def_id() == Some(def_id)
1180            {
1181                // Silence `unused_imports` on the fallback import as well.
1182                self.get_mut().record_use(ident, fallback_binding, Used::Other);
1183            } else {
1184                let location = match parent_scope.module.kind {
1185                    ModuleKind::Def(kind, def_id, _, name) => {
1186                        if let Some(name) = name {
1187                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} `{1}`", kind.descr(def_id),
                name))
    })format!("{} `{name}`", kind.descr(def_id))
1188                        } else {
1189                            "the crate root".to_string()
1190                        }
1191                    }
1192                    ModuleKind::Block => "this scope".to_string(),
1193                };
1194                self.tcx.sess.psess.buffer_lint(
1195                    OUT_OF_SCOPE_MACRO_CALLS,
1196                    path.span,
1197                    node_id,
1198                    errors::OutOfScopeMacroCalls {
1199                        span: path.span,
1200                        path: pprust::path_to_string(path),
1201                        location,
1202                    },
1203                );
1204            }
1205        }
1206    }
1207
1208    pub(crate) fn check_reserved_macro_name(&self, name: Symbol, span: Span, res: Res) {
1209        // Reserve some names that are not quite covered by the general check
1210        // performed on `Resolver::builtin_attrs`.
1211        if name == sym::cfg || name == sym::cfg_attr {
1212            let macro_kinds = res.macro_kinds();
1213            if macro_kinds.is_some() && sub_namespace_match(macro_kinds, Some(MacroKind::Attr)) {
1214                self.dcx().emit_err(errors::NameReservedInAttributeNamespace { span, ident: name });
1215            }
1216        }
1217    }
1218
1219    /// Compile the macro into a `SyntaxExtension` and its rule spans.
1220    ///
1221    /// Possibly replace its expander to a pre-defined one for built-in macros.
1222    pub(crate) fn compile_macro(
1223        &self,
1224        macro_def: &ast::MacroDef,
1225        ident: Ident,
1226        attrs: &[rustc_hir::Attribute],
1227        span: Span,
1228        node_id: NodeId,
1229        edition: Edition,
1230    ) -> SyntaxExtension {
1231        let mut ext = compile_declarative_macro(
1232            self.tcx.sess,
1233            self.tcx.features(),
1234            macro_def,
1235            ident,
1236            attrs,
1237            span,
1238            node_id,
1239            edition,
1240        );
1241
1242        if let Some(builtin_name) = ext.builtin_name {
1243            // The macro was marked with `#[rustc_builtin_macro]`.
1244            if let Some(builtin_ext_kind) = self.builtin_macros.get(&builtin_name) {
1245                // The macro is a built-in, replace its expander function
1246                // while still taking everything else from the source code.
1247                ext.kind = builtin_ext_kind.clone();
1248            } else {
1249                self.dcx().emit_err(errors::CannotFindBuiltinMacroWithName { span, ident });
1250            }
1251        }
1252
1253        ext
1254    }
1255
1256    fn path_accessible(
1257        &mut self,
1258        expn_id: LocalExpnId,
1259        path: &ast::Path,
1260        namespaces: &[Namespace],
1261    ) -> Result<bool, Indeterminate> {
1262        let span = path.span;
1263        let path = &Segment::from_path(path);
1264        let parent_scope = self.invocation_parent_scopes[&expn_id];
1265
1266        let mut indeterminate = false;
1267        for ns in namespaces {
1268            match self.cm().maybe_resolve_path(path, Some(*ns), &parent_scope, None) {
1269                PathResult::Module(ModuleOrUniformRoot::Module(_)) => return Ok(true),
1270                PathResult::NonModule(partial_res) if partial_res.unresolved_segments() == 0 => {
1271                    return Ok(true);
1272                }
1273                PathResult::NonModule(..) |
1274                // HACK(Urgau): This shouldn't be necessary
1275                PathResult::Failed { is_error_from_last_segment: false, .. } => {
1276                    self.dcx().emit_err(errors::CfgAccessibleUnsure { span });
1277
1278                    // If we get a partially resolved NonModule in one namespace, we should get the
1279                    // same result in any other namespaces, so we can return early.
1280                    return Ok(false);
1281                }
1282                PathResult::Indeterminate => indeterminate = true,
1283                // We can only be sure that a path doesn't exist after having tested all the
1284                // possibilities, only at that time we can return false.
1285                PathResult::Failed { .. } => {}
1286                PathResult::Module(_) => { ::core::panicking::panic_fmt(format_args!("unexpected path resolution")); }panic!("unexpected path resolution"),
1287            }
1288        }
1289
1290        if indeterminate {
1291            return Err(Indeterminate);
1292        }
1293
1294        Ok(false)
1295    }
1296}