From 976a3226fe0f145dfefd473e9fecd63d58aca50e Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 6 May 2021 19:59:54 +0200 Subject: Don't store call-site text offsets in hygiene info --- crates/hir_def/src/attr.rs | 21 ++++++++++++------ crates/hir_def/src/body.rs | 8 +++---- crates/hir_def/src/body/lower.rs | 30 +++++++++++++++----------- crates/hir_def/src/find_path.rs | 2 +- crates/hir_def/src/item_tree.rs | 2 +- crates/hir_def/src/item_tree/lower.rs | 34 +++++++++++++++++------------- crates/hir_def/src/lib.rs | 4 ++-- crates/hir_def/src/nameres.rs | 1 + crates/hir_def/src/path.rs | 15 +++++++------ crates/hir_def/src/path/lower.rs | 14 +++++++----- crates/hir_def/src/path/lower/lower_use.rs | 23 ++++++++++++++------ crates/hir_def/src/visibility.rs | 8 ++++--- 12 files changed, 99 insertions(+), 63 deletions(-) (limited to 'crates/hir_def/src') diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 0171d8a92..a2479016e 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs @@ -95,13 +95,17 @@ impl ops::Deref for AttrsWithOwner { impl RawAttrs { pub(crate) const EMPTY: Self = Self { entries: None }; - pub(crate) fn new(owner: &dyn ast::AttrsOwner, hygiene: &Hygiene) -> Self { + pub(crate) fn new( + db: &dyn DefDatabase, + owner: &dyn ast::AttrsOwner, + hygiene: &Hygiene, + ) -> Self { let entries = collect_attrs(owner) .enumerate() .flat_map(|(i, attr)| { let index = AttrId(i as u32); match attr { - Either::Left(attr) => Attr::from_src(attr, hygiene, index), + Either::Left(attr) => Attr::from_src(db, attr, hygiene, index), Either::Right(comment) => comment.doc_comment().map(|doc| Attr { id: index, input: Some(AttrInput::Literal(SmolStr::new(doc))), @@ -116,7 +120,7 @@ impl RawAttrs { fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn ast::AttrsOwner>) -> Self { let hygiene = Hygiene::new(db.upcast(), owner.file_id); - Self::new(owner.value, &hygiene) + Self::new(db, owner.value, &hygiene) } pub(crate) fn merge(&self, other: Self) -> Self { @@ -170,7 +174,7 @@ impl RawAttrs { let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?; // FIXME hygiene let hygiene = Hygiene::new_unhygienic(); - Attr::from_src(attr, &hygiene, index) + Attr::from_src(db, attr, &hygiene, index) }); let cfg_options = &crate_graph[krate].cfg_options; @@ -627,8 +631,13 @@ pub enum AttrInput { } impl Attr { - fn from_src(ast: ast::Attr, hygiene: &Hygiene, id: AttrId) -> Option { - let path = Interned::new(ModPath::from_src(ast.path()?, hygiene)?); + fn from_src( + db: &dyn DefDatabase, + ast: ast::Attr, + hygiene: &Hygiene, + id: AttrId, + ) -> Option { + let path = Interned::new(ModPath::from_src(db, ast.path()?, hygiene)?); let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() { let value = match lit.kind() { ast::LiteralKind::String(string) => string.value()?.into(), diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index 131f424cc..9510a8575 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs @@ -72,7 +72,7 @@ impl CfgExpander { } pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> Attrs { - RawAttrs::new(owner, &self.hygiene).filter(db, self.krate) + RawAttrs::new(db, owner, &self.hygiene).filter(db, self.krate) } pub(crate) fn is_cfg_enabled(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> bool { @@ -192,9 +192,9 @@ impl Expander { self.current_file_id } - fn parse_path(&mut self, path: ast::Path) -> Option { - let ctx = LowerCtx::with_hygiene(&self.cfg_expander.hygiene); - Path::from_src(path, &ctx) + fn parse_path(&mut self, db: &dyn DefDatabase, path: ast::Path) -> Option { + let ctx = LowerCtx::with_hygiene(db, &self.cfg_expander.hygiene); + Path::from_src(db, path, &ctx) } fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option { diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index c11da30d2..e4fa7f9c9 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs @@ -40,23 +40,25 @@ use crate::{ use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource}; -pub struct LowerCtx { +pub struct LowerCtx<'a> { + db: &'a dyn DefDatabase, hygiene: Hygiene, file_id: Option, source_ast_id_map: Option>, } -impl LowerCtx { - pub fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self { +impl<'a> LowerCtx<'a> { + pub fn new(db: &'a dyn DefDatabase, file_id: HirFileId) -> Self { LowerCtx { + db, hygiene: Hygiene::new(db.upcast(), file_id), file_id: Some(file_id), source_ast_id_map: Some(db.ast_id_map(file_id)), } } - pub fn with_hygiene(hygiene: &Hygiene) -> Self { - LowerCtx { hygiene: hygiene.clone(), file_id: None, source_ast_id_map: None } + pub fn with_hygiene(db: &'a dyn DefDatabase, hygiene: &Hygiene) -> Self { + LowerCtx { db, hygiene: hygiene.clone(), file_id: None, source_ast_id_map: None } } pub(crate) fn hygiene(&self) -> &Hygiene { @@ -68,7 +70,7 @@ impl LowerCtx { } pub(crate) fn lower_path(&self, ast: ast::Path) -> Option { - Path::from_src(ast, self) + Path::from_src(self.db, ast, self) } pub(crate) fn ast_id(&self, item: &N) -> Option> { @@ -145,7 +147,7 @@ impl ExprCollector<'_> { (self.body, self.source_map) } - fn ctx(&self) -> LowerCtx { + fn ctx(&self) -> LowerCtx<'_> { LowerCtx::new(self.db, self.expander.current_file_id) } @@ -376,7 +378,7 @@ impl ExprCollector<'_> { ast::Expr::PathExpr(e) => { let path = e .path() - .and_then(|path| self.expander.parse_path(path)) + .and_then(|path| self.expander.parse_path(self.db, path)) .map(Expr::Path) .unwrap_or(Expr::Missing); self.alloc_expr(path, syntax_ptr) @@ -408,7 +410,8 @@ impl ExprCollector<'_> { self.alloc_expr(Expr::Yield { expr }, syntax_ptr) } ast::Expr::RecordExpr(e) => { - let path = e.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); + let path = + e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new); let record_lit = if let Some(nfl) = e.record_expr_field_list() { let fields = nfl .fields() @@ -791,7 +794,8 @@ impl ExprCollector<'_> { } } ast::Pat::TupleStructPat(p) => { - let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); + let path = + p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new); let (args, ellipsis) = self.collect_tuple_pat(p.fields()); Pat::TupleStruct { path, args, ellipsis } } @@ -801,7 +805,8 @@ impl ExprCollector<'_> { Pat::Ref { pat, mutability } } ast::Pat::PathPat(p) => { - let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); + let path = + p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new); path.map(Pat::Path).unwrap_or(Pat::Missing) } ast::Pat::OrPat(p) => { @@ -815,7 +820,8 @@ impl ExprCollector<'_> { } ast::Pat::WildcardPat(_) => Pat::Wild, ast::Pat::RecordPat(p) => { - let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); + let path = + p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new); let args: Vec<_> = p .record_pat_field_list() .expect("every struct should have a field list") diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs index c06a37294..858e88038 100644 --- a/crates/hir_def/src/find_path.rs +++ b/crates/hir_def/src/find_path.rs @@ -386,7 +386,7 @@ mod tests { let parsed_path_file = syntax::SourceFile::parse(&format!("use {};", path)); let ast_path = parsed_path_file.syntax_node().descendants().find_map(syntax::ast::Path::cast).unwrap(); - let mod_path = ModPath::from_src(ast_path, &Hygiene::new_unhygienic()).unwrap(); + let mod_path = ModPath::from_src(&db, ast_path, &Hygiene::new_unhygienic()).unwrap(); let def_map = module.def_map(&db); let resolved = def_map diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index eaeca01bd..8d13c7e04 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -88,7 +88,7 @@ impl ItemTree { let mut item_tree = match_ast! { match syntax { ast::SourceFile(file) => { - top_attrs = Some(RawAttrs::new(&file, &hygiene)); + top_attrs = Some(RawAttrs::new(db, &file, &hygiene)); ctx.lower_module_items(&file) }, ast::MacroItems(items) => { diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 45b099cf3..5743b3386 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -31,18 +31,20 @@ where } } -pub(super) struct Ctx { +pub(super) struct Ctx<'a> { + db: &'a dyn DefDatabase, tree: ItemTree, hygiene: Hygiene, file: HirFileId, source_ast_id_map: Arc, - body_ctx: crate::body::LowerCtx, + body_ctx: crate::body::LowerCtx<'a>, forced_visibility: Option, } -impl Ctx { - pub(super) fn new(db: &dyn DefDatabase, hygiene: Hygiene, file: HirFileId) -> Self { +impl<'a> Ctx<'a> { + pub(super) fn new(db: &'a dyn DefDatabase, hygiene: Hygiene, file: HirFileId) -> Self { Self { + db, tree: ItemTree::default(), hygiene, file, @@ -126,7 +128,7 @@ impl Ctx { | ast::Item::MacroDef(_) => {} }; - let attrs = RawAttrs::new(item, &self.hygiene); + let attrs = RawAttrs::new(self.db, item, &self.hygiene); let items = match item { ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into), ast::Item::Union(ast) => self.lower_union(ast).map(Into::into), @@ -256,7 +258,7 @@ impl Ctx { for field in fields.fields() { if let Some(data) = self.lower_record_field(&field) { let idx = self.data().fields.alloc(data); - self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene)); + self.add_attrs(idx.into(), RawAttrs::new(self.db, &field, &self.hygiene)); } } let end = self.next_field_idx(); @@ -276,7 +278,7 @@ impl Ctx { for (i, field) in fields.fields().enumerate() { let data = self.lower_tuple_field(i, &field); let idx = self.data().fields.alloc(data); - self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene)); + self.add_attrs(idx.into(), RawAttrs::new(self.db, &field, &self.hygiene)); } let end = self.next_field_idx(); IdRange::new(start..end) @@ -321,7 +323,7 @@ impl Ctx { for variant in variants.variants() { if let Some(data) = self.lower_variant(&variant) { let idx = self.data().variants.alloc(data); - self.add_attrs(idx.into(), RawAttrs::new(&variant, &self.hygiene)); + self.add_attrs(idx.into(), RawAttrs::new(self.db, &variant, &self.hygiene)); } } let end = self.next_variant_idx(); @@ -364,7 +366,7 @@ impl Ctx { }; let ty = Interned::new(self_type); let idx = self.data().params.alloc(Param::Normal(ty)); - self.add_attrs(idx.into(), RawAttrs::new(&self_param, &self.hygiene)); + self.add_attrs(idx.into(), RawAttrs::new(self.db, &self_param, &self.hygiene)); has_self_param = true; } for param in param_list.params() { @@ -376,7 +378,7 @@ impl Ctx { self.data().params.alloc(Param::Normal(ty)) } }; - self.add_attrs(idx.into(), RawAttrs::new(¶m, &self.hygiene)); + self.add_attrs(idx.into(), RawAttrs::new(self.db, ¶m, &self.hygiene)); } } let end_param = self.next_param_idx(); @@ -522,10 +524,11 @@ impl Ctx { let is_unsafe = trait_def.unsafe_token().is_some(); let bounds = self.lower_type_bounds(trait_def); let items = trait_def.assoc_item_list().map(|list| { + let db = self.db; self.with_inherited_visibility(visibility, |this| { list.assoc_items() .filter_map(|item| { - let attrs = RawAttrs::new(&item, &this.hygiene); + let attrs = RawAttrs::new(db, &item, &this.hygiene); this.collect_inner_items(item.syntax()); this.lower_assoc_item(&item).map(|item| { this.add_attrs(ModItem::from(item).into(), attrs); @@ -567,7 +570,7 @@ impl Ctx { .filter_map(|item| { self.collect_inner_items(item.syntax()); let assoc = self.lower_assoc_item(&item)?; - let attrs = RawAttrs::new(&item, &self.hygiene); + let attrs = RawAttrs::new(self.db, &item, &self.hygiene); self.add_attrs(ModItem::from(assoc).into(), attrs); Some(assoc) }) @@ -585,6 +588,7 @@ impl Ctx { let mut imports = Vec::new(); let tree = self.tree.data_mut(); ModPath::expand_use_item( + self.db, InFile::new(self.file, use_item.clone()), &self.hygiene, |path, _use_tree, is_glob, alias| { @@ -618,7 +622,7 @@ impl Ctx { } fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option> { - let path = Interned::new(ModPath::from_src(m.path()?, &self.hygiene)?); + let path = Interned::new(ModPath::from_src(self.db, m.path()?, &self.hygiene)?); let ast_id = self.source_ast_id_map.ast_id(m); let res = MacroCall { path, ast_id }; Some(id(self.data().macro_calls.alloc(res))) @@ -647,7 +651,7 @@ impl Ctx { list.extern_items() .filter_map(|item| { self.collect_inner_items(item.syntax()); - let attrs = RawAttrs::new(&item, &self.hygiene); + let attrs = RawAttrs::new(self.db, &item, &self.hygiene); let id: ModItem = match item { ast::ExternItem::Fn(ast) => { let func_id = self.lower_function(&ast)?; @@ -755,7 +759,7 @@ impl Ctx { fn lower_visibility(&mut self, item: &impl ast::VisibilityOwner) -> RawVisibilityId { let vis = match self.forced_visibility { Some(vis) => return vis, - None => RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene), + None => RawVisibility::from_ast_with_hygiene(self.db, item.visibility(), &self.hygiene), }; self.data().vis.alloc(vis) diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 25694f037..da46f16f7 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs @@ -654,7 +654,7 @@ impl AsMacroCall for InFile<&ast::MacroCall> { ) -> Result, UnresolvedMacro> { let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value)); let h = Hygiene::new(db.upcast(), self.file_id); - let path = self.value.path().and_then(|path| path::ModPath::from_src(path, &h)); + let path = self.value.path().and_then(|path| path::ModPath::from_src(db, path, &h)); let path = match error_sink .option(path, || mbe::ExpandError::Other("malformed macro invocation".into())) @@ -712,7 +712,7 @@ fn macro_call_as_call_id( krate, macro_call, def, - &|path: ast::Path| resolver(path::ModPath::from_src(path, &hygiene)?), + &|path: ast::Path| resolver(path::ModPath::from_src(db, path, &hygiene)?), error_sink, ) .map(MacroCallId::from) diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs index ba027c44a..1bc72ec1f 100644 --- a/crates/hir_def/src/nameres.rs +++ b/crates/hir_def/src/nameres.rs @@ -599,6 +599,7 @@ mod diagnostics { let mut cur = 0; let mut tree = None; ModPath::expand_use_item( + db, InFile::new(ast.file_id, use_item), &hygiene, |_mod_path, use_tree, _is_glob, _alias| { diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs index 509f77850..64bff318e 100644 --- a/crates/hir_def/src/path.rs +++ b/crates/hir_def/src/path.rs @@ -7,7 +7,7 @@ use std::{ sync::Arc, }; -use crate::{body::LowerCtx, intern::Interned, type_ref::LifetimeRef}; +use crate::{body::LowerCtx, db::DefDatabase, intern::Interned, type_ref::LifetimeRef}; use base_db::CrateId; use hir_expand::{ hygiene::Hygiene, @@ -47,9 +47,9 @@ pub enum ImportAlias { } impl ModPath { - pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option { - let ctx = LowerCtx::with_hygiene(hygiene); - lower::lower_path(path, &ctx).map(|it| (*it.mod_path).clone()) + pub fn from_src(db: &dyn DefDatabase, path: ast::Path, hygiene: &Hygiene) -> Option { + let ctx = LowerCtx::with_hygiene(db, hygiene); + lower::lower_path(db, path, &ctx).map(|it| (*it.mod_path).clone()) } pub fn from_segments(kind: PathKind, segments: impl IntoIterator) -> ModPath { @@ -64,12 +64,13 @@ impl ModPath { /// Calls `cb` with all paths, represented by this use item. pub(crate) fn expand_use_item( + db: &dyn DefDatabase, item_src: InFile, hygiene: &Hygiene, mut cb: impl FnMut(ModPath, &ast::UseTree, /* is_glob */ bool, Option), ) { if let Some(tree) = item_src.value.use_tree() { - lower::lower_use_tree(None, tree, hygiene, &mut cb); + lower::lower_use_tree(db, None, tree, hygiene, &mut cb); } } @@ -168,8 +169,8 @@ pub enum GenericArg { impl Path { /// Converts an `ast::Path` to `Path`. Works with use trees. /// It correctly handles `$crate` based path from macro call. - pub fn from_src(path: ast::Path, ctx: &LowerCtx) -> Option { - lower::lower_path(path, ctx) + pub fn from_src(db: &dyn DefDatabase, path: ast::Path, ctx: &LowerCtx) -> Option { + lower::lower_path(db, path, ctx) } /// Converts a known mod path to `Path`. diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index 1df6db525..3b3a3738f 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs @@ -2,7 +2,7 @@ mod lower_use; -use crate::intern::Interned; +use crate::{db::DefDatabase, intern::Interned}; use std::sync::Arc; use either::Either; @@ -20,7 +20,11 @@ pub(super) use lower_use::lower_use_tree; /// Converts an `ast::Path` to `Path`. Works with use trees. /// It correctly handles `$crate` based path from macro call. -pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option { +pub(super) fn lower_path( + db: &dyn DefDatabase, + mut path: ast::Path, + ctx: &LowerCtx, +) -> Option { let mut kind = PathKind::Plain; let mut type_anchor = None; let mut segments = Vec::new(); @@ -36,7 +40,7 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option { match segment.kind()? { ast::PathSegmentKind::Name(name_ref) => { // FIXME: this should just return name - match hygiene.name_ref_to_name(name_ref) { + match hygiene.name_ref_to_name(db.upcast(), name_ref) { Either::Left(name) => { let args = segment .generic_arg_list() @@ -71,7 +75,7 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option { } // >::Foo desugars to Trait::Foo Some(trait_ref) => { - let path = Path::from_src(trait_ref.path()?, ctx)?; + let path = Path::from_src(db, trait_ref.path()?, ctx)?; let mod_path = (*path.mod_path).clone(); let num_segments = path.mod_path.segments.len(); kind = mod_path.kind; @@ -133,7 +137,7 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option { // We follow what it did anyway :) if segments.len() == 1 && kind == PathKind::Plain { if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { - if let Some(crate_id) = hygiene.local_inner_macros(path) { + if let Some(crate_id) = hygiene.local_inner_macros(db.upcast(), path) { kind = PathKind::DollarCrate(crate_id); } } diff --git a/crates/hir_def/src/path/lower/lower_use.rs b/crates/hir_def/src/path/lower/lower_use.rs index e2965b033..ee80e3df3 100644 --- a/crates/hir_def/src/path/lower/lower_use.rs +++ b/crates/hir_def/src/path/lower/lower_use.rs @@ -7,9 +7,13 @@ use either::Either; use hir_expand::{hygiene::Hygiene, name::AsName}; use syntax::ast::{self, NameOwner}; -use crate::path::{ImportAlias, ModPath, PathKind}; +use crate::{ + db::DefDatabase, + path::{ImportAlias, ModPath, PathKind}, +}; pub(crate) fn lower_use_tree( + db: &dyn DefDatabase, prefix: Option, tree: ast::UseTree, hygiene: &Hygiene, @@ -21,13 +25,13 @@ pub(crate) fn lower_use_tree( None => prefix, // E.g. `use something::{inner}` (prefix is `None`, path is `something`) // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) - Some(path) => match convert_path(prefix, path, hygiene) { + Some(path) => match convert_path(db, prefix, path, hygiene) { Some(it) => Some(it), None => return, // FIXME: report errors somewhere }, }; for child_tree in use_tree_list.use_trees() { - lower_use_tree(prefix.clone(), child_tree, hygiene, cb); + lower_use_tree(db, prefix.clone(), child_tree, hygiene, cb); } } else { let alias = tree.rename().map(|a| { @@ -47,7 +51,7 @@ pub(crate) fn lower_use_tree( } } } - if let Some(path) = convert_path(prefix, ast_path, hygiene) { + if let Some(path) = convert_path(db, prefix, ast_path, hygiene) { cb(path, &tree, is_glob, alias) } // FIXME: report errors somewhere @@ -61,9 +65,14 @@ pub(crate) fn lower_use_tree( } } -fn convert_path(prefix: Option, path: ast::Path, hygiene: &Hygiene) -> Option { +fn convert_path( + db: &dyn DefDatabase, + prefix: Option, + path: ast::Path, + hygiene: &Hygiene, +) -> Option { let prefix = if let Some(qual) = path.qualifier() { - Some(convert_path(prefix, qual, hygiene)?) + Some(convert_path(db, prefix, qual, hygiene)?) } else { prefix }; @@ -71,7 +80,7 @@ fn convert_path(prefix: Option, path: ast::Path, hygiene: &Hygiene) -> let segment = path.segment()?; let res = match segment.kind()? { ast::PathSegmentKind::Name(name_ref) => { - match hygiene.name_ref_to_name(name_ref) { + match hygiene.name_ref_to_name(db.upcast(), name_ref) { Either::Left(name) => { // no type args in use let mut res = prefix.unwrap_or_else(|| { diff --git a/crates/hir_def/src/visibility.rs b/crates/hir_def/src/visibility.rs index d4b7c9970..83500f54e 100644 --- a/crates/hir_def/src/visibility.rs +++ b/crates/hir_def/src/visibility.rs @@ -33,17 +33,19 @@ impl RawVisibility { db: &dyn DefDatabase, node: InFile>, ) -> RawVisibility { - Self::from_ast_with_hygiene(node.value, &Hygiene::new(db.upcast(), node.file_id)) + Self::from_ast_with_hygiene(db, node.value, &Hygiene::new(db.upcast(), node.file_id)) } pub(crate) fn from_ast_with_hygiene( + db: &dyn DefDatabase, node: Option, hygiene: &Hygiene, ) -> RawVisibility { - Self::from_ast_with_hygiene_and_default(node, RawVisibility::private(), hygiene) + Self::from_ast_with_hygiene_and_default(db, node, RawVisibility::private(), hygiene) } pub(crate) fn from_ast_with_hygiene_and_default( + db: &dyn DefDatabase, node: Option, default: RawVisibility, hygiene: &Hygiene, @@ -54,7 +56,7 @@ impl RawVisibility { }; match node.kind() { ast::VisibilityKind::In(path) => { - let path = ModPath::from_src(path, hygiene); + let path = ModPath::from_src(db, path, hygiene); let path = match path { None => return RawVisibility::private(), Some(path) => path, -- cgit v1.2.3 From 548e5a5c29bb0b453ef170e65d45a6673d8443f1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 4 May 2021 15:31:23 +0300 Subject: internal: add failing incremental test --- crates/hir_def/src/nameres/tests/incremental.rs | 52 +++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'crates/hir_def/src') diff --git a/crates/hir_def/src/nameres/tests/incremental.rs b/crates/hir_def/src/nameres/tests/incremental.rs index 509e1bbbc..747407ec7 100644 --- a/crates/hir_def/src/nameres/tests/incremental.rs +++ b/crates/hir_def/src/nameres/tests/incremental.rs @@ -105,3 +105,55 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() { assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) } } + +#[test] +fn typing_inside_a_function_doe_should_not_invalidate_expansions() { + let (mut db, pos) = TestDB::with_position( + r#" +//- /lib.rs +macro_rules! m { + ($ident:ident) => { + fn $ident() { }; + } +} +mod foo; + +//- /foo/mod.rs +pub mod bar; + +//- /foo/bar.rs +m!(X); +fn quux() { 1$0 } +m!(Y); +m!(Z); +"#, + ); + let krate = db.test_crate(); + { + let events = db.log_executed(|| { + let crate_def_map = db.crate_def_map(krate); + let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); + assert_eq!(module_data.scope.resolutions().count(), 4); + }); + let n_recalculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count(); + assert_eq!(n_recalculated_item_trees, 6); + } + + let new_text = r#" +m!(X); +fn quux() { 92 } +m!(Y); +m!(Z); +"#; + db.set_file_text(pos.file_id, Arc::new(new_text.to_string())); + + { + let events = db.log_executed(|| { + let crate_def_map = db.crate_def_map(krate); + let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); + assert_eq!(module_data.scope.resolutions().count(), 4); + }); + let n_recalculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count(); + assert_eq!(n_recalculated_item_trees, 1); + } +} -- cgit v1.2.3 From c4f9cb9b53314b584f6451908ce40bbd65453116 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 4 May 2021 17:12:35 +0300 Subject: Update crates/hir_def/src/nameres/tests/incremental.rs Co-authored-by: Jonas Schievink --- crates/hir_def/src/nameres/tests/incremental.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/hir_def/src') diff --git a/crates/hir_def/src/nameres/tests/incremental.rs b/crates/hir_def/src/nameres/tests/incremental.rs index 747407ec7..227ecd162 100644 --- a/crates/hir_def/src/nameres/tests/incremental.rs +++ b/crates/hir_def/src/nameres/tests/incremental.rs @@ -107,7 +107,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() { } #[test] -fn typing_inside_a_function_doe_should_not_invalidate_expansions() { +fn typing_inside_a_function_should_not_invalidate_expansions() { let (mut db, pos) = TestDB::with_position( r#" //- /lib.rs -- cgit v1.2.3 From 20ae41c1a12963e938cb3bd4c7c84007412d6fa6 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 6 May 2021 23:23:50 +0200 Subject: Reuse database in LowerCtx --- crates/hir_def/src/body.rs | 2 +- crates/hir_def/src/body/lower.rs | 4 ++-- crates/hir_def/src/path.rs | 6 +++--- crates/hir_def/src/path/lower.rs | 14 +++++--------- 4 files changed, 11 insertions(+), 15 deletions(-) (limited to 'crates/hir_def/src') diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index 9510a8575..8360426f1 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs @@ -194,7 +194,7 @@ impl Expander { fn parse_path(&mut self, db: &dyn DefDatabase, path: ast::Path) -> Option { let ctx = LowerCtx::with_hygiene(db, &self.cfg_expander.hygiene); - Path::from_src(db, path, &ctx) + Path::from_src(path, &ctx) } fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option { diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index e4fa7f9c9..75dc19c11 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs @@ -41,7 +41,7 @@ use crate::{ use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource}; pub struct LowerCtx<'a> { - db: &'a dyn DefDatabase, + pub db: &'a dyn DefDatabase, hygiene: Hygiene, file_id: Option, source_ast_id_map: Option>, @@ -70,7 +70,7 @@ impl<'a> LowerCtx<'a> { } pub(crate) fn lower_path(&self, ast: ast::Path) -> Option { - Path::from_src(self.db, ast, self) + Path::from_src(ast, self) } pub(crate) fn ast_id(&self, item: &N) -> Option> { diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs index 64bff318e..a43441b1c 100644 --- a/crates/hir_def/src/path.rs +++ b/crates/hir_def/src/path.rs @@ -49,7 +49,7 @@ pub enum ImportAlias { impl ModPath { pub fn from_src(db: &dyn DefDatabase, path: ast::Path, hygiene: &Hygiene) -> Option { let ctx = LowerCtx::with_hygiene(db, hygiene); - lower::lower_path(db, path, &ctx).map(|it| (*it.mod_path).clone()) + lower::lower_path(path, &ctx).map(|it| (*it.mod_path).clone()) } pub fn from_segments(kind: PathKind, segments: impl IntoIterator) -> ModPath { @@ -169,8 +169,8 @@ pub enum GenericArg { impl Path { /// Converts an `ast::Path` to `Path`. Works with use trees. /// It correctly handles `$crate` based path from macro call. - pub fn from_src(db: &dyn DefDatabase, path: ast::Path, ctx: &LowerCtx) -> Option { - lower::lower_path(db, path, ctx) + pub fn from_src(path: ast::Path, ctx: &LowerCtx) -> Option { + lower::lower_path(path, ctx) } /// Converts a known mod path to `Path`. diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index 3b3a3738f..a873325b2 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs @@ -2,7 +2,7 @@ mod lower_use; -use crate::{db::DefDatabase, intern::Interned}; +use crate::intern::Interned; use std::sync::Arc; use either::Either; @@ -20,11 +20,7 @@ pub(super) use lower_use::lower_use_tree; /// Converts an `ast::Path` to `Path`. Works with use trees. /// It correctly handles `$crate` based path from macro call. -pub(super) fn lower_path( - db: &dyn DefDatabase, - mut path: ast::Path, - ctx: &LowerCtx, -) -> Option { +pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option { let mut kind = PathKind::Plain; let mut type_anchor = None; let mut segments = Vec::new(); @@ -40,7 +36,7 @@ pub(super) fn lower_path( match segment.kind()? { ast::PathSegmentKind::Name(name_ref) => { // FIXME: this should just return name - match hygiene.name_ref_to_name(db.upcast(), name_ref) { + match hygiene.name_ref_to_name(ctx.db.upcast(), name_ref) { Either::Left(name) => { let args = segment .generic_arg_list() @@ -75,7 +71,7 @@ pub(super) fn lower_path( } // >::Foo desugars to Trait::Foo Some(trait_ref) => { - let path = Path::from_src(db, trait_ref.path()?, ctx)?; + let path = Path::from_src(trait_ref.path()?, ctx)?; let mod_path = (*path.mod_path).clone(); let num_segments = path.mod_path.segments.len(); kind = mod_path.kind; @@ -137,7 +133,7 @@ pub(super) fn lower_path( // We follow what it did anyway :) if segments.len() == 1 && kind == PathKind::Plain { if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { - if let Some(crate_id) = hygiene.local_inner_macros(db.upcast(), path) { + if let Some(crate_id) = hygiene.local_inner_macros(ctx.db.upcast(), path) { kind = PathKind::DollarCrate(crate_id); } } -- cgit v1.2.3