about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml1
-rw-r--r--crates/hir-def/Cargo.toml2
-rw-r--r--crates/hir-def/src/item_tree.rs4
-rw-r--r--crates/hir-def/src/item_tree/lower.rs2
-rw-r--r--crates/hir-def/src/lib.rs12
-rw-r--r--crates/hir-def/src/nameres/collector.rs17
-rw-r--r--crates/hir-expand/src/attrs.rs12
-rw-r--r--crates/hir-expand/src/builtin_attr_macro.rs14
-rw-r--r--crates/hir-expand/src/db.rs18
-rw-r--r--crates/hir-expand/src/eager.rs8
-rw-r--r--crates/hir-expand/src/hygiene.rs2
-rw-r--r--crates/hir-expand/src/lib.rs8
-rw-r--r--crates/hir-ty/Cargo.toml2
-rw-r--r--crates/hir/Cargo.toml2
-rw-r--r--crates/ide-db/Cargo.toml2
-rw-r--r--crates/ide/Cargo.toml2
-rw-r--r--crates/mbe/src/benchmark.rs4
-rw-r--r--crates/mbe/src/expander.rs12
-rw-r--r--crates/mbe/src/expander/transcriber.rs50
-rw-r--r--crates/mbe/src/lib.rs3
20 files changed, 90 insertions, 87 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 80ec679db3d..556d159ab7d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -93,6 +93,7 @@ lsp-server = { version = "0.7.4" }
 
 # non-local crates
 anyhow = "1.0.75"
+arrayvec = "0.7.4"
 bitflags = "2.4.1"
 cargo_metadata = "0.18.1"
 command-group = "2.0.1"
diff --git a/crates/hir-def/Cargo.toml b/crates/hir-def/Cargo.toml
index 8348003cdc6..5e8cf0d7e4a 100644
--- a/crates/hir-def/Cargo.toml
+++ b/crates/hir-def/Cargo.toml
@@ -12,7 +12,7 @@ rust-version.workspace = true
 doctest = false
 
 [dependencies]
-arrayvec = "0.7.2"
+arrayvec.workspace = true
 bitflags.workspace = true
 cov-mark = "2.0.0-pre.1"
 dashmap.workspace = true
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs
index 50253e4c8fd..cf087613bf4 100644
--- a/crates/hir-def/src/item_tree.rs
+++ b/crates/hir-def/src/item_tree.rs
@@ -55,7 +55,7 @@ use la_arena::{Arena, Idx, IdxRange, RawIdx};
 use profile::Count;
 use rustc_hash::FxHashMap;
 use smallvec::SmallVec;
-use span::SyntaxContextId;
+use span::Span;
 use stdx::never;
 use syntax::{ast, match_ast, SyntaxKind};
 use triomphe::Arc;
@@ -747,7 +747,7 @@ pub struct MacroCall {
     pub path: Interned<ModPath>,
     pub ast_id: FileAstId<ast::MacroCall>,
     pub expand_to: ExpandTo,
-    pub call_site: SyntaxContextId,
+    pub call_site: Span,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index ed40f299d68..d1043a5bd0b 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -549,7 +549,7 @@ impl<'a> Ctx<'a> {
             path,
             ast_id,
             expand_to,
-            call_site: span_map.span_for_range(m.syntax().text_range()).ctx,
+            call_site: span_map.span_for_range(m.syntax().text_range()),
         };
         Some(id(self.data().macro_calls.alloc(res)))
     }
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index 41a41d6df31..2fbd0bdec0f 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -80,7 +80,7 @@ use hir_expand::{
 use item_tree::ExternBlock;
 use la_arena::Idx;
 use nameres::DefMap;
-use span::SyntaxContextId;
+use span::Span;
 use stdx::impl_from;
 use syntax::{ast, AstNode};
 
@@ -1172,7 +1172,7 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
             return Ok(ExpandResult::only_err(ExpandError::other("malformed macro invocation")));
         };
 
-        let call_site = span_map.span_for_range(self.value.syntax().text_range()).ctx;
+        let call_site = span_map.span_for_range(self.value.syntax().text_range());
 
         macro_call_as_call_id_with_eager(
             db,
@@ -1202,7 +1202,7 @@ impl<T: AstIdNode> AstIdWithPath<T> {
 fn macro_call_as_call_id(
     db: &dyn ExpandDatabase,
     call: &AstIdWithPath<ast::MacroCall>,
-    call_site: SyntaxContextId,
+    call_site: Span,
     expand_to: ExpandTo,
     krate: CrateId,
     resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
@@ -1214,7 +1214,7 @@ fn macro_call_as_call_id(
 fn macro_call_as_call_id_with_eager(
     db: &dyn ExpandDatabase,
     call: &AstIdWithPath<ast::MacroCall>,
-    call_site: SyntaxContextId,
+    call_site: Span,
     expand_to: ExpandTo,
     krate: CrateId,
     resolver: impl FnOnce(path::ModPath) -> Option<MacroDefId>,
@@ -1320,7 +1320,7 @@ fn derive_macro_as_call_id(
     item_attr: &AstIdWithPath<ast::Adt>,
     derive_attr_index: AttrId,
     derive_pos: u32,
-    call_site: SyntaxContextId,
+    call_site: Span,
     krate: CrateId,
     resolver: impl Fn(path::ModPath) -> Option<(MacroId, MacroDefId)>,
 ) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro> {
@@ -1365,7 +1365,7 @@ fn attr_macro_as_call_id(
             attr_args: arg.map(Arc::new),
             invoc_attr_index: macro_attr.id,
         },
-        macro_attr.ctxt,
+        macro_attr.span,
     )
 }
 
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 71071b45128..541edf0845d 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -228,13 +228,13 @@ enum MacroDirectiveKind {
     FnLike {
         ast_id: AstIdWithPath<ast::MacroCall>,
         expand_to: ExpandTo,
-        call_site: SyntaxContextId,
+        call_site: Span,
     },
     Derive {
         ast_id: AstIdWithPath<ast::Adt>,
         derive_attr: AttrId,
         derive_pos: usize,
-        call_site: SyntaxContextId,
+        call_site: Span,
     },
     Attr {
         ast_id: AstIdWithPath<ast::Item>,
@@ -1305,14 +1305,13 @@ impl DefCollector<'_> {
                     // Not resolved to a derive helper or the derive attribute, so try to treat as a normal attribute.
                     let call_id =
                         attr_macro_as_call_id(self.db, file_ast_id, attr, self.def_map.krate, def);
-                    let loc: MacroCallLoc = self.db.lookup_intern_macro_call(call_id);
 
                     // If proc attribute macro expansion is disabled, skip expanding it here
                     if !self.db.expand_proc_attr_macros() {
                         self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
                             directive.module_id,
-                            loc.kind,
-                            loc.def.krate,
+                            self.db.lookup_intern_macro_call(call_id).kind,
+                            def.krate,
                         ));
                         return recollect_without(self);
                     }
@@ -1320,14 +1319,14 @@ impl DefCollector<'_> {
                     // Skip #[test]/#[bench] expansion, which would merely result in more memory usage
                     // due to duplicating functions into macro expansions
                     if matches!(
-                        loc.def.kind,
+                        def.kind,
                         MacroDefKind::BuiltInAttr(expander, _)
                         if expander.is_test() || expander.is_bench()
                     ) {
                         return recollect_without(self);
                     }
 
-                    if let MacroDefKind::ProcMacro(exp, ..) = loc.def.kind {
+                    if let MacroDefKind::ProcMacro(exp, ..) = def.kind {
                         if exp.is_dummy() {
                             // If there's no expander for the proc macro (e.g.
                             // because proc macros are disabled, or building the
@@ -1335,8 +1334,8 @@ impl DefCollector<'_> {
                             // expansion like we would if it was disabled
                             self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
                                 directive.module_id,
-                                loc.kind,
-                                loc.def.krate,
+                                self.db.lookup_intern_macro_call(call_id).kind,
+                                def.krate,
                             ));
 
                             return recollect_without(self);
diff --git a/crates/hir-expand/src/attrs.rs b/crates/hir-expand/src/attrs.rs
index 16a8518bc39..a8d055af585 100644
--- a/crates/hir-expand/src/attrs.rs
+++ b/crates/hir-expand/src/attrs.rs
@@ -7,7 +7,7 @@ use either::Either;
 use intern::Interned;
 use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
 use smallvec::{smallvec, SmallVec};
-use span::SyntaxContextId;
+use span::Span;
 use syntax::{ast, match_ast, AstNode, AstToken, SmolStr, SyntaxNode};
 use triomphe::Arc;
 
@@ -53,7 +53,7 @@ impl RawAttrs {
                 id,
                 input: Some(Interned::new(AttrInput::Literal(SmolStr::new(doc)))),
                 path: Interned::new(ModPath::from(crate::name!(doc))),
-                ctxt: span_map.span_for_range(comment.syntax().text_range()).ctx,
+                span: span_map.span_for_range(comment.syntax().text_range()),
             }),
         });
         let entries: Arc<[Attr]> = Arc::from_iter(entries);
@@ -177,7 +177,7 @@ pub struct Attr {
     pub id: AttrId,
     pub path: Interned<ModPath>,
     pub input: Option<Interned<AttrInput>>,
-    pub ctxt: SyntaxContextId,
+    pub span: Span,
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -218,7 +218,7 @@ impl Attr {
         } else {
             None
         };
-        Some(Attr { id, path, input, ctxt: span_map.span_for_range(ast.syntax().text_range()).ctx })
+        Some(Attr { id, path, input, span: span_map.span_for_range(ast.syntax().text_range()) })
     }
 
     fn from_tt(db: &dyn ExpandDatabase, tt: &tt::Subtree, id: AttrId) -> Option<Attr> {
@@ -266,7 +266,7 @@ impl Attr {
     pub fn parse_path_comma_token_tree<'a>(
         &'a self,
         db: &'a dyn ExpandDatabase,
-    ) -> Option<impl Iterator<Item = (ModPath, SyntaxContextId)> + 'a> {
+    ) -> Option<impl Iterator<Item = (ModPath, Span)> + 'a> {
         let args = self.token_tree_value()?;
 
         if args.delimiter.kind != DelimiterKind::Parenthesis {
@@ -294,7 +294,7 @@ impl Attr {
                     return None;
                 }
                 let path = meta.path()?;
-                let call_site = span_map.span_at(path.syntax().text_range().start()).ctx;
+                let call_site = span_map.span_at(path.syntax().text_range().start());
                 Some((
                     ModPath::from_src(db, path, SpanMapRef::ExpansionSpanMap(&span_map))?,
                     call_site,
diff --git a/crates/hir-expand/src/builtin_attr_macro.rs b/crates/hir-expand/src/builtin_attr_macro.rs
index 33ba6d37d57..9f77700bd0c 100644
--- a/crates/hir-expand/src/builtin_attr_macro.rs
+++ b/crates/hir-expand/src/builtin_attr_macro.rs
@@ -1,6 +1,5 @@
 //! Builtin attributes.
-use span::{FileId, MacroCallId, Span, SyntaxContextId, ROOT_ERASED_FILE_AST_ID};
-use syntax::{TextRange, TextSize};
+use span::{MacroCallId, Span};
 
 use crate::{db::ExpandDatabase, name, tt, ExpandResult, MacroCallKind};
 
@@ -110,20 +109,13 @@ fn derive_attr_expand(
 pub fn pseudo_derive_attr_expansion(
     tt: &tt::Subtree,
     args: &tt::Subtree,
-    call_site: SyntaxContextId,
+    call_site: Span,
 ) -> ExpandResult<tt::Subtree> {
     let mk_leaf = |char| {
         tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
             char,
             spacing: tt::Spacing::Alone,
-            span: Span {
-                range: TextRange::empty(TextSize::new(0)),
-                anchor: span::SpanAnchor {
-                    file_id: FileId::BOGUS,
-                    ast_id: ROOT_ERASED_FILE_AST_ID,
-                },
-                ctx: call_site,
-            },
+            span: call_site,
         }))
     };
 
diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs
index 4585a532ab9..e425a0338ed 100644
--- a/crates/hir-expand/src/db.rs
+++ b/crates/hir-expand/src/db.rs
@@ -10,7 +10,7 @@ use either::Either;
 use limit::Limit;
 use mbe::{syntax_node_to_token_tree, ValueResult};
 use rustc_hash::FxHashSet;
-use span::SyntaxContextId;
+use span::{Span, SyntaxContextId};
 use syntax::{
     ast::{self, HasAttrs},
     AstNode, Parse, SyntaxError, SyntaxNode, SyntaxToken, T,
@@ -57,7 +57,8 @@ impl DeclarativeMacroExpander {
         tt: tt::Subtree,
         call_id: MacroCallId,
     ) -> ExpandResult<tt::Subtree> {
-        let toolchain = &db.crate_graph()[db.lookup_intern_macro_call(call_id).def.krate].toolchain;
+        let loc = db.lookup_intern_macro_call(call_id);
+        let toolchain = &db.crate_graph()[loc.def.krate].toolchain;
         let new_meta_vars = toolchain.as_ref().map_or(false, |version| {
             REQUIREMENT.get_or_init(|| VersionReq::parse(">=1.76").unwrap()).matches(
                 &base_db::Version {
@@ -80,6 +81,7 @@ impl DeclarativeMacroExpander {
                     &tt,
                     |s| s.ctx = apply_mark(db, s.ctx, call_id, self.transparency),
                     new_meta_vars,
+                    loc.call_site,
                 )
                 .map_err(Into::into),
         }
@@ -90,6 +92,7 @@ impl DeclarativeMacroExpander {
         db: &dyn ExpandDatabase,
         tt: tt::Subtree,
         krate: CrateId,
+        call_site: Span,
     ) -> ExpandResult<tt::Subtree> {
         let toolchain = &db.crate_graph()[krate].toolchain;
         let new_meta_vars = toolchain.as_ref().map_or(false, |version| {
@@ -108,7 +111,7 @@ impl DeclarativeMacroExpander {
                 tt::Subtree::empty(tt::DelimSpan::DUMMY),
                 ExpandError::other(format!("invalid macro definition: {e}")),
             ),
-            None => self.mac.expand(&tt, |_| (), new_meta_vars).map_err(Into::into),
+            None => self.mac.expand(&tt, |_| (), new_meta_vars, call_site).map_err(Into::into),
         }
     }
 }
@@ -315,9 +318,12 @@ pub fn expand_speculative(
             let adt = ast::Adt::cast(speculative_args.clone()).unwrap();
             expander.expand(db, actual_macro_call, &adt, span_map)
         }
-        MacroDefKind::Declarative(it) => {
-            db.decl_macro_expander(loc.krate, it).expand_unhygienic(db, tt, loc.def.krate)
-        }
+        MacroDefKind::Declarative(it) => db.decl_macro_expander(loc.krate, it).expand_unhygienic(
+            db,
+            tt,
+            loc.def.krate,
+            loc.call_site,
+        ),
         MacroDefKind::BuiltIn(it, _) => it.expand(db, actual_macro_call, &tt).map_err(Into::into),
         MacroDefKind::BuiltInEager(it, _) => {
             it.expand(db, actual_macro_call, &tt).map_err(Into::into)
diff --git a/crates/hir-expand/src/eager.rs b/crates/hir-expand/src/eager.rs
index 03b664fd951..5208964f9a2 100644
--- a/crates/hir-expand/src/eager.rs
+++ b/crates/hir-expand/src/eager.rs
@@ -19,7 +19,7 @@
 //!
 //! See the full discussion : <https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Eager.20expansion.20of.20built-in.20macros>
 use base_db::CrateId;
-use span::SyntaxContextId;
+use span::Span;
 use syntax::{ted, Parse, SyntaxElement, SyntaxNode, TextSize, WalkEvent};
 use triomphe::Arc;
 
@@ -37,7 +37,7 @@ pub fn expand_eager_macro_input(
     krate: CrateId,
     macro_call: InFile<ast::MacroCall>,
     def: MacroDefId,
-    call_site: SyntaxContextId,
+    call_site: Span,
     resolver: &dyn Fn(ModPath) -> Option<MacroDefId>,
 ) -> ExpandResult<Option<MacroCallId>> {
     let ast_map = db.ast_id_map(macro_call.file_id);
@@ -102,7 +102,7 @@ fn lazy_expand(
     def: &MacroDefId,
     macro_call: InFile<ast::MacroCall>,
     krate: CrateId,
-    call_site: SyntaxContextId,
+    call_site: Span,
 ) -> ExpandResult<(InFile<Parse<SyntaxNode>>, Arc<ExpansionSpanMap>)> {
     let ast_id = db.ast_id_map(macro_call.file_id).ast_id(&macro_call.value);
 
@@ -122,7 +122,7 @@ fn eager_macro_recur(
     mut offset: TextSize,
     curr: InFile<SyntaxNode>,
     krate: CrateId,
-    call_site: SyntaxContextId,
+    call_site: Span,
     macro_resolver: &dyn Fn(ModPath) -> Option<MacroDefId>,
 ) -> ExpandResult<Option<(SyntaxNode, TextSize)>> {
     let original = curr.value.clone_for_update();
diff --git a/crates/hir-expand/src/hygiene.rs b/crates/hir-expand/src/hygiene.rs
index 5ab8581aead..1c84103c7f6 100644
--- a/crates/hir-expand/src/hygiene.rs
+++ b/crates/hir-expand/src/hygiene.rs
@@ -116,7 +116,7 @@ pub(super) fn apply_mark(
         return apply_mark_internal(db, ctxt, Some(call_id), transparency);
     }
 
-    let call_site_ctxt = db.lookup_intern_macro_call(call_id).call_site;
+    let call_site_ctxt = db.lookup_intern_macro_call(call_id).call_site.ctx;
     let mut call_site_ctxt = if transparency == Transparency::SemiTransparent {
         call_site_ctxt.normalize_to_macros_2_0(db)
     } else {
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index 1f91e0e6692..1a5ed30cbe1 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -116,18 +116,20 @@ pub struct MacroCallLoc {
     pub krate: CrateId,
     /// Some if this is a macro call for an eager macro. Note that this is `None`
     /// for the eager input macro file.
+    // FIXME: This seems bad to save in an interned structure
     eager: Option<Arc<EagerCallInfo>>,
     pub kind: MacroCallKind,
-    pub call_site: SyntaxContextId,
+    pub call_site: Span,
 }
 
+// FIXME: Might make sense to intern this? Given it's gonna be the same for a bunch of macro calls
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct MacroDefId {
     pub krate: CrateId,
     pub kind: MacroDefKind,
     pub local_inner: bool,
     pub allow_internal_unsafe: bool,
-    // pub def_site: SyntaxContextId,
+    // pub def_site: Span,
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -348,7 +350,7 @@ impl MacroDefId {
         db: &dyn db::ExpandDatabase,
         krate: CrateId,
         kind: MacroCallKind,
-        call_site: SyntaxContextId,
+        call_site: Span,
     ) -> MacroCallId {
         db.intern_macro_call(MacroCallLoc { def: self, krate, eager: None, kind, call_site })
     }
diff --git a/crates/hir-ty/Cargo.toml b/crates/hir-ty/Cargo.toml
index c498d50af50..45e69c59d71 100644
--- a/crates/hir-ty/Cargo.toml
+++ b/crates/hir-ty/Cargo.toml
@@ -14,7 +14,7 @@ doctest = false
 [dependencies]
 cov-mark = "2.0.0-pre.1"
 itertools.workspace = true
-arrayvec = "0.7.2"
+arrayvec.workspace = true
 bitflags.workspace = true
 smallvec.workspace = true
 ena = "0.14.0"
diff --git a/crates/hir/Cargo.toml b/crates/hir/Cargo.toml
index a234b2d1f64..063365a16bc 100644
--- a/crates/hir/Cargo.toml
+++ b/crates/hir/Cargo.toml
@@ -14,7 +14,7 @@ doctest = false
 [dependencies]
 rustc-hash.workspace = true
 either.workspace = true
-arrayvec = "0.7.2"
+arrayvec.workspace = true
 itertools.workspace = true
 smallvec.workspace = true
 triomphe.workspace = true
diff --git a/crates/ide-db/Cargo.toml b/crates/ide-db/Cargo.toml
index 07309d37da8..a3b1dc5b604 100644
--- a/crates/ide-db/Cargo.toml
+++ b/crates/ide-db/Cargo.toml
@@ -20,7 +20,7 @@ rustc-hash.workspace = true
 once_cell = "1.17.0"
 either.workspace = true
 itertools.workspace = true
-arrayvec = "0.7.2"
+arrayvec.workspace = true
 indexmap.workspace = true
 memchr = "2.6.4"
 triomphe.workspace = true
diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml
index 22850bae888..daff8bdac12 100644
--- a/crates/ide/Cargo.toml
+++ b/crates/ide/Cargo.toml
@@ -14,7 +14,7 @@ doctest = false
 [dependencies]
 cov-mark = "2.0.0-pre.1"
 crossbeam-channel = "0.5.5"
-arrayvec = "0.7.4"
+arrayvec.workspace = true
 either.workspace = true
 itertools.workspace = true
 tracing.workspace = true
diff --git a/crates/mbe/src/benchmark.rs b/crates/mbe/src/benchmark.rs
index 22e962a8147..f654e7ea7d7 100644
--- a/crates/mbe/src/benchmark.rs
+++ b/crates/mbe/src/benchmark.rs
@@ -41,7 +41,7 @@ fn benchmark_expand_macro_rules() {
         invocations
             .into_iter()
             .map(|(id, tt)| {
-                let res = rules[&id].expand(&tt, |_| (), true);
+                let res = rules[&id].expand(&tt, |_| (), true, DUMMY);
                 assert!(res.err.is_none());
                 res.value.token_trees.len()
             })
@@ -108,7 +108,7 @@ fn invocation_fixtures(
                     for op in rule.lhs.iter() {
                         collect_from_op(op, &mut subtree, &mut seed);
                     }
-                    if it.expand(&subtree, |_| (), true).err.is_none() {
+                    if it.expand(&subtree, |_| (), true, DUMMY).err.is_none() {
                         res.push((name.clone(), subtree));
                         break;
                     }
diff --git a/crates/mbe/src/expander.rs b/crates/mbe/src/expander.rs
index 11c0ac25828..52c1ec43c4c 100644
--- a/crates/mbe/src/expander.rs
+++ b/crates/mbe/src/expander.rs
@@ -17,6 +17,7 @@ pub(crate) fn expand_rules<S: Span>(
     marker: impl Fn(&mut S) + Copy,
     is_2021: bool,
     new_meta_vars: bool,
+    call_site: S,
 ) -> ExpandResult<tt::Subtree<S>> {
     let mut match_: Option<(matcher::Match<S>, &crate::Rule<S>)> = None;
     for rule in rules {
@@ -26,8 +27,13 @@ pub(crate) fn expand_rules<S: Span>(
             // If we find a rule that applies without errors, we're done.
             // Unconditionally returning the transcription here makes the
             // `test_repeat_bad_var` test fail.
-            let ExpandResult { value, err: transcribe_err } =
-                transcriber::transcribe(&rule.rhs, &new_match.bindings, marker, new_meta_vars);
+            let ExpandResult { value, err: transcribe_err } = transcriber::transcribe(
+                &rule.rhs,
+                &new_match.bindings,
+                marker,
+                new_meta_vars,
+                call_site,
+            );
             if transcribe_err.is_none() {
                 return ExpandResult::ok(value);
             }
@@ -46,7 +52,7 @@ pub(crate) fn expand_rules<S: Span>(
     if let Some((match_, rule)) = match_ {
         // if we got here, there was no match without errors
         let ExpandResult { value, err: transcribe_err } =
-            transcriber::transcribe(&rule.rhs, &match_.bindings, marker, new_meta_vars);
+            transcriber::transcribe(&rule.rhs, &match_.bindings, marker, new_meta_vars, call_site);
         ExpandResult { value, err: match_.err.or(transcribe_err) }
     } else {
         ExpandResult::new(
diff --git a/crates/mbe/src/expander/transcriber.rs b/crates/mbe/src/expander/transcriber.rs
index d1bcf3dbccc..0c15b68591b 100644
--- a/crates/mbe/src/expander/transcriber.rs
+++ b/crates/mbe/src/expander/transcriber.rs
@@ -132,8 +132,9 @@ pub(super) fn transcribe<S: Span>(
     bindings: &Bindings<S>,
     marker: impl Fn(&mut S) + Copy,
     new_meta_vars: bool,
+    call_site: S,
 ) -> ExpandResult<tt::Subtree<S>> {
-    let mut ctx = ExpandCtx { bindings, nesting: Vec::new(), new_meta_vars };
+    let mut ctx = ExpandCtx { bindings, nesting: Vec::new(), new_meta_vars, call_site };
     let mut arena: Vec<tt::TokenTree<S>> = Vec::new();
     expand_subtree(&mut ctx, template, None, &mut arena, marker)
 }
@@ -154,6 +155,7 @@ struct ExpandCtx<'a, S> {
     bindings: &'a Bindings<S>,
     nesting: Vec<NestingState>,
     new_meta_vars: bool,
+    call_site: S,
 }
 
 fn expand_subtree<S: Span>(
@@ -208,13 +210,13 @@ fn expand_subtree<S: Span>(
             Op::Var { name, id, .. } => {
                 let ExpandResult { value: fragment, err: e } = expand_var(ctx, name, *id, marker);
                 err = err.or(e);
-                push_fragment(arena, fragment);
+                push_fragment(ctx, arena, fragment);
             }
             Op::Repeat { tokens: subtree, kind, separator } => {
                 let ExpandResult { value: fragment, err: e } =
                     expand_repeat(ctx, subtree, *kind, separator, arena, marker);
                 err = err.or(e);
-                push_fragment(arena, fragment)
+                push_fragment(ctx, arena, fragment)
             }
             Op::Ignore { name, id } => {
                 // Expand the variable, but ignore the result. This registers the repetition count.
@@ -227,9 +229,7 @@ fn expand_subtree<S: Span>(
                 arena.push(
                     tt::Leaf::Literal(tt::Literal {
                         text: index.to_string().into(),
-                        // FIXME
-                        #[allow(deprecated)]
-                        span: S::DUMMY,
+                        span: ctx.call_site,
                     })
                     .into(),
                 );
@@ -242,9 +242,7 @@ fn expand_subtree<S: Span>(
                 arena.push(
                     tt::Leaf::Literal(tt::Literal {
                         text: length.to_string().into(),
-                        // FIXME
-                        #[allow(deprecated)]
-                        span: S::DUMMY,
+                        span: ctx.call_site,
                     })
                     .into(),
                 );
@@ -309,9 +307,7 @@ fn expand_subtree<S: Span>(
                 arena.push(
                     tt::Leaf::Literal(tt::Literal {
                         text: c.to_string().into(),
-                        // FIXME
-                        #[allow(deprecated)]
-                        span: S::DUMMY,
+                        span: ctx.call_site,
                     })
                     .into(),
                 );
@@ -367,12 +363,8 @@ fn expand_var<S: Span>(
         }
         Err(e) => ExpandResult {
             value: Fragment::Tokens(tt::TokenTree::Subtree(tt::Subtree::empty(tt::DelimSpan {
-                // FIXME
-                #[allow(deprecated)]
-                open: S::DUMMY,
-                // FIXME
-                #[allow(deprecated)]
-                close: S::DUMMY,
+                open: ctx.call_site,
+                close: ctx.call_site,
             }))),
             err: Some(e),
         },
@@ -475,13 +467,17 @@ fn expand_repeat<S: Span>(
     ExpandResult { value: Fragment::Tokens(tt), err }
 }
 
-fn push_fragment<S: Span>(buf: &mut Vec<tt::TokenTree<S>>, fragment: Fragment<S>) {
+fn push_fragment<S: Span>(
+    ctx: &ExpandCtx<'_, S>,
+    buf: &mut Vec<tt::TokenTree<S>>,
+    fragment: Fragment<S>,
+) {
     match fragment {
         Fragment::Tokens(tt::TokenTree::Subtree(tt)) => push_subtree(buf, tt),
         Fragment::Expr(sub) => {
             push_subtree(buf, sub);
         }
-        Fragment::Path(tt) => fix_up_and_push_path_tt(buf, tt),
+        Fragment::Path(tt) => fix_up_and_push_path_tt(ctx, buf, tt),
         Fragment::Tokens(tt) => buf.push(tt),
     }
 }
@@ -496,7 +492,11 @@ fn push_subtree<S>(buf: &mut Vec<tt::TokenTree<S>>, tt: tt::Subtree<S>) {
 /// Inserts the path separator `::` between an identifier and its following generic
 /// argument list, and then pushes into the buffer. See [`Fragment::Path`] for why
 /// we need this fixup.
-fn fix_up_and_push_path_tt<S: Span>(buf: &mut Vec<tt::TokenTree<S>>, subtree: tt::Subtree<S>) {
+fn fix_up_and_push_path_tt<S: Span>(
+    ctx: &ExpandCtx<'_, S>,
+    buf: &mut Vec<tt::TokenTree<S>>,
+    subtree: tt::Subtree<S>,
+) {
     stdx::always!(matches!(subtree.delimiter.kind, tt::DelimiterKind::Invisible));
     let mut prev_was_ident = false;
     // Note that we only need to fix up the top-level `TokenTree`s because the
@@ -513,9 +513,7 @@ fn fix_up_and_push_path_tt<S: Span>(buf: &mut Vec<tt::TokenTree<S>>, subtree: tt
                     tt::Leaf::Punct(tt::Punct {
                         char: ':',
                         spacing: tt::Spacing::Joint,
-                        // FIXME
-                        #[allow(deprecated)]
-                        span: S::DUMMY,
+                        span: ctx.call_site,
                     })
                     .into(),
                 );
@@ -523,9 +521,7 @@ fn fix_up_and_push_path_tt<S: Span>(buf: &mut Vec<tt::TokenTree<S>>, subtree: tt
                     tt::Leaf::Punct(tt::Punct {
                         char: ':',
                         spacing: tt::Spacing::Alone,
-                        // FIXME
-                        #[allow(deprecated)]
-                        span: S::DUMMY,
+                        span: ctx.call_site,
                     })
                     .into(),
                 );
diff --git a/crates/mbe/src/lib.rs b/crates/mbe/src/lib.rs
index d0b0da9724b..2622d7eac10 100644
--- a/crates/mbe/src/lib.rs
+++ b/crates/mbe/src/lib.rs
@@ -252,8 +252,9 @@ impl<S: Span> DeclarativeMacro<S> {
         tt: &tt::Subtree<S>,
         marker: impl Fn(&mut S) + Copy,
         new_meta_vars: bool,
+        call_site: S,
     ) -> ExpandResult<tt::Subtree<S>> {
-        expander::expand_rules(&self.rules, &tt, marker, self.is_2021, new_meta_vars)
+        expander::expand_rules(&self.rules, &tt, marker, self.is_2021, new_meta_vars, call_site)
     }
 }