Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit c04c0dd

Browse files
committed
fix: Don't force draw a dependency edge to the real_span_map query
1 parent bd0ffb0 commit c04c0dd

File tree

16 files changed

+125
-114
lines changed

16 files changed

+125
-114
lines changed

crates/hir-def/src/data/adt.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ pub(crate) fn lower_struct(
400400
item_tree: &ItemTree,
401401
fields: &Fields,
402402
) -> StructKind {
403-
let ctx = LowerCtx::with_file_id(db, ast.file_id);
403+
let ctx = LowerCtx::new(db, ast.file_id);
404404

405405
match (&ast.value, fields) {
406406
(ast::StructKind::Tuple(fl), Fields::Tuple(fields)) => {
@@ -415,7 +415,9 @@ pub(crate) fn lower_struct(
415415
|| FieldData {
416416
name: Name::new_tuple_field(i),
417417
type_ref: Interned::new(TypeRef::from_ast_opt(&ctx, fd.ty())),
418-
visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())),
418+
visibility: RawVisibility::from_ast(db, fd.visibility(), &mut |range| {
419+
ctx.span_map().span_for_range(range).ctx
420+
}),
419421
},
420422
);
421423
}
@@ -433,7 +435,9 @@ pub(crate) fn lower_struct(
433435
|| FieldData {
434436
name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing),
435437
type_ref: Interned::new(TypeRef::from_ast_opt(&ctx, fd.ty())),
436-
visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())),
438+
visibility: RawVisibility::from_ast(db, fd.visibility(), &mut |range| {
439+
ctx.span_map().span_for_range(range).ctx
440+
}),
437441
},
438442
);
439443
}

crates/hir-def/src/expander.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Macro expansion utilities.
22
3+
use std::cell::OnceCell;
4+
35
use base_db::CrateId;
46
use cfg::CfgOptions;
57
use drop_bomb::DropBomb;
@@ -18,7 +20,7 @@ use crate::{
1820
#[derive(Debug)]
1921
pub struct Expander {
2022
cfg_options: CfgOptions,
21-
span_map: SpanMap,
23+
span_map: OnceCell<SpanMap>,
2224
krate: CrateId,
2325
current_file_id: HirFileId,
2426
pub(crate) module: ModuleId,
@@ -42,7 +44,7 @@ impl Expander {
4244
recursion_depth: 0,
4345
recursion_limit,
4446
cfg_options: db.crate_graph()[module.krate].cfg_options.clone(),
45-
span_map: db.span_map(current_file_id),
47+
span_map: OnceCell::new(),
4648
krate: module.krate,
4749
}
4850
}
@@ -100,15 +102,23 @@ impl Expander {
100102
}
101103

102104
pub fn ctx<'a>(&self, db: &'a dyn DefDatabase) -> LowerCtx<'a> {
103-
LowerCtx::new(db, self.span_map.clone(), self.current_file_id)
105+
LowerCtx::with_span_map_cell(db, self.current_file_id, self.span_map.clone())
104106
}
105107

106108
pub(crate) fn in_file<T>(&self, value: T) -> InFile<T> {
107109
InFile { file_id: self.current_file_id, value }
108110
}
109111

110112
pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::HasAttrs) -> Attrs {
111-
Attrs::filter(db, self.krate, RawAttrs::new(db.upcast(), owner, self.span_map.as_ref()))
113+
Attrs::filter(
114+
db,
115+
self.krate,
116+
RawAttrs::new(
117+
db.upcast(),
118+
owner,
119+
self.span_map.get_or_init(|| db.span_map(self.current_file_id)).as_ref(),
120+
),
121+
)
112122
}
113123

114124
pub(crate) fn cfg_options(&self) -> &CfgOptions {
@@ -120,7 +130,7 @@ impl Expander {
120130
}
121131

122132
pub(crate) fn parse_path(&mut self, db: &dyn DefDatabase, path: ast::Path) -> Option<Path> {
123-
let ctx = LowerCtx::new(db, self.span_map.clone(), self.current_file_id);
133+
let ctx = LowerCtx::with_span_map_cell(db, self.current_file_id, self.span_map.clone());
124134
Path::from_src(&ctx, path)
125135
}
126136

@@ -165,10 +175,11 @@ impl Expander {
165175
let parse = res.value.0.cast::<T>()?;
166176

167177
self.recursion_depth += 1;
168-
let old_span_map = std::mem::replace(
169-
&mut self.span_map,
170-
SpanMap::ExpansionSpanMap(res.value.1),
171-
);
178+
let old_span_map = OnceCell::new();
179+
if let Some(prev) = self.span_map.take() {
180+
_ = old_span_map.set(prev);
181+
};
182+
_ = self.span_map.set(SpanMap::ExpansionSpanMap(res.value.1));
172183
let old_file_id =
173184
std::mem::replace(&mut self.current_file_id, macro_file.into());
174185
let mark = Mark {
@@ -187,6 +198,6 @@ impl Expander {
187198
#[derive(Debug)]
188199
pub struct Mark {
189200
file_id: HirFileId,
190-
span_map: SpanMap,
201+
span_map: OnceCell<SpanMap>,
191202
bomb: DropBomb,
192203
}

crates/hir-def/src/find_path.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,10 @@ mod tests {
611611
let parsed_path_file = syntax::SourceFile::parse(&format!("use {path};"));
612612
let ast_path =
613613
parsed_path_file.syntax_node().descendants().find_map(syntax::ast::Path::cast).unwrap();
614-
let mod_path =
615-
ModPath::from_src(&db, ast_path, db.span_map(pos.file_id.into()).as_ref()).unwrap();
614+
let mod_path = ModPath::from_src(&db, ast_path, &mut |range| {
615+
db.span_map(pos.file_id.into()).as_ref().span_for_range(range).ctx
616+
})
617+
.unwrap();
616618

617619
let def_map = module.def_map(&db);
618620
let resolved = def_map

crates/hir-def/src/hir/type_ref.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ impl TypeRef {
251251
TypeRef::DynTrait(type_bounds_from_ast(ctx, inner.type_bound_list()))
252252
}
253253
ast::Type::MacroType(mt) => match mt.macro_call() {
254-
Some(mc) => ctx.ast_id(&mc).map(TypeRef::Macro).unwrap_or(TypeRef::Error),
254+
Some(mc) => TypeRef::Macro(ctx.ast_id(&mc)),
255255
None => TypeRef::Error,
256256
},
257257
}
@@ -398,9 +398,8 @@ pub enum ConstRef {
398398
impl ConstRef {
399399
pub(crate) fn from_const_arg(lower_ctx: &LowerCtx<'_>, arg: Option<ast::ConstArg>) -> Self {
400400
if let Some(arg) = arg {
401-
let ast_id = lower_ctx.ast_id(&arg);
402401
if let Some(expr) = arg.expr() {
403-
return Self::from_expr(expr, ast_id);
402+
return Self::from_expr(expr, Some(lower_ctx.ast_id(&arg)));
404403
}
405404
}
406405
Self::Scalar(LiteralConstRef::Unknown)

crates/hir-def/src/item_tree.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@
2929
//!
3030
//! In general, any item in the `ItemTree` stores its `AstId`, which allows mapping it back to its
3131
//! surface syntax.
32-
//!
33-
//! Note that we cannot store [`span::Span`]s inside of this, as typing in an item invalidates its
34-
//! encompassing span!
3532
3633
mod lower;
3734
mod pretty;
@@ -824,11 +821,13 @@ impl Use {
824821
// Note: The AST unwraps are fine, since if they fail we should have never obtained `index`.
825822
let ast = InFile::new(file_id, self.ast_id).to_node(db.upcast());
826823
let ast_use_tree = ast.use_tree().expect("missing `use_tree`");
827-
let span_map = db.span_map(file_id);
828-
let (_, source_map) = lower::lower_use_tree(db, span_map.as_ref(), ast_use_tree)
829-
.expect("failed to lower use tree");
824+
let (_, source_map) = lower::lower_use_tree(db, ast_use_tree, &mut |range| {
825+
db.span_map(file_id).span_for_range(range).ctx
826+
})
827+
.expect("failed to lower use tree");
830828
source_map[index].clone()
831829
}
830+
832831
/// Maps a `UseTree` contained in this import back to its AST node.
833832
pub fn use_tree_source_map(
834833
&self,
@@ -839,10 +838,11 @@ impl Use {
839838
// Note: The AST unwraps are fine, since if they fail we should have never obtained `index`.
840839
let ast = InFile::new(file_id, self.ast_id).to_node(db.upcast());
841840
let ast_use_tree = ast.use_tree().expect("missing `use_tree`");
842-
let span_map = db.span_map(file_id);
843-
lower::lower_use_tree(db, span_map.as_ref(), ast_use_tree)
844-
.expect("failed to lower use tree")
845-
.1
841+
lower::lower_use_tree(db, ast_use_tree, &mut |range| {
842+
db.span_map(file_id).span_for_range(range).ctx
843+
})
844+
.expect("failed to lower use tree")
845+
.1
846846
}
847847
}
848848

crates/hir-def/src/item_tree/lower.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::collections::hash_map::Entry;
44

55
use hir_expand::{mod_path::path, name, name::AsName, span_map::SpanMapRef, HirFileId};
66
use la_arena::Arena;
7-
use span::AstIdMap;
7+
use span::{AstIdMap, SyntaxContextId};
88
use syntax::{
99
ast::{self, HasModuleItem, HasName, HasTypeBounds, IsString},
1010
AstNode,
@@ -45,7 +45,7 @@ impl<'a> Ctx<'a> {
4545
db,
4646
tree: ItemTree::default(),
4747
source_ast_id_map: db.ast_id_map(file),
48-
body_ctx: crate::lower::LowerCtx::with_file_id(db, file),
48+
body_ctx: crate::lower::LowerCtx::new(db, file),
4949
}
5050
}
5151

@@ -535,7 +535,9 @@ impl<'a> Ctx<'a> {
535535
fn lower_use(&mut self, use_item: &ast::Use) -> Option<FileItemTreeId<Use>> {
536536
let visibility = self.lower_visibility(use_item);
537537
let ast_id = self.source_ast_id_map.ast_id(use_item);
538-
let (use_tree, _) = lower_use_tree(self.db, self.span_map(), use_item.use_tree()?)?;
538+
let (use_tree, _) = lower_use_tree(self.db, use_item.use_tree()?, &mut |range| {
539+
self.span_map().span_for_range(range).ctx
540+
})?;
539541

540542
let res = Use { visibility, ast_id, use_tree };
541543
Some(id(self.data().uses.alloc(res)))
@@ -558,7 +560,9 @@ impl<'a> Ctx<'a> {
558560

559561
fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> {
560562
let span_map = self.span_map();
561-
let path = Interned::new(ModPath::from_src(self.db.upcast(), m.path()?, span_map)?);
563+
let path = Interned::new(ModPath::from_src(self.db.upcast(), m.path()?, &mut |range| {
564+
span_map.span_for_range(range).ctx
565+
})?);
562566
let ast_id = self.source_ast_id_map.ast_id(m);
563567
let expand_to = hir_expand::ExpandTo::from_call_site(m);
564568
let res = MacroCall {
@@ -672,8 +676,9 @@ impl<'a> Ctx<'a> {
672676
}
673677

674678
fn lower_visibility(&mut self, item: &dyn ast::HasVisibility) -> RawVisibilityId {
675-
let vis =
676-
RawVisibility::from_opt_ast_with_span_map(self.db, item.visibility(), self.span_map());
679+
let vis = RawVisibility::from_ast(self.db, item.visibility(), &mut |range| {
680+
self.span_map().span_for_range(range).ctx
681+
});
677682
self.data().vis.alloc(vis)
678683
}
679684

@@ -745,28 +750,33 @@ fn lower_abi(abi: ast::Abi) -> Interned<str> {
745750

746751
struct UseTreeLowering<'a> {
747752
db: &'a dyn DefDatabase,
748-
span_map: SpanMapRef<'a>,
749753
mapping: Arena<ast::UseTree>,
750754
}
751755

752756
impl UseTreeLowering<'_> {
753-
fn lower_use_tree(&mut self, tree: ast::UseTree) -> Option<UseTree> {
757+
fn lower_use_tree(
758+
&mut self,
759+
tree: ast::UseTree,
760+
span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContextId,
761+
) -> Option<UseTree> {
754762
if let Some(use_tree_list) = tree.use_tree_list() {
755763
let prefix = match tree.path() {
756764
// E.g. use something::{{{inner}}};
757765
None => None,
758766
// E.g. `use something::{inner}` (prefix is `None`, path is `something`)
759767
// or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`)
760768
Some(path) => {
761-
match ModPath::from_src(self.db.upcast(), path, self.span_map) {
769+
match ModPath::from_src(self.db.upcast(), path, span_for_range) {
762770
Some(it) => Some(it),
763771
None => return None, // FIXME: report errors somewhere
764772
}
765773
}
766774
};
767775

768-
let list =
769-
use_tree_list.use_trees().filter_map(|tree| self.lower_use_tree(tree)).collect();
776+
let list = use_tree_list
777+
.use_trees()
778+
.filter_map(|tree| self.lower_use_tree(tree, span_for_range))
779+
.collect();
770780

771781
Some(
772782
self.use_tree(
@@ -777,7 +787,7 @@ impl UseTreeLowering<'_> {
777787
} else {
778788
let is_glob = tree.star_token().is_some();
779789
let path = match tree.path() {
780-
Some(path) => Some(ModPath::from_src(self.db.upcast(), path, self.span_map)?),
790+
Some(path) => Some(ModPath::from_src(self.db.upcast(), path, span_for_range)?),
781791
None => None,
782792
};
783793
let alias = tree.rename().map(|a| {
@@ -813,10 +823,10 @@ impl UseTreeLowering<'_> {
813823

814824
pub(crate) fn lower_use_tree(
815825
db: &dyn DefDatabase,
816-
span_map: SpanMapRef<'_>,
817826
tree: ast::UseTree,
827+
span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContextId,
818828
) -> Option<(UseTree, Arena<ast::UseTree>)> {
819-
let mut lowering = UseTreeLowering { db, span_map, mapping: Arena::new() };
820-
let tree = lowering.lower_use_tree(tree)?;
829+
let mut lowering = UseTreeLowering { db, mapping: Arena::new() };
830+
let tree = lowering.lower_use_tree(tree, span_for_range)?;
821831
Some((tree, lowering.mapping))
822832
}

crates/hir-def/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,8 +1341,11 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
13411341
let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
13421342
let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
13431343
let span_map = db.span_map(self.file_id);
1344-
let path =
1345-
self.value.path().and_then(|path| path::ModPath::from_src(db, path, span_map.as_ref()));
1344+
let path = self.value.path().and_then(|path| {
1345+
path::ModPath::from_src(db, path, &mut |range| {
1346+
span_map.as_ref().span_for_range(range).ctx
1347+
})
1348+
});
13461349

13471350
let Some(path) = path else {
13481351
return Ok(ExpandResult::only_err(ExpandError::other("malformed macro invocation")));

crates/hir-def/src/lower.rs

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,36 @@ use crate::{db::DefDatabase, path::Path};
1313

1414
pub struct LowerCtx<'a> {
1515
pub db: &'a dyn DefDatabase,
16-
span_map: SpanMap,
17-
// FIXME: This optimization is probably pointless, ast id map should pretty much always exist anyways.
18-
ast_id_map: Option<(HirFileId, OnceCell<Arc<AstIdMap>>)>,
16+
file_id: HirFileId,
17+
span_map: OnceCell<SpanMap>,
18+
ast_id_map: OnceCell<Arc<AstIdMap>>,
1919
}
2020

2121
impl<'a> LowerCtx<'a> {
22-
pub fn new(db: &'a dyn DefDatabase, span_map: SpanMap, file_id: HirFileId) -> Self {
23-
LowerCtx { db, span_map, ast_id_map: Some((file_id, OnceCell::new())) }
22+
pub fn new(db: &'a dyn DefDatabase, file_id: HirFileId) -> Self {
23+
LowerCtx { db, file_id, span_map: OnceCell::new(), ast_id_map: OnceCell::new() }
2424
}
2525

26-
pub fn with_file_id(db: &'a dyn DefDatabase, file_id: HirFileId) -> Self {
27-
LowerCtx {
28-
db,
29-
span_map: db.span_map(file_id),
30-
ast_id_map: Some((file_id, OnceCell::new())),
31-
}
32-
}
33-
34-
pub fn with_span_map(db: &'a dyn DefDatabase, span_map: SpanMap) -> Self {
35-
LowerCtx { db, span_map, ast_id_map: None }
26+
pub fn with_span_map_cell(
27+
db: &'a dyn DefDatabase,
28+
file_id: HirFileId,
29+
span_map: OnceCell<SpanMap>,
30+
) -> Self {
31+
LowerCtx { db, file_id, span_map, ast_id_map: OnceCell::new() }
3632
}
3733

3834
pub(crate) fn span_map(&self) -> SpanMapRef<'_> {
39-
self.span_map.as_ref()
35+
self.span_map.get_or_init(|| self.db.span_map(self.file_id)).as_ref()
4036
}
4137

4238
pub(crate) fn lower_path(&self, ast: ast::Path) -> Option<Path> {
4339
Path::from_src(self, ast)
4440
}
4541

46-
pub(crate) fn ast_id<N: AstIdNode>(&self, item: &N) -> Option<AstId<N>> {
47-
let &(file_id, ref ast_id_map) = self.ast_id_map.as_ref()?;
48-
let ast_id_map = ast_id_map.get_or_init(|| self.db.ast_id_map(file_id));
49-
Some(InFile::new(file_id, ast_id_map.ast_id(item)))
42+
pub(crate) fn ast_id<N: AstIdNode>(&self, item: &N) -> AstId<N> {
43+
InFile::new(
44+
self.file_id,
45+
self.ast_id_map.get_or_init(|| self.db.ast_id_map(self.file_id)).ast_id(item),
46+
)
5047
}
5148
}

0 commit comments

Comments
 (0)