macros.rs 51.4 KB
Newer Older
1 2 3
//! A bunch of methods and structures more or less related to resolving macros and
//! interface provided by `Resolver` to macro expander.

4
use crate::imports::ImportResolver;
M
Mark Rousskov 已提交
5
use crate::Namespace::*;
6
use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BuiltinMacroState, Determinacy};
M
Mark Rousskov 已提交
7 8
use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak};
use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
U
Ujjwal Sharma 已提交
9
use rustc_ast::{self as ast, NodeId};
10
use rustc_ast_lowering::ResolverAstLowering;
11
use rustc_ast_pretty::pprust;
12
use rustc_attr::StabilityLevel;
13
use rustc_data_structures::fx::FxHashSet;
14
use rustc_data_structures::ptr_key::PtrKey;
15
use rustc_data_structures::sync::Lrc;
16
use rustc_errors::struct_span_err;
17
use rustc_expand::base::{Indeterminate, ResolverExpand, SyntaxExtension, SyntaxExtensionKind};
18
use rustc_expand::compile_declarative_macro;
19
use rustc_expand::expand::{AstFragment, Invocation, InvocationKind};
20
use rustc_feature::is_builtin_attr_name;
21 22
use rustc_hir::def::{self, DefKind, NonMacroAttrKind};
use rustc_hir::def_id;
23
use rustc_hir::PrimTy;
24
use rustc_middle::middle::stability;
25
use rustc_middle::ty;
26 27
use rustc_session::lint::builtin::{LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE, UNUSED_MACROS};
use rustc_session::lint::BuiltinLintDiagnostics;
28
use rustc_session::parse::feature_err;
29
use rustc_session::Session;
30
use rustc_span::edition::Edition;
31
use rustc_span::hygiene::{self, ExpnData, ExpnId, ExpnKind};
32
use rustc_span::hygiene::{AstPass, MacroKind};
33
use rustc_span::symbol::{kw, sym, Ident, Symbol};
34
use rustc_span::{Span, DUMMY_SP};
35
use std::cell::Cell;
M
Mark Rousskov 已提交
36
use std::{mem, ptr};
37

38
type Res = def::Res<NodeId>;
L
ljedrz 已提交
39

40
/// Binding produced by a `macro_rules` item.
41
/// Not modularized, can shadow previous `macro_rules` bindings, etc.
42
#[derive(Debug)]
43
pub struct MacroRulesBinding<'a> {
44
    crate binding: &'a NameBinding<'a>,
45
    /// `macro_rules` scope into which the `macro_rules` item was planted.
46
    crate parent_macro_rules_scope: MacroRulesScopeRef<'a>,
47
    crate ident: Ident,
48 49
}

A
Alexander Regueiro 已提交
50 51 52
/// The scope introduced by a `macro_rules!` macro.
/// This starts at the macro's definition and ends at the end of the macro's parent
/// module (named or unnamed), or even further if it escapes with `#[macro_use]`.
53
/// Some macro invocations need to introduce `macro_rules` scopes too because they
A
Alexander Regueiro 已提交
54
/// can potentially expand into macro definitions.
55
#[derive(Copy, Clone, Debug)]
56
pub enum MacroRulesScope<'a> {
57
    /// Empty "root" scope at the crate start containing no names.
J
Jeffrey Seyfried 已提交
58
    Empty,
A
Alexander Regueiro 已提交
59
    /// The scope introduced by a `macro_rules!` macro definition.
60
    Binding(&'a MacroRulesBinding<'a>),
A
Alexander Regueiro 已提交
61
    /// The scope introduced by a macro invocation that can potentially
62
    /// create a `macro_rules!` macro definition.
63
    Invocation(ExpnId),
64 65
}

66
/// `macro_rules!` scopes are always kept by reference and inside a cell.
67 68
/// The reason is that we update scopes with value `MacroRulesScope::Invocation(invoc_id)`
/// in-place after `invoc_id` gets expanded.
69 70 71 72 73
/// This helps to avoid uncontrollable growth of `macro_rules!` scope chains,
/// which usually grow lineraly with the number of macro invocations
/// in a module (including derives) and hurt performance.
pub(crate) type MacroRulesScopeRef<'a> = PtrKey<'a, Cell<MacroRulesScope<'a>>>;

74 75 76
// Macro namespace is separated into two sub-namespaces, one for bang macros and
// one for attribute-like macros (attributes, derives).
// We ignore resolutions from one sub-namespace when searching names in scope for another.
77
fn sub_namespace_match(candidate: Option<MacroKind>, requirement: Option<MacroKind>) -> bool {
78
    #[derive(PartialEq)]
M
Mark Rousskov 已提交
79 80 81 82
    enum SubNS {
        Bang,
        AttrLike,
    }
83
    let sub_ns = |kind| match kind {
84 85
        MacroKind::Bang => SubNS::Bang,
        MacroKind::Attr | MacroKind::Derive => SubNS::AttrLike,
86
    };
87 88
    let candidate = candidate.map(sub_ns);
    let requirement = requirement.map(sub_ns);
89
    // "No specific sub-namespace" means "matches anything" for both requirements and candidates.
90
    candidate.is_none() || requirement.is_none() || candidate == requirement
91 92
}

93 94 95
// We don't want to format a path using pretty-printing,
// `format!("{}", path)`, because that tries to insert
// line-breaks and is slow.
96 97
fn fast_print_path(path: &ast::Path) -> Symbol {
    if path.segments.len() == 1 {
98
        path.segments[0].ident.name
99 100 101 102 103 104 105 106 107
    } else {
        let mut path_str = String::with_capacity(64);
        for (i, segment) in path.segments.iter().enumerate() {
            if i != 0 {
                path_str.push_str("::");
            }
            if segment.ident.name != kw::PathRoot {
                path_str.push_str(&segment.ident.as_str())
            }
108
        }
109
        Symbol::intern(&path_str)
110 111 112
    }
}

V
Vadim Petrochenkov 已提交
113
/// The code common between processing `#![register_tool]` and `#![register_attr]`.
114 115 116 117 118 119 120
fn registered_idents(
    sess: &Session,
    attrs: &[ast::Attribute],
    attr_name: Symbol,
    descr: &str,
) -> FxHashSet<Ident> {
    let mut registered = FxHashSet::default();
121
    for attr in sess.filter_by_name(attrs, attr_name) {
122 123
        for nested_meta in attr.meta_item_list().unwrap_or_default() {
            match nested_meta.ident() {
M
Mark Rousskov 已提交
124 125 126 127 128 129 130
                Some(ident) => {
                    if let Some(old_ident) = registered.replace(ident) {
                        let msg = format!("{} `{}` was already registered", descr, ident);
                        sess.struct_span_err(ident.span, &msg)
                            .span_label(old_ident.span, "already registered here")
                            .emit();
                    }
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
                }
                None => {
                    let msg = format!("`{}` only accepts identifiers", attr_name);
                    let span = nested_meta.span();
                    sess.struct_span_err(span, &msg).span_label(span, "not an identifier").emit();
                }
            }
        }
    }
    registered
}

crate fn registered_attrs_and_tools(
    sess: &Session,
    attrs: &[ast::Attribute],
) -> (FxHashSet<Ident>, FxHashSet<Ident>) {
    let registered_attrs = registered_idents(sess, attrs, sym::register_attr, "attribute");
    let mut registered_tools = registered_idents(sess, attrs, sym::register_tool, "tool");
    // We implicitly add `rustfmt` and `clippy` to known tools,
    // but it's not an error to register them explicitly.
    let predefined_tools = [sym::clippy, sym::rustfmt];
    registered_tools.extend(predefined_tools.iter().cloned().map(Ident::with_dummy_span));
    (registered_attrs, registered_tools)
}

156
impl<'a> ResolverExpand for Resolver<'a> {
157
    fn next_node_id(&mut self) -> NodeId {
M
Mark Rousskov 已提交
158
        self.next_node_id()
159 160
    }

161 162 163 164
    fn resolve_dollar_crates(&mut self) {
        hygiene::update_dollar_crate_names(|ctxt| {
            let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt));
            match self.resolve_crate_root(ident).kind {
J
Joshua Nelson 已提交
165
                ModuleKind::Def(.., name) if name != kw::Empty => name,
166
                _ => kw::Crate,
167
            }
168
        });
169 170
    }

171
    fn visit_ast_fragment_with_placeholders(&mut self, expansion: ExpnId, fragment: &AstFragment) {
172
        // Integrate the new AST fragment into all the definition and module structures.
173 174
        // We are inside the `expansion` now, but other parent scope components are still the same.
        let parent_scope = ParentScope { expansion, ..self.invocation_parent_scopes[&expansion] };
175 176
        let output_macro_rules_scope = self.build_reduced_graph(fragment, parent_scope);
        self.output_macro_rules_scopes.insert(expansion, output_macro_rules_scope);
177

178
        parent_scope.module.unexpanded_invocations.borrow_mut().remove(&expansion);
179 180
    }

181 182
    fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind) {
        if self.builtin_macros.insert(name, BuiltinMacroState::NotYetSeen(ext)).is_some() {
M
Mark Rousskov 已提交
183
            self.session
184 185
                .diagnostic()
                .bug(&format!("built-in macro `{}` was already registered", name));
186
        }
187 188
    }

M
Matthew Jasper 已提交
189 190
    // Create a new Expansion with a definition site of the provided module, or
    // a fake empty `#[no_implicit_prelude]` module if no module is provided.
191
    fn expansion_for_ast_pass(
192
        &mut self,
193
        call_site: Span,
194 195 196
        pass: AstPass,
        features: &[Symbol],
        parent_module_id: Option<NodeId>,
197 198 199 200 201 202
    ) -> ExpnId {
        let expn_id = ExpnId::fresh(Some(ExpnData::allow_unstable(
            ExpnKind::AstPass(pass),
            call_site,
            self.session.edition(),
            features.into(),
A
Aaron Hill 已提交
203
            None,
204 205
        )));

206
        let parent_scope = if let Some(module_id) = parent_module_id {
207
            let parent_def_id = self.local_def_id(module_id);
208
            self.definitions.add_parent_module_of_macro_def(expn_id, parent_def_id.to_def_id());
209 210 211 212 213 214 215 216 217
            self.module_map[&parent_def_id]
        } else {
            self.definitions.add_parent_module_of_macro_def(
                expn_id,
                def_id::DefId::local(def_id::CRATE_DEF_INDEX),
            );
            self.empty_module
        };
        self.ast_transform_scopes.insert(expn_id, parent_scope);
218
        expn_id
219 220
    }

221
    fn resolve_imports(&mut self) {
222
        ImportResolver { r: self }.resolve_imports()
223 224
    }

225
    fn resolve_macro_invocation(
M
Mark Rousskov 已提交
226 227 228 229
        &mut self,
        invoc: &Invocation,
        eager_expansion_root: ExpnId,
        force: bool,
230
    ) -> Result<Lrc<SyntaxExtension>, Indeterminate> {
231 232 233 234 235 236 237
        let invoc_id = invoc.expansion_data.id;
        let parent_scope = match self.invocation_parent_scopes.get(&invoc_id) {
            Some(parent_scope) => *parent_scope,
            None => {
                // If there's no entry in the table, then we are resolving an eagerly expanded
                // macro, which should inherit its parent scope from its eager expansion root -
                // the macro that requested this eager expansion.
M
Mark Rousskov 已提交
238 239 240
                let parent_scope = *self
                    .invocation_parent_scopes
                    .get(&eager_expansion_root)
241 242 243 244 245 246
                    .expect("non-eager expansion without a parent scope");
                self.invocation_parent_scopes.insert(invoc_id, parent_scope);
                parent_scope
            }
        };

247 248
        let (path, kind, inner_attr, derives) = match invoc.kind {
            InvocationKind::Attr { ref attr, ref derives, .. } => (
M
Mark Rousskov 已提交
249 250
                &attr.get_normal_item().path,
                MacroKind::Attr,
251
                attr.style == ast::AttrStyle::Inner,
M
Mark Rousskov 已提交
252 253
                self.arenas.alloc_ast_paths(derives),
            ),
254 255
            InvocationKind::Bang { ref mac, .. } => (&mac.path, MacroKind::Bang, false, &[][..]),
            InvocationKind::Derive { ref path, .. } => (path, MacroKind::Derive, false, &[][..]),
256
        };
257

258
        // Derives are not included when `invocations` are collected, so we have to add them here.
259
        let parent_scope = &ParentScope { derives, ..parent_scope };
260
        let require_inert = !invoc.fragment_kind.supports_macro_expansion();
261
        let node_id = self.lint_node_id(eager_expansion_root);
262 263 264 265 266 267 268 269 270
        let (ext, res) = self.smart_resolve_macro_path(
            path,
            kind,
            require_inert,
            inner_attr,
            parent_scope,
            node_id,
            force,
        )?;
271

272
        let span = invoc.span();
A
Aaron Hill 已提交
273 274 275 276 277 278
        invoc_id.set_expn_data(ext.expn_data(
            parent_scope.expansion,
            span,
            fast_print_path(path),
            res.opt_def_id(),
        ));
279

A
Aaron Hill 已提交
280
        if let Res::Def(_, _) = res {
C
Camelid 已提交
281
            let normal_module_def_id = self.macro_def_scope(invoc_id).nearest_parent_mod;
282
            self.definitions.add_parent_module_of_macro_def(invoc_id, normal_module_def_id);
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312

            // Gate macro attributes in `#[derive]` output.
            if !self.session.features_untracked().macro_attributes_in_derive_output
                && kind == MacroKind::Attr
                && ext.builtin_name != Some(sym::derive)
            {
                let mut expn_id = parent_scope.expansion;
                loop {
                    // Helper attr table is a quick way to determine whether the attr is `derive`.
                    if self.helper_attrs.contains_key(&expn_id) {
                        feature_err(
                            &self.session.parse_sess,
                            sym::macro_attributes_in_derive_output,
                            path.span,
                            "macro attributes in `#[derive]` output are unstable",
                        )
                        .emit();
                        break;
                    } else {
                        let expn_data = expn_id.expn_data();
                        match expn_data.kind {
                            ExpnKind::Root
                            | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
                                break;
                            }
                            _ => expn_id = expn_data.parent,
                        }
                    }
                }
            }
313
        }
314

315
        Ok(ext)
316 317
    }

318
    fn check_unused_macros(&mut self) {
319
        for (_, &(node_id, span)) in self.unused_macros.iter() {
320
            self.lint_buffer.buffer_lint(UNUSED_MACROS, node_id, span, "unused macro definition");
E
est31 已提交
321
        }
322
    }
323

324
    fn lint_node_id(&self, expn_id: ExpnId) -> NodeId {
325 326
        // FIXME - make this more precise. This currently returns the NodeId of the
        // nearest closing item - we should try to return the closest parent of the ExpnId
327 328
        self.invocation_parents
            .get(&expn_id)
329
            .map_or(ast::CRATE_NODE_ID, |id| self.def_id_to_node_id[id.0])
330 331
    }

332
    fn has_derive_copy(&self, expn_id: ExpnId) -> bool {
333
        self.containers_deriving_copy.contains(&expn_id)
334 335
    }

336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
    fn resolve_derives(
        &mut self,
        expn_id: ExpnId,
        derives: Vec<ast::Path>,
        force: bool,
    ) -> Result<(), Indeterminate> {
        // Block expansion of the container until we resolve all derives in it.
        // This is required for two reasons:
        // - Derive helper attributes are in scope for the item to which the `#[derive]`
        //   is applied, so they have to be produced by the container's expansion rather
        //   than by individual derives.
        // - Derives in the container need to know whether one of them is a built-in `Copy`.
        // FIXME: Try to cache intermediate results to avoid resolving same derives multiple times.
        let parent_scope = self.invocation_parent_scopes[&expn_id];
        let mut exts = Vec::new();
        let mut helper_attrs = Vec::new();
        let mut has_derive_copy = false;
        for path in derives {
            exts.push((
                match self.resolve_macro_path(
                    &path,
                    Some(MacroKind::Derive),
                    &parent_scope,
                    true,
                    force,
                ) {
                    Ok((Some(ext), _)) => {
                        let span =
                            path.segments.last().unwrap().ident.span.normalize_to_macros_2_0();
                        helper_attrs
                            .extend(ext.helper_attrs.iter().map(|name| Ident::new(*name, span)));
                        has_derive_copy |= ext.builtin_name == Some(sym::Copy);
                        ext
                    }
                    Ok(_) | Err(Determinacy::Determined) => self.dummy_ext(MacroKind::Derive),
                    Err(Determinacy::Undetermined) => return Err(Indeterminate),
                },
                path,
            ))
        }
        self.derive_resolutions.insert(expn_id, exts);
        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
        // has `Copy`, to support cases like `#[derive(Clone, Copy)] #[derive(Debug)]`.
        if has_derive_copy || self.has_derive_copy(parent_scope.expansion) {
            self.containers_deriving_copy.insert(expn_id);
        }
        Ok(())
    }

    fn take_derive_resolutions(
        &mut self,
        expn_id: ExpnId,
    ) -> Option<Vec<(Lrc<SyntaxExtension>, ast::Path)>> {
        self.derive_resolutions.remove(&expn_id)
    }

393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
    // The function that implements the resolution logic of `#[cfg_accessible(path)]`.
    // Returns true if the path can certainly be resolved in one of three namespaces,
    // returns false if the path certainly cannot be resolved in any of the three namespaces.
    // Returns `Indeterminate` if we cannot give a certain answer yet.
    fn cfg_accessible(&mut self, expn_id: ExpnId, path: &ast::Path) -> Result<bool, Indeterminate> {
        let span = path.span;
        let path = &Segment::from_path(path);
        let parent_scope = self.invocation_parent_scopes[&expn_id];

        let mut indeterminate = false;
        for ns in [TypeNS, ValueNS, MacroNS].iter().copied() {
            match self.resolve_path(path, Some(ns), &parent_scope, false, span, CrateLint::No) {
                PathResult::Module(ModuleOrUniformRoot::Module(_)) => return Ok(true),
                PathResult::NonModule(partial_res) if partial_res.unresolved_segments() == 0 => {
                    return Ok(true);
                }
                PathResult::Indeterminate => indeterminate = true,
                // FIXME: `resolve_path` is not ready to report partially resolved paths
                // correctly, so we just report an error if the path was reported as unresolved.
                // This needs to be fixed for `cfg_accessible` to be useful.
                PathResult::NonModule(..) | PathResult::Failed { .. } => {}
                PathResult::Module(_) => panic!("unexpected path resolution"),
            }
        }

        if indeterminate {
            return Err(Indeterminate);
        }

        self.session
            .struct_span_err(span, "not sure whether the path is accessible or not")
            .span_note(span, "`cfg_accessible` is not fully implemented")
            .emit();
        Ok(false)
    }
428 429
}

J
John Kåre Alsaker 已提交
430
impl<'a> Resolver<'a> {
431
    /// Resolve macro path with error reporting and recovery.
432 433
    /// Uses dummy syntax extensions for unresolved macros or macros with unexpected resolutions
    /// for better error recovery.
434
    fn smart_resolve_macro_path(
435 436 437
        &mut self,
        path: &ast::Path,
        kind: MacroKind,
438 439
        require_inert: bool,
        inner_attr: bool,
440
        parent_scope: &ParentScope<'a>,
441
        node_id: NodeId,
442
        force: bool,
443
    ) -> Result<(Lrc<SyntaxExtension>, Res), Indeterminate> {
M
Mark Rousskov 已提交
444 445
        let (ext, res) = match self.resolve_macro_path(path, Some(kind), parent_scope, true, force)
        {
446 447 448 449 450
            Ok((Some(ext), res)) => (ext, res),
            Ok((None, res)) => (self.dummy_ext(kind), res),
            Err(Determinacy::Determined) => (self.dummy_ext(kind), Res::Err),
            Err(Determinacy::Undetermined) => return Err(Indeterminate),
        };
451

452
        // Report errors for the resolved macro.
453 454 455
        for segment in &path.segments {
            if let Some(args) = &segment.args {
                self.session.span_err(args.span(), "generic arguments in macro path");
456
            }
457 458 459 460 461
            if kind == MacroKind::Attr && segment.ident.as_str().starts_with("rustc") {
                self.session.span_err(
                    segment.ident.span,
                    "attributes starting with `rustc` are reserved for use by the `rustc` compiler",
                );
462
            }
463
        }
464

465
        match res {
466
            Res::Def(DefKind::Macro(_), def_id) => {
467 468 469
                if let Some(def_id) = def_id.as_local() {
                    self.unused_macros.remove(&def_id);
                    if self.proc_macro_stubs.contains(&def_id) {
470 471 472 473 474
                        self.session.span_err(
                            path.span,
                            "can't use a procedural macro from the same crate that defines it",
                        );
                    }
475
                }
476
            }
477
            Res::NonMacroAttr(..) | Res::Err => {}
478
            _ => panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"),
479
        };
480

481
        self.check_stability_and_deprecation(&ext, path, node_id);
482

483 484 485 486 487 488 489 490
        let unexpected_res = if ext.macro_kind() != kind {
            Some((kind.article(), kind.descr_expected()))
        } else if require_inert && matches!(res, Res::Def(..)) {
            Some(("a", "non-macro attribute"))
        } else {
            None
        };
        if let Some((article, expected)) = unexpected_res {
491 492
            let path_str = pprust::path_to_string(path);
            let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path_str);
M
Mark Rousskov 已提交
493 494
            self.session
                .struct_span_err(path.span, &msg)
495
                .span_label(path.span, format!("not {} {}", article, expected))
M
Mark Rousskov 已提交
496
                .emit();
497 498 499 500
            return Ok((self.dummy_ext(kind), Res::Err));
        }

        // We are trying to avoid reporting this error if other related errors were reported.
501 502
        if res != Res::Err
            && inner_attr
503 504
            && !self.session.features_untracked().custom_inner_attributes
        {
505 506 507 508 509 510 511 512 513 514 515
            let msg = match res {
                Res::Def(..) => "inner macro attributes are unstable",
                Res::NonMacroAttr(..) => "custom inner attributes are unstable",
                _ => unreachable!(),
            };
            if path == &sym::test {
                self.session.parse_sess.buffer_lint(SOFT_UNSTABLE, path.span, node_id, msg);
            } else {
                feature_err(&self.session.parse_sess, sym::custom_inner_attributes, path.span, msg)
                    .emit();
            }
516 517 518
        }

        Ok((ext, res))
519
    }
520

521
    pub fn resolve_macro_path(
522 523
        &mut self,
        path: &ast::Path,
524
        kind: Option<MacroKind>,
525
        parent_scope: &ParentScope<'a>,
526
        trace: bool,
527
        force: bool,
528
    ) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
529
        let path_span = path.span;
N
Nick Cameron 已提交
530
        let mut path = Segment::from_path(path);
531

532
        // Possibly apply the macro helper hack
M
Mark Rousskov 已提交
533 534 535 536
        if kind == Some(MacroKind::Bang)
            && path.len() == 1
            && path[0].ident.span.ctxt().outer_expn_data().local_inner_macros
        {
537
            let root = Ident::new(kw::DollarCrate, path[0].ident.span);
N
Nick Cameron 已提交
538
            path.insert(0, Segment::from_ident(root));
539 540
        }

541
        let res = if path.len() > 1 {
M
Mark Rousskov 已提交
542 543 544 545 546 547 548 549
            let res = match self.resolve_path(
                &path,
                Some(MacroNS),
                parent_scope,
                false,
                path_span,
                CrateLint::No,
            ) {
550
                PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
551
                    Ok(path_res.base_res())
552
                }
553
                PathResult::Indeterminate if !force => return Err(Determinacy::Undetermined),
554 555 556
                PathResult::NonModule(..)
                | PathResult::Indeterminate
                | PathResult::Failed { .. } => Err(Determinacy::Determined),
557
                PathResult::Module(..) => unreachable!(),
558
            };
559

560
            if trace {
561
                let kind = kind.expect("macro kind must be specified if tracing is enabled");
M
Mark Rousskov 已提交
562 563 564 565 566 567 568
                self.multi_segment_macro_resolutions.push((
                    path,
                    path_span,
                    kind,
                    *parent_scope,
                    res.ok(),
                ));
569
            }
570

571 572
            self.prohibit_imported_non_macro_attrs(None, res.ok(), path_span);
            res
573
        } else {
574
            let scope_set = kind.map_or(ScopeSet::All(MacroNS, false), ScopeSet::Macro);
575
            let binding = self.early_resolve_ident_in_lexical_scope(
M
Mark Rousskov 已提交
576 577 578 579 580 581
                path[0].ident,
                scope_set,
                parent_scope,
                false,
                force,
                path_span,
582
            );
583 584
            if let Err(Determinacy::Undetermined) = binding {
                return Err(Determinacy::Undetermined);
585
            }
586

587
            if trace {
588
                let kind = kind.expect("macro kind must be specified if tracing is enabled");
M
Mark Rousskov 已提交
589 590 591 592 593 594
                self.single_segment_macro_resolutions.push((
                    path[0].ident,
                    kind,
                    *parent_scope,
                    binding.ok(),
                ));
595
            }
596

597 598 599
            let res = binding.map(|binding| binding.res());
            self.prohibit_imported_non_macro_attrs(binding.ok(), res.ok(), path_span);
            res
600 601 602
        };

        res.map(|res| (self.get_macro(res), res))
603
    }
604

605
    // Resolve an identifier in lexical scope.
606 607
    // This is a variation of `fn resolve_ident_in_lexical_scope` that can be run during
    // expansion and import resolution (perhaps they can be merged in the future).
608
    // The function is used for resolving initial segments of macro paths (e.g., `foo` in
609
    // `foo::bar!(); or `foo!();`) and also for import paths on 2018 edition.
610
    crate fn early_resolve_ident_in_lexical_scope(
611
        &mut self,
612
        orig_ident: Ident,
613
        scope_set: ScopeSet,
614
        parent_scope: &ParentScope<'a>,
615 616
        record_used: bool,
        force: bool,
617
        path_span: Span,
618
    ) -> Result<&'a NameBinding<'a>, Determinacy> {
T
Taiki Endo 已提交
619
        bitflags::bitflags! {
620
            struct Flags: u8 {
621 622
                const MACRO_RULES          = 1 << 0;
                const MODULE               = 1 << 1;
623 624 625
                const MISC_SUGGEST_CRATE   = 1 << 2;
                const MISC_SUGGEST_SELF    = 1 << 3;
                const MISC_FROM_PRELUDE    = 1 << 4;
626 627
            }
        }
628

V
Vadim Petrochenkov 已提交
629
        assert!(force || !record_used); // `record_used` implies `force`
630

631
        // Make sure `self`, `super` etc produce an error when passed to here.
632
        if orig_ident.is_path_segment_keyword() {
633 634 635
            return Err(Determinacy::Determined);
        }

636
        let (ns, macro_kind, is_import) = match scope_set {
637
            ScopeSet::All(ns, is_import) => (ns, None, is_import),
638 639
            ScopeSet::AbsolutePath(ns) => (ns, None, false),
            ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false),
640 641
        };

642 643 644 645
        // This is *the* result, resolution from the scope closest to the resolved identifier.
        // However, sometimes this result is "weak" because it comes from a glob import or
        // a macro expansion, and in this case it cannot shadow names from outer scopes, e.g.
        // mod m { ... } // solution in outer scope
646
        // {
647 648
        //     use prefix::*; // imports another `m` - innermost solution
        //                    // weak, cannot shadow the outer `m`, need to report ambiguity error
649 650
        //     m::mac!();
        // }
651 652
        // So we have to save the innermost solution and continue searching in outer scopes
        // to detect potential ambiguities.
T
Taiki Endo 已提交
653
        let mut innermost_result: Option<(&NameBinding<'_>, Flags)> = None;
654
        let mut determinacy = Determinacy::Determined;
655 656

        // Go through all the scopes and try to resolve the name.
M
Mark Rousskov 已提交
657 658 659
        let break_result = self.visit_scopes(
            scope_set,
            parent_scope,
660 661 662
            orig_ident.span.ctxt(),
            |this, scope, use_prelude, ctxt| {
                let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
M
Mark Rousskov 已提交
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686
                let ok = |res, span, arenas| {
                    Ok((
                        (res, ty::Visibility::Public, span, ExpnId::root()).to_name_binding(arenas),
                        Flags::empty(),
                    ))
                };
                let result = match scope {
                    Scope::DeriveHelpers(expn_id) => {
                        if let Some(attr) = this
                            .helper_attrs
                            .get(&expn_id)
                            .and_then(|attrs| attrs.iter().rfind(|i| ident == **i))
                        {
                            let binding = (
                                Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
                                ty::Visibility::Public,
                                attr.span,
                                expn_id,
                            )
                                .to_name_binding(this.arenas);
                            Ok((binding, Flags::empty()))
                        } else {
                            Err(Determinacy::Determined)
                        }
687
                    }
M
Mark Rousskov 已提交
688 689 690 691 692 693 694 695 696 697 698 699 700
                    Scope::DeriveHelpersCompat => {
                        let mut result = Err(Determinacy::Determined);
                        for derive in parent_scope.derives {
                            let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
                            match this.resolve_macro_path(
                                derive,
                                Some(MacroKind::Derive),
                                parent_scope,
                                true,
                                force,
                            ) {
                                Ok((Some(ext), _)) => {
                                    if ext.helper_attrs.contains(&ident.name) {
701 702
                                        result = ok(
                                            Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
M
Mark Rousskov 已提交
703
                                            derive.span,
704 705
                                            this.arenas,
                                        );
M
Mark Rousskov 已提交
706 707 708 709 710 711 712
                                        break;
                                    }
                                }
                                Ok(_) | Err(Determinacy::Determined) => {}
                                Err(Determinacy::Undetermined) => {
                                    result = Err(Determinacy::Undetermined)
                                }
713 714
                            }
                        }
M
Mark Rousskov 已提交
715
                        result
716
                    }
717
                    Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
718 719 720 721
                        MacroRulesScope::Binding(macro_rules_binding)
                            if ident == macro_rules_binding.ident =>
                        {
                            Ok((macro_rules_binding.binding, Flags::MACRO_RULES))
722
                        }
723
                        MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),
M
Mark Rousskov 已提交
724 725 726 727 728 729 730
                        _ => Err(Determinacy::Determined),
                    },
                    Scope::CrateRoot => {
                        let root_ident = Ident::new(kw::PathRoot, ident.span);
                        let root_module = this.resolve_crate_root(root_ident);
                        let binding = this.resolve_ident_in_module_ext(
                            ModuleOrUniformRoot::Module(root_module),
731 732
                            ident,
                            ns,
733
                            parent_scope,
M
Mark Rousskov 已提交
734
                            record_used,
735
                            path_span,
M
Mark Rousskov 已提交
736 737 738 739 740 741 742 743
                        );
                        match binding {
                            Ok(binding) => Ok((binding, Flags::MODULE | Flags::MISC_SUGGEST_CRATE)),
                            Err((Determinacy::Undetermined, Weak::No)) => {
                                return Some(Err(Determinacy::determined(force)));
                            }
                            Err((Determinacy::Undetermined, Weak::Yes)) => {
                                Err(Determinacy::Undetermined)
744
                            }
M
Mark Rousskov 已提交
745
                            Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
746 747
                        }
                    }
M
Mark Rousskov 已提交
748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
                    Scope::Module(module) => {
                        let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
                        let binding = this.resolve_ident_in_module_unadjusted_ext(
                            ModuleOrUniformRoot::Module(module),
                            ident,
                            ns,
                            adjusted_parent_scope,
                            true,
                            record_used,
                            path_span,
                        );
                        match binding {
                            Ok(binding) => {
                                let misc_flags = if ptr::eq(module, this.graph_root) {
                                    Flags::MISC_SUGGEST_CRATE
                                } else if module.is_normal() {
                                    Flags::MISC_SUGGEST_SELF
                                } else {
                                    Flags::empty()
                                };
                                Ok((binding, Flags::MODULE | misc_flags))
                            }
                            Err((Determinacy::Undetermined, Weak::No)) => {
                                return Some(Err(Determinacy::determined(force)));
                            }
                            Err((Determinacy::Undetermined, Weak::Yes)) => {
                                Err(Determinacy::Undetermined)
                            }
                            Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
                        }
                    }
                    Scope::RegisteredAttrs => match this.registered_attrs.get(&ident).cloned() {
                        Some(ident) => ok(
                            Res::NonMacroAttr(NonMacroAttrKind::Registered),
                            ident.span,
                            this.arenas,
                        ),
                        None => Err(Determinacy::Determined),
                    },
                    Scope::MacroUsePrelude => {
                        match this.macro_use_prelude.get(&ident.name).cloned() {
                            Some(binding) => Ok((binding, Flags::MISC_FROM_PRELUDE)),
                            None => Err(Determinacy::determined(
                                this.graph_root.unexpanded_invocations.borrow().is_empty(),
                            )),
                        }
                    }
                    Scope::BuiltinAttrs => {
                        if is_builtin_attr_name(ident.name) {
797 798 799 800 801
                            ok(
                                Res::NonMacroAttr(NonMacroAttrKind::Builtin(ident.name)),
                                DUMMY_SP,
                                this.arenas,
                            )
M
Mark Rousskov 已提交
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
                        } else {
                            Err(Determinacy::Determined)
                        }
                    }
                    Scope::ExternPrelude => match this.extern_prelude_get(ident, !record_used) {
                        Some(binding) => Ok((binding, Flags::empty())),
                        None => Err(Determinacy::determined(
                            this.graph_root.unexpanded_invocations.borrow().is_empty(),
                        )),
                    },
                    Scope::ToolPrelude => match this.registered_tools.get(&ident).cloned() {
                        Some(ident) => ok(Res::ToolMod, ident.span, this.arenas),
                        None => Err(Determinacy::Determined),
                    },
                    Scope::StdLibPrelude => {
                        let mut result = Err(Determinacy::Determined);
                        if let Some(prelude) = this.prelude {
                            if let Ok(binding) = this.resolve_ident_in_module_unadjusted(
                                ModuleOrUniformRoot::Module(prelude),
                                ident,
                                ns,
                                parent_scope,
                                false,
                                path_span,
                            ) {
                                if use_prelude || this.is_builtin_macro(binding.res()) {
                                    result = Ok((binding, Flags::MISC_FROM_PRELUDE));
                                }
                            }
                        }
                        result
833
                    }
834 835 836 837
                    Scope::BuiltinTypes => match PrimTy::from_name(ident.name) {
                        Some(prim_ty) => ok(Res::PrimTy(prim_ty), DUMMY_SP, this.arenas),
                        None => Err(Determinacy::Determined),
                    },
M
Mark Rousskov 已提交
838 839 840 841 842 843 844 845 846 847 848 849 850 851
                };

                match result {
                    Ok((binding, flags))
                        if sub_namespace_match(binding.macro_kind(), macro_kind) =>
                    {
                        if !record_used {
                            return Some(Ok(binding));
                        }

                        if let Some((innermost_binding, innermost_flags)) = innermost_result {
                            // Found another solution, if the first one was "weak", report an error.
                            let (res, innermost_res) = (binding.res(), innermost_binding.res());
                            if res != innermost_res {
852 853 854
                                let is_builtin = |res| {
                                    matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)))
                                };
855 856
                                let derive_helper =
                                    Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
857 858
                                let derive_helper_compat =
                                    Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
859

M
Mark Rousskov 已提交
860 861
                                let ambiguity_error_kind = if is_import {
                                    Some(AmbiguityKind::Import)
862
                                } else if is_builtin(innermost_res) || is_builtin(res) {
M
Mark Rousskov 已提交
863
                                    Some(AmbiguityKind::BuiltinAttr)
864
                                } else if innermost_res == derive_helper_compat
865
                                    || res == derive_helper_compat && innermost_res != derive_helper
M
Mark Rousskov 已提交
866 867 868 869
                                {
                                    Some(AmbiguityKind::DeriveHelper)
                                } else if innermost_flags.contains(Flags::MACRO_RULES)
                                    && flags.contains(Flags::MODULE)
870 871 872 873
                                    && !this.disambiguate_macro_rules_vs_modularized(
                                        innermost_binding,
                                        binding,
                                    )
M
Mark Rousskov 已提交
874 875
                                    || flags.contains(Flags::MACRO_RULES)
                                        && innermost_flags.contains(Flags::MODULE)
876
                                        && !this.disambiguate_macro_rules_vs_modularized(
M
Mark Rousskov 已提交
877 878 879 880
                                            binding,
                                            innermost_binding,
                                        )
                                {
881
                                    Some(AmbiguityKind::MacroRulesVsModularized)
M
Mark Rousskov 已提交
882 883 884 885 886 887
                                } else if innermost_binding.is_glob_import() {
                                    Some(AmbiguityKind::GlobVsOuter)
                                } else if innermost_binding
                                    .may_appear_after(parent_scope.expansion, binding)
                                {
                                    Some(AmbiguityKind::MoreExpandedVsOuter)
888
                                } else {
M
Mark Rousskov 已提交
889
                                    None
890
                                };
M
Mark Rousskov 已提交
891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912
                                if let Some(kind) = ambiguity_error_kind {
                                    let misc = |f: Flags| {
                                        if f.contains(Flags::MISC_SUGGEST_CRATE) {
                                            AmbiguityErrorMisc::SuggestCrate
                                        } else if f.contains(Flags::MISC_SUGGEST_SELF) {
                                            AmbiguityErrorMisc::SuggestSelf
                                        } else if f.contains(Flags::MISC_FROM_PRELUDE) {
                                            AmbiguityErrorMisc::FromPrelude
                                        } else {
                                            AmbiguityErrorMisc::None
                                        }
                                    };
                                    this.ambiguity_errors.push(AmbiguityError {
                                        kind,
                                        ident: orig_ident,
                                        b1: innermost_binding,
                                        b2: binding,
                                        misc1: misc(innermost_flags),
                                        misc2: misc(flags),
                                    });
                                    return Some(Ok(innermost_binding));
                                }
913
                            }
M
Mark Rousskov 已提交
914 915 916
                        } else {
                            // Found the first solution.
                            innermost_result = Some((binding, flags));
917
                        }
918
                    }
M
Mark Rousskov 已提交
919 920
                    Ok(..) | Err(Determinacy::Determined) => {}
                    Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,
921
                }
922

M
Mark Rousskov 已提交
923 924 925
                None
            },
        );
926

927 928
        if let Some(break_result) = break_result {
            return break_result;
929
        }
930

931
        // The first found solution was the only one, return it.
932
        if let Some((binding, _)) = innermost_result {
933
            return Ok(binding);
934
        }
935

936
        Err(Determinacy::determined(determinacy == Determinacy::Determined || force))
937 938
    }

939
    crate fn finalize_macro_resolutions(&mut self) {
M
Mark Rousskov 已提交
940 941 942 943 944 945
        let check_consistency = |this: &mut Self,
                                 path: &[Segment],
                                 span,
                                 kind: MacroKind,
                                 initial_res: Option<Res>,
                                 res: Res| {
946
            if let Some(initial_res) = initial_res {
947
                if res != initial_res {
948 949
                    // Make sure compilation does not succeed if preferred macro resolution
                    // has changed after the macro had been expanded. In theory all such
950 951
                    // situations should be reported as errors, so this is a bug.
                    this.session.delay_span_bug(span, "inconsistent resolution for a macro");
952 953 954 955 956 957 958 959 960 961
                }
            } else {
                // It's possible that the macro was unresolved (indeterminate) and silently
                // expanded into a dummy fragment for recovery during expansion.
                // Now, post-expansion, the resolution may succeed, but we can't change the
                // past and need to report an error.
                // However, non-speculative `resolve_path` can successfully return private items
                // even if speculative `resolve_path` returned nothing previously, so we skip this
                // less informative error if the privacy error is reported elsewhere.
                if this.privacy_errors.is_empty() {
M
Mark Rousskov 已提交
962 963 964 965 966
                    let msg = format!(
                        "cannot determine resolution for the {} `{}`",
                        kind.descr(),
                        Segment::names_to_string(path)
                    );
967 968 969 970 971 972
                    let msg_note = "import resolution is stuck, try simplifying macro imports";
                    this.session.struct_span_err(span, &msg).note(msg_note).emit();
                }
            }
        };

973
        let macro_resolutions = mem::take(&mut self.multi_segment_macro_resolutions);
974
        for (mut path, path_span, kind, parent_scope, initial_res) in macro_resolutions {
975
            // FIXME: Path resolution will ICE if segment IDs present.
M
Mark Rousskov 已提交
976 977 978
            for seg in &mut path {
                seg.id = None;
            }
979
            match self.resolve_path(
M
Mark Rousskov 已提交
980 981 982 983 984 985
                &path,
                Some(MacroNS),
                &parent_scope,
                true,
                path_span,
                CrateLint::No,
986
            ) {
987
                PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
988 989
                    let res = path_res.base_res();
                    check_consistency(self, &path, path_span, kind, initial_res, res);
990
                }
991 992 993
                path_res @ PathResult::NonModule(..) | path_res @ PathResult::Failed { .. } => {
                    let (span, label) = if let PathResult::Failed { span, label, .. } = path_res {
                        (span, label)
994
                    } else {
M
Mark Rousskov 已提交
995 996 997 998 999 1000 1001 1002
                        (
                            path_span,
                            format!(
                                "partially resolved path in {} {}",
                                kind.article(),
                                kind.descr()
                            ),
                        )
1003
                    };
M
Mark Rousskov 已提交
1004 1005 1006 1007
                    self.report_error(
                        span,
                        ResolutionError::FailedToResolve { label, suggestion: None },
                    );
1008
                }
1009
                PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
1010 1011 1012
            }
        }

1013
        let macro_resolutions = mem::take(&mut self.single_segment_macro_resolutions);
1014
        for (ident, kind, parent_scope, initial_binding) in macro_resolutions {
M
Mark Rousskov 已提交
1015 1016 1017 1018 1019 1020 1021 1022
            match self.early_resolve_ident_in_lexical_scope(
                ident,
                ScopeSet::Macro(kind),
                &parent_scope,
                true,
                true,
                ident.span,
            ) {
1023
                Ok(binding) => {
1024
                    let initial_res = initial_binding.map(|initial_binding| {
1025
                        self.record_use(ident, MacroNS, initial_binding, false);
1026
                        initial_binding.res()
1027
                    });
1028
                    let res = binding.res();
V
Vadim Petrochenkov 已提交
1029
                    let seg = Segment::from_ident(ident);
1030
                    check_consistency(self, &[seg], ident.span, kind, initial_res, res);
1031 1032 1033 1034 1035 1036 1037 1038 1039
                    if res == Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat) {
                        self.lint_buffer.buffer_lint_with_diagnostic(
                            LEGACY_DERIVE_HELPERS,
                            self.lint_node_id(parent_scope.expansion),
                            ident.span,
                            "derive helper attribute is used before it is introduced",
                            BuiltinLintDiagnostics::LegacyDeriveHelpers(binding.span),
                        );
                    }
1040
                }
1041
                Err(..) => {
1042
                    let expected = kind.descr_expected();
1043
                    let msg = format!("cannot find {} `{}` in this scope", expected, ident);
1044
                    let mut err = self.session.struct_span_err(ident.span, &msg);
1045
                    self.unresolved_macro_suggestions(&mut err, kind, &parent_scope, ident);
1046
                    err.emit();
1047
                }
1048
            }
J
Jeffrey Seyfried 已提交
1049
        }
1050

1051
        let builtin_attrs = mem::take(&mut self.builtin_attrs);
1052
        for (ident, parent_scope) in builtin_attrs {
1053
            let _ = self.early_resolve_ident_in_lexical_scope(
M
Mark Rousskov 已提交
1054 1055 1056 1057 1058 1059
                ident,
                ScopeSet::Macro(MacroKind::Attr),
                &parent_scope,
                true,
                true,
                ident.span,
1060
            );
1061
        }
1062
    }
1063

1064 1065 1066 1067 1068 1069
    fn check_stability_and_deprecation(
        &mut self,
        ext: &SyntaxExtension,
        path: &ast::Path,
        node_id: NodeId,
    ) {
1070
        let span = path.span;
1071
        if let Some(stability) = &ext.stability {
1072
            if let StabilityLevel::Unstable { reason, issue, is_soft } = stability.level {
1073 1074
                let feature = stability.feature;
                if !self.active_features.contains(&feature) && !span.allows_unstable(feature) {
1075
                    let lint_buffer = &mut self.lint_buffer;
M
Mark Rousskov 已提交
1076 1077
                    let soft_handler =
                        |lint, span, msg: &_| lint_buffer.buffer_lint(lint, node_id, span, msg);
1078
                    stability::report_unstable(
M
Mark Rousskov 已提交
1079 1080 1081 1082 1083 1084 1085
                        self.session,
                        feature,
                        reason,
                        issue,
                        is_soft,
                        span,
                        soft_handler,
1086
                    );
1087 1088 1089 1090
                }
            }
        }
        if let Some(depr) = &ext.deprecation {
1091
            let path = pprust::path_to_string(&path);
1092
            let (message, lint) = stability::deprecation_message(depr, "macro", &path);
1093 1094 1095 1096 1097 1098
            stability::early_report_deprecation(
                &mut self.lint_buffer,
                &message,
                depr.suggestion,
                lint,
                span,
1099
                node_id,
1100
            );
1101 1102 1103
        }
    }

M
Mark Rousskov 已提交
1104 1105 1106 1107 1108 1109
    fn prohibit_imported_non_macro_attrs(
        &self,
        binding: Option<&'a NameBinding<'a>>,
        res: Option<Res>,
        span: Span,
    ) {
1110
        if let Some(Res::NonMacroAttr(kind)) = res {
1111
            if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) {
V
Vadim Petrochenkov 已提交
1112 1113
                let msg =
                    format!("cannot use {} {} through an import", kind.article(), kind.descr());
1114 1115 1116 1117 1118 1119 1120 1121 1122
                let mut err = self.session.struct_span_err(span, &msg);
                if let Some(binding) = binding {
                    err.span_note(binding.span, &format!("the {} imported here", kind.descr()));
                }
                err.emit();
            }
        }
    }

1123 1124 1125
    crate fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) {
        // Reserve some names that are not quite covered by the general check
        // performed on `Resolver::builtin_attrs`.
1126
        if ident.name == sym::cfg || ident.name == sym::cfg_attr {
1127
            let macro_kind = self.get_macro(res).map(|ext| ext.macro_kind());
1128 1129
            if macro_kind.is_some() && sub_namespace_match(macro_kind, Some(MacroKind::Attr)) {
                self.session.span_err(
M
Mark Rousskov 已提交
1130 1131
                    ident.span,
                    &format!("name `{}` is reserved in attribute namespace", ident),
1132 1133 1134 1135 1136
                );
            }
        }
    }

1137 1138
    /// Compile the macro into a `SyntaxExtension` and possibly replace
    /// its expander to a pre-defined one for built-in macros.
1139
    crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> SyntaxExtension {
1140
        let mut result = compile_declarative_macro(
1141
            &self.session,
M
Mark Rousskov 已提交
1142 1143 1144
            self.session.features_untracked(),
            item,
            edition,
1145 1146
        );

1147
        if let Some(builtin_name) = result.builtin_name {
1148
            // The macro was marked with `#[rustc_builtin_macro]`.
1149
            if let Some(builtin_macro) = self.builtin_macros.get_mut(&builtin_name) {
1150 1151
                // The macro is a built-in, replace its expander function
                // while still taking everything else from the source code.
1152 1153
                // If we already loaded this builtin macro, give a better error message than 'no such builtin macro'.
                match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(item.span)) {
1154
                    BuiltinMacroState::NotYetSeen(ext) => result.kind = ext,
1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165
                    BuiltinMacroState::AlreadySeen(span) => {
                        struct_span_err!(
                            self.session,
                            item.span,
                            E0773,
                            "attempted to define built-in macro more than once"
                        )
                        .span_note(span, "previously defined here")
                        .emit();
                    }
                }
1166 1167 1168 1169 1170 1171
            } else {
                let msg = format!("cannot find a built-in macro with name `{}`", item.ident);
                self.session.span_err(item.span, &msg);
            }
        }

1172
        result
1173
    }
1174
}