diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 47280a936779f..3aba4c8de1919 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -53,6 +53,10 @@ resolve_binding_shadows_something_unacceptable = resolve_binding_shadows_something_unacceptable_suggestion = try specify the pattern arguments +resolve_cannot_access_the_local_binding = + cannot access the local binding `{$name}` + .note = `{$name}` is defined here + resolve_cannot_be_reexported_crate_public = `{$ident}` is only public within the crate, and cannot be re-exported outside diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index f75a625a279bb..000103ed5ede9 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -455,10 +455,9 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { fn block_needs_anonymous_module(&self, block: &Block) -> bool { // If any statements are items, we need to create an anonymous module - block - .stmts - .iter() - .any(|statement| matches!(statement.kind, StmtKind::Item(_) | StmtKind::MacCall(_))) + block.stmts.iter().any(|statement| { + matches!(statement.kind, StmtKind::Item(_) | StmtKind::MacCall(_) | StmtKind::Let(_)) + }) } // Add an import to the current module. diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 63d6fa23a148d..cfda8436f7081 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1264,3 +1264,13 @@ pub(crate) struct TraitImplMismatch { #[label(resolve_trait_impl_mismatch_label_item)] pub(crate) trait_item_span: Span, } + +#[derive(Diagnostic)] +#[diag(resolve_cannot_access_the_local_binding)] +pub(crate) struct CannotAccessTheLocalBinding { + #[primary_span] + pub(crate) span: Span, + pub(crate) name: Symbol, + #[note] + pub(crate) local_binding_def_span: Span, +} diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index dae42645becdd..023a6dce2bc57 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -17,9 +17,9 @@ use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib use crate::macros::{MacroRulesScope, sub_namespace_match}; use crate::{ AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, CmResolver, Determinacy, - Finalize, ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot, - NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res, ResolutionError, - Resolver, Scope, ScopeSet, Segment, Stage, Used, Weak, errors, + Finalize, ImportKind, LexicalScopeBinding, LookaheadItemInBlock, Module, ModuleKind, + ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res, + ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Used, Weak, errors, }; #[derive(Copy, Clone)] @@ -40,6 +40,13 @@ enum Shadowing { Unrestricted, } +pub(crate) enum ResolveIdentInBlockRes<'ra> { + Res(Res), + Item(NameBinding<'ra>), + DefinedLater { def_site: Span }, + NotFound, +} + impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// A generic scope visitor. /// Visits scopes in order to resolve some identifier in them or perform other actions. @@ -270,6 +277,168 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None } + pub(crate) fn resolve_ident_in_block_lexical_scope( + &mut self, + ident: &mut Ident, + ns: Namespace, + parent_scope: &ParentScope<'ra>, + finalize: Option, + rib_index: usize, + ribs: &[Rib<'ra>], + ignore_binding: Option>, + ) -> ResolveIdentInBlockRes<'ra> { + let mut original_ident = *ident; + + fn resolve_ident_in_forward_macro_of_block<'ra>( + r: &mut Resolver<'ra, '_>, + expansion: &mut Option, // macro_def_id + module: Module<'ra>, + resolving_block: NodeId, + ident: &mut Ident, + rib_index: usize, + finalize: Option, + ribs: &[Rib<'ra>], + ) -> Option { + let items = r.lookahead_items_in_block.get(&resolving_block)?; + for (node_id, item) in items.iter().rev() { + match item { + LookaheadItemInBlock::MacroDef { def_id } => { + if *def_id != r.macro_def(ident.span.ctxt()) { + continue; + } + expansion.get_or_insert(*node_id); + ident.span.remove_mark(); + if let Some((original_rib_ident_def, (module_of_res, res, _))) = + r.bindings_of_macro_def[def_id].get_key_value(ident) + && module_of_res.is_ancestor_of(module) + { + // The ident resolves to a type parameter or local variable. + return Some(r.validate_res_from_ribs( + rib_index, + *ident, + *res, + finalize.map(|finalize| finalize.path_span), + *original_rib_ident_def, + ribs, + )); + } + } + LookaheadItemInBlock::Block => { + // resolve child block later + } + LookaheadItemInBlock::Binding { .. } => {} + } + } + + let subs = items + .iter() + .filter_map(|(node_id, item)| { + if matches!(item, LookaheadItemInBlock::Block) { Some(*node_id) } else { None } + }) + .collect::>(); + for node_id in subs { + if let Some(res) = resolve_ident_in_forward_macro_of_block( + r, expansion, module, node_id, ident, rib_index, finalize, ribs, + ) { + return Some(res); + } + } + + None + } + + fn is_defined_later( + r: &Resolver<'_, '_>, + macro_def_node: NodeId, + resolving_block: NodeId, + ident: &Ident, + ) -> Option { + let Some(items) = r.lookahead_items_in_block.get(&resolving_block) else { + return None; + }; + for (node_id, item) in items { + match item { + LookaheadItemInBlock::Binding { name } => { + if name.name == ident.name { + return Some(name.span); + } + } + LookaheadItemInBlock::Block => { + if let Some(def_span) = is_defined_later(r, macro_def_node, *node_id, ident) + { + return Some(def_span); + } + } + LookaheadItemInBlock::MacroDef { .. } => { + if macro_def_node.eq(node_id) { + return None; + } + } + } + } + + None + } + + let RibKind::Block { module: block_module, id: resolving_block } = ribs[rib_index].kind + else { + bug!("expected a block rib"); + }; + let mut expansion = None; + if let Some(res) = resolve_ident_in_forward_macro_of_block( + self, + &mut expansion, + parent_scope.module, + resolving_block, + ident, + rib_index, + finalize, + ribs, + ) { + return ResolveIdentInBlockRes::Res(res); + } + + if let Some(expansion) = expansion + && let Some(def_site) = is_defined_later(self, expansion, resolving_block, &ident) + { + // return `None` for this case: + // + // ``` + // let a = m!(); + // let b = 1; + // macro_rules! m { () => { b } } + // use b; + // ``` + return ResolveIdentInBlockRes::DefinedLater { def_site }; + } + + if let Some(module) = block_module { + if let Some(seen_macro_def_list) = self.seen_macro_def_in_block.get(&resolving_block) { + for m in seen_macro_def_list.iter().rev() { + if self.macro_def(original_ident.span.ctxt()) == *m { + original_ident.span.remove_mark(); + } + } + } + + if let Ok(binding) = self.cm().resolve_ident_in_module_unadjusted( + ModuleOrUniformRoot::Module(module), + original_ident, + ns, + parent_scope, + Shadowing::Unrestricted, + finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }), + ignore_binding, + None, + ) { + // The ident resolves to an item in a block. + return ResolveIdentInBlockRes::Item(binding); + } + } + + ResolveIdentInBlockRes::NotFound + } + /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope. /// More specifically, we proceed up the hierarchy of scopes and return the binding for /// `ident` in the first scope that defines it (or None if no scopes define it). @@ -328,20 +497,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { *original_rib_ident_def, ribs, ))); - } else if let RibKind::Block(Some(module)) = rib.kind - && let Ok(binding) = self.cm().resolve_ident_in_module_unadjusted( - ModuleOrUniformRoot::Module(module), - ident, + } else if let RibKind::Block { .. } = rib.kind { + match self.resolve_ident_in_block_lexical_scope( + &mut ident, ns, parent_scope, - Shadowing::Unrestricted, - finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }), + finalize, + i, + ribs, ignore_binding, - None, - ) - { - // The ident resolves to an item in a block. - return Some(LexicalScopeBinding::Item(binding)); + ) { + ResolveIdentInBlockRes::Res(res) => return Some(LexicalScopeBinding::Res(res)), + ResolveIdentInBlockRes::Item(item) => { + return Some(LexicalScopeBinding::Item(item)); + } + ResolveIdentInBlockRes::DefinedLater { .. } => return None, + ResolveIdentInBlockRes::NotFound => {} + } } else if let RibKind::Module(module) = rib.kind { // Encountered a module item, abandon ribs and look into that module and preludes. let parent_scope = &ParentScope { module, ..*parent_scope }; @@ -360,14 +532,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .ok() .map(LexicalScopeBinding::Item); } - - if let RibKind::MacroDefinition(def) = rib.kind - && def == self.macro_def(ident.span.ctxt()) - { - // If an invocation of this macro created `ident`, give up on `ident` - // and switch to `ident`'s source from the macro definition. - ident.span.remove_mark(); - } } unreachable!() @@ -1163,10 +1327,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { for rib in ribs { match rib.kind { RibKind::Normal - | RibKind::Block(..) + | RibKind::Block { .. } | RibKind::FnOrCoroutine | RibKind::Module(..) - | RibKind::MacroDefinition(..) | RibKind::ForwardGenericParamBan(_) => { // Nothing to do. Continue. } @@ -1256,10 +1419,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { for rib in ribs { let (has_generic_params, def_kind) = match rib.kind { RibKind::Normal - | RibKind::Block(..) + | RibKind::Block { .. } | RibKind::FnOrCoroutine | RibKind::Module(..) - | RibKind::MacroDefinition(..) | RibKind::InlineAsmSym | RibKind::AssocItem | RibKind::ForwardGenericParamBan(_) => { @@ -1350,10 +1512,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { for rib in ribs { let (has_generic_params, def_kind) = match rib.kind { RibKind::Normal - | RibKind::Block(..) + | RibKind::Block { .. } | RibKind::FnOrCoroutine | RibKind::Module(..) - | RibKind::MacroDefinition(..) | RibKind::InlineAsmSym | RibKind::AssocItem | RibKind::ForwardGenericParamBan(_) => continue, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index d4f7fb276a979..7c6bc4034ea98 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -16,7 +16,7 @@ use rustc_ast::visit::{ AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, try_visit, visit_opt, walk_list, }; use rustc_ast::*; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::codes::*; use rustc_errors::{ @@ -39,9 +39,9 @@ use thin_vec::ThinVec; use tracing::{debug, instrument, trace}; use crate::{ - BindingError, BindingKey, Finalize, LexicalScopeBinding, Module, ModuleOrUniformRoot, - NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, TyCtxt, UseError, - Used, errors, path_names_to_string, rustdoc, + BindingError, BindingKey, Finalize, LexicalScopeBinding, LookaheadItemInBlock, Module, + ModuleOrUniformRoot, NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, + TyCtxt, UseError, Used, errors, path_names_to_string, rustdoc, }; mod diagnostics; @@ -102,7 +102,7 @@ impl IntoDiagArg for PatternSource { /// Denotes whether the context for the set of already bound bindings is a `Product` /// or `Or` context. This is used in e.g., `fresh_binding` and `resolve_pattern_inner`. /// See those functions for more information. -#[derive(PartialEq)] +#[derive(PartialEq, Debug)] enum PatBoundCtx { /// A product pattern context, e.g., `Variant(a, b)`. Product, @@ -197,7 +197,29 @@ pub(crate) enum RibKind<'ra> { /// `Block(None)` must be always processed in the same way as `Block(Some(module))` /// with empty `module`. The module can be `None` only because creation of some definitely /// empty modules is skipped as an optimization. - Block(Option>), + Block { + module: Option>, + /// The node id of block kind, which stores all bindings defined in + /// this local scope, for these features: + /// + /// - Forward reference detection: + /// + /// ```ignore (illustrative) + /// let a = b; // displays '`b` is defined at ' instead of ''b' not found' + /// let b = 42; + /// ``` + /// + /// - Correctly resolves the hoisting bindings within macro expand: + /// + /// ```ignore (illustrative) + /// fn f() {} + /// let a: i16 = m!(); // throw error because it should use the local `f` rather than `fn f` + /// let f = || -> i16 { 42 }; + /// macro_rules! m {() => ( f() )} + /// use m; + /// ``` + id: NodeId, + }, /// We passed through an impl or trait and are now in one of its /// methods or associated types. Allow references to ty params that impl or trait @@ -220,9 +242,6 @@ pub(crate) enum RibKind<'ra> { /// We passed through a module item. Module(Module<'ra>), - /// We passed through a `macro_rules!` statement - MacroDefinition(DefId), - /// All bindings in this rib are generic parameters that can't be used /// from the default of a generic parameter because they're not declared /// before said generic parameter. Also see the `visit_generics` override. @@ -249,11 +268,10 @@ impl RibKind<'_> { pub(crate) fn contains_params(&self) -> bool { match self { RibKind::Normal - | RibKind::Block(..) + | RibKind::Block { .. } | RibKind::FnOrCoroutine | RibKind::ConstantItem(..) | RibKind::Module(_) - | RibKind::MacroDefinition(_) | RibKind::InlineAsmSym => false, RibKind::ConstParamTy | RibKind::AssocItem @@ -265,7 +283,7 @@ impl RibKind<'_> { /// This rib forbids referring to labels defined in upwards ribs. fn is_label_barrier(self) -> bool { match self { - RibKind::Normal | RibKind::MacroDefinition(..) => false, + RibKind::Normal | RibKind::Block { .. } => false, RibKind::FnOrCoroutine | RibKind::ConstantItem(..) => true, kind => bug!("unexpected rib kind: {kind:?}"), } @@ -2465,12 +2483,16 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { for i in (0..self.label_ribs.len()).rev() { let rib = &self.label_ribs[i]; - if let RibKind::MacroDefinition(def) = rib.kind - // If an invocation of this macro created `ident`, give up on `ident` - // and switch to `ident`'s source from the macro definition. - && def == self.r.macro_def(label.span.ctxt()) + if let RibKind::Block { id, .. } = rib.kind + && let Some(seen_macro_def_list) = self.r.seen_macro_def_in_block.get(&id) { - label.span.remove_mark(); + for def in seen_macro_def_list.iter().rev() { + if *def == self.r.macro_def(label.span.ctxt()) { + // If an invocation of this macro created `ident`, give up on `ident` + // and switch to `ident`'s source from the macro definition. + label.span.remove_mark(); + } + } } let ident = label.normalize_to_macro_rules(); @@ -2816,7 +2838,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { for parent_rib in self.ribs[ns].iter().rev() { // Break at module or block level, to account for nested items which are // allowed to shadow generic param names. - if matches!(parent_rib.kind, RibKind::Module(..) | RibKind::Block(..)) { + if matches!(parent_rib.kind, RibKind::Module(..) | RibKind::Block { .. }) { break; } @@ -3765,10 +3787,102 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }); } + fn feed_macro_bindings_for_sub_block( + &self, + block_id: NodeId, + start: usize, + bindings: &PatternBindings, + // `need_removed` used for avoid injecting masked names into macro definition bindings: + // + // ``` + // let x = 0; + // macro_rules! m0 {() => { x; }} // Injects `let x = 0` into `m0` + // { + // let x = 1; + // macro_rules! m1 {() => { x; }} // Should NOT inject `let x = 0` into `m1` + // } + // macro_rules! m2 {() => { x; }} // Injects `let x = 0` into `m2` + // ``` + need_removed: &mut FxIndexSet, + macro_bindings: &mut FxHashMap<(NodeId, NodeId, Ident), Res>, // (block_id, macro_def_id, Ident) -> Res + ) { + let Some(items) = self.r.lookahead_items_in_block.get(&block_id) else { + return; + }; + for (node_id, item) in items.iter().skip(start) { + match item { + LookaheadItemInBlock::Binding { name } => { + need_removed.insert(*name); + } + LookaheadItemInBlock::MacroDef { .. } => { + let bindings = bindings.last().unwrap().1.iter().filter_map(|(name, res)| { + if !need_removed.contains(name) { Some((*name, *res)) } else { None } + }); + for (name, res) in bindings { + let key = (block_id, *node_id, name); + macro_bindings.insert(key, res); + } + } + LookaheadItemInBlock::Block => { + let saved_len = need_removed.len(); + self.feed_macro_bindings_for_sub_block( + *node_id, + 0, + bindings, + need_removed, + macro_bindings, + ); + need_removed.truncate(saved_len); + } + } + } + } + /// Arising from `source`, resolve a top level pattern. fn resolve_pattern_top(&mut self, pat: &'ast Pat, pat_src: PatternSource) { let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())]; self.resolve_pattern(pat, pat_src, &mut bindings); + + let mut last_pat_id = None; + pat.walk(&mut |pat| { + if let PatKind::Ident(..) = pat.kind { + last_pat_id = Some(pat.id); + } + true + }); + + if let Some(last_pat_id) = last_pat_id + && let RibKind::Block { id, .. } = self.ribs[ValueNS].last_mut().unwrap().kind + && let Some(items) = self.r.lookahead_items_in_block.get(&id) + { + let start = items.get_index_of(&last_pat_id).unwrap_or_else(|| { + panic!("pattern({pat:#?}) not found in lookahead items"); + }); + let mut need_removed = FxIndexSet::default(); + let mut extend_bindings = FxHashMap::default(); + self.feed_macro_bindings_for_sub_block( + id, + start + 1, + &bindings, + &mut need_removed, + &mut extend_bindings, + ); + // We don't care the order here + #[allow(rustc::potential_query_instability)] + for ((block_id, macro_id, ident), res) in extend_bindings { + let Some(LookaheadItemInBlock::MacroDef { def_id }) = self + .r + .lookahead_items_in_block + .get(&block_id) + .and_then(|block| block.get(¯o_id)) + else { + unreachable!() + }; + let macro_bindings = self.r.bindings_of_macro_def.get_mut(def_id).unwrap(); + macro_bindings.insert(ident, (self.parent_scope.module, res, ident.span)); + } + } + self.apply_pattern_bindings(bindings); } @@ -4647,14 +4761,17 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let orig_module = self.parent_scope.module; let anonymous_module = self.r.block_map.get(&block.id).copied(); - let mut num_macro_definition_ribs = 0; if let Some(anonymous_module) = anonymous_module { debug!("(resolving block) found anonymous module, moving down"); - self.ribs[ValueNS].push(Rib::new(RibKind::Block(Some(anonymous_module)))); - self.ribs[TypeNS].push(Rib::new(RibKind::Block(Some(anonymous_module)))); + let rib_kind = RibKind::Block { module: Some(anonymous_module), id: block.id }; + self.ribs[ValueNS].push(Rib::new(rib_kind)); + self.ribs[TypeNS].push(Rib::new(rib_kind)); + self.label_ribs.push(Rib::new(rib_kind)); self.parent_scope.module = anonymous_module; } else { - self.ribs[ValueNS].push(Rib::new(RibKind::Block(None))); + let rib_kind = RibKind::Block { module: None, id: block.id }; + self.ribs[ValueNS].push(Rib::new(rib_kind)); + self.label_ribs.push(Rib::new(rib_kind)); } // Descend into the block. @@ -4662,10 +4779,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { if let StmtKind::Item(ref item) = stmt.kind && let ItemKind::MacroDef(..) = item.kind { - num_macro_definition_ribs += 1; let res = self.r.local_def_id(item.id).to_def_id(); - self.ribs[ValueNS].push(Rib::new(RibKind::MacroDefinition(res))); - self.label_ribs.push(Rib::new(RibKind::MacroDefinition(res))); + let seen = self.r.seen_macro_def_in_block.entry(block.id).or_default(); + seen.insert(res); } self.visit_stmt(stmt); @@ -4673,10 +4789,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Move back up. self.parent_scope.module = orig_module; - for _ in 0..num_macro_definition_ribs { - self.ribs[ValueNS].pop(); - self.label_ribs.pop(); - } + self.label_ribs.pop(); self.last_block_rib = self.ribs[ValueNS].pop(); if anonymous_module.is_some() { self.ribs[TypeNS].pop(); @@ -5134,6 +5247,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { /// lifetime generic parameters and function parameters. struct ItemInfoCollector<'a, 'ra, 'tcx> { r: &'a mut Resolver<'ra, 'tcx>, + current_block: Option, } impl ItemInfoCollector<'_, '_, '_> { @@ -5189,12 +5303,18 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> { } } } - + ItemKind::MacroDef(_, _) => { + if let Some(current_block) = self.current_block { + let def_id = self.r.local_def_id(item.id).to_def_id(); + let items = self.r.lookahead_items_in_block.entry(current_block).or_default(); + items.insert(item.id, LookaheadItemInBlock::MacroDef { def_id }); + self.r.bindings_of_macro_def.insert(def_id, Default::default()); + } + } ItemKind::Mod(..) | ItemKind::Static(..) | ItemKind::Use(..) | ItemKind::ExternCrate(..) - | ItemKind::MacroDef(..) | ItemKind::GlobalAsm(..) | ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => {} @@ -5205,7 +5325,9 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> { // but for delegation items we are never actually retrieving that count in practice. } } - visit::walk_item(self, item) + let old_block = self.current_block.take(); + visit::walk_item(self, item); + self.current_block = old_block; } fn visit_assoc_item(&mut self, item: &'ast AssocItem, ctxt: AssocCtxt) { @@ -5214,11 +5336,86 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> { } visit::walk_assoc_item(self, item, ctxt); } + + fn visit_local(&mut self, node: &'ast Local) -> Self::Result { + // collect local bindings into block + node.pat.walk(&mut |pat| { + if let PatKind::Ident(_, name, _) = &pat.kind { + let current_block = self.current_block.unwrap(); + let items = self.r.lookahead_items_in_block.entry(current_block).or_default(); + items.insert(pat.id, LookaheadItemInBlock::Binding { name: *name }); + } + true + }); + visit::walk_local(self, node) + } + + fn visit_block(&mut self, node: &'ast Block) -> Self::Result { + if let Some(current_block) = self.current_block { + let items = self.r.lookahead_items_in_block.entry(current_block).or_default(); + items.insert(node.id, LookaheadItemInBlock::Block); + } + let saved_block_id = self.current_block.replace(node.id); + visit::walk_block(self, node); + self.current_block = saved_block_id; + } +} + +struct FreshBindingInMacroExpandChecker<'a, 'ra, 'tcx> { + r: &'a Resolver<'ra, 'tcx>, + blocks: Vec, +} + +impl<'ast> Visitor<'ast> for FreshBindingInMacroExpandChecker<'_, '_, '_> { + fn visit_block(&mut self, node: &'ast Block) -> Self::Result { + self.blocks.push(node.id); + visit::walk_block(self, node); + self.blocks.pop(); + } + + fn visit_ident(&mut self, node: &'ast Ident) -> Self::Result { + let macro_def = self.r.macro_def(node.span.ctxt()); + if let Some(bindings) = self.r.bindings_of_macro_def.get(¯o_def) + && let mut ident = node.clone() + && let Some((_, res, local_binding_def_span)) = bindings + .get({ + ident.span.remove_mark(); + &ident + }) + .copied() + && let Res::Local(_) = res + && let macro_def_scope = self.r.macro_def_scope(macro_def) + && !self + .blocks + .iter() + .filter_map(|b| self.r.block_map.get(b)) + .any(|m| m.is_ancestor_of(macro_def_scope)) + { + // throw error for this case: + // ``` + // fn f() { + // let a = 42; + // #[macro_export] + // macro_rules! m { () => { a }} + // } + // + // fn g() { + // fn a() {} + // crate::a!(); // ERROR: cannot access the local binding `a` + // } + // ``` + self.r.dcx().emit_err(errors::CannotAccessTheLocalBinding { + span: node.span, + name: node.name, + local_binding_def_span, + }); + } + } } impl<'ra, 'tcx> Resolver<'ra, 'tcx> { pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) { - visit::walk_crate(&mut ItemInfoCollector { r: self }, krate); + visit::walk_crate(&mut ItemInfoCollector { r: self, current_block: None }, krate); let mut late_resolution_visitor = LateResolutionVisitor::new(self); late_resolution_visitor.resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID)); visit::walk_crate(&mut late_resolution_visitor, krate); @@ -5230,6 +5427,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { BuiltinLintDiag::UnusedLabel, ); } + let mut fresh_binding_in_macro_expand_checker = + FreshBindingInMacroExpandChecker { r: self, blocks: vec![] }; + visit::walk_crate(&mut fresh_binding_in_macro_expand_checker, krate); } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 80b2095d8ccff..ca832995ee173 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -32,6 +32,7 @@ use tracing::debug; use super::NoConstantGenericsReason; use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion}; +use crate::ident::ResolveIdentInBlockRes; use crate::late::{ AliasPossibility, LateResolutionVisitor, LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet, QSelf, RibKind, @@ -438,6 +439,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } self.detect_missing_binding_available_from_pattern(&mut err, path, following_seg); + self.detect_is_defined_later_in_block_for_macro_expansion(&mut err, path, source); self.suggest_at_operator_in_slice_pat_with_range(&mut err, path); self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span); @@ -898,7 +900,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { if path.len() == 1 { for rib in self.ribs[ns].iter().rev() { let item = path[0].ident; - if let RibKind::Module(module) | RibKind::Block(Some(module)) = rib.kind + if let RibKind::Module(module) | RibKind::Block { module: Some(module), .. } = + rib.kind && let Some(did) = find_doc_alias_name(self.r, module, item.name) { return Some((did, item)); @@ -1248,6 +1251,37 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { true } + fn detect_is_defined_later_in_block_for_macro_expansion( + &mut self, + err: &mut Diag<'_>, + path: &[Segment], + source: PathSource<'_, 'ast, 'ra>, + ) { + let ns = source.namespace(); + if ns != Namespace::ValueNS { + return; + } + let [segment] = path else { return }; + let mut ident = segment.ident; + for (rib_index, rib) in self.ribs[ns].iter().enumerate().rev() { + if let RibKind::Block { .. } = rib.kind + && let ResolveIdentInBlockRes::DefinedLater { def_site } = + self.r.resolve_ident_in_block_lexical_scope( + &mut ident, + ns, + &self.parent_scope, + None, + rib_index, + &self.ribs[ns], + None, + ) + { + err.span_label(def_site, format!("`{}` is defined here", segment.ident.name)); + break; + } + } + } + fn detect_missing_binding_available_from_pattern( &self, err: &mut Diag<'_>, @@ -2438,7 +2472,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ) -> TypoCandidate { let mut names = Vec::new(); if let [segment] = path { - let mut ctxt = segment.ident.span.ctxt(); + let ctxt = segment.ident.span.ctxt(); // Search in lexical scope. // Walk backwards up the ribs in scope and collect candidates. @@ -2456,7 +2490,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } - if let RibKind::Block(Some(module)) = rib.kind { + if let RibKind::Block { module: Some(module), .. } = rib.kind { self.r.add_module_candidates(module, &mut names, &filter_fn, Some(ctxt)); } else if let RibKind::Module(module) = rib.kind { // Encountered a module item, abandon ribs and look into that module and preludes. @@ -2470,14 +2504,6 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ); break; } - - if let RibKind::MacroDefinition(def) = rib.kind - && def == self.r.macro_def(ctxt) - { - // If an invocation of this macro created `ident`, give up on `ident` - // and switch to `ident`'s source from the macro definition. - ctxt.remove_mark(); - } } } else { // Search in module. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 2afb52ef4d4be..df1b6b4024f8b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -58,7 +58,9 @@ use rustc_hir::def::{ self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, MacroKinds, NonMacroAttrKind, PartialRes, PerNS, }; -use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; +use rustc_hir::def_id::{ + CRATE_DEF_ID, CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId, LocalDefIdMap, +}; use rustc_hir::definitions::DisambiguatorState; use rustc_hir::{PrimTy, TraitCandidate}; use rustc_index::bit_set::DenseBitSet; @@ -1062,6 +1064,22 @@ pub struct ResolverOutputs { pub ast_lowering: ResolverAstLowering, } +#[derive(Debug)] +enum LookaheadItemInBlock { + /// such as `let x = 1;` + Binding { name: Ident }, + /// such as `macro_rules! foo { ... }` + MacroDef { def_id: DefId }, + /// block item in this block, such as: + /// ```ignore (illustrative) + /// { + /// { let x = 1 } + /// //~ ~ + /// } + /// ``` + Block, +} + /// The main resolver class. /// /// This is the visitor that walks the whole crate. @@ -1130,6 +1148,9 @@ pub struct Resolver<'ra, 'tcx> { /// There will be an anonymous module created around `g` with the ID of the /// entry block for `f`. block_map: NodeMap>, + lookahead_items_in_block: NodeMap>, + bindings_of_macro_def: DefIdMap, Res, Span)>>, + seen_macro_def_in_block: NodeMap>, /// A fake module that contains no definition and no prelude. Used so that /// some AST passes can generate identifiers that only resolve to local or /// lang items. @@ -1657,6 +1678,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { current_crate_outer_attr_insert_span, mods_with_parse_errors: Default::default(), impl_trait_names: Default::default(), + lookahead_items_in_block: Default::default(), + bindings_of_macro_def: Default::default(), + seen_macro_def_in_block: Default::default(), .. }; diff --git a/tests/ui/proc-macro/weird-hygiene.stderr b/tests/ui/proc-macro/weird-hygiene.stderr index 256e68e8970e6..6ead8904b077d 100644 --- a/tests/ui/proc-macro/weird-hygiene.stderr +++ b/tests/ui/proc-macro/weird-hygiene.stderr @@ -4,6 +4,8 @@ error[E0425]: cannot find value `hidden_ident` in this scope LL | Value = (stringify!($tokens + hidden_ident), 1).1 | ^^^^^^^^^^^^ not found in this scope ... +LL | let hidden_ident = "Hello1"; + | ------------ `hidden_ident` is defined here LL | other!(50); | ---------- in this macro invocation | diff --git a/tests/ui/resolve/binding-should-not-shadow-def-in-macro-expand.rs b/tests/ui/resolve/binding-should-not-shadow-def-in-macro-expand.rs new file mode 100644 index 0000000000000..71ae1592158e6 --- /dev/null +++ b/tests/ui/resolve/binding-should-not-shadow-def-in-macro-expand.rs @@ -0,0 +1,144 @@ +//@ edition:2018 + +type FnF = i8; +type BindingF = i16; + +fn main() {} + +fn f_without_definition_f(f: impl Fn() -> BindingF) { + // param f -> macro m + let a: BindingF = m!(); + macro_rules! m {() => ( f() )} + use m; +} + +fn fn0(f: impl Fn() -> BindingF) { + // param f -> fn f -> macro m + + let a0: FnF = m!(); + fn f() -> FnF { 42 } + let a1: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; + let a2: FnF = m!(); +} + +fn fn1(f: impl Fn() -> BindingF) { + // param f -> macro m -> fn f + + let a0: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; + let a1: FnF = m!(); + fn f() -> FnF { 42 } + let a2: FnF = m!(); +} + +fn closure() { + let c_without_definition_f = |f: BindingF| { + // param f -> macro m + let a1: BindingF = m!(); + macro_rules! m {() => ( f )} + use m; + }; + + let c0 = |f: BindingF| { + // param f -> fn f -> macro m + let a0: FnF = m!(); + fn f() -> FnF { 42 } + let a1: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; + let a2: FnF = m!(); + }; + + let c1 = |f: BindingF| { + // param f -> macro m -> fn f + let a0: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; + let a1: FnF = m!(); + fn f() -> FnF { 42 } + let a2: FnF = m!(); + }; +} + +fn for_loop() { + // for f -> macro m -> fn f + for f in 0..42 as BindingF { + let a0: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; + let a1: FnF = m!(); + fn f() -> FnF { 42 } + let a2: FnF = m!(); + } + + // for f -> fn f -> macro m + for f in 0..42 as BindingF { + let a0: FnF = m!(); + fn f() -> FnF { 42 } + let a1: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; + let a2: FnF = m!(); + } +} + +fn match_arm() { + // match f -> macro m -> fn f + match 42 as BindingF { + f => { + let a0: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; + let a1: FnF = m!(); + fn f() -> FnF { 42 } + let a2: FnF = m!(); + } + } + + // match f -> fn f -> macro m + match 42 as BindingF { + f => { + let a0: FnF = m!(); + fn f() -> FnF { 42 } + let a1: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; + let a2: FnF = m!(); + } + } +} + +fn let_in_if_expr() { + if let Some(f) = Some(|| -> BindingF { 42 }) { + // expr let f -> fn f -> macro f + let a0: FnF = m!(); + fn f() -> FnF { 42 } + let a1: FnF = m!(); + macro_rules! m {() => { f() };} + use m; + let a2: FnF = m!(); + } + + if let Some(f) = Some(|| -> BindingF { 42 }) { + // expr let f -> macro f -> fn f + let a0: FnF = m!(); + macro_rules! m {() => { f() };} + use m; + let a1: FnF = m!(); + fn f() -> FnF { 42 } + let a2: FnF = m!(); + } +} + +fn cannot_access_cross_fn() { + let f = || -> BindingF { 42 }; + fn g() { + macro_rules! m { + () => { f() }; //~ ERROR can't capture dynamic environment in a fn item + } + m!(); + } +} diff --git a/tests/ui/resolve/binding-should-not-shadow-def-in-macro-expand.stderr b/tests/ui/resolve/binding-should-not-shadow-def-in-macro-expand.stderr new file mode 100644 index 0000000000000..77e8955f89f8f --- /dev/null +++ b/tests/ui/resolve/binding-should-not-shadow-def-in-macro-expand.stderr @@ -0,0 +1,15 @@ +error[E0434]: can't capture dynamic environment in a fn item + --> $DIR/binding-should-not-shadow-def-in-macro-expand.rs:140:21 + | +LL | () => { f() }; + | ^ +LL | } +LL | m!(); + | ---- in this macro invocation + | + = help: use the `|| { ... }` closure form instead + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0434`. diff --git a/tests/ui/resolve/fresh-should-shadow-definitation-in-decl-macro-expand.rs b/tests/ui/resolve/fresh-should-shadow-definitation-in-decl-macro-expand.rs new file mode 100644 index 0000000000000..42bd81acbe505 --- /dev/null +++ b/tests/ui/resolve/fresh-should-shadow-definitation-in-decl-macro-expand.rs @@ -0,0 +1,100 @@ +//@ edition:2018 +// issue#95237 + +#![feature(decl_macro)] + +type FnF = i8; +type BindingF = i16; + +fn f_without_definition_f() { + let f = || -> BindingF { 42 }; + let a: BindingF = m!(); + macro m() { f() } +} + +fn f_without_closure_f() { + fn f() -> FnF { 42 } + let a: FnF = m!(); + macro m() { f() } +} + +fn f0() { + // let f -> macro m -> fn f + + let a0: BindingF = m!(); //~ NOTE in this expansion of m! + let f = || -> BindingF { 42 }; //~ NOTE `f` is defined here + let a1: BindingF = m!(); + macro m() { f() } //~ ERROR cannot find function `f` in this scope + //~| NOTE not found in this scope + let a2: BindingF = m!(); + fn f() -> FnF { 42 } //~ NOTE you might have meant to refer to this function + let a3: BindingF = m!(); +} + +fn f1() { + // let f -> fn f -> macro m + + let a0: BindingF = m!(); //~ NOTE in this expansion of m! + let f = || -> BindingF { 42 }; //~ NOTE `f` is defined here + let a1: BindingF = m!(); + fn f() -> FnF { 42 } //~ NOTE you might have meant to refer to this function + let a2: BindingF = m!(); + macro m() { f() } //~ ERROR cannot find function `f` in this scope + //~| NOTE not found in this scope + let a3: BindingF = m!(); +} + +fn f2() { + // fn f -> let f -> macro m + + let a0: BindingF = m!(); //~ NOTE in this expansion of m! + fn f() -> FnF { 42 } //~ NOTE you might have meant to refer to this function + //~| NOTE you might have meant to refer to this function + let a1: BindingF = m!(); //~ NOTE in this expansion of m! + let f = || -> BindingF { 42 }; //~ NOTE `f` is defined here + //~| NOTE `f` is defined here + let a2: BindingF = m!(); + macro m() { f() } //~ ERROR cannot find function `f` in this scope + //~| ERROR cannot find function `f` in this scope + //~| NOTE not found in this scope + //~| NOTE not found in this scope + let a3: BindingF = m!(); +} + +fn f3() { + // fn f -> macro m -> let f + + let a0: FnF = m!(); + fn f() -> FnF { 42 } + let a1: FnF = m!(); + macro m() { f() } + let a2: FnF = m!(); + let f = || -> BindingF { 42 }; + let a3: FnF = m!(); +} + +fn f4() { + // macro m -> fn f -> let f; + + let a0: FnF = m!(); + macro m() { f() } + let a1: FnF = m!(); + fn f() -> FnF { 42 } + let a2: FnF = m!(); + let f = || -> BindingF { 42 }; + let a3: FnF = m!(); +} + +fn f5() { + // macro m -> let f -> fn f; + + let a0: FnF = m!(); + macro m() { f() } + let a1: FnF = m!(); + let f = || -> BindingF { 42 }; + let a2: FnF = m!(); + fn f() -> FnF { 42 } + let a3: FnF = m!(); +} + +fn main () {} diff --git a/tests/ui/resolve/fresh-should-shadow-definitation-in-decl-macro-expand.stderr b/tests/ui/resolve/fresh-should-shadow-definitation-in-decl-macro-expand.stderr new file mode 100644 index 0000000000000..074c6e2edf2a0 --- /dev/null +++ b/tests/ui/resolve/fresh-should-shadow-definitation-in-decl-macro-expand.stderr @@ -0,0 +1,67 @@ +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-decl-macro-expand.rs:27:17 + | +LL | let a0: BindingF = m!(); + | ---- in this macro invocation +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +LL | let a1: BindingF = m!(); +LL | macro m() { f() } + | ^ not found in this scope +... +LL | fn f() -> FnF { 42 } + | - you might have meant to refer to this function + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-decl-macro-expand.rs:42:17 + | +LL | let a0: BindingF = m!(); + | ---- in this macro invocation +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +LL | let a1: BindingF = m!(); +LL | fn f() -> FnF { 42 } + | - you might have meant to refer to this function +LL | let a2: BindingF = m!(); +LL | macro m() { f() } + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-decl-macro-expand.rs:57:17 + | +LL | let a0: BindingF = m!(); + | ---- in this macro invocation +LL | fn f() -> FnF { 42 } + | - you might have meant to refer to this function +... +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +... +LL | macro m() { f() } + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-decl-macro-expand.rs:57:17 + | +LL | fn f() -> FnF { 42 } + | - you might have meant to refer to this function +LL | +LL | let a1: BindingF = m!(); + | ---- in this macro invocation +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +... +LL | macro m() { f() } + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/resolve/fresh-should-shadow-definitation-in-macro-expand-in-block.rs b/tests/ui/resolve/fresh-should-shadow-definitation-in-macro-expand-in-block.rs new file mode 100644 index 0000000000000..a1880b1ee8823 --- /dev/null +++ b/tests/ui/resolve/fresh-should-shadow-definitation-in-macro-expand-in-block.rs @@ -0,0 +1,276 @@ +//@ edition:2018 + +// issue#95237 + +type FnF = i8; +type BindingF = i16; + +fn b_without_definition_f() { + let f = || -> BindingF { 42 }; + { + let a: BindingF = m!(); + } + macro_rules! m {() => ( f() )} + use m; +} + +fn b_without_closure_f() { + fn f() -> FnF { 42 } + { + let a: FnF = m!(); + } + macro_rules! m {() => ( f() )} + use m; +} + +fn ff0() { + // let f -> macro m -> fn f + + { + let a0: BindingF = m!(); //~ NOTE in this expansion of m! + } + let f = || -> BindingF { 42 }; //~ NOTE `f` is defined here + { + let a1: BindingF = m!(); + } + macro_rules! m {() => ( f() )} //~ ERROR cannot find function `f` in this scope + //~| NOTE not found in this scope + use m; + { + let a2: BindingF = m!(); + } + fn f() -> FnF { 42 } + { + let a3: BindingF = m!(); + } +} + +fn ff1() { + // let f -> fn f -> macro m + + { + let a0: BindingF = m!(); //~ NOTE in this expansion of m! + } + let f = || -> BindingF { 42 }; //~ NOTE `f` is defined here + { + let a1: BindingF = m!(); + } + fn f() -> FnF { 42 } + { + let a2: BindingF = m!(); + } + macro_rules! m {() => ( f() )} //~ ERROR cannot find function `f` in this scope + //~| NOTE not found in this scope + use m; + { + let a3: BindingF = m!(); + } +} + +fn ff2() { + // fn f -> let f -> macro m + + { + let a0: BindingF = m!(); //~ NOTE in this expansion of m! + } + fn f() -> FnF { 42 } + { + let a1: BindingF = m!(); //~ NOTE in this expansion of m! + } + let f = || -> BindingF { 42 }; //~ NOTE `f` is defined here + //~| NOTE `f` is defined here + { + let a2: BindingF = m!(); + } + macro_rules! m {() => ( f() )} //~ ERROR cannot find function `f` in this scope + //~| ERROR cannot find function `f` in this scope + //~| NOTE not found in this scope + //~| NOTE not found in this scope + use m; + { + let a3: BindingF = m!(); + } +} + +fn ff3() { + // fn f -> macro m -> let f + + { + let a0: FnF = m!(); + } + fn f() -> FnF { 42 } + { + let a1: FnF = m!(); + } + macro_rules! m {() => ( f() )} + use m; + { + let a2: FnF = m!(); + } + let f = || -> BindingF { 42 }; + { + let a3: FnF = m!(); + } +} + +fn ff4() { + // macro m -> fn f -> let f; + + { + let a0: FnF = m!(); + } + macro_rules! m {() => ( f() )} + use m; + { + let a1: FnF = m!(); + } + fn f() -> FnF { 42 } + { + let a2: FnF = m!(); + } + let f = || -> BindingF { 42 }; + { + let a3: FnF = m!(); + } +} + +fn ff5() { + // macro m -> let f -> fn f; + + { + let a0: FnF = m!(); + } + macro_rules! m {() => ( f() )} + use m; + { + let a1: FnF = m!(); + } + let f = || -> BindingF { 42 }; + { + let a2: FnF = m!(); + } + fn f() -> FnF { 42 } + { + let a3: FnF = m!(); + } +} + +fn ff6() { + // macro m6 -> let f -> fn f; + let a0: FnF = crate::m6!(); + { + #[macro_export] + macro_rules! m6 { () => { f() } } + let f = || -> BindingF { 42 }; + let a1: FnF = crate::m6!(); + } + let a2: FnF = crate::m6!(); + fn f() -> FnF { 42 } + let a3: FnF = crate::m6!(); +} + +fn f_with_macro_export0() { + { + let a: BindingF = 42; //~ NOTE `a` is defined here + let c0: BindingF = crate::m1!(); + { + { + { + { + let d0: BindingF = m1!(); + let d1: BindingF = crate::m1!(); + + #[macro_export] + macro_rules! m1 { () => { a } } //~ ERROR cannot find value `a` in this scope + //~| NOTE not found in this scope + use m1; + + let d2: BindingF = m1!(); + let d3: BindingF = crate::m1!(); + } + } + + let e0: BindingF = m0!(); + #[macro_export] + macro_rules! m0 { () => { a } } + use m0; + let e1: BindingF = m0!(); + } + } + let c1: BindingF = crate::m1!(); + } + crate::m1!(); //~ NOTE in this expansion of crate::m1! +} + +fn f_with_macro_export2() { + fn a() {}; + { + let a: BindingF = 42; //~ NOTE `a` is defined here + let c0: BindingF = crate::m2!(); + { + let d0: BindingF = m2!(); + let d1: BindingF = crate::m2!(); + #[macro_export] + macro_rules! m2 { () => { a } } //~ ERROR cannot find value `a` in this scope + //~| NOTE not found in this scope + use m2; + let d2: BindingF = m2!(); + let d3: BindingF = crate::m2!(); + } + let c1: BindingF = crate::m2!(); + } + crate::m2!(); //~ NOTE in this expansion of crate::m2! +} + +fn f_with_macro_export3() { + crate::m3!(); //~ NOTE in this expansion of crate::m3! + { + let a: BindingF = 42; //~ NOTE `a` is defined here + //~| NOTE `a` is defined here + #[macro_export] + macro_rules! m3 { () => { a } } //~ ERROR cannot find value `a` in this scope + //~| ERROR cannot find value `a` in this scope + //~| NOTE not found in this scope + //~| NOTE not found in this scope + + } + crate::m3!(); //~ NOTE in this expansion of crate::m3! +} + +fn f_with_macro_export4() { + crate::m4!(); //~ NOTE in this expansion of crate::m4! + { + { + let a: BindingF = 42; //~ NOTE `a` is defined here + //~| NOTE `a` is defined here + { + #[macro_export] + macro_rules! m4 { () => { a } } //~ ERROR cannot find value `a` in this scope + //~| ERROR cannot find value `a` in this scope + //~| NOTE not found in this scope + //~| NOTE not found in this scope + } + } + } + crate::m4!(); //~ NOTE in this expansion of crate::m4! +} + + +fn f_with_macro_export5() { + crate::m5!(); //~ NOTE in this expansion of crate::m5! + { + let a: BindingF = 42; //~ NOTE `a` is defined here + //~| NOTE `a` is defined here + { + #[macro_export] + macro_rules! m5 { () => { a } } //~ ERROR cannot find value `a` in this scope + //~| ERROR cannot find value `a` in this scope + //~| NOTE not found in this scope + //~| NOTE not found in this scope + } + } + fn a() {}; + crate::m5!(); //~ NOTE in this expansion of crate::m5! +} + +fn main () {} diff --git a/tests/ui/resolve/fresh-should-shadow-definitation-in-macro-expand-in-block.stderr b/tests/ui/resolve/fresh-should-shadow-definitation-in-macro-expand-in-block.stderr new file mode 100644 index 0000000000000..ff88c9f124fc5 --- /dev/null +++ b/tests/ui/resolve/fresh-should-shadow-definitation-in-macro-expand-in-block.stderr @@ -0,0 +1,171 @@ +error[E0425]: cannot find value `a` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand-in-block.rs:184:51 + | +LL | let a: BindingF = 42; + | - `a` is defined here +... +LL | macro_rules! m1 { () => { a } } + | ^ not found in this scope +... +LL | crate::m1!(); + | ------------ in this macro invocation + | + = note: this error originates in the macro `crate::m1` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find value `a` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand-in-block.rs:214:39 + | +LL | let a: BindingF = 42; + | - `a` is defined here +... +LL | macro_rules! m2 { () => { a } } + | ^ not found in this scope +... +LL | crate::m2!(); + | ------------ in this macro invocation + | + = note: this error originates in the macro `crate::m2` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find value `a` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand-in-block.rs:231:35 + | +LL | crate::m3!(); + | ------------ in this macro invocation +LL | { +LL | let a: BindingF = 42; + | - `a` is defined here +... +LL | macro_rules! m3 { () => { a } } + | ^ not found in this scope + | + = note: this error originates in the macro `crate::m3` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find value `a` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand-in-block.rs:231:35 + | +LL | let a: BindingF = 42; + | - `a` is defined here +... +LL | macro_rules! m3 { () => { a } } + | ^ not found in this scope +... +LL | crate::m3!(); + | ------------ in this macro invocation + | + = note: this error originates in the macro `crate::m3` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find value `a` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand-in-block.rs:248:43 + | +LL | crate::m4!(); + | ------------ in this macro invocation +... +LL | let a: BindingF = 42; + | - `a` is defined here +... +LL | macro_rules! m4 { () => { a } } + | ^ not found in this scope + | + = note: this error originates in the macro `crate::m4` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find value `a` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand-in-block.rs:248:43 + | +LL | let a: BindingF = 42; + | - `a` is defined here +... +LL | macro_rules! m4 { () => { a } } + | ^ not found in this scope +... +LL | crate::m4!(); + | ------------ in this macro invocation + | + = note: this error originates in the macro `crate::m4` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find value `a` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand-in-block.rs:266:39 + | +LL | crate::m5!(); + | ------------ in this macro invocation +LL | { +LL | let a: BindingF = 42; + | - `a` is defined here +... +LL | macro_rules! m5 { () => { a } } + | ^ not found in this scope + | + = note: this error originates in the macro `crate::m5` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find value `a` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand-in-block.rs:266:39 + | +LL | let a: BindingF = 42; + | - `a` is defined here +... +LL | macro_rules! m5 { () => { a } } + | ^ not found in this scope +... +LL | crate::m5!(); + | ------------ in this macro invocation + | + = note: this error originates in the macro `crate::m5` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand-in-block.rs:36:29 + | +LL | let a0: BindingF = m!(); + | ---- in this macro invocation +LL | } +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +... +LL | macro_rules! m {() => ( f() )} + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand-in-block.rs:62:29 + | +LL | let a0: BindingF = m!(); + | ---- in this macro invocation +LL | } +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +... +LL | macro_rules! m {() => ( f() )} + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand-in-block.rs:85:29 + | +LL | let a0: BindingF = m!(); + | ---- in this macro invocation +... +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +... +LL | macro_rules! m {() => ( f() )} + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand-in-block.rs:85:29 + | +LL | let a1: BindingF = m!(); + | ---- in this macro invocation +LL | } +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +... +LL | macro_rules! m {() => ( f() )} + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/resolve/fresh-should-shadow-definitation-in-macro-expand.rs b/tests/ui/resolve/fresh-should-shadow-definitation-in-macro-expand.rs new file mode 100644 index 0000000000000..4fcf37fd6e4bc --- /dev/null +++ b/tests/ui/resolve/fresh-should-shadow-definitation-in-macro-expand.rs @@ -0,0 +1,236 @@ +//@ edition:2018 + +// issue#95237 + +type FnF = i8; +type BindingF = i16; + +fn f_without_definition_f0() { + // let f -> macro m + let f = || -> BindingF { 42 }; + let a0: BindingF = m!(); + macro_rules! m {() => ( f() )} + use m; + let a1: BindingF = m!(); +} + +fn f_without_definition_f1() { + // macro m -> let f + let a: BindingF = m!(); //~ NOTE in this expansion of m! + macro_rules! m {() => ( f() )} //~ ERROR cannot find function `f` in this scope + //~| NOTE not found in this scope + use m; + let f = || -> BindingF { 42 }; +} + +fn f_without_closure_f0() { + // fn f -> macro f + fn f() -> FnF { 42 } + let a: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; +} + +fn f_without_closure_f1() { + // macro f -> fn f + let a: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; + fn f() -> FnF { 42 } +} + +fn ff0() { + // let f -> macro m -> fn f + + let a0: BindingF = m!(); //~ NOTE in this expansion of m! + let f = || -> BindingF { 42 }; //~ NOTE `f` is defined here + let a1: BindingF = m!(); + macro_rules! m {() => ( f() )} //~ ERROR cannot find function `f` in this scope + //~| NOTE not found in this scope + use m; + let a2: BindingF = m!(); + fn f() -> FnF { 42 } + let a3: BindingF = m!(); +} + +fn ff1() { + // let f -> fn f -> macro m + + let a0: BindingF = m!(); //~ NOTE in this expansion of m! + let f = || -> BindingF { 42 }; //~ NOTE `f` is defined here + let a1: BindingF = m!(); + fn f() -> FnF { 42 } + let a2: BindingF = m!(); + macro_rules! m {() => ( f() )} //~ ERROR cannot find function `f` in this scope + //~| NOTE not found in this scope + use m; + let a3: BindingF = m!(); +} + +fn ff2() { + // fn f -> let f -> macro m + + let a0: BindingF = m!(); //~ NOTE in this expansion of m! + fn f() -> FnF { 42 } + let a1: BindingF = m!(); //~ NOTE in this expansion of m! + let f = || -> BindingF { 42 }; //~ NOTE `f` is defined here + //~| NOTE `f` is defined here + let a2: BindingF = m!(); + macro_rules! m {() => ( f() )} //~ ERROR cannot find function `f` in this scope + //~| ERROR cannot find function `f` in this scope + //~| NOTE not found in this scope + //~| NOTE not found in this scope + use m; + let a3: BindingF = m!(); +} + +fn ff3() { + // fn f -> macro m -> let f + + let a0: FnF = m!(); + fn f() -> FnF { 42 } + let a1: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; + let a2: FnF = m!(); + let f = || -> BindingF { 42 }; + let a3: FnF = m!(); +} + +fn ff4() { + // macro m -> fn f -> let f; + + let a0: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; + let a1: FnF = m!(); + fn f() -> FnF { 42 } + let a2: FnF = m!(); + let f = || -> BindingF { 42 }; + let a3: FnF = m!(); +} + +fn ff5() { + // macro m -> let f -> fn f; + + let a0: FnF = m!(); + macro_rules! m {() => ( f() )} + use m; + let a1: FnF = m!(); + let f = || -> BindingF { 42 }; + let a2: FnF = m!(); + fn f() -> FnF { 42 } + let a3: FnF = m!(); +} + +fn tuple_f() { + // fn f -> let f in tuple -> macro m + + let a0: BindingF = m!(); //~ NOTE in this expansion of m! + fn f() -> FnF { 42 } + let a1: BindingF = m!(); //~ NOTE in this expansion of m! + let (f, _) = (|| -> BindingF { 42 }, ()); //~ NOTE `f` is defined here + //~| NOTE `f` is defined here + let a2: BindingF = m!(); + macro_rules! m {() => ( f() )} //~ ERROR cannot find function `f` in this scope + //~| ERROR cannot find function `f` in this scope + //~| NOTE not found in this scope + //~| NOTE not found in this scope + use m; + let a3: BindingF = m!(); +} + +fn multiple() { + fn f() -> FnF { 42 } + let f = || -> BindingF { 42 }; //~ NOTE `f` is defined here + //~| NOTE `f` is defined here + + let m0_0: BindingF = m0!(); + let m1_0: BindingF = m1!(); + let m2_0: i32 = m2!(); //~ NOTE in this expansion of m2! + + macro_rules! m0 { + () => { f() } + } + macro_rules! m1 { + () => { f() } + } + + let m0_1: BindingF = m0!(); + let m1_1: BindingF = m1!(); + let m2_1: i32 = m2!(); //~ NOTE in this expansion of m2! + + let f = || -> i32 { 42 }; + + let m0_2: BindingF = m0!(); + let m1_2: BindingF = m1!(); + let m2_2: i32 = m2!(); + + macro_rules! m2 { + () => { f() } //~ ERROR cannot find function `f` in this scope + } //~| ERROR cannot find function `f` in this scope + //~| NOTE not found in this scope + //~| NOTE not found in this scope + + let m0_3: BindingF = m0!(); + let m1_3: BindingF = m1!(); + let m2_3: i32 = m2!(); + + use {m0, m1, m2}; +} + +fn f_with_macro_export0() { + let a: BindingF = 42; //~ NOTE `a` is defined here + //~| NOTE `a` is defined here + //~| NOTE `a` is defined here + + #[macro_export] + macro_rules! m4 { () => { a } } //~ ERROR cannot access the local binding `a` + //~| ERROR cannot access the local binding `a` + //~| ERROR cannot access the local binding `a` + //~| ERROR cannot find value `a` in this scope + //~| ERROR cannot find value `a` in this scope + //~| NOTE not found in this scope + //~| NOTE not found in this scope + let b: BindingF = crate::m4!(); +} + +fn f_use_macro_export_1() { + fn a() {} + + crate::m4!(); //~ NOTE in this expansion of crate::m4! + crate::m5!(); //~ NOTE in this expansion of crate::m5! +} + +fn f_use_macro_export_2() { + crate::m4!(); //~ NOTE in this expansion of crate::m4! + //~| NOTE in this expansion of crate::m4! + crate::m5!(); //~ NOTE in this expansion of crate::m5! + //~| NOTE in this expansion of crate::m5! +} + +fn f_use_macro_export_3() { + let a = 42; + crate::m4!(); //~ NOTE in this expansion of crate::m4! + //~| NOTE in this expansion of crate::m4! + crate::m5!(); //~ NOTE in this expansion of crate::m5! + //~| NOTE in this expansion of crate::m5! +} + +fn f_with_macro_export1() { + let a: BindingF = 42; //~ NOTE `a` is defined here + //~| NOTE `a` is defined here + //~| NOTE `a` is defined here + + #[macro_export] + macro_rules! m5 { () => { a } } //~ ERROR cannot access the local binding `a` + //~| ERROR cannot access the local binding `a` + //~| ERROR cannot access the local binding `a` + //~| ERROR cannot find value `a` in this scope + //~| ERROR cannot find value `a` in this scope + //~| NOTE not found in this scope + //~| NOTE not found in this scope + +} + +fn main() {} diff --git a/tests/ui/resolve/fresh-should-shadow-definitation-in-macro-expand.stderr b/tests/ui/resolve/fresh-should-shadow-definitation-in-macro-expand.stderr new file mode 100644 index 0000000000000..2601ef54fde79 --- /dev/null +++ b/tests/ui/resolve/fresh-should-shadow-definitation-in-macro-expand.stderr @@ -0,0 +1,261 @@ +error: cannot access the local binding `a` + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:188:31 + | +LL | macro_rules! m4 { () => { a } } + | ^ +... +LL | crate::m4!(); + | ------------ in this macro invocation + | +note: `a` is defined here + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:183:9 + | +LL | let a: BindingF = 42; + | ^ + = note: this error originates in the macro `crate::m4` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot access the local binding `a` + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:226:31 + | +LL | crate::m5!(); + | ------------ in this macro invocation +... +LL | macro_rules! m5 { () => { a } } + | ^ + | +note: `a` is defined here + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:221:9 + | +LL | let a: BindingF = 42; + | ^ + = note: this error originates in the macro `crate::m5` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot access the local binding `a` + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:188:31 + | +LL | macro_rules! m4 { () => { a } } + | ^ +... +LL | crate::m4!(); + | ------------ in this macro invocation + | +note: `a` is defined here + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:183:9 + | +LL | let a: BindingF = 42; + | ^ + = note: this error originates in the macro `crate::m4` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot access the local binding `a` + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:226:31 + | +LL | crate::m5!(); + | ------------ in this macro invocation +... +LL | macro_rules! m5 { () => { a } } + | ^ + | +note: `a` is defined here + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:221:9 + | +LL | let a: BindingF = 42; + | ^ + = note: this error originates in the macro `crate::m5` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot access the local binding `a` + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:188:31 + | +LL | macro_rules! m4 { () => { a } } + | ^ +... +LL | crate::m4!(); + | ------------ in this macro invocation + | +note: `a` is defined here + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:183:9 + | +LL | let a: BindingF = 42; + | ^ + = note: this error originates in the macro `crate::m4` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot access the local binding `a` + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:226:31 + | +LL | crate::m5!(); + | ------------ in this macro invocation +... +LL | macro_rules! m5 { () => { a } } + | ^ + | +note: `a` is defined here + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:221:9 + | +LL | let a: BindingF = 42; + | ^ + = note: this error originates in the macro `crate::m5` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find value `a` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:188:31 + | +LL | macro_rules! m4 { () => { a } } + | ^ not found in this scope +... +LL | crate::m4!(); + | ------------ in this macro invocation + | + = note: this error originates in the macro `crate::m4` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find value `a` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:226:31 + | +LL | crate::m5!(); + | ------------ in this macro invocation +... +LL | macro_rules! m5 { () => { a } } + | ^ not found in this scope + | + = note: this error originates in the macro `crate::m5` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find value `a` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:188:31 + | +LL | macro_rules! m4 { () => { a } } + | ^ not found in this scope +... +LL | crate::m4!(); + | ------------ in this macro invocation + | + = note: this error originates in the macro `crate::m4` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find value `a` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:226:31 + | +LL | crate::m5!(); + | ------------ in this macro invocation +... +LL | macro_rules! m5 { () => { a } } + | ^ not found in this scope + | + = note: this error originates in the macro `crate::m5` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:20:29 + | +LL | let a: BindingF = m!(); + | ---- in this macro invocation +LL | macro_rules! m {() => ( f() )} + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:48:29 + | +LL | let a0: BindingF = m!(); + | ---- in this macro invocation +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +LL | let a1: BindingF = m!(); +LL | macro_rules! m {() => ( f() )} + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:64:29 + | +LL | let a0: BindingF = m!(); + | ---- in this macro invocation +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +... +LL | macro_rules! m {() => ( f() )} + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:79:29 + | +LL | let a0: BindingF = m!(); + | ---- in this macro invocation +... +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +... +LL | macro_rules! m {() => ( f() )} + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:79:29 + | +LL | let a1: BindingF = m!(); + | ---- in this macro invocation +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +... +LL | macro_rules! m {() => ( f() )} + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:135:29 + | +LL | let a0: BindingF = m!(); + | ---- in this macro invocation +... +LL | let (f, _) = (|| -> BindingF { 42 }, ()); + | - `f` is defined here +... +LL | macro_rules! m {() => ( f() )} + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:135:29 + | +LL | let a1: BindingF = m!(); + | ---- in this macro invocation +LL | let (f, _) = (|| -> BindingF { 42 }, ()); + | - `f` is defined here +... +LL | macro_rules! m {() => ( f() )} + | ^ not found in this scope + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:170:17 + | +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +... +LL | let m2_0: i32 = m2!(); + | ----- in this macro invocation +... +LL | () => { f() } + | ^ not found in this scope + | + = note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0425]: cannot find function `f` in this scope + --> $DIR/fresh-should-shadow-definitation-in-macro-expand.rs:170:17 + | +LL | let f = || -> BindingF { 42 }; + | - `f` is defined here +... +LL | let m2_1: i32 = m2!(); + | ----- in this macro invocation +... +LL | () => { f() } + | ^ not found in this scope + | + = note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 19 previous errors + +For more information about this error, try `rustc --explain E0425`.