Skip to content

Commit 6fccb15

Browse files
bors[bot]jonas-schievinkmatklad
authored
Merge #8746
8746: Don't store call-site text offsets in hygiene info r=matklad a=jonas-schievink This threads a lot more database references around in order to avoid storing a bare `TextOffset` in the hygiene info. This `TextOffset` made hygiene info and `ItemTree`s more volatile than they should be, leading to excessive recomputation of `ItemTree`s. The incremental test added in #8721 is now passing with these changes. closes #8721 Co-authored-by: Jonas Schievink <[email protected]> Co-authored-by: Aleksey Kladov <[email protected]>
2 parents b37b709 + 20ae41c commit 6fccb15

File tree

19 files changed

+180
-81
lines changed

19 files changed

+180
-81
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ debug = 0 # Set this to 1 or 2 to get more useful backtraces in debugger.
2727
# chalk-recursive = { path = "../chalk/chalk-recursive" }
2828

2929
# ungrammar = { path = "../ungrammar" }
30+
31+
# salsa = { path = "../salsa" }

crates/hir/src/attrs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ fn resolve_doc_path(
112112
AttrDefId::MacroDefId(_) => return None,
113113
};
114114
let path = ast::Path::parse(link).ok()?;
115-
let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap();
115+
let modpath = ModPath::from_src(db.upcast(), path, &Hygiene::new_unhygienic()).unwrap();
116116
let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
117117
if resolved == PerNs::none() {
118118
if let Some(trait_id) = resolver.resolve_module_path_in_trait_items(db.upcast(), &modpath) {

crates/hir/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1666,7 +1666,7 @@ impl Impl {
16661666
.value
16671667
.attrs()
16681668
.filter_map(|it| {
1669-
let path = ModPath::from_src(it.path()?, &hygenic)?;
1669+
let path = ModPath::from_src(db.upcast(), it.path()?, &hygenic)?;
16701670
if path.as_ident()?.to_string() == "derive" {
16711671
Some(it)
16721672
} else {

crates/hir/src/source_analyzer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ impl SourceAnalyzer {
283283

284284
// This must be a normal source file rather than macro file.
285285
let hygiene = Hygiene::new(db.upcast(), self.file_id);
286-
let ctx = body::LowerCtx::with_hygiene(&hygiene);
286+
let ctx = body::LowerCtx::with_hygiene(db.upcast(), &hygiene);
287287
let hir_path = Path::from_src(path.clone(), &ctx)?;
288288

289289
// Case where path is a qualifier of another path, e.g. foo::bar::Baz where we

crates/hir_def/src/attr.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,17 @@ impl ops::Deref for AttrsWithOwner {
9595
impl RawAttrs {
9696
pub(crate) const EMPTY: Self = Self { entries: None };
9797

98-
pub(crate) fn new(owner: &dyn ast::AttrsOwner, hygiene: &Hygiene) -> Self {
98+
pub(crate) fn new(
99+
db: &dyn DefDatabase,
100+
owner: &dyn ast::AttrsOwner,
101+
hygiene: &Hygiene,
102+
) -> Self {
99103
let entries = collect_attrs(owner)
100104
.enumerate()
101105
.flat_map(|(i, attr)| {
102106
let index = AttrId(i as u32);
103107
match attr {
104-
Either::Left(attr) => Attr::from_src(attr, hygiene, index),
108+
Either::Left(attr) => Attr::from_src(db, attr, hygiene, index),
105109
Either::Right(comment) => comment.doc_comment().map(|doc| Attr {
106110
id: index,
107111
input: Some(AttrInput::Literal(SmolStr::new(doc))),
@@ -116,7 +120,7 @@ impl RawAttrs {
116120

117121
fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn ast::AttrsOwner>) -> Self {
118122
let hygiene = Hygiene::new(db.upcast(), owner.file_id);
119-
Self::new(owner.value, &hygiene)
123+
Self::new(db, owner.value, &hygiene)
120124
}
121125

122126
pub(crate) fn merge(&self, other: Self) -> Self {
@@ -170,7 +174,7 @@ impl RawAttrs {
170174
let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?;
171175
// FIXME hygiene
172176
let hygiene = Hygiene::new_unhygienic();
173-
Attr::from_src(attr, &hygiene, index)
177+
Attr::from_src(db, attr, &hygiene, index)
174178
});
175179

176180
let cfg_options = &crate_graph[krate].cfg_options;
@@ -627,8 +631,13 @@ pub enum AttrInput {
627631
}
628632

629633
impl Attr {
630-
fn from_src(ast: ast::Attr, hygiene: &Hygiene, id: AttrId) -> Option<Attr> {
631-
let path = Interned::new(ModPath::from_src(ast.path()?, hygiene)?);
634+
fn from_src(
635+
db: &dyn DefDatabase,
636+
ast: ast::Attr,
637+
hygiene: &Hygiene,
638+
id: AttrId,
639+
) -> Option<Attr> {
640+
let path = Interned::new(ModPath::from_src(db, ast.path()?, hygiene)?);
632641
let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() {
633642
let value = match lit.kind() {
634643
ast::LiteralKind::String(string) => string.value()?.into(),

crates/hir_def/src/body.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl CfgExpander {
7272
}
7373

7474
pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> Attrs {
75-
RawAttrs::new(owner, &self.hygiene).filter(db, self.krate)
75+
RawAttrs::new(db, owner, &self.hygiene).filter(db, self.krate)
7676
}
7777

7878
pub(crate) fn is_cfg_enabled(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> bool {
@@ -192,8 +192,8 @@ impl Expander {
192192
self.current_file_id
193193
}
194194

195-
fn parse_path(&mut self, path: ast::Path) -> Option<Path> {
196-
let ctx = LowerCtx::with_hygiene(&self.cfg_expander.hygiene);
195+
fn parse_path(&mut self, db: &dyn DefDatabase, path: ast::Path) -> Option<Path> {
196+
let ctx = LowerCtx::with_hygiene(db, &self.cfg_expander.hygiene);
197197
Path::from_src(path, &ctx)
198198
}
199199

crates/hir_def/src/body/lower.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,25 @@ use crate::{
4040

4141
use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource};
4242

43-
pub struct LowerCtx {
43+
pub struct LowerCtx<'a> {
44+
pub db: &'a dyn DefDatabase,
4445
hygiene: Hygiene,
4546
file_id: Option<HirFileId>,
4647
source_ast_id_map: Option<Arc<AstIdMap>>,
4748
}
4849

49-
impl LowerCtx {
50-
pub fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self {
50+
impl<'a> LowerCtx<'a> {
51+
pub fn new(db: &'a dyn DefDatabase, file_id: HirFileId) -> Self {
5152
LowerCtx {
53+
db,
5254
hygiene: Hygiene::new(db.upcast(), file_id),
5355
file_id: Some(file_id),
5456
source_ast_id_map: Some(db.ast_id_map(file_id)),
5557
}
5658
}
5759

58-
pub fn with_hygiene(hygiene: &Hygiene) -> Self {
59-
LowerCtx { hygiene: hygiene.clone(), file_id: None, source_ast_id_map: None }
60+
pub fn with_hygiene(db: &'a dyn DefDatabase, hygiene: &Hygiene) -> Self {
61+
LowerCtx { db, hygiene: hygiene.clone(), file_id: None, source_ast_id_map: None }
6062
}
6163

6264
pub(crate) fn hygiene(&self) -> &Hygiene {
@@ -145,7 +147,7 @@ impl ExprCollector<'_> {
145147
(self.body, self.source_map)
146148
}
147149

148-
fn ctx(&self) -> LowerCtx {
150+
fn ctx(&self) -> LowerCtx<'_> {
149151
LowerCtx::new(self.db, self.expander.current_file_id)
150152
}
151153

@@ -376,7 +378,7 @@ impl ExprCollector<'_> {
376378
ast::Expr::PathExpr(e) => {
377379
let path = e
378380
.path()
379-
.and_then(|path| self.expander.parse_path(path))
381+
.and_then(|path| self.expander.parse_path(self.db, path))
380382
.map(Expr::Path)
381383
.unwrap_or(Expr::Missing);
382384
self.alloc_expr(path, syntax_ptr)
@@ -408,7 +410,8 @@ impl ExprCollector<'_> {
408410
self.alloc_expr(Expr::Yield { expr }, syntax_ptr)
409411
}
410412
ast::Expr::RecordExpr(e) => {
411-
let path = e.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
413+
let path =
414+
e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
412415
let record_lit = if let Some(nfl) = e.record_expr_field_list() {
413416
let fields = nfl
414417
.fields()
@@ -791,7 +794,8 @@ impl ExprCollector<'_> {
791794
}
792795
}
793796
ast::Pat::TupleStructPat(p) => {
794-
let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
797+
let path =
798+
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
795799
let (args, ellipsis) = self.collect_tuple_pat(p.fields());
796800
Pat::TupleStruct { path, args, ellipsis }
797801
}
@@ -801,7 +805,8 @@ impl ExprCollector<'_> {
801805
Pat::Ref { pat, mutability }
802806
}
803807
ast::Pat::PathPat(p) => {
804-
let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
808+
let path =
809+
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
805810
path.map(Pat::Path).unwrap_or(Pat::Missing)
806811
}
807812
ast::Pat::OrPat(p) => {
@@ -815,7 +820,8 @@ impl ExprCollector<'_> {
815820
}
816821
ast::Pat::WildcardPat(_) => Pat::Wild,
817822
ast::Pat::RecordPat(p) => {
818-
let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
823+
let path =
824+
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
819825
let args: Vec<_> = p
820826
.record_pat_field_list()
821827
.expect("every struct should have a field list")

crates/hir_def/src/find_path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ mod tests {
386386
let parsed_path_file = syntax::SourceFile::parse(&format!("use {};", path));
387387
let ast_path =
388388
parsed_path_file.syntax_node().descendants().find_map(syntax::ast::Path::cast).unwrap();
389-
let mod_path = ModPath::from_src(ast_path, &Hygiene::new_unhygienic()).unwrap();
389+
let mod_path = ModPath::from_src(&db, ast_path, &Hygiene::new_unhygienic()).unwrap();
390390

391391
let def_map = module.def_map(&db);
392392
let resolved = def_map

crates/hir_def/src/item_tree.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ impl ItemTree {
8888
let mut item_tree = match_ast! {
8989
match syntax {
9090
ast::SourceFile(file) => {
91-
top_attrs = Some(RawAttrs::new(&file, &hygiene));
91+
top_attrs = Some(RawAttrs::new(db, &file, &hygiene));
9292
ctx.lower_module_items(&file)
9393
},
9494
ast::MacroItems(items) => {

crates/hir_def/src/item_tree/lower.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,20 @@ where
3131
}
3232
}
3333

34-
pub(super) struct Ctx {
34+
pub(super) struct Ctx<'a> {
35+
db: &'a dyn DefDatabase,
3536
tree: ItemTree,
3637
hygiene: Hygiene,
3738
file: HirFileId,
3839
source_ast_id_map: Arc<AstIdMap>,
39-
body_ctx: crate::body::LowerCtx,
40+
body_ctx: crate::body::LowerCtx<'a>,
4041
forced_visibility: Option<RawVisibilityId>,
4142
}
4243

43-
impl Ctx {
44-
pub(super) fn new(db: &dyn DefDatabase, hygiene: Hygiene, file: HirFileId) -> Self {
44+
impl<'a> Ctx<'a> {
45+
pub(super) fn new(db: &'a dyn DefDatabase, hygiene: Hygiene, file: HirFileId) -> Self {
4546
Self {
47+
db,
4648
tree: ItemTree::default(),
4749
hygiene,
4850
file,
@@ -126,7 +128,7 @@ impl Ctx {
126128
| ast::Item::MacroDef(_) => {}
127129
};
128130

129-
let attrs = RawAttrs::new(item, &self.hygiene);
131+
let attrs = RawAttrs::new(self.db, item, &self.hygiene);
130132
let items = match item {
131133
ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into),
132134
ast::Item::Union(ast) => self.lower_union(ast).map(Into::into),
@@ -256,7 +258,7 @@ impl Ctx {
256258
for field in fields.fields() {
257259
if let Some(data) = self.lower_record_field(&field) {
258260
let idx = self.data().fields.alloc(data);
259-
self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene));
261+
self.add_attrs(idx.into(), RawAttrs::new(self.db, &field, &self.hygiene));
260262
}
261263
}
262264
let end = self.next_field_idx();
@@ -276,7 +278,7 @@ impl Ctx {
276278
for (i, field) in fields.fields().enumerate() {
277279
let data = self.lower_tuple_field(i, &field);
278280
let idx = self.data().fields.alloc(data);
279-
self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene));
281+
self.add_attrs(idx.into(), RawAttrs::new(self.db, &field, &self.hygiene));
280282
}
281283
let end = self.next_field_idx();
282284
IdRange::new(start..end)
@@ -321,7 +323,7 @@ impl Ctx {
321323
for variant in variants.variants() {
322324
if let Some(data) = self.lower_variant(&variant) {
323325
let idx = self.data().variants.alloc(data);
324-
self.add_attrs(idx.into(), RawAttrs::new(&variant, &self.hygiene));
326+
self.add_attrs(idx.into(), RawAttrs::new(self.db, &variant, &self.hygiene));
325327
}
326328
}
327329
let end = self.next_variant_idx();
@@ -364,7 +366,7 @@ impl Ctx {
364366
};
365367
let ty = Interned::new(self_type);
366368
let idx = self.data().params.alloc(Param::Normal(ty));
367-
self.add_attrs(idx.into(), RawAttrs::new(&self_param, &self.hygiene));
369+
self.add_attrs(idx.into(), RawAttrs::new(self.db, &self_param, &self.hygiene));
368370
has_self_param = true;
369371
}
370372
for param in param_list.params() {
@@ -376,7 +378,7 @@ impl Ctx {
376378
self.data().params.alloc(Param::Normal(ty))
377379
}
378380
};
379-
self.add_attrs(idx.into(), RawAttrs::new(&param, &self.hygiene));
381+
self.add_attrs(idx.into(), RawAttrs::new(self.db, &param, &self.hygiene));
380382
}
381383
}
382384
let end_param = self.next_param_idx();
@@ -522,10 +524,11 @@ impl Ctx {
522524
let is_unsafe = trait_def.unsafe_token().is_some();
523525
let bounds = self.lower_type_bounds(trait_def);
524526
let items = trait_def.assoc_item_list().map(|list| {
527+
let db = self.db;
525528
self.with_inherited_visibility(visibility, |this| {
526529
list.assoc_items()
527530
.filter_map(|item| {
528-
let attrs = RawAttrs::new(&item, &this.hygiene);
531+
let attrs = RawAttrs::new(db, &item, &this.hygiene);
529532
this.collect_inner_items(item.syntax());
530533
this.lower_assoc_item(&item).map(|item| {
531534
this.add_attrs(ModItem::from(item).into(), attrs);
@@ -567,7 +570,7 @@ impl Ctx {
567570
.filter_map(|item| {
568571
self.collect_inner_items(item.syntax());
569572
let assoc = self.lower_assoc_item(&item)?;
570-
let attrs = RawAttrs::new(&item, &self.hygiene);
573+
let attrs = RawAttrs::new(self.db, &item, &self.hygiene);
571574
self.add_attrs(ModItem::from(assoc).into(), attrs);
572575
Some(assoc)
573576
})
@@ -585,6 +588,7 @@ impl Ctx {
585588
let mut imports = Vec::new();
586589
let tree = self.tree.data_mut();
587590
ModPath::expand_use_item(
591+
self.db,
588592
InFile::new(self.file, use_item.clone()),
589593
&self.hygiene,
590594
|path, _use_tree, is_glob, alias| {
@@ -618,7 +622,7 @@ impl Ctx {
618622
}
619623

620624
fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> {
621-
let path = Interned::new(ModPath::from_src(m.path()?, &self.hygiene)?);
625+
let path = Interned::new(ModPath::from_src(self.db, m.path()?, &self.hygiene)?);
622626
let ast_id = self.source_ast_id_map.ast_id(m);
623627
let res = MacroCall { path, ast_id };
624628
Some(id(self.data().macro_calls.alloc(res)))
@@ -647,7 +651,7 @@ impl Ctx {
647651
list.extern_items()
648652
.filter_map(|item| {
649653
self.collect_inner_items(item.syntax());
650-
let attrs = RawAttrs::new(&item, &self.hygiene);
654+
let attrs = RawAttrs::new(self.db, &item, &self.hygiene);
651655
let id: ModItem = match item {
652656
ast::ExternItem::Fn(ast) => {
653657
let func_id = self.lower_function(&ast)?;
@@ -755,7 +759,7 @@ impl Ctx {
755759
fn lower_visibility(&mut self, item: &impl ast::VisibilityOwner) -> RawVisibilityId {
756760
let vis = match self.forced_visibility {
757761
Some(vis) => return vis,
758-
None => RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene),
762+
None => RawVisibility::from_ast_with_hygiene(self.db, item.visibility(), &self.hygiene),
759763
};
760764

761765
self.data().vis.alloc(vis)

0 commit comments

Comments
 (0)