diff --git a/crates/hir-def/src/child_by_source.rs b/crates/hir-def/src/child_by_source.rs index f1c6b3b89fc..0b41984bdd8 100644 --- a/crates/hir-def/src/child_by_source.rs +++ b/crates/hir-def/src/child_by_source.rs @@ -76,7 +76,7 @@ impl ChildBySource for ItemScope { self.extern_crate_decls() .for_each(|ext| insert_item_loc(db, res, file_id, ext, keys::EXTERN_CRATE)); self.use_decls().for_each(|ext| insert_item_loc(db, res, file_id, ext, keys::USE)); - self.unnamed_consts(db) + self.unnamed_consts() .for_each(|konst| insert_item_loc(db, res, file_id, konst, keys::CONST)); self.attr_macro_invocs().filter(|(id, _)| id.file_id == file_id).for_each( |(ast_id, call_id)| { diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs index 0e6826a75a6..2b059d1f8dc 100644 --- a/crates/hir-def/src/item_scope.rs +++ b/crates/hir-def/src/item_scope.rs @@ -241,30 +241,8 @@ impl ItemScope { }) } - pub fn unnamed_consts<'a>( - &'a self, - db: &'a dyn DefDatabase, - ) -> impl Iterator + 'a { - // FIXME: Also treat consts named `_DERIVE_*` as unnamed, since synstructure generates those. - // Should be removed once synstructure stops doing that. - let synstructure_hack_consts = self.values.values().filter_map(|(item, _, _)| match item { - &ModuleDefId::ConstId(id) => { - let loc = id.lookup(db); - let item_tree = loc.id.item_tree(db); - if item_tree[loc.id.value] - .name - .as_ref() - .map_or(false, |n| n.to_smol_str().starts_with("_DERIVE_")) - { - Some(id) - } else { - None - } - } - _ => None, - }); - - self.unnamed_consts.iter().copied().chain(synstructure_hack_consts) + pub fn unnamed_consts(&self) -> impl Iterator + '_ { + self.unnamed_consts.iter().copied() } /// Iterate over all module scoped macros diff --git a/crates/hir-def/src/src.rs b/crates/hir-def/src/src.rs index 4283f003f89..2b1da8c34e1 100644 --- a/crates/hir-def/src/src.rs +++ b/crates/hir-def/src/src.rs @@ -3,7 +3,7 @@ use either::Either; use hir_expand::InFile; use la_arena::ArenaMap; -use syntax::ast; +use syntax::{ast, AstNode, AstPtr}; use crate::{ data::adt::lower_struct, db::DefDatabase, item_tree::ItemTreeNode, trace::Trace, GenericDefId, @@ -12,8 +12,12 @@ use crate::{ }; pub trait HasSource { - type Value; - fn source(&self, db: &dyn DefDatabase) -> InFile; + type Value: AstNode; + fn source(&self, db: &dyn DefDatabase) -> InFile { + let InFile { file_id, value } = self.ast_ptr(db); + InFile::new(file_id, value.to_node(&db.parse_or_expand(file_id))) + } + fn ast_ptr(&self, db: &dyn DefDatabase) -> InFile>; } impl HasSource for T @@ -22,16 +26,14 @@ where T::Id: ItemTreeNode, { type Value = ::Source; - - fn source(&self, db: &dyn DefDatabase) -> InFile { + fn ast_ptr(&self, db: &dyn DefDatabase) -> InFile> { let id = self.item_tree_id(); let file_id = id.file_id(); let tree = id.item_tree(db); let ast_id_map = db.ast_id_map(file_id); - let root = db.parse_or_expand(file_id); let node = &tree[id.value]; - InFile::new(file_id, ast_id_map.get(node.ast_id()).to_node(&root)) + InFile::new(file_id, ast_id_map.get(node.ast_id())) } } diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index e68dbe7b02e..b6054695214 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -213,7 +213,7 @@ impl TraitImpls { // To better support custom derives, collect impls in all unnamed const items. // const _: () = { ... }; - for konst in module_data.scope.unnamed_consts(db.upcast()) { + for konst in module_data.scope.unnamed_consts() { let body = db.body(konst.into()); for (_, block_def_map) in body.blocks(db.upcast()) { Self::collect_def_map(db, map, &block_def_map); @@ -337,7 +337,7 @@ impl InherentImpls { // To better support custom derives, collect impls in all unnamed const items. // const _: () = { ... }; - for konst in module_data.scope.unnamed_consts(db.upcast()) { + for konst in module_data.scope.unnamed_consts() { let body = db.body(konst.into()); for (_, block_def_map) in body.blocks(db.upcast()) { self.collect_def_map(db, &block_def_map); diff --git a/crates/hir-ty/src/tests/method_resolution.rs b/crates/hir-ty/src/tests/method_resolution.rs index c837fae3fef..c521dbf1675 100644 --- a/crates/hir-ty/src/tests/method_resolution.rs +++ b/crates/hir-ty/src/tests/method_resolution.rs @@ -1461,28 +1461,6 @@ fn f() { ); } -#[test] -fn trait_impl_in_synstructure_const() { - check_types( - r#" -struct S; - -trait Tr { - fn method(&self) -> u16; -} - -const _DERIVE_Tr_: () = { - impl Tr for S {} -}; - -fn f() { - S.method(); - //^^^^^^^^^^ u16 -} - "#, - ); -} - #[test] fn inherent_impl_in_unnamed_const() { check_types( diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 5eed7ecd5b2..74e6c000ed4 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -754,7 +754,7 @@ impl Module { scope .declarations() .map(ModuleDef::from) - .chain(scope.unnamed_consts(db.upcast()).map(|id| ModuleDef::Const(Const::from(id)))) + .chain(scope.unnamed_consts().map(|id| ModuleDef::Const(Const::from(id)))) .collect() } diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs index 28ac5940e69..d9205eb5419 100644 --- a/crates/hir/src/symbols.rs +++ b/crates/hir/src/symbols.rs @@ -165,7 +165,6 @@ impl<'a> SymbolCollector<'a> { // Record renamed imports. // FIXME: In case it imports multiple items under different namespaces we just pick one arbitrarily // for now. - // FIXME: This parses! for id in scope.imports() { let source = id.import.child_source(self.db.upcast()); let Some(use_tree_src) = source.value.get(id.idx) else { continue }; @@ -196,7 +195,7 @@ impl<'a> SymbolCollector<'a> { }); } - for const_id in scope.unnamed_consts(self.db.upcast()) { + for const_id in scope.unnamed_consts() { self.collect_from_body(const_id); } diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs index 674ce6d52bf..caa10a1ed68 100644 --- a/crates/ide/src/navigation_target.rs +++ b/crates/ide/src/navigation_target.rs @@ -176,14 +176,12 @@ impl NavigationTarget { impl TryToNav for FileSymbol { fn try_to_nav(&self, db: &RootDatabase) -> Option> { - let root = db.parse_or_expand(self.loc.hir_file_id); - self.loc.ptr.to_node(&root); Some( - orig_range_with_focus( + orig_range_with_focus_r( db, self.loc.hir_file_id, - &self.loc.ptr.to_node(&root), - Some(self.loc.name_ptr.to_node(&root)), + self.loc.ptr.text_range(), + Some(self.loc.name_ptr.text_range()), ) .map(|(FileRange { file_id, range: full_range }, focus_range)| { NavigationTarget { @@ -722,7 +720,21 @@ fn orig_range_with_focus( value: &SyntaxNode, name: Option, ) -> UpmappingResult<(FileRange, Option)> { - let Some(name) = name else { return orig_range(db, hir_file, value) }; + orig_range_with_focus_r( + db, + hir_file, + value.text_range(), + name.map(|it| it.syntax().text_range()), + ) +} + +fn orig_range_with_focus_r( + db: &RootDatabase, + hir_file: HirFileId, + value: TextRange, + name: Option, +) -> UpmappingResult<(FileRange, Option)> { + let Some(name) = name else { return orig_range_r(db, hir_file, value) }; let call_kind = || db.lookup_intern_macro_call(hir_file.macro_file().unwrap().macro_call_id).kind; @@ -733,9 +745,9 @@ fn orig_range_with_focus( .definition_range(db) }; - let value_range = InFile::new(hir_file, value).original_file_range_opt(db); + let value_range = InFile::new(hir_file, value).original_node_file_range_opt(db); let ((call_site_range, call_site_focus), def_site) = - match InFile::new(hir_file, name.syntax()).original_file_range_opt(db) { + match InFile::new(hir_file, name).original_node_file_range_opt(db) { // call site name Some((focus_range, ctxt)) if ctxt.is_root() => { // Try to upmap the node as well, if it ends up in the def site, go back to the call site @@ -802,7 +814,7 @@ fn orig_range_with_focus( } } // lost name? can't happen for single tokens - None => return orig_range(db, hir_file, value), + None => return orig_range_r(db, hir_file, value), }; UpmappingResult { @@ -845,6 +857,17 @@ fn orig_range( } } +fn orig_range_r( + db: &RootDatabase, + hir_file: HirFileId, + value: TextRange, +) -> UpmappingResult<(FileRange, Option)> { + UpmappingResult { + call_site: (InFile::new(hir_file, value).original_node_file_range(db).0, None), + def_site: None, + } +} + #[cfg(test)] mod tests { use expect_test::expect;