From 51cdba5f428cf6f27b636c5307d595805f50b781 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 14 Jun 2025 08:54:55 +0200 Subject: [PATCH 1/4] Make `ModuleId` a tracked struct --- crates/base-db/src/lib.rs | 9 +- crates/hir-def/src/attr.rs | 12 +- crates/hir-def/src/db.rs | 6 +- crates/hir-def/src/expr_store/lower.rs | 42 +-- crates/hir-def/src/expr_store/tests/body.rs | 4 +- .../src/expr_store/tests/body/block.rs | 60 +++- crates/hir-def/src/find_path.rs | 114 ++++---- crates/hir-def/src/import_map.rs | 15 +- crates/hir-def/src/item_scope.rs | 26 +- crates/hir-def/src/lib.rs | 169 +++-------- .../hir-def/src/macro_expansion_tests/mbe.rs | 16 +- .../hir-def/src/macro_expansion_tests/mod.rs | 7 +- crates/hir-def/src/nameres.rs | 228 ++++++++------- crates/hir-def/src/nameres/assoc.rs | 18 +- crates/hir-def/src/nameres/attr_resolution.rs | 4 +- crates/hir-def/src/nameres/collector.rs | 265 ++++++++---------- crates/hir-def/src/nameres/diagnostics.rs | 29 +- crates/hir-def/src/nameres/path_resolution.rs | 109 ++++--- .../hir-def/src/nameres/tests/incremental.rs | 16 +- crates/hir-def/src/nameres/tests/macros.rs | 10 +- crates/hir-def/src/resolver.rs | 47 ++-- crates/hir-def/src/signatures.rs | 4 +- crates/hir-def/src/src.rs | 4 +- crates/hir-def/src/test_db.rs | 42 +-- crates/hir-def/src/visibility.rs | 69 +++-- crates/hir-ty/src/chalk_db.rs | 10 +- crates/hir-ty/src/chalk_ext.rs | 4 +- crates/hir-ty/src/consteval.rs | 2 +- crates/hir-ty/src/consteval/tests.rs | 2 +- crates/hir-ty/src/diagnostics/decl_check.rs | 2 +- .../diagnostics/match_check/pat_analysis.rs | 2 +- crates/hir-ty/src/diagnostics/unsafe_check.rs | 2 +- crates/hir-ty/src/display.rs | 11 +- crates/hir-ty/src/drop.rs | 6 +- crates/hir-ty/src/dyn_compatibility.rs | 10 +- crates/hir-ty/src/dyn_compatibility/tests.rs | 2 +- crates/hir-ty/src/infer/closure.rs | 8 +- crates/hir-ty/src/layout/tests.rs | 4 +- crates/hir-ty/src/lower.rs | 2 +- crates/hir-ty/src/method_resolution.rs | 28 +- crates/hir-ty/src/mir/borrowck.rs | 11 +- crates/hir-ty/src/mir/eval.rs | 2 +- crates/hir-ty/src/mir/eval/shim.rs | 4 +- crates/hir-ty/src/mir/eval/tests.rs | 4 +- crates/hir-ty/src/mir/lower.rs | 2 +- crates/hir-ty/src/test_db.rs | 2 +- crates/hir-ty/src/tests.rs | 18 +- crates/hir-ty/src/tests/closure_captures.rs | 4 +- crates/hir-ty/src/tests/incremental.rs | 28 +- crates/hir-ty/src/variance.rs | 2 +- crates/hir/src/attrs.rs | 24 +- crates/hir/src/has_source.rs | 16 +- crates/hir/src/lib.rs | 147 +++++----- crates/hir/src/semantics.rs | 12 +- crates/hir/src/semantics/child_by_source.rs | 5 +- crates/hir/src/semantics/source_to_def.rs | 10 +- crates/hir/src/symbols.rs | 9 +- crates/hir/src/term_search/tactics.rs | 2 +- .../src/handlers/add_missing_impl_members.rs | 2 +- .../src/handlers/add_missing_match_arms.rs | 36 +-- .../src/handlers/apply_demorgan.rs | 2 +- .../ide-assists/src/handlers/auto_import.rs | 9 +- .../src/handlers/convert_bool_to_enum.rs | 2 +- .../src/handlers/convert_for_to_while_let.rs | 2 +- .../src/handlers/convert_from_to_tryfrom.rs | 2 +- .../src/handlers/convert_into_to_from.rs | 4 +- .../handlers/convert_iter_for_each_to_for.rs | 4 +- .../convert_tuple_return_type_to_struct.rs | 5 +- .../handlers/destructure_struct_binding.rs | 5 +- .../src/handlers/expand_glob_import.rs | 8 +- .../src/handlers/extract_function.rs | 2 +- .../src/handlers/fix_visibility.rs | 4 +- .../generate_default_from_enum_variant.rs | 2 +- .../src/handlers/generate_default_from_new.rs | 2 +- .../src/handlers/generate_delegate_methods.rs | 2 +- .../src/handlers/generate_delegate_trait.rs | 2 +- .../src/handlers/generate_deref.rs | 10 +- .../handlers/generate_from_impl_for_enum.rs | 2 +- .../src/handlers/generate_function.rs | 17 +- .../ide-assists/src/handlers/generate_new.rs | 2 +- .../ide-assists/src/handlers/inline_call.rs | 4 +- .../ide-assists/src/handlers/inline_macro.rs | 2 +- .../src/handlers/qualify_method_call.rs | 2 +- .../ide-assists/src/handlers/qualify_path.rs | 2 +- .../replace_derive_with_manual_impl.rs | 4 +- crates/ide-completion/src/completions.rs | 2 +- .../src/completions/attribute/derive.rs | 2 +- .../src/completions/attribute/macro_use.rs | 2 +- crates/ide-completion/src/lib.rs | 2 +- crates/ide-completion/src/render/variant.rs | 2 +- crates/ide-db/src/defs.rs | 8 +- crates/ide-db/src/documentation.rs | 5 +- crates/ide-db/src/famous_defs.rs | 2 +- crates/ide-db/src/helpers.rs | 2 +- crates/ide-db/src/imports/import_assets.rs | 2 +- crates/ide-db/src/path_transform.rs | 4 +- crates/ide-db/src/rename.rs | 2 +- crates/ide-db/src/search.rs | 20 +- .../ide-db/src/test_data/test_doc_alias.txt | 22 +- .../test_symbol_index_collection.txt | 100 +++---- crates/ide-db/src/traits.rs | 2 +- .../src/handlers/missing_fields.rs | 4 +- .../src/handlers/no_such_field.rs | 2 +- .../trait_impl_redundant_assoc_item.rs | 2 +- .../src/handlers/unlinked_file.rs | 4 +- .../src/handlers/unresolved_field.rs | 2 +- crates/ide-diagnostics/src/lib.rs | 4 +- crates/ide/src/expand_macro.rs | 2 +- crates/ide/src/goto_definition.rs | 4 +- crates/ide/src/goto_implementation.rs | 2 +- crates/ide/src/hover/render.rs | 4 +- crates/ide/src/inlay_hints.rs | 2 +- crates/ide/src/interpret.rs | 2 +- crates/ide/src/moniker.rs | 9 +- crates/ide/src/navigation_target.rs | 20 +- crates/ide/src/runnables.rs | 6 +- crates/ide/src/static_index.rs | 2 +- .../ide/src/syntax_highlighting/highlight.rs | 4 +- crates/ide/src/test_explorer.rs | 6 +- .../rust-analyzer/src/cli/analysis_stats.rs | 8 +- crates/rust-analyzer/src/cli/diagnostics.rs | 10 +- crates/rust-analyzer/src/cli/run_tests.rs | 2 +- .../src/cli/unresolved_references.rs | 10 +- 123 files changed, 1029 insertions(+), 1123 deletions(-) diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs index 478fae67c807..6f34f43bdff3 100644 --- a/crates/base-db/src/lib.rs +++ b/crates/base-db/src/lib.rs @@ -167,12 +167,19 @@ impl Files { } } -#[salsa_macros::interned(no_lifetime, debug, constructor=from_span)] +#[salsa_macros::interned(no_lifetime, constructor=from_span)] #[derive(PartialOrd, Ord)] pub struct EditionedFileId { pub editioned_file_id: span::EditionedFileId, } +impl std::fmt::Debug for EditionedFileId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + salsa::with_attached_database(|db| self.editioned_file_id(db).fmt(f)) + .unwrap_or_else(|| f.debug_tuple("EditionedFileId").field(&self.0).finish()) + } +} + impl EditionedFileId { // Salsa already uses the name `new`... #[inline] diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs index b509e69b0d37..086c7aa18937 100644 --- a/crates/hir-def/src/attr.rs +++ b/crates/hir-def/src/attr.rs @@ -108,19 +108,19 @@ impl Attrs { let (fields, file_id, krate) = match v { VariantId::EnumVariantId(it) => { let loc = it.lookup(db); - let krate = loc.parent.lookup(db).container.krate; + let krate = loc.parent.lookup(db).container.krate(db); let source = loc.source(db); (source.value.field_list(), source.file_id, krate) } VariantId::StructId(it) => { let loc = it.lookup(db); - let krate = loc.container.krate; + let krate = loc.container.krate(db); let source = loc.source(db); (source.value.field_list(), source.file_id, krate) } VariantId::UnionId(it) => { let loc = it.lookup(db); - let krate = loc.container.krate; + let krate = loc.container.krate(db); let source = loc.source(db); ( source.value.record_field_list().map(ast::FieldList::RecordFieldList), @@ -520,7 +520,7 @@ impl AttrsWithOwner { match def { AttrDefId::ModuleId(module) => { let def_map = module.def_map(db); - let mod_data = &def_map[module.local_id]; + let mod_data = &def_map[module]; let raw_attrs = match mod_data.origin { ModuleOrigin::File { definition, declaration_tree_id, declaration, .. } => { @@ -544,7 +544,7 @@ impl AttrsWithOwner { tree.top_level_raw_attrs().clone() } }; - Attrs::expand_cfg_attr(db, module.krate, raw_attrs) + Attrs::expand_cfg_attr(db, module.krate(db), raw_attrs) } AttrDefId::FieldId(it) => db.fields_attrs(it.parent)[it.local_id].clone(), AttrDefId::EnumVariantId(it) => attrs_from_ast_id_loc(db, it), @@ -618,7 +618,7 @@ impl AttrsWithOwner { // Modules can have 2 attribute owners (the `mod x;` item, and the module file itself). let def_map = module.def_map(db); - let mod_data = &def_map[module.local_id]; + let mod_data = &def_map[module]; match mod_data.declaration_source(db) { Some(it) => { let mut map = AttrSourceMap::new(InFile::new(it.file_id, &it.value)); diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs index f024f04efe03..a0e950c1693a 100644 --- a/crates/hir-def/src/db.rs +++ b/crates/hir-def/src/db.rs @@ -418,7 +418,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId { let loc: Macro2Loc = it.lookup(db); MacroDefId { - krate: loc.container.krate, + krate: loc.container.krate(db), kind: kind(loc.expander, loc.id.file_id, loc.id.value.upcast()), local_inner: false, allow_internal_unsafe: loc.allow_internal_unsafe, @@ -429,7 +429,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId { let loc: MacroRulesLoc = it.lookup(db); MacroDefId { - krate: loc.container.krate, + krate: loc.container.krate(db), kind: kind(loc.expander, loc.id.file_id, loc.id.value.upcast()), local_inner: loc.flags.contains(MacroRulesLocFlags::LOCAL_INNER), allow_internal_unsafe: loc @@ -442,7 +442,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId { let loc = it.lookup(db); MacroDefId { - krate: loc.container.krate, + krate: loc.container.krate(db), kind: MacroDefKind::ProcMacro(loc.id, loc.expander, loc.kind), local_inner: false, allow_internal_unsafe: false, diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs index 03683ec9203c..7b88501a7380 100644 --- a/crates/hir-def/src/expr_store/lower.rs +++ b/crates/hir-def/src/expr_store/lower.rs @@ -458,6 +458,7 @@ pub struct ExprCollector<'db> { current_binding_owner: Option, awaitable_context: Option, + krate: base_db::Crate, } #[derive(Clone, Debug)] @@ -547,7 +548,7 @@ impl ExprCollector<'_> { let expander = Expander::new(db, current_file_id, def_map); ExprCollector { db, - cfg_options: module.krate().cfg_options(db), + cfg_options: module.krate(db).cfg_options(db), module, def_map, local_def_map, @@ -561,6 +562,7 @@ impl ExprCollector<'_> { awaitable_context: None, current_block_legacy_macro_defs_count: FxHashMap::default(), outer_impl_trait: false, + krate: module.krate(db), } } @@ -1940,9 +1942,8 @@ impl ExprCollector<'_> { T: ast::AstNode, { let macro_call_ptr = self.expander.in_file(syntax_ptr); - let module = self.module.local_id; - let block_call = self.def_map.modules[self.module.local_id].scope.macro_invoc( + let block_call = self.def_map.modules[self.module].scope.macro_invoc( self.expander.in_file(self.expander.ast_id_map().ast_id_for_ptr(syntax_ptr)), ); let res = match block_call { @@ -1954,7 +1955,7 @@ impl ExprCollector<'_> { .resolve_path( self.local_def_map, self.db, - module, + self.module, path, crate::item_scope::BuiltinShadowMode::Other, Some(MacroSubNs::Bang), @@ -1965,7 +1966,7 @@ impl ExprCollector<'_> { self.expander.enter_expand( self.db, mcall, - self.module.krate(), + self.krate, resolver, &mut |ptr, call| { _ = self.source_map.expansions.insert(ptr.map(|(it, _)| it), call); @@ -2095,7 +2096,8 @@ impl ExprCollector<'_> { return; }; let name = name.as_name(); - let macro_id = self.def_map.modules[DefMap::ROOT].scope.get(&name).take_macros(); + let macro_id = + self.def_map.modules[self.def_map.root].scope.get(&name).take_macros(); self.collect_macro_def(statements, macro_id); } ast::Stmt::Item(ast::Item::MacroRules(macro_)) => { @@ -2109,7 +2111,7 @@ impl ExprCollector<'_> { let name = name.as_name(); let macro_defs_count = self.current_block_legacy_macro_defs_count.entry(name.clone()).or_insert(0); - let macro_id = self.def_map.modules[DefMap::ROOT] + let macro_id = self.def_map.modules[self.def_map.root] .scope .get_legacy_macro(&name) .and_then(|it| it.get(*macro_defs_count)) @@ -2155,7 +2157,7 @@ impl ExprCollector<'_> { match block_id.map(|block_id| (block_def_map(self.db, block_id), block_id)) { Some((def_map, block_id)) => { self.store.block_scopes.push(block_id); - (def_map.module_id(DefMap::ROOT), def_map) + (def_map.root_module_id(), def_map) } None => (self.module, self.def_map), }; @@ -2238,7 +2240,7 @@ impl ExprCollector<'_> { let (resolved, _) = self.def_map.resolve_path( self.local_def_map, self.db, - self.module.local_id, + self.module, &name.clone().into(), BuiltinShadowMode::Other, None, @@ -2865,12 +2867,12 @@ impl ExprCollector<'_> { let new_v1_formatted = LangItem::FormatArguments.ty_rel_path( self.db, - self.module.krate(), + self.krate, Name::new_symbol_root(sym::new_v1_formatted), ); let unsafe_arg_new = LangItem::FormatUnsafeArg.ty_rel_path( self.db, - self.module.krate(), + self.krate, Name::new_symbol_root(sym::new), ); let new_v1_formatted = @@ -2961,7 +2963,7 @@ impl ExprCollector<'_> { let precision_expr = self.make_count(precision, argmap); let width_expr = self.make_count(width, argmap); - if self.module.krate().workspace_data(self.db).is_atleast_187() { + if self.krate.workspace_data(self.db).is_atleast_187() { // These need to match the constants in library/core/src/fmt/rt.rs. let align = match alignment { Some(FormatAlignment::Left) => 0, @@ -2996,7 +2998,7 @@ impl ExprCollector<'_> { let width = RecordLitField { name: Name::new_symbol_root(sym::width), expr: width_expr }; self.alloc_expr_desugared(Expr::RecordLit { - path: LangItem::FormatPlaceholder.path(self.db, self.module.krate()).map(Box::new), + path: LangItem::FormatPlaceholder.path(self.db, self.krate).map(Box::new), fields: Box::new([position, flags, precision, width]), spread: None, }) @@ -3004,7 +3006,7 @@ impl ExprCollector<'_> { let format_placeholder_new = { let format_placeholder_new = LangItem::FormatPlaceholder.ty_rel_path( self.db, - self.module.krate(), + self.krate, Name::new_symbol_root(sym::new), ); match format_placeholder_new { @@ -3027,7 +3029,7 @@ impl ExprCollector<'_> { let align = { let align = LangItem::FormatAlignment.ty_rel_path( self.db, - self.module.krate(), + self.krate, match alignment { Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left), Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right), @@ -3080,7 +3082,7 @@ impl ExprCollector<'_> { ))); let count_is = match LangItem::FormatCount.ty_rel_path( self.db, - self.module.krate(), + self.krate, Name::new_symbol_root(sym::Is), ) { Some(count_is) => self.alloc_expr_desugared(Expr::Path(count_is)), @@ -3098,7 +3100,7 @@ impl ExprCollector<'_> { ))); let count_param = match LangItem::FormatCount.ty_rel_path( self.db, - self.module.krate(), + self.krate, Name::new_symbol_root(sym::Param), ) { Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), @@ -3116,7 +3118,7 @@ impl ExprCollector<'_> { } None => match LangItem::FormatCount.ty_rel_path( self.db, - self.module.krate(), + self.krate, Name::new_symbol_root(sym::Implied), ) { Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), @@ -3138,7 +3140,7 @@ impl ExprCollector<'_> { let new_fn = match LangItem::FormatArgument.ty_rel_path( self.db, - self.module.krate(), + self.krate, Name::new_symbol_root(match ty { Format(Display) => sym::new_display, Format(Debug) => sym::new_debug, @@ -3161,7 +3163,7 @@ impl ExprCollector<'_> { // endregion: format fn lang_path(&self, lang: LangItem) -> Option { - lang.path(self.db, self.module.krate()) + lang.path(self.db, self.krate) } } diff --git a/crates/hir-def/src/expr_store/tests/body.rs b/crates/hir-def/src/expr_store/tests/body.rs index 29e249b07a72..58d8ad6c5aaa 100644 --- a/crates/hir-def/src/expr_store/tests/body.rs +++ b/crates/hir-def/src/expr_store/tests/body.rs @@ -32,14 +32,14 @@ fn def_map_at(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String { let (db, position) = TestDB::with_position(ra_fixture); let module = db.module_at_position(position); - module.def_map(&db).dump(&db) + salsa::plumbing::attach(&db, || module.def_map(&db).dump(&db)) } fn check_block_scopes_at(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { let (db, position) = TestDB::with_position(ra_fixture); let module = db.module_at_position(position); - let actual = module.def_map(&db).dump_block_scopes(&db); + let actual = salsa::plumbing::attach(&db, || format!("{module:#?}")); expect.assert_eq(&actual); } diff --git a/crates/hir-def/src/expr_store/tests/body/block.rs b/crates/hir-def/src/expr_store/tests/body/block.rs index 5fe72778172f..21a618344810 100644 --- a/crates/hir-def/src/expr_store/tests/body/block.rs +++ b/crates/hir-def/src/expr_store/tests/body/block.rs @@ -176,6 +176,7 @@ fn outer() { #[test] fn nested_module_scoping() { + cov_mark::check!(nested_module_scoping); check_block_scopes_at( r#" fn f() { @@ -189,10 +190,57 @@ fn f() { } "#, expect![[r#" - BlockIdLt { [salsa id]: Id(3c01) } in BlockRelativeModuleId { block: Some(BlockIdLt { [salsa id]: Id(3c00) }), local_id: Idx::(1) } - BlockIdLt { [salsa id]: Id(3c00) } in BlockRelativeModuleId { block: None, local_id: Idx::(0) } - crate scope - "#]], + ModuleIdLt { + [salsa id]: Id(3003), + krate: Crate( + Id(2000), + ), + block: Some( + BlockIdLt { + [salsa id]: Id(4001), + loc: BlockLoc { + ast_id: InFileWrapper { + file_id: FileId( + EditionedFileId( + 0, + Edition2024, + ), + ), + value: FileAstId::(ErasedFileAstId { kind: BlockExpr, index: 0, hash: DA08 }), + }, + module: ModuleIdLt { + [salsa id]: Id(3002), + krate: Crate( + Id(2000), + ), + block: Some( + BlockIdLt { + [salsa id]: Id(4000), + loc: BlockLoc { + ast_id: InFileWrapper { + file_id: FileId( + EditionedFileId( + 0, + Edition2024, + ), + ), + value: FileAstId::(ErasedFileAstId { kind: BlockExpr, index: 0, hash: 2997 }), + }, + module: ModuleIdLt { + [salsa id]: Id(3000), + krate: Crate( + Id(2000), + ), + block: None, + }, + }, + }, + ), + }, + }, + }, + ), + }"#]], ); } @@ -455,9 +503,8 @@ fn foo() { } #[test] -fn is_visible_from_same_def_map() { +fn is_visible_from_same_def_map_regression_9481() { // Regression test for https://github.com/rust-lang/rust-analyzer/issues/9481 - cov_mark::check!(is_visible_from_same_block_def_map); check_at( r#" fn outer() { @@ -474,7 +521,6 @@ fn outer() { tests: t block scope::tests - name: _ outer: vg crate diff --git a/crates/hir-def/src/find_path.rs b/crates/hir-def/src/find_path.rs index bb75621c7e07..64d4ecc88d49 100644 --- a/crates/hir-def/src/find_path.rs +++ b/crates/hir-def/src/find_path.rs @@ -39,20 +39,23 @@ pub fn find_path( // within block modules, forcing a `self` or `crate` prefix will not allow using inner items, so // default to plain paths. let item_module = item.module(db)?; - if item_module.is_within_block() { + if item_module.block(db).is_some() { prefix_kind = PrefixKind::Plain; } - cfg.prefer_no_std = cfg.prefer_no_std || db.crate_supports_no_std(from.krate()); + cfg.prefer_no_std = cfg.prefer_no_std || db.crate_supports_no_std(from.krate(db)); + let from_def_map = from.def_map(db); find_path_inner( &FindPathCtx { db, prefix: prefix_kind, cfg, ignore_local_imports, - is_std_item: item_module.krate().data(db).origin.is_lang(), + is_std_item: item_module.krate(db).data(db).origin.is_lang(), from, - from_def_map: from.def_map(db), + from_crate: from.krate(db), + crate_root: from_def_map.crate_root(db), + from_def_map, fuel: Cell::new(FIND_PATH_FUEL), }, item, @@ -100,6 +103,8 @@ struct FindPathCtx<'db> { ignore_local_imports: bool, is_std_item: bool, from: ModuleId, + from_crate: Crate, + crate_root: ModuleId, from_def_map: &'db DefMap, fuel: Cell, } @@ -116,7 +121,7 @@ fn find_path_inner(ctx: &FindPathCtx<'_>, item: ItemInNs, max_len: usize) -> Opt let may_be_in_scope = match ctx.prefix { PrefixKind::Plain | PrefixKind::BySelf => true, - PrefixKind::ByCrate => ctx.from.is_crate_root(), + PrefixKind::ByCrate => ctx.crate_root == ctx.from, }; if may_be_in_scope { // - if the item is already in scope, return the name under which it is @@ -163,8 +168,9 @@ fn find_path_for_module( // recursive base case, we can't find a path of length 0 return None; } - if let Some(crate_root) = module_id.as_crate_root() { - if !maybe_extern || crate_root == ctx.from.derive_crate_root() { + let module_crate_root = module_id.def_map(ctx.db).crate_root(ctx.db); + if module_crate_root == module_id { + if !maybe_extern || module_crate_root == ctx.crate_root { // - if the item is the crate root, return `crate` return Some(Choice { path: ModPath::from_segments(PathKind::Crate, None), @@ -175,19 +181,19 @@ fn find_path_for_module( } // - otherwise if the item is the crate root of a dependency crate, return the name from the extern prelude - let root_local_def_map = ctx.from.derive_crate_root().local_def_map(ctx.db).1; + let root_local_def_map = ctx.crate_root.local_def_map(ctx.db).1; // rev here so we prefer looking at renamed extern decls first for (name, (def_id, _extern_crate)) in root_local_def_map.extern_prelude().rev() { - if crate_root != def_id { + if module_crate_root != def_id { continue; } let name_already_occupied_in_type_ns = ctx .from_def_map - .with_ancestor_maps(ctx.db, ctx.from.local_id, &mut |def_map, local_id| { + .with_ancestor_maps(ctx.db, ctx.from, &mut |def_map, local_id| { def_map[local_id] .scope .type_(name) - .filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id.into())) + .filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id)) }) .is_some(); let kind = if name_already_occupied_in_type_ns { @@ -204,7 +210,7 @@ fn find_path_for_module( let may_be_in_scope = match ctx.prefix { PrefixKind::Plain | PrefixKind::BySelf => true, - PrefixKind::ByCrate => ctx.from.is_crate_root(), + PrefixKind::ByCrate => ctx.crate_root == ctx.from, }; if may_be_in_scope { let scope_name = find_in_scope( @@ -226,7 +232,7 @@ fn find_path_for_module( } // - if the module can be referenced as self, super or crate, do that - if let Some(kind) = is_kw_kind_relative_to_from(ctx.from_def_map, module_id, ctx.from) { + if let Some(kind) = is_kw_kind_relative_to_from(ctx.db, ctx.from_def_map, module_id, ctx.from) { if ctx.prefix != PrefixKind::ByCrate || kind == PathKind::Crate { return Some(Choice { path: ModPath::from_segments(kind, None), @@ -259,7 +265,7 @@ fn find_in_scope( ignore_local_imports: bool, ) -> Option { // FIXME: We could have multiple applicable names here, but we currently only return the first - def_map.with_ancestor_maps(db, from.local_id, &mut |def_map, local_id| { + def_map.with_ancestor_maps(db, from, &mut |def_map, local_id| { def_map[local_id].scope.names_of(item, |name, _, declared| { (declared || !ignore_local_imports).then(|| name.clone()) }) @@ -276,7 +282,7 @@ fn find_in_prelude( ) -> Option { let (prelude_module, _) = local_def_map.prelude()?; let prelude_def_map = prelude_module.def_map(db); - let prelude_scope = &prelude_def_map[prelude_module.local_id].scope; + let prelude_scope = &prelude_def_map[prelude_module].scope; let (name, vis, _declared) = prelude_scope.name_of(item)?; if !vis.is_visible_from(db, from) { return None; @@ -284,7 +290,7 @@ fn find_in_prelude( // Check if the name is in current scope and it points to the same def. let found_and_same_def = - local_def_map.with_ancestor_maps(db, from.local_id, &mut |def_map, local_id| { + local_def_map.with_ancestor_maps(db, from, &mut |def_map, local_id| { let per_ns = def_map[local_id].scope.get(name); let same_def = match item { ItemInNs::Types(it) => per_ns.take_types()? == it, @@ -302,22 +308,21 @@ fn find_in_prelude( } fn is_kw_kind_relative_to_from( + db: &dyn DefDatabase, def_map: &DefMap, item: ModuleId, from: ModuleId, ) -> Option { - if item.krate != from.krate || item.is_within_block() || from.is_within_block() { + if item.krate(db) != from.krate(db) || item.block(db).is_some() || from.block(db).is_some() { return None; } - let item = item.local_id; - let from = from.local_id; if item == from { // - if the item is the module we're in, use `self` Some(PathKind::SELF) } else if let Some(parent_id) = def_map[from].parent { if item == parent_id { // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly) - Some(if parent_id == DefMap::ROOT { PathKind::Crate } else { PathKind::Super(1) }) + Some(if parent_id == def_map.root { PathKind::Crate } else { PathKind::Super(1) }) } else { None } @@ -340,13 +345,13 @@ fn calculate_best_path( tracing::warn!( "ran out of fuel while searching for a path for item {item:?} of krate {:?} from krate {:?}", item.krate(ctx.db), - ctx.from.krate() + ctx.from_crate ); return; } ctx.fuel.set(fuel - 1); - if item.krate(ctx.db) == Some(ctx.from.krate) { + if item.krate(ctx.db) == Some(ctx.from_crate) { // Item was defined in the same crate that wants to import it. It cannot be found in any // dependency in this case. calculate_best_path_local(ctx, visited_modules, item, max_len, best_choice) @@ -361,7 +366,7 @@ fn calculate_best_path( // too (unless we can't name it at all). It could *also* be (re)exported by the same crate // that wants to import it here, but we always prefer to use the external path here. - ctx.from.krate.data(ctx.db).dependencies.iter().for_each(|dep| { + ctx.from_crate.data(ctx.db).dependencies.iter().for_each(|dep| { find_in_dep(ctx, visited_modules, item, max_len, best_choice, dep.crate_id) }); } @@ -374,7 +379,7 @@ fn find_in_sysroot( max_len: usize, best_choice: &mut Option, ) { - let dependencies = &ctx.from.krate.data(ctx.db).dependencies; + let dependencies = &ctx.from_crate.data(ctx.db).dependencies; let mut search = |lang, best_choice: &mut _| { if let Some(dep) = dependencies.iter().filter(|it| it.is_sysroot()).find(|dep| { match dep.crate_id.data(ctx.db).origin { @@ -464,26 +469,19 @@ fn calculate_best_path_local( best_choice: &mut Option, ) { // FIXME: cache the `find_local_import_locations` output? - find_local_import_locations( - ctx.db, - item, - ctx.from, - ctx.from_def_map, - visited_modules, - |visited_modules, name, module_id| { - // we are looking for paths of length up to best_path_len, any longer will make it be - // less optimal. The -1 is due to us pushing name onto it afterwards. - if let Some(choice) = find_path_for_module( - ctx, - visited_modules, - module_id, - false, - best_choice.as_ref().map_or(max_len, |it| it.path.len()) - 1, - ) { - Choice::try_select(best_choice, choice, ctx.cfg.prefer_prelude, name.clone()); - } - }, - ); + find_local_import_locations(ctx, item, visited_modules, |visited_modules, name, module_id| { + // we are looking for paths of length up to best_path_len, any longer will make it be + // less optimal. The -1 is due to us pushing name onto it afterwards. + if let Some(choice) = find_path_for_module( + ctx, + visited_modules, + module_id, + false, + best_choice.as_ref().map_or(max_len, |it| it.path.len()) - 1, + ) { + Choice::try_select(best_choice, choice, ctx.cfg.prefer_prelude, name.clone()); + } + }); } #[derive(Debug)] @@ -561,14 +559,13 @@ fn path_kind_len(kind: PathKind) -> usize { /// Finds locations in `from.krate` from which `item` can be imported by `from`. fn find_local_import_locations( - db: &dyn DefDatabase, + ctx: &FindPathCtx<'_>, item: ItemInNs, - from: ModuleId, - def_map: &DefMap, visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, mut cb: impl FnMut(&mut FxHashSet<(ItemInNs, ModuleId)>, &Name, ModuleId), ) { let _p = tracing::info_span!("find_local_import_locations").entered(); + let db = ctx.db; // `from` can import anything below `from` with visibility of at least `from`, and anything // above `from` with any visibility. That means we do not need to descend into private siblings @@ -576,15 +573,16 @@ fn find_local_import_locations( // Compute the initial worklist. We start with all direct child modules of `from` as well as all // of its (recursive) parent modules. - let mut worklist = def_map[from.local_id] + let mut worklist = ctx.from_def_map[ctx.from] .children .values() - .map(|&child| def_map.module_id(child)) - .chain(iter::successors(from.containing_module(db), |m| m.containing_module(db))) + .copied() + .chain(iter::successors(ctx.from.containing_module(db), |m| m.containing_module(db))) .zip(iter::repeat(false)) .collect::>(); - let def_map = def_map.crate_root().def_map(db); + let def_map = + if ctx.crate_root == ctx.from { ctx.from_def_map } else { ctx.crate_root.def_map(db) }; let mut block_def_map; let mut cursor = 0; @@ -595,17 +593,17 @@ fn find_local_import_locations( continue; } *processed = true; - let data = if module.block.is_some() { + let data = if module.block(db).is_some() { // Re-query the block's DefMap block_def_map = module.def_map(db); - &block_def_map[module.local_id] + &block_def_map[module] } else { // Reuse the root DefMap - &def_map[module.local_id] + &def_map[module] }; if let Some((name, vis, declared)) = data.scope.name_of(item) { - if vis.is_visible_from(db, from) { + if vis.is_visible_from(db, ctx.from) { let is_pub_or_explicit = match vis { Visibility::Module(_, VisibilityExplicitness::Explicit) => { cov_mark::hit!(explicit_private_imports); @@ -631,7 +629,7 @@ fn find_local_import_locations( // Descend into all modules visible from `from`. for (module, vis) in data.scope.modules_in_scope() { - if module.krate != from.krate { + if module.krate(db) != ctx.from.krate(db) { // We don't need to look at modules from other crates as our item has to be in the // current crate continue; @@ -640,7 +638,7 @@ fn find_local_import_locations( continue; } - if vis.is_visible_from(db, from) { + if vis.is_visible_from(db, ctx.from) { worklist.push((module, false)); } } @@ -693,7 +691,7 @@ mod tests { .resolve_path( local_def_map, &db, - module.local_id, + module, &mod_path, crate::item_scope::BuiltinShadowMode::Module, None, diff --git a/crates/hir-def/src/import_map.rs b/crates/hir-def/src/import_map.rs index a6138fb6821d..a0e9430577c7 100644 --- a/crates/hir-def/src/import_map.rs +++ b/crates/hir-def/src/import_map.rs @@ -16,7 +16,7 @@ use crate::{ AssocItemId, AttrDefId, Complete, FxIndexMap, ModuleDefId, ModuleId, TraitId, db::DefDatabase, item_scope::{ImportOrExternCrate, ItemInNs}, - nameres::{DefMap, crate_def_map}, + nameres::crate_def_map, visibility::Visibility, }; @@ -133,7 +133,7 @@ impl ImportMap { let mut map = FxIndexMap::default(); // We look only into modules that are public(ly reexported), starting with the crate root. - let root = def_map.module_id(DefMap::ROOT); + let root = def_map.root_module_id(); let mut worklist = vec![root]; let mut visited = FxHashSet::default(); @@ -142,12 +142,12 @@ impl ImportMap { continue; } let ext_def_map; - let mod_data = if module.krate == krate { - &def_map[module.local_id] + let mod_data = if module.krate(db) == krate { + &def_map[module] } else { // The crate might reexport a module defined in another crate. ext_def_map = module.def_map(db); - &ext_def_map[module.local_id] + &ext_def_map[module] }; let visible_items = mod_data.scope.entries().filter_map(|(name, per_ns)| { @@ -622,9 +622,8 @@ mod tests { assert!(def_map.block_id().is_none(), "block local items should not be in `ImportMap`"); while let Some(parent) = module.containing_module(db) { - let parent_data = &def_map[parent.local_id]; - let (name, _) = - parent_data.children.iter().find(|(_, id)| **id == module.local_id).unwrap(); + let parent_data = &def_map[parent]; + let (name, _) = parent_data.children.iter().find(|(_, id)| **id == module).unwrap(); segments.push(name); module = parent; } diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs index 8591874eb943..583781211ec4 100644 --- a/crates/hir-def/src/item_scope.rs +++ b/crates/hir-def/src/item_scope.rs @@ -17,7 +17,7 @@ use thin_vec::ThinVec; use crate::{ AdtId, BuiltinType, ConstId, ExternBlockId, ExternCrateId, FxIndexMap, HasModule, ImplId, - LocalModuleId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, UseId, + Lookup, MacroId, ModuleDefId, ModuleId, TraitId, UseId, db::DefDatabase, per_ns::{Item, MacrosItem, PerNs, TypesItem, ValuesItem}, visibility::{Visibility, VisibilityExplicitness}, @@ -25,9 +25,9 @@ use crate::{ #[derive(Debug, Default)] pub struct PerNsGlobImports { - types: FxHashSet<(LocalModuleId, Name)>, - values: FxHashSet<(LocalModuleId, Name)>, - macros: FxHashSet<(LocalModuleId, Name)>, + types: FxHashSet<(ModuleId, Name)>, + values: FxHashSet<(ModuleId, Name)>, + macros: FxHashSet<(ModuleId, Name)>, } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -133,13 +133,13 @@ pub struct GlobId { } impl PerNsGlobImports { - pub(crate) fn contains_type(&self, module_id: LocalModuleId, name: Name) -> bool { + pub(crate) fn contains_type(&self, module_id: ModuleId, name: Name) -> bool { self.types.contains(&(module_id, name)) } - pub(crate) fn contains_value(&self, module_id: LocalModuleId, name: Name) -> bool { + pub(crate) fn contains_value(&self, module_id: ModuleId, name: Name) -> bool { self.values.contains(&(module_id, name)) } - pub(crate) fn contains_macro(&self, module_id: LocalModuleId, name: Name) -> bool { + pub(crate) fn contains_macro(&self, module_id: ModuleId, name: Name) -> bool { self.macros.contains(&(module_id, name)) } } @@ -268,7 +268,7 @@ impl ItemScope { ImportOrDef::Import(i) => { let module_id = i.use_.lookup(db).container; def_map = module_id.def_map(db); - scope = &def_map[module_id.local_id].scope; + scope = &def_map[module_id].scope; import = i; } ImportOrDef::Def(ModuleDefId::MacroId(def)) => { @@ -284,7 +284,7 @@ impl ItemScope { ImportOrDef::Import(i) => { let module_id = i.use_.lookup(db).container; def_map = module_id.def_map(db); - scope = &def_map[module_id.local_id].scope; + scope = &def_map[module_id].scope; import = i; } ImportOrDef::Def(def) => { @@ -300,7 +300,7 @@ impl ItemScope { ImportOrDef::Import(i) => { let module_id = i.use_.lookup(db).container; def_map = module_id.def_map(db); - scope = &def_map[module_id.local_id].scope; + scope = &def_map[module_id].scope; import = i; } ImportOrDef::Def(def) => { @@ -579,7 +579,7 @@ impl ItemScope { pub(crate) fn push_res_with_import( &mut self, glob_imports: &mut PerNsGlobImports, - lookup: (LocalModuleId, Name), + lookup: (ModuleId, Name), def: PerNs, import: Option, ) -> bool { @@ -913,8 +913,8 @@ impl ItemInNs { /// Returns the crate defining this item (or `None` if `self` is built-in). pub fn krate(&self, db: &dyn DefDatabase) -> Option { match self { - ItemInNs::Types(id) | ItemInNs::Values(id) => id.module(db).map(|m| m.krate), - ItemInNs::Macros(id) => Some(id.module(db).krate), + ItemInNs::Types(id) | ItemInNs::Values(id) => id.module(db).map(|m| m.krate(db)), + ItemInNs::Macros(id) => Some(id.module(db).krate(db)), } } diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index e7ab2b4d77d1..ae1ccd948374 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -74,7 +74,6 @@ use hir_expand::{ name::Name, proc_macro::{CustomProcMacroExpander, ProcMacroKind}, }; -use la_arena::Idx; use nameres::DefMap; use span::{AstIdNode, Edition, FileAstId, SyntaxContext}; use stdx::impl_from; @@ -329,14 +328,14 @@ pub enum MacroExpander { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ProcMacroLoc { - pub container: CrateRootModuleId, + pub container: ModuleId, pub id: AstId, pub expander: CustomProcMacroExpander, pub kind: ProcMacroKind, pub edition: Edition, } impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro); -impl_loc!(ProcMacroLoc, id: Fn, container: CrateRootModuleId); +impl_loc!(ProcMacroLoc, id: Fn, container: ModuleId); #[derive(Debug, Hash, PartialEq, Eq, Clone)] pub struct BlockLoc { @@ -365,164 +364,75 @@ impl hir_expand::Lookup for BlockId { } } -/// A `ModuleId` that is always a crate's root module. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct CrateRootModuleId { - krate: Crate, -} - -impl CrateRootModuleId { - pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap { - crate_def_map(db, self.krate) - } - - pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) { - let def_map = crate_local_def_map(db, self.krate); - (def_map.def_map(db), def_map.local(db)) - } - - pub fn krate(self) -> Crate { - self.krate - } -} - -impl HasModule for CrateRootModuleId { - #[inline] - fn module(&self, _db: &dyn DefDatabase) -> ModuleId { - ModuleId { krate: self.krate, block: None, local_id: DefMap::ROOT } - } - - #[inline] - fn krate(&self, _db: &dyn DefDatabase) -> Crate { - self.krate - } -} - -impl PartialEq for CrateRootModuleId { - fn eq(&self, other: &ModuleId) -> bool { - other.block.is_none() && other.local_id == DefMap::ROOT && self.krate == other.krate - } -} -impl PartialEq for ModuleId { - fn eq(&self, other: &CrateRootModuleId) -> bool { - other == self - } -} - -impl From for ModuleId { - fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self { - ModuleId { krate, block: None, local_id: DefMap::ROOT } - } -} - -impl From for ModuleDefId { - fn from(value: CrateRootModuleId) -> Self { - ModuleDefId::ModuleId(value.into()) - } -} - -impl From for CrateRootModuleId { - fn from(krate: Crate) -> Self { - CrateRootModuleId { krate } - } -} - -impl TryFrom for CrateRootModuleId { - type Error = (); - - fn try_from(ModuleId { krate, block, local_id }: ModuleId) -> Result { - if block.is_none() && local_id == DefMap::ROOT { - Ok(CrateRootModuleId { krate }) - } else { - Err(()) - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct ModuleId { - krate: Crate, +#[salsa_macros::tracked(debug)] +#[derive(PartialOrd, Ord)] +pub struct ModuleIdLt<'db> { + /// The crate this module belongs to. + pub krate: Crate, /// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the /// `BlockId` of that block expression. If `None`, this module is part of the crate-level /// `DefMap` of `krate`. - block: Option, - /// The module's ID in its originating `DefMap`. - pub local_id: LocalModuleId, + pub block: Option, } +pub type ModuleId = ModuleIdLt<'static>; +impl ModuleIdLt<'_> { + /// # SAFETY + /// + /// you know + pub unsafe fn to_static(self) -> ModuleId { + unsafe { std::mem::transmute(self) } + } +} impl ModuleId { + /// # SAFETY + /// + /// you know + pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> ModuleIdLt<'db> { + unsafe { std::mem::transmute(self) } + } + pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap { - match self.block { + match self.block(db) { Some(block) => block_def_map(db, block), - None => crate_def_map(db, self.krate), + None => crate_def_map(db, self.krate(db)), } } pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) { - match self.block { + match self.block(db) { Some(block) => (block_def_map(db, block), self.only_local_def_map(db)), None => { - let def_map = crate_local_def_map(db, self.krate); + let def_map = crate_local_def_map(db, self.krate(db)); (def_map.def_map(db), def_map.local(db)) } } } pub(crate) fn only_local_def_map(self, db: &dyn DefDatabase) -> &LocalDefMap { - crate_local_def_map(db, self.krate).local(db) + crate_local_def_map(db, self.krate(db)).local(db) } pub fn crate_def_map(self, db: &dyn DefDatabase) -> &DefMap { - crate_def_map(db, self.krate) - } - - pub fn krate(self) -> Crate { - self.krate + crate_def_map(db, self.krate(db)) } pub fn name(self, db: &dyn DefDatabase) -> Option { let def_map = self.def_map(db); - let parent = def_map[self.local_id].parent?; + let parent = def_map[self].parent?; def_map[parent].children.iter().find_map(|(name, module_id)| { - if *module_id == self.local_id { Some(name.clone()) } else { None } + if *module_id == self { Some(name.clone()) } else { None } }) } /// Returns the module containing `self`, either the parent `mod`, or the module (or block) containing /// the block, if `self` corresponds to a block expression. pub fn containing_module(self, db: &dyn DefDatabase) -> Option { - self.def_map(db).containing_module(self.local_id) + self.def_map(db).containing_module(self) } - pub fn containing_block(self) -> Option { - self.block - } - - pub fn is_block_module(self) -> bool { - self.block.is_some() && self.local_id == DefMap::ROOT - } - - pub fn is_within_block(self) -> bool { - self.block.is_some() - } - - /// Returns the [`CrateRootModuleId`] for this module if it is the crate root module. - pub fn as_crate_root(&self) -> Option { - if self.local_id == DefMap::ROOT && self.block.is_none() { - Some(CrateRootModuleId { krate: self.krate }) - } else { - None - } - } - - /// Returns the [`CrateRootModuleId`] for this module. - pub fn derive_crate_root(&self) -> CrateRootModuleId { - CrateRootModuleId { krate: self.krate } - } - - /// Whether this module represents the crate root module - pub fn is_crate_root(&self) -> bool { - self.local_id == DefMap::ROOT && self.block.is_none() + pub fn is_block_module(self, db: &dyn DefDatabase) -> bool { + self.block(db).is_some() && self.def_map(db).root_module_id() == self } } @@ -533,9 +443,6 @@ impl HasModule for ModuleId { } } -/// An ID of a module, **local** to a `DefMap`. -pub type LocalModuleId = Idx; - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct FieldId { pub parent: VariantId, @@ -615,7 +522,7 @@ pub struct LifetimeParamId { pub local_id: LocalLifetimeParamId, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)] pub enum ItemContainerId { ExternBlockId(ExternBlockId), ModuleId(ModuleId), @@ -1019,7 +926,7 @@ pub trait HasModule { #[inline] #[doc(alias = "crate")] fn krate(&self, db: &dyn DefDatabase) -> Crate { - self.module(db).krate + self.module(db).krate(db) } } @@ -1123,7 +1030,7 @@ impl HasModule for Macro2Id { impl HasModule for ProcMacroId { #[inline] fn module(&self, db: &dyn DefDatabase) -> ModuleId { - self.lookup(db).container.into() + self.lookup(db).container } } diff --git a/crates/hir-def/src/macro_expansion_tests/mbe.rs b/crates/hir-def/src/macro_expansion_tests/mbe.rs index eea50d16f5a0..3a655b74ad3b 100644 --- a/crates/hir-def/src/macro_expansion_tests/mbe.rs +++ b/crates/hir-def/src/macro_expansion_tests/mbe.rs @@ -35,9 +35,9 @@ macro_rules! f { }; } -struct#0:MacroRules[8C8E, 0]@58..64#14336# MyTraitMap2#0:MacroCall[D499, 0]@31..42#ROOT2024# {#0:MacroRules[8C8E, 0]@72..73#14336# - map#0:MacroRules[8C8E, 0]@86..89#14336#:#0:MacroRules[8C8E, 0]@89..90#14336# #0:MacroRules[8C8E, 0]@89..90#14336#::#0:MacroRules[8C8E, 0]@91..93#14336#std#0:MacroRules[8C8E, 0]@93..96#14336#::#0:MacroRules[8C8E, 0]@96..98#14336#collections#0:MacroRules[8C8E, 0]@98..109#14336#::#0:MacroRules[8C8E, 0]@109..111#14336#HashSet#0:MacroRules[8C8E, 0]@111..118#14336#<#0:MacroRules[8C8E, 0]@118..119#14336#(#0:MacroRules[8C8E, 0]@119..120#14336#)#0:MacroRules[8C8E, 0]@120..121#14336#>#0:MacroRules[8C8E, 0]@121..122#14336#,#0:MacroRules[8C8E, 0]@122..123#14336# -}#0:MacroRules[8C8E, 0]@132..133#14336# +struct#0:MacroRules[8C8E, 0]@58..64#15360# MyTraitMap2#0:MacroCall[D499, 0]@31..42#ROOT2024# {#0:MacroRules[8C8E, 0]@72..73#15360# + map#0:MacroRules[8C8E, 0]@86..89#15360#:#0:MacroRules[8C8E, 0]@89..90#15360# #0:MacroRules[8C8E, 0]@89..90#15360#::#0:MacroRules[8C8E, 0]@91..93#15360#std#0:MacroRules[8C8E, 0]@93..96#15360#::#0:MacroRules[8C8E, 0]@96..98#15360#collections#0:MacroRules[8C8E, 0]@98..109#15360#::#0:MacroRules[8C8E, 0]@109..111#15360#HashSet#0:MacroRules[8C8E, 0]@111..118#15360#<#0:MacroRules[8C8E, 0]@118..119#15360#(#0:MacroRules[8C8E, 0]@119..120#15360#)#0:MacroRules[8C8E, 0]@120..121#15360#>#0:MacroRules[8C8E, 0]@121..122#15360#,#0:MacroRules[8C8E, 0]@122..123#15360# +}#0:MacroRules[8C8E, 0]@132..133#15360# "#]], ); } @@ -197,7 +197,7 @@ macro_rules! mk_struct { #[macro_use] mod foo; -struct#1:MacroRules[E572, 0]@59..65#14336# Foo#0:MacroCall[BDD3, 0]@32..35#ROOT2024#(#1:MacroRules[E572, 0]@70..71#14336#u32#0:MacroCall[BDD3, 0]@41..44#ROOT2024#)#1:MacroRules[E572, 0]@74..75#14336#;#1:MacroRules[E572, 0]@75..76#14336# +struct#1:MacroRules[E572, 0]@59..65#15360# Foo#0:MacroCall[BDD3, 0]@32..35#ROOT2024#(#1:MacroRules[E572, 0]@70..71#15360#u32#0:MacroCall[BDD3, 0]@41..44#ROOT2024#)#1:MacroRules[E572, 0]@74..75#15360#;#1:MacroRules[E572, 0]@75..76#15360# "#]], ); } @@ -423,10 +423,10 @@ m! { foo, bar } macro_rules! m { ($($i:ident),*) => ( impl Bar { $(fn $i() {})* } ); } -impl#\14336# Bar#\14336# {#\14336# - fn#\14336# foo#\ROOT2024#(#\14336#)#\14336# {#\14336#}#\14336# - fn#\14336# bar#\ROOT2024#(#\14336#)#\14336# {#\14336#}#\14336# -}#\14336# +impl#\15360# Bar#\15360# {#\15360# + fn#\15360# foo#\ROOT2024#(#\15360#)#\15360# {#\15360#}#\15360# + fn#\15360# bar#\ROOT2024#(#\15360#)#\15360# {#\15360#}#\15360# +}#\15360# "#]], ); } diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs index b5321560918e..9b5aa431ec75 100644 --- a/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -128,8 +128,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream let db = TestDB::with_files_extra_proc_macros(ra_fixture, extra_proc_macros); let krate = db.fetch_test_crate(); let def_map = crate_def_map(&db, krate); - let local_id = DefMap::ROOT; - let source = def_map[local_id].definition_source(&db); + let source = def_map[def_map.root].definition_source(&db); let source_file = match source.value { ModuleSource::SourceFile(it) => it, ModuleSource::Module(_) | ModuleSource::BlockExpr(_) => panic!(), @@ -206,7 +205,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream expanded_text.replace_range(range, &text); } - for decl_id in def_map[local_id].scope.declarations() { + for decl_id in def_map[def_map.root].scope.declarations() { // FIXME: I'm sure there's already better way to do this let src = match decl_id { ModuleDefId::AdtId(AdtId::StructId(struct_id)) => { @@ -246,7 +245,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream } } - for impl_id in def_map[local_id].scope.impls() { + for impl_id in def_map[def_map.root].scope.impls() { let src = impl_id.lookup(&db).source(&db); if let Some(macro_file) = src.file_id.macro_file() { if let MacroKind::DeriveBuiltIn | MacroKind::Derive = macro_file.kind(&db) { diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 610bb6b00b02..0419d1c8769d 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -58,7 +58,7 @@ pub mod proc_macro; #[cfg(test)] mod tests; -use std::ops::Deref; +use std::ops::{Deref, DerefMut, Index, IndexMut}; use base_db::Crate; use hir_expand::{ @@ -67,7 +67,6 @@ use hir_expand::{ }; use intern::Symbol; use itertools::Itertools; -use la_arena::Arena; use rustc_hash::{FxHashMap, FxHashSet}; use span::{Edition, FileAstId, FileId, ROOT_ERASED_FILE_AST_ID}; use stdx::format_to; @@ -76,8 +75,8 @@ use triomphe::Arc; use tt::TextRange; use crate::{ - AstId, BlockId, BlockLoc, CrateRootModuleId, ExternCrateId, FunctionId, FxIndexMap, - LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId, + AstId, BlockId, BlockLoc, ExternCrateId, FunctionId, FxIndexMap, Lookup, MacroExpander, + MacroId, ModuleId, ModuleIdLt, ProcMacroId, UseId, db::DefDatabase, item_scope::{BuiltinShadowMode, ItemScope}, item_tree::TreeId, @@ -109,7 +108,7 @@ pub struct LocalDefMap { // FIXME: There are probably some other things that could be here, but this is less severe and you // need to be careful with things that block def maps also have. /// The extern prelude which contains all root modules of external crates that are in scope. - extern_prelude: FxIndexMap)>, + extern_prelude: FxIndexMap)>, } impl std::hash::Hash for LocalDefMap { @@ -135,8 +134,7 @@ impl LocalDefMap { pub(crate) fn extern_prelude( &self, - ) -> impl DoubleEndedIterator))> + '_ - { + ) -> impl DoubleEndedIterator))> + '_ { self.extern_prelude.iter().map(|(name, &def)| (name, def)) } } @@ -157,8 +155,9 @@ pub struct DefMap { /// When this is a block def map, this will hold the block id of the block and module that /// contains this block. block: Option, + pub root: ModuleId, /// The modules and their data declared in this crate. - pub modules: Arena, + pub modules: ModulesMap, /// The prelude module for this crate. This either comes from an import /// marked with the `prelude_import` attribute, or (in the normal case) from /// a dependency (`std` or `core`). @@ -250,33 +249,22 @@ struct BlockInfo { /// The `BlockId` this `DefMap` was created from. block: BlockId, /// The containing module. - parent: BlockRelativeModuleId, + parent: ModuleId, } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -struct BlockRelativeModuleId { - block: Option, - local_id: LocalModuleId, -} - -impl BlockRelativeModuleId { - fn def_map(self, db: &dyn DefDatabase, krate: Crate) -> &DefMap { - self.into_module(krate).def_map(db) - } - - fn into_module(self, krate: Crate) -> ModuleId { - ModuleId { krate, block: self.block, local_id: self.local_id } - } +impl std::ops::Index for DefMap { + type Output = ModuleData; - fn is_block_module(self) -> bool { - self.block.is_some() && self.local_id == DefMap::ROOT + fn index(&self, id: ModuleId) -> &ModuleData { + self.modules + .get(&id) + .unwrap_or_else(|| panic!("ModuleId not found in ModulesMap {:#?}: {id:#?}", self.root)) } } -impl std::ops::Index for DefMap { - type Output = ModuleData; - fn index(&self, id: LocalModuleId) -> &ModuleData { - &self.modules[id] +impl std::ops::IndexMut for DefMap { + fn index_mut(&mut self, id: ModuleId) -> &mut ModuleData { + &mut self.modules[id] } } @@ -363,8 +351,8 @@ pub struct ModuleData { /// Parent module in the same `DefMap`. /// /// [`None`] for block modules because they are always its `DefMap`'s root. - pub parent: Option, - pub children: FxIndexMap, + pub parent: Option, + pub children: FxIndexMap, pub scope: ItemScope, } @@ -404,10 +392,16 @@ pub(crate) fn crate_local_def_map(db: &dyn DefDatabase, crate_id: Crate) -> DefM let module_data = ModuleData::new( ModuleOrigin::CrateRoot { definition: krate.root_file_id(db) }, Visibility::Public, + None, ); - let def_map = - DefMap::empty(crate_id, Arc::new(DefMapCrateData::new(krate.edition)), module_data, None); + let def_map = DefMap::empty( + db, + crate_id, + Arc::new(DefMapCrateData::new(krate.edition)), + module_data, + None, + ); let (def_map, local_def_map) = collector::collect_defs( db, def_map, @@ -422,22 +416,17 @@ pub(crate) fn crate_local_def_map(db: &dyn DefDatabase, crate_id: Crate) -> DefM pub fn block_def_map(db: &dyn DefDatabase, block_id: BlockId) -> DefMap { let BlockLoc { ast_id, module } = block_id.lookup(db); - let visibility = Visibility::Module( - ModuleId { krate: module.krate, local_id: DefMap::ROOT, block: module.block }, - VisibilityExplicitness::Implicit, - ); + let visibility = Visibility::Module(module, VisibilityExplicitness::Implicit); let module_data = - ModuleData::new(ModuleOrigin::BlockExpr { block: ast_id, id: block_id }, visibility); + ModuleData::new(ModuleOrigin::BlockExpr { block: ast_id, id: block_id }, visibility, None); - let local_def_map = crate_local_def_map(db, module.krate); + let local_def_map = crate_local_def_map(db, module.krate(db)); let def_map = DefMap::empty( - module.krate, + db, + module.krate(db), local_def_map.def_map(db).data.clone(), module_data, - Some(BlockInfo { - block: block_id, - parent: BlockRelativeModuleId { block: module.block, local_id: module.local_id }, - }), + Some(BlockInfo { block: block_id, parent: module }), ); let (def_map, _) = collector::collect_defs( @@ -450,25 +439,24 @@ pub fn block_def_map(db: &dyn DefDatabase, block_id: BlockId) -> DefMap { } impl DefMap { - /// The module id of a crate or block root. - pub const ROOT: LocalModuleId = LocalModuleId::from_raw(la_arena::RawIdx::from_u32(0)); - pub fn edition(&self) -> Edition { self.data.edition } fn empty( + db: &dyn DefDatabase, krate: Crate, crate_data: Arc, module_data: ModuleData, block: Option, ) -> DefMap { - let mut modules: Arena = Arena::default(); - let root = modules.alloc(module_data); - assert_eq!(root, Self::ROOT); + let mut modules = ModulesMap::new(); + let root = unsafe { ModuleIdLt::new(db, krate, block.map(|it| it.block)).to_static() }; + modules.insert(root, module_data); DefMap { block, + root, modules, krate, prelude: None, @@ -486,6 +474,7 @@ impl DefMap { diagnostics, modules, derive_helpers_in_scope, + root: _, block: _, krate: _, prelude: _, @@ -510,7 +499,7 @@ impl DefMap { &'a self, db: &'a dyn DefDatabase, file_id: FileId, - ) -> impl Iterator + 'a { + ) -> impl Iterator + 'a { self.modules .iter() .filter(move |(_id, data)| { @@ -519,7 +508,7 @@ impl DefMap { .map(|(id, _data)| id) } - pub fn modules(&self) -> impl Iterator + '_ { + pub fn modules(&self) -> impl Iterator + '_ { self.modules.iter() } @@ -558,40 +547,32 @@ impl DefMap { self.krate } - pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId { - let block = self.block.map(|b| b.block); - ModuleId { krate: self.krate, local_id, block } - } - - pub fn crate_root(&self) -> CrateRootModuleId { - CrateRootModuleId { krate: self.krate } + #[inline] + pub fn crate_root(&self, db: &dyn DefDatabase) -> ModuleId { + match self.block { + Some(_) => crate_def_map(db, self.krate()).root, + None => self.root, + } } /// This is the same as [`Self::crate_root`] for crate def maps, but for block def maps, it /// returns the root block module. pub fn root_module_id(&self) -> ModuleId { - self.module_id(Self::ROOT) + self.root } /// If this `DefMap` is for a block expression, returns the module containing the block (which /// might again be a block, or a module inside a block). pub fn parent(&self) -> Option { - let BlockRelativeModuleId { block, local_id } = self.block?.parent; - Some(ModuleId { krate: self.krate, block, local_id }) + Some(self.block?.parent) } /// Returns the module containing `local_mod`, either the parent `mod`, or the module (or block) containing /// the block, if `self` corresponds to a block expression. - pub fn containing_module(&self, local_mod: LocalModuleId) -> Option { + pub fn containing_module(&self, local_mod: ModuleId) -> Option { match self[local_mod].parent { - Some(parent) => Some(self.module_id(parent)), - None => { - self.block.map( - |BlockInfo { parent: BlockRelativeModuleId { block, local_id }, .. }| { - ModuleId { krate: self.krate, block, local_id } - }, - ) - } + Some(parent) => Some(parent), + None => self.block.map(|BlockInfo { parent, .. }| parent), } } @@ -609,30 +590,21 @@ impl DefMap { // even), as this should be a great debugging aid. pub fn dump(&self, db: &dyn DefDatabase) -> String { let mut buf = String::new(); - let mut arc; let mut current_map = self; while let Some(block) = current_map.block { - go(&mut buf, db, current_map, "block scope", Self::ROOT); + go(&mut buf, db, current_map, "block scope", current_map.root); buf.push('\n'); - arc = block.parent.def_map(db, self.krate); - current_map = arc; + current_map = block.parent.def_map(db); } - go(&mut buf, db, current_map, "crate", Self::ROOT); + go(&mut buf, db, current_map, "crate", current_map.root); return buf; - fn go( - buf: &mut String, - db: &dyn DefDatabase, - map: &DefMap, - path: &str, - module: LocalModuleId, - ) { + fn go(buf: &mut String, db: &dyn DefDatabase, map: &DefMap, path: &str, module: ModuleId) { format_to!(buf, "{}\n", path); - map.modules[module].scope.dump(db, buf); + map[module].scope.dump(db, buf); - for (name, child) in - map.modules[module].children.iter().sorted_by(|a, b| Ord::cmp(&a.0, &b.0)) + for (name, child) in map[module].children.iter().sorted_by(|a, b| Ord::cmp(&a.0, &b.0)) { let path = format!("{path}::{}", name.display(db, Edition::LATEST)); buf.push('\n'); @@ -640,20 +612,6 @@ impl DefMap { } } } - - pub fn dump_block_scopes(&self, db: &dyn DefDatabase) -> String { - let mut buf = String::new(); - let mut arc; - let mut current_map = self; - while let Some(block) = current_map.block { - format_to!(buf, "{:?} in {:?}\n", block.block, block.parent); - arc = block.parent.def_map(db, self.krate); - current_map = arc; - } - - format_to!(buf, "crate scope\n"); - buf - } } impl DefMap { @@ -673,7 +631,7 @@ impl DefMap { &self, local_def_map: &LocalDefMap, db: &dyn DefDatabase, - original_module: LocalModuleId, + original_module: ModuleId, path: &ModPath, shadow: BuiltinShadowMode, expected_macro_subns: Option, @@ -696,7 +654,7 @@ impl DefMap { &self, local_def_map: &LocalDefMap, db: &dyn DefDatabase, - original_module: LocalModuleId, + original_module: ModuleId, path: &ModPath, shadow: BuiltinShadowMode, ) -> (PerNs, Option, ResolvePathResultPrefixInfo) { @@ -719,16 +677,16 @@ impl DefMap { pub(crate) fn with_ancestor_maps( &self, db: &dyn DefDatabase, - local_mod: LocalModuleId, - f: &mut dyn FnMut(&DefMap, LocalModuleId) -> Option, + local_mod: ModuleId, + f: &mut dyn FnMut(&DefMap, ModuleId) -> Option, ) -> Option { if let Some(it) = f(self, local_mod) { return Some(it); } let mut block = self.block; while let Some(block_info) = block { - let parent = block_info.parent.def_map(db, self.krate); - if let Some(it) = f(parent, block_info.parent.local_id) { + let parent = block_info.parent.def_map(db); + if let Some(it) = f(parent, block_info.parent) { return Some(it); } block = parent.block; @@ -739,11 +697,15 @@ impl DefMap { } impl ModuleData { - pub(crate) fn new(origin: ModuleOrigin, visibility: Visibility) -> Self { + pub(crate) fn new( + origin: ModuleOrigin, + visibility: Visibility, + parent: Option, + ) -> Self { ModuleData { origin, visibility, - parent: None, + parent, children: Default::default(), scope: ItemScope::default(), } @@ -858,3 +820,53 @@ fn sub_namespace_match(candidate: Option, expected: Option true, } } + +/// A newtype wrapper around `FxHashMap` that implements `IndexMut`. +#[derive(Debug, PartialEq, Eq)] +pub struct ModulesMap { + inner: FxIndexMap, +} + +impl ModulesMap { + fn new() -> Self { + Self { inner: FxIndexMap::default() } + } + + fn iter(&self) -> impl Iterator + '_ { + self.inner.iter().map(|(&k, v)| (k, v)) + } + + fn iter_mut(&mut self) -> impl Iterator + '_ { + self.inner.iter_mut().map(|(&k, v)| (k, v)) + } +} + +impl Deref for ModulesMap { + type Target = FxIndexMap; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for ModulesMap { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + +impl Index for ModulesMap { + type Output = ModuleData; + + fn index(&self, id: ModuleId) -> &ModuleData { + self.inner.get(&id).unwrap_or_else(|| panic!("ModuleId not found in ModulesMap: {id:#?}")) + } +} + +impl IndexMut for ModulesMap { + fn index_mut(&mut self, id: ModuleId) -> &mut ModuleData { + self.inner + .get_mut(&id) + .unwrap_or_else(|| panic!("ModuleId not found in ModulesMap: {id:#?}")) + } +} diff --git a/crates/hir-def/src/nameres/assoc.rs b/crates/hir-def/src/nameres/assoc.rs index cf123d14f502..00678511cf26 100644 --- a/crates/hir-def/src/nameres/assoc.rs +++ b/crates/hir-def/src/nameres/assoc.rs @@ -158,7 +158,7 @@ impl<'a> AssocItemCollector<'a> { local_def_map, ast_id_map: db.ast_id_map(file_id), span_map: db.span_map(file_id), - cfg_options: module_id.krate.cfg_options(db), + cfg_options: module_id.krate(db).cfg_options(db), file_id, container, items: Vec::new(), @@ -188,7 +188,7 @@ impl<'a> AssocItemCollector<'a> { let attrs = Attrs::new(self.db, &item, self.span_map.as_ref(), self.cfg_options); if let Err(cfg) = attrs.is_cfg_enabled(self.cfg_options) { self.diagnostics.push(DefDiagnostic::unconfigured_code( - self.module_id.local_id, + self.module_id, InFile::new(self.file_id, ast_id.erase()), cfg, self.cfg_options.clone(), @@ -203,7 +203,7 @@ impl<'a> AssocItemCollector<'a> { match self.def_map.resolve_attr_macro( self.local_def_map, self.db, - self.module_id.local_id, + self.module_id, ast_id_with_path, attr, ) { @@ -215,9 +215,9 @@ impl<'a> AssocItemCollector<'a> { // crate failed), skip expansion like we would if it was // disabled. This is analogous to the handling in // `DefCollector::collect_macros`. - if let Some(err) = exp.as_expand_error(self.module_id.krate) { + if let Some(err) = exp.as_expand_error(self.module_id.krate(self.db)) { self.diagnostics.push(DefDiagnostic::macro_error( - self.module_id.local_id, + self.module_id, ast_id, (*attr.path).clone(), err, @@ -233,7 +233,7 @@ impl<'a> AssocItemCollector<'a> { Ok(_) => (), Err(_) => { self.diagnostics.push(DefDiagnostic::unresolved_macro_call( - self.module_id.local_id, + self.module_id, MacroCallKind::Attr { ast_id, attr_args: None, invoc_attr_index: attr.id }, attr.path().clone(), )); @@ -292,7 +292,7 @@ impl<'a> AssocItemCollector<'a> { .resolve_path( self.local_def_map, self.db, - self.module_id.local_id, + self.module_id, path, crate::item_scope::BuiltinShadowMode::Other, Some(MacroSubNs::Bang), @@ -307,7 +307,7 @@ impl<'a> AssocItemCollector<'a> { &path, ctxt, ExpandTo::Items, - self.module_id.krate(), + self.module_id.krate(self.db), resolver, &mut |ptr, call_id| { self.macro_calls.push((ptr.map(|(_, it)| it.upcast()), call_id)) @@ -323,7 +323,7 @@ impl<'a> AssocItemCollector<'a> { }, Err(_) => { self.diagnostics.push(DefDiagnostic::unresolved_macro_call( - self.module_id.local_id, + self.module_id, MacroCallKind::FnLike { ast_id, expand_to: ExpandTo::Items, diff --git a/crates/hir-def/src/nameres/attr_resolution.rs b/crates/hir-def/src/nameres/attr_resolution.rs index e7e96804ae73..b53d537a9122 100644 --- a/crates/hir-def/src/nameres/attr_resolution.rs +++ b/crates/hir-def/src/nameres/attr_resolution.rs @@ -12,7 +12,7 @@ use syntax::ast; use triomphe::Arc; use crate::{ - AstIdWithPath, LocalModuleId, MacroId, UnresolvedMacro, + AstIdWithPath, MacroId, ModuleId, UnresolvedMacro, db::DefDatabase, item_scope::BuiltinShadowMode, nameres::{LocalDefMap, path_resolution::ResolveMode}, @@ -32,7 +32,7 @@ impl DefMap { &self, local_def_map: &LocalDefMap, db: &dyn DefDatabase, - original_module: LocalModuleId, + original_module: ModuleId, ast_id: AstIdWithPath, attr: &Attr, ) -> Result { diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 29f94ac2dca1..3d2a246bc66c 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -3,7 +3,7 @@ //! `DefCollector::collect` contains the fixed-point iteration loop which //! resolves imports and expands macros. -use std::{cmp::Ordering, iter, mem, ops::Not}; +use std::{iter, mem, ops::Not}; use base_db::{BuiltDependency, Crate, CrateOrigin, LangCrateOrigin}; use cfg::{CfgAtom, CfgExpr, CfgOptions}; @@ -26,11 +26,11 @@ use syntax::ast; use triomphe::Arc; use crate::{ - AdtId, AssocItemId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, ExternBlockLoc, - ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId, - LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, - MacroRulesLoc, MacroRulesLocFlags, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, - StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, UseLoc, + AdtId, AssocItemId, AstId, AstIdWithPath, ConstLoc, EnumLoc, ExternBlockLoc, ExternCrateId, + ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId, Lookup, Macro2Id, + Macro2Loc, MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, + ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, + TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, UseLoc, attr::Attrs, db::DefDatabase, item_scope::{GlobId, ImportId, ImportOrExternCrate, PerNsGlobImports}, @@ -174,14 +174,14 @@ impl Import { #[derive(Debug, Eq, PartialEq)] struct ImportDirective { /// The module this import directive is in. - module_id: LocalModuleId, + module_id: ModuleId, import: Import, status: PartialResolvedImport, } #[derive(Clone, Debug, Eq, PartialEq)] struct MacroDirective<'db> { - module_id: LocalModuleId, + module_id: ModuleId, depth: usize, kind: MacroDirectiveKind<'db>, container: ItemContainerId, @@ -220,7 +220,7 @@ struct DefCollector<'db> { crate_local_def_map: Option<&'db LocalDefMap>, // The dependencies of the current crate, including optional deps like `test`. deps: FxHashMap, - glob_imports: FxHashMap>, + glob_imports: FxHashMap>, unresolved_imports: Vec, indeterminate_imports: Vec<(ImportDirective, PerNs)>, unresolved_macros: Vec>, @@ -228,7 +228,7 @@ struct DefCollector<'db> { // resolve. When we emit diagnostics for unresolved imports, we only do so if the import // doesn't start with an unresolved crate's name. unresolved_extern_crates: FxHashSet, - mod_dirs: FxHashMap, + mod_dirs: FxHashMap, cfg_options: &'db CfgOptions, /// List of procedural macros defined by this crate. This is read from the dynamic library /// built by the build system, and is the list of proc-macros we can actually expand. It is @@ -338,9 +338,14 @@ impl<'db> DefCollector<'db> { continue; } - self.local_def_map - .extern_prelude - .insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None)); + // This eagerly draws a dependency edge between the crate def maps even if the + // things the crates are not used. This is not great, but at the same time we would + // like to compute our dependency def maps in parallel here anyways in the future + // which will have the same effect. + self.local_def_map.extern_prelude.insert( + name.clone(), + (crate_def_map(self.db, dep.crate_id).root_module_id(), None), + ); } } @@ -350,10 +355,11 @@ impl<'db> DefCollector<'db> { return; } + let module_id = self.def_map.root; ModCollector { def_collector: self, macro_depth: 0, - module_id: DefMap::ROOT, + module_id, tree_id: TreeId::new(file_id.into(), None), item_tree, mod_dir: ModDir::root(), @@ -371,10 +377,11 @@ impl<'db> DefCollector<'db> { if is_cfg_enabled { self.inject_prelude(); + let module_id = self.def_map.root; ModCollector { def_collector: self, macro_depth: 0, - module_id: DefMap::ROOT, + module_id, tree_id, item_tree, mod_dir: ModDir::root(), @@ -437,8 +444,8 @@ impl<'db> DefCollector<'db> { // Additionally, while the proc macro entry points must be `pub`, they are not publicly // exported in type/value namespace. This function reduces the visibility of all items // in the crate root that aren't proc macros. - let module_id = self.def_map.module_id(DefMap::ROOT); - let root = &mut self.def_map.modules[DefMap::ROOT]; + let module_id = self.def_map.root_module_id(); + let root = &mut self.def_map.modules[module_id]; root.scope.censor_non_proc_macros(module_id); } } @@ -542,7 +549,7 @@ impl<'db> DefCollector<'db> { let (per_ns, _) = self.def_map.resolve_path( self.crate_local_def_map.unwrap_or(&self.local_def_map), self.db, - DefMap::ROOT, + self.def_map.root_module_id(), &path, BuiltinShadowMode::Other, None, @@ -597,7 +604,7 @@ impl<'db> DefCollector<'db> { }; let proc_macro_id = ProcMacroLoc { - container: self.def_map.crate_root(), + container: self.def_map.root_module_id(), id: ast_id, expander, kind, @@ -641,7 +648,7 @@ impl<'db> DefCollector<'db> { /// ``` fn define_macro_rules( &mut self, - module_id: LocalModuleId, + module_id: ModuleId, name: Name, macro_: MacroRulesId, export: bool, @@ -653,7 +660,7 @@ impl<'db> DefCollector<'db> { // In Rust, `#[macro_export]` macros are unconditionally visible at the // crate root, even if the parent modules is **not** visible. if export { - let module_id = DefMap::ROOT; + let module_id = self.def_map.root; self.def_map.modules[module_id].scope.declare(macro_.into()); self.update( module_id, @@ -671,7 +678,7 @@ impl<'db> DefCollector<'db> { /// the definition of current module. /// And also, `macro_use` on a module will import all legacy macros visible inside to /// current legacy scope, with possible shadowing. - fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, mac: MacroId) { + fn define_legacy_macro(&mut self, module_id: ModuleId, name: Name, mac: MacroId) { // Always shadowing self.def_map.modules[module_id].scope.define_legacy_macro(name, mac); } @@ -681,7 +688,7 @@ impl<'db> DefCollector<'db> { /// The scoped of macro 2.0 macro is equal to normal function fn define_macro_def( &mut self, - module_id: LocalModuleId, + module_id: ModuleId, name: Name, macro_: Macro2Id, vis: &RawVisibility, @@ -710,7 +717,7 @@ impl<'db> DefCollector<'db> { /// A proc macro is similar to normal macro scope, but it would not visible in legacy textual scoped. /// And unconditionally exported. fn define_proc_macro(&mut self, name: Name, macro_: ProcMacroId) { - let module_id = DefMap::ROOT; + let module_id = self.def_map.root; self.def_map.modules[module_id].scope.declare(macro_.into()); self.update( module_id, @@ -735,7 +742,7 @@ impl<'db> DefCollector<'db> { let def_map = crate_def_map(self.db, krate); // `#[macro_use]` brings macros into macro_use prelude. Yes, even non-`macro_rules!` // macros. - let root_scope = &def_map[DefMap::ROOT].scope; + let root_scope = &def_map[def_map.root].scope; match names { Some(names) => { for name in names { @@ -808,7 +815,7 @@ impl<'db> DefCollector<'db> { res } - fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport { + fn resolve_import(&self, module_id: ModuleId, import: &Import) -> PartialResolvedImport { let _p = tracing::info_span!("resolve_import", import_path = %import.path.display(self.db, Edition::LATEST)) .entered(); tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition); @@ -921,11 +928,10 @@ impl<'db> DefCollector<'db> { // implementation seems to work the same though. cov_mark::hit!(std_prelude); self.def_map.prelude = Some((m, Some(id))); - } else if m.krate != self.def_map.krate { + } else if m.krate(self.db) != self.def_map.krate { cov_mark::hit!(glob_across_crates); // glob import from other crate => we can just import everything once - let item_map = m.def_map(self.db); - let scope = &item_map[m.local_id].scope; + let scope = &m.def_map(self.db)[m].scope; // Module scoped macros is included let items = scope @@ -947,12 +953,10 @@ impl<'db> DefCollector<'db> { // glob import from same crate => we do an initial // import, and then need to propagate any further // additions - let def_map; - let scope = if m.block == self.def_map.block_id() { - &self.def_map[m.local_id].scope + let scope = if m.block(self.db) == self.def_map.block_id() { + &self.def_map[m].scope } else { - def_map = m.def_map(self.db); - &def_map[m.local_id].scope + &m.def_map(self.db)[m].scope }; // Module scoped macros is included @@ -981,11 +985,12 @@ impl<'db> DefCollector<'db> { Some(ImportOrExternCrate::Glob(glob)), ); // record the glob import in case we add further items - let glob_imports = self.glob_imports.entry(m.local_id).or_default(); + let glob_imports = self.glob_imports.entry(m).or_default(); match glob_imports.iter_mut().find(|(mid, _, _)| *mid == module_id) { None => glob_imports.push((module_id, vis, glob)), Some((_, old_vis, _)) => { - if let Some(new_vis) = old_vis.max(vis, &self.def_map) { + if let Some(new_vis) = old_vis.max(self.db, vis, &self.def_map) + { *old_vis = new_vis; } } @@ -1063,7 +1068,7 @@ impl<'db> DefCollector<'db> { fn update( &mut self, // The module for which `resolutions` have been resolve - module_id: LocalModuleId, + module_id: ModuleId, resolutions: &[(Option, PerNs)], // Visibility this import will have vis: Visibility, @@ -1076,7 +1081,7 @@ impl<'db> DefCollector<'db> { fn update_recursive( &mut self, // The module for which `resolutions` have been resolved. - module_id: LocalModuleId, + module_id: ModuleId, resolutions: &[(Option, PerNs)], // All resolutions are imported with this visibility; the visibilities in // the `PerNs` values are ignored and overwritten @@ -1111,7 +1116,7 @@ impl<'db> DefCollector<'db> { let should_update = match old_vis { None => true, Some(old_vis) => { - let max_vis = old_vis.max(vis, &self.def_map).unwrap_or_else(|| { + let max_vis = old_vis.max(self.db, vis, &self.def_map).unwrap_or_else(|| { panic!("`Tr as _` imports with unrelated visibilities {old_vis:?} and {vis:?} (trait {tr:?})"); }); @@ -1153,7 +1158,7 @@ impl<'db> DefCollector<'db> { .collect::>(); for (glob_importing_module, glob_import_vis, glob) in glob_imports { - let vis = glob_import_vis.min(vis, &self.def_map).unwrap_or(glob_import_vis); + let vis = glob_import_vis.min(self.db, vis, &self.def_map).unwrap_or(glob_import_vis); self.update_recursive( glob_importing_module, resolutions, @@ -1166,20 +1171,20 @@ impl<'db> DefCollector<'db> { fn push_res_and_update_glob_vis( &mut self, - module_id: LocalModuleId, + module_id: ModuleId, name: &Name, mut defs: PerNs, vis: Visibility, def_import_type: Option, ) -> bool { if let Some(def) = defs.types.as_mut() { - def.vis = def.vis.min(vis, &self.def_map).unwrap_or(vis); + def.vis = def.vis.min(self.db, vis, &self.def_map).unwrap_or(vis); } if let Some(def) = defs.values.as_mut() { - def.vis = def.vis.min(vis, &self.def_map).unwrap_or(vis); + def.vis = def.vis.min(self.db, vis, &self.def_map).unwrap_or(vis); } if let Some(def) = defs.macros.as_mut() { - def.vis = def.vis.min(vis, &self.def_map).unwrap_or(vis); + def.vis = def.vis.min(self.db, vis, &self.def_map).unwrap_or(vis); } let mut changed = false; @@ -1195,7 +1200,7 @@ impl<'db> DefCollector<'db> { if def.def == prev_def.def && self.from_glob_import.contains_type(module_id, name.clone()) && def.vis != prev_def.vis - && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis) + && def.vis.max(self.db, prev_def.vis, &self.def_map) == Some(def.vis) { changed = true; // This import is being handled here, don't pass it down to @@ -1213,7 +1218,7 @@ impl<'db> DefCollector<'db> { if def.def == prev_def.def && self.from_glob_import.contains_value(module_id, name.clone()) && def.vis != prev_def.vis - && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis) + && def.vis.max(self.db, prev_def.vis, &self.def_map) == Some(def.vis) { changed = true; // See comment above. @@ -1230,7 +1235,7 @@ impl<'db> DefCollector<'db> { if def.def == prev_def.def && self.from_glob_import.contains_macro(module_id, name.clone()) && def.vis != prev_def.vis - && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis) + && def.vis.max(self.db, prev_def.vis, &self.def_map) == Some(def.vis) { changed = true; // See comment above. @@ -1549,7 +1554,7 @@ impl<'db> DefCollector<'db> { fn collect_macro_expansion( &mut self, - module_id: LocalModuleId, + module_id: ModuleId, macro_call_id: MacroCallId, depth: usize, container: ItemContainerId, @@ -1678,7 +1683,7 @@ impl<'db> DefCollector<'db> { struct ModCollector<'a, 'db> { def_collector: &'a mut DefCollector<'db>, macro_depth: usize, - module_id: LocalModuleId, + module_id: ModuleId, tree_id: TreeId, item_tree: &'db ItemTree, mod_dir: ModDir, @@ -1686,14 +1691,13 @@ struct ModCollector<'a, 'db> { impl ModCollector<'_, '_> { fn collect_in_top_module(&mut self, items: &[ModItemId]) { - let module = self.def_collector.def_map.module_id(self.module_id); - self.collect(items, module.into()) + self.collect(items, self.module_id.into()) } fn collect(&mut self, items: &[ModItemId], container: ItemContainerId) { let krate = self.def_collector.def_map.krate; - let is_crate_root = - self.module_id == DefMap::ROOT && self.def_collector.def_map.block.is_none(); + let is_crate_root = self.module_id == self.def_collector.def_map.root + && self.def_collector.def_map.block.is_none(); // Note: don't assert that inserted value is fresh: it's simply not true // for macros. @@ -1702,10 +1706,10 @@ impl ModCollector<'_, '_> { // Prelude module is always considered to be `#[macro_use]`. if let Some((prelude_module, _use)) = self.def_collector.def_map.prelude { // Don't insert macros from the prelude into blocks, as they can be shadowed by other macros. - if prelude_module.krate != krate && is_crate_root { + if prelude_module.krate(self.def_collector.db) != krate && is_crate_root { cov_mark::hit!(prelude_is_macro_use); self.def_collector.import_macros_from_extern_crate( - prelude_module.krate, + prelude_module.krate(self.def_collector.db), None, None, ); @@ -1745,7 +1749,6 @@ impl ModCollector<'_, '_> { return; } - let module = self.def_collector.def_map.module_id(module_id); let def_map = &mut self.def_collector.def_map; let local_def_map = self.def_collector.crate_local_def_map.unwrap_or(&self.def_collector.local_def_map); @@ -1753,9 +1756,11 @@ impl ModCollector<'_, '_> { match item { ModItemId::Mod(m) => self.collect_module(m, &attrs), ModItemId::Use(item_tree_id) => { - let id = - UseLoc { container: module, id: InFile::new(self.file_id(), item_tree_id) } - .intern(db); + let id = UseLoc { + container: module_id, + id: InFile::new(self.file_id(), item_tree_id), + } + .intern(db); let is_prelude = attrs.by_key(sym::prelude_import).exists(); Import::from_use(self.item_tree, item_tree_id, id, is_prelude, |import| { self.def_collector.unresolved_imports.push(ImportDirective { @@ -1770,7 +1775,7 @@ impl ModCollector<'_, '_> { &self.item_tree[item_tree_id]; let id = ExternCrateLoc { - container: module, + container: module_id, id: InFile::new(self.tree_id.file_id(), item_tree_id), } .intern(db); @@ -1779,12 +1784,12 @@ impl ModCollector<'_, '_> { let is_self = *name == sym::self_; let resolved = if is_self { cov_mark::hit!(extern_crate_self_as); - Some(def_map.crate_root()) + Some(def_map.crate_root(db)) } else { self.def_collector .deps .get(name) - .map(|dep| CrateRootModuleId { krate: dep.crate_id }) + .map(|dep| crate_def_map(db, dep.crate_id).root_module_id()) }; let name = match alias { @@ -1809,7 +1814,7 @@ impl ModCollector<'_, '_> { self.process_macro_use_extern_crate( id, attrs.by_key(sym::macro_use).attrs(), - resolved.krate, + resolved.krate(self.def_collector.db), ); } } @@ -1841,7 +1846,7 @@ impl ModCollector<'_, '_> { } ModItemId::ExternBlock(block) => { let extern_block_id = ExternBlockLoc { - container: module, + container: module_id, id: InFile::new(self.file_id(), block), } .intern(db); @@ -1854,11 +1859,11 @@ impl ModCollector<'_, '_> { ) } ModItemId::MacroCall(mac) => self.collect_macro_call(mac, container), - ModItemId::MacroRules(id) => self.collect_macro_rules(id, module), - ModItemId::Macro2(id) => self.collect_macro_def(id, module), + ModItemId::MacroRules(id) => self.collect_macro_rules(id, module_id), + ModItemId::Macro2(id) => self.collect_macro_def(id, module_id), ModItemId::Impl(imp) => { let impl_id = - ImplLoc { container: module, id: InFile::new(self.file_id(), imp) } + ImplLoc { container: module_id, id: InFile::new(self.file_id(), imp) } .intern(db); self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id) } @@ -1872,7 +1877,7 @@ impl ModCollector<'_, '_> { if self.def_collector.def_map.block.is_none() && self.def_collector.is_proc_macro - && self.module_id == DefMap::ROOT + && self.module_id == self.def_collector.def_map.root { if let Some(proc_macro) = attrs.parse_proc_macro_decl(&it.name) { self.def_collector.export_proc_macro( @@ -1891,7 +1896,7 @@ impl ModCollector<'_, '_> { let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, - StructLoc { container: module, id: InFile::new(self.file_id(), id) } + StructLoc { container: module_id, id: InFile::new(self.file_id(), id) } .intern(db) .into(), &it.name, @@ -1905,7 +1910,7 @@ impl ModCollector<'_, '_> { let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, - UnionLoc { container: module, id: InFile::new(self.file_id(), id) } + UnionLoc { container: module_id, id: InFile::new(self.file_id(), id) } .intern(db) .into(), &it.name, @@ -1915,9 +1920,11 @@ impl ModCollector<'_, '_> { } ModItemId::Enum(id) => { let it = &self.item_tree[id]; - let enum_ = - EnumLoc { container: module, id: InFile::new(self.tree_id.file_id(), id) } - .intern(db); + let enum_ = EnumLoc { + container: module_id, + id: InFile::new(self.tree_id.file_id(), id), + } + .intern(db); let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def(self.def_collector, enum_.into(), &it.name, vis, false); @@ -1962,7 +1969,7 @@ impl ModCollector<'_, '_> { let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, - TraitLoc { container: module, id: InFile::new(self.file_id(), id) } + TraitLoc { container: module_id, id: InFile::new(self.file_id(), id) } .intern(db) .into(), &it.name, @@ -1976,7 +1983,7 @@ impl ModCollector<'_, '_> { let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, - TraitAliasLoc { container: module, id: InFile::new(self.file_id(), id) } + TraitAliasLoc { container: module_id, id: InFile::new(self.file_id(), id) } .intern(db) .into(), &it.name, @@ -2159,9 +2166,10 @@ impl ModCollector<'_, '_> { declaration: FileAstId, definition: Option<(EditionedFileId, bool)>, visibility: &crate::visibility::RawVisibility, - ) -> LocalModuleId { - let def_map = &mut self.def_collector.def_map; - let vis = def_map + ) -> ModuleId { + let vis = self + .def_collector + .def_map .resolve_visibility( self.def_collector.crate_local_def_map.unwrap_or(&self.def_collector.local_def_map), self.def_collector.db, @@ -2182,21 +2190,25 @@ impl ModCollector<'_, '_> { }, }; + let module = unsafe { + crate::ModuleIdLt::new( + self.def_collector.db, + self.def_collector.def_map.krate, + self.def_collector.def_map.block_id(), + ) + .to_static() + }; + let def_map = &mut self.def_collector.def_map; let modules = &mut def_map.modules; - let res = modules.alloc(ModuleData::new(origin, vis)); - modules[res].parent = Some(self.module_id); - - if let Some((target, source)) = Self::borrow_modules(modules.as_mut(), res, self.module_id) - { - for (name, macs) in source.scope.legacy_macros() { - for &mac in macs { - target.scope.define_legacy_macro(name.clone(), mac); - } + let mut data = ModuleData::new(origin, vis, Some(self.module_id)); + for (name, macs) in modules[self.module_id].scope.legacy_macros() { + for &mac in macs { + data.scope.define_legacy_macro(name.clone(), mac); } } - modules[self.module_id].children.insert(name.clone(), res); + modules[self.module_id].children.insert(name.clone(), module); + modules.insert(module, data); - let module = def_map.module_id(res); let def = ModuleDefId::from(module); def_map.modules[self.module_id].scope.declare(def); @@ -2206,7 +2218,7 @@ impl ModCollector<'_, '_> { vis, None, ); - res + module } /// Resolves attributes on an item. @@ -2508,12 +2520,10 @@ impl ModCollector<'_, '_> { }); } - fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) { - let Some((source, target)) = Self::borrow_modules( - self.def_collector.def_map.modules.as_mut(), - module_id, - self.module_id, - ) else { + fn import_all_legacy_macros(&mut self, module_id: ModuleId) { + let [Some(source), Some(target)] = + self.def_collector.def_map.modules.get_disjoint_mut([&module_id, &self.module_id]) + else { return; }; @@ -2524,29 +2534,6 @@ impl ModCollector<'_, '_> { } } - /// Mutably borrow two modules at once, retu - fn borrow_modules( - modules: &mut [ModuleData], - a: LocalModuleId, - b: LocalModuleId, - ) -> Option<(&mut ModuleData, &mut ModuleData)> { - let a = a.into_raw().into_u32() as usize; - let b = b.into_raw().into_u32() as usize; - - let (a, b) = match a.cmp(&b) { - Ordering::Equal => return None, - Ordering::Less => { - let (prefix, b) = modules.split_at_mut(b); - (&mut prefix[a], &mut b[0]) - } - Ordering::Greater => { - let (prefix, a) = modules.split_at_mut(a); - (&mut a[0], &mut prefix[b]) - } - }; - Some((a, b)) - } - fn is_cfg_enabled(&self, cfg: &CfgExpr) -> bool { self.def_collector.cfg_options.check(cfg) != Some(false) } @@ -2570,47 +2557,15 @@ impl ModCollector<'_, '_> { mod tests { use test_fixture::WithFixture; - use crate::{nameres::DefMapCrateData, test_db::TestDB}; + use crate::test_db::TestDB; use super::*; - fn do_collect_defs(db: &dyn DefDatabase, def_map: DefMap) -> DefMap { - let mut collector = DefCollector { - db, - def_map, - local_def_map: LocalDefMap::default(), - crate_local_def_map: None, - deps: FxHashMap::default(), - glob_imports: FxHashMap::default(), - unresolved_imports: Vec::new(), - indeterminate_imports: Vec::new(), - unresolved_macros: Vec::new(), - mod_dirs: FxHashMap::default(), - cfg_options: &CfgOptions::default(), - proc_macros: Default::default(), - from_glob_import: Default::default(), - skip_attrs: Default::default(), - is_proc_macro: false, - unresolved_extern_crates: Default::default(), - }; - collector.seed_with_top_level(); - collector.collect(); - collector.def_map - } - - fn do_resolve(not_ra_fixture: &str) -> DefMap { - let (db, file_id) = TestDB::with_single_file(not_ra_fixture); + fn do_resolve(not_ra_fixture: &str) { + let (db, _) = TestDB::with_single_file(not_ra_fixture); let krate = db.test_crate(); - let edition = krate.data(&db).edition; - let module_origin = ModuleOrigin::CrateRoot { definition: file_id }; - let def_map = DefMap::empty( - krate, - Arc::new(DefMapCrateData::new(edition)), - ModuleData::new(module_origin, Visibility::Public), - None, - ); - do_collect_defs(&db, def_map) + crate_def_map(&db, krate); } #[test] diff --git a/crates/hir-def/src/nameres/diagnostics.rs b/crates/hir-def/src/nameres/diagnostics.rs index c495a0744919..2172d3a03a55 100644 --- a/crates/hir-def/src/nameres/diagnostics.rs +++ b/crates/hir-def/src/nameres/diagnostics.rs @@ -7,7 +7,7 @@ use hir_expand::{ErasedAstId, ExpandErrorKind, MacroCallKind, attrs::AttrId, mod use la_arena::Idx; use syntax::ast; -use crate::{AstId, nameres::LocalModuleId}; +use crate::{AstId, nameres::ModuleId}; #[derive(Debug, PartialEq, Eq)] pub enum DefDiagnosticKind { @@ -43,13 +43,13 @@ impl DefDiagnostics { #[derive(Debug, PartialEq, Eq)] pub struct DefDiagnostic { - pub in_module: LocalModuleId, + pub in_module: ModuleId, pub kind: DefDiagnosticKind, } impl DefDiagnostic { pub(super) fn unresolved_module( - container: LocalModuleId, + container: ModuleId, declaration: AstId, candidates: Box<[String]>, ) -> Self { @@ -60,7 +60,7 @@ impl DefDiagnostic { } pub(super) fn unresolved_extern_crate( - container: LocalModuleId, + container: ModuleId, declaration: AstId, ) -> Self { Self { @@ -70,7 +70,7 @@ impl DefDiagnostic { } pub(super) fn unresolved_import( - container: LocalModuleId, + container: ModuleId, id: AstId, index: Idx, ) -> Self { @@ -78,7 +78,7 @@ impl DefDiagnostic { } pub fn macro_error( - container: LocalModuleId, + container: ModuleId, ast: AstId, path: ModPath, err: ExpandErrorKind, @@ -87,7 +87,7 @@ impl DefDiagnostic { } pub fn unconfigured_code( - container: LocalModuleId, + container: ModuleId, ast_id: ErasedAstId, cfg: CfgExpr, opts: CfgOptions, @@ -100,22 +100,19 @@ impl DefDiagnostic { // FIXME: Whats the difference between this and unresolved_proc_macro pub(crate) fn unresolved_macro_call( - container: LocalModuleId, + container: ModuleId, ast: MacroCallKind, path: ModPath, ) -> Self { Self { in_module: container, kind: DefDiagnosticKind::UnresolvedMacroCall { ast, path } } } - pub(super) fn unimplemented_builtin_macro( - container: LocalModuleId, - ast: AstId, - ) -> Self { + pub(super) fn unimplemented_builtin_macro(container: ModuleId, ast: AstId) -> Self { Self { in_module: container, kind: DefDiagnosticKind::UnimplementedBuiltinMacro { ast } } } pub(super) fn invalid_derive_target( - container: LocalModuleId, + container: ModuleId, ast: AstId, id: AttrId, ) -> Self { @@ -125,11 +122,7 @@ impl DefDiagnostic { } } - pub(super) fn malformed_derive( - container: LocalModuleId, - ast: AstId, - id: AttrId, - ) -> Self { + pub(super) fn malformed_derive(container: ModuleId, ast: AstId, id: AttrId) -> Self { Self { in_module: container, kind: DefDiagnosticKind::MalformedDerive { ast, id: id.ast_index() }, diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs index e0e32a777356..74ac47981f24 100644 --- a/crates/hir-def/src/nameres/path_resolution.rs +++ b/crates/hir-def/src/nameres/path_resolution.rs @@ -19,7 +19,7 @@ use span::Edition; use stdx::TupleExt; use crate::{ - AdtId, LocalModuleId, ModuleDefId, + AdtId, ModuleDefId, ModuleId, db::DefDatabase, item_scope::{BUILTIN_SCOPE, ImportOrExternCrate}, item_tree::FieldsShape, @@ -100,7 +100,7 @@ impl DefMap { local_def_map: &LocalDefMap, db: &dyn DefDatabase, // module to import to - original_module: LocalModuleId, + original_module: ModuleId, // pub(path) // ^^^^ this visibility: &RawVisibility, @@ -136,9 +136,9 @@ impl DefMap { // DefMap they're written in, so we restrict them when that happens. if let Visibility::Module(m, mv) = vis { // ...unless we're resolving visibility for an associated item in an impl. - if self.block_id() != m.block && !within_impl { + if self.block_id() != m.block(db) && !within_impl { cov_mark::hit!(adjust_vis_in_block_def_map); - vis = Visibility::Module(self.module_id(Self::ROOT), mv); + vis = Visibility::Module(self.root, mv); tracing::debug!("visibility {:?} points outside DefMap, adjusting to {:?}", m, vis); } } @@ -154,7 +154,7 @@ impl DefMap { db: &dyn DefDatabase, mode: ResolveMode, // module to import to - mut original_module: LocalModuleId, + mut original_module: ModuleId, path: &ModPath, shadow: BuiltinShadowMode, // Pass `MacroSubNs` if we know we're resolving macro names and which kind of macro we're @@ -194,17 +194,17 @@ impl DefMap { loop { match current_map.block { - Some(block) if original_module == Self::ROOT => { + Some(block) if original_module == current_map.root => { // Block modules "inherit" names from its parent module. - original_module = block.parent.local_id; - current_map = block.parent.def_map(db, current_map.krate); + original_module = block.parent; + current_map = block.parent.def_map(db); } // Proper (non-block) modules, including those in block `DefMap`s, don't. _ => { - if original_module != Self::ROOT && current_map.block.is_some() { + if original_module != current_map.root && current_map.block.is_some() { // A module inside a block. Do not resolve items declared in upper blocks, but we do need to get // the prelude items (which are not inserted into blocks because they can be overridden there). - original_module = Self::ROOT; + original_module = current_map.root; current_map = crate_def_map(db, self.krate); let new = current_map.resolve_path_fp_in_all_preludes( @@ -241,7 +241,7 @@ impl DefMap { local_def_map: &LocalDefMap, db: &dyn DefDatabase, mode: ResolveMode, - original_module: LocalModuleId, + original_module: ModuleId, path: &ModPath, shadow: BuiltinShadowMode, expected_macro_subns: Option, @@ -251,15 +251,15 @@ impl DefMap { PathKind::DollarCrate(krate) => { if krate == self.krate { cov_mark::hit!(macro_dollar_crate_self); - PerNs::types(self.crate_root().into(), Visibility::Public, None) + PerNs::types(self.crate_root(db).into(), Visibility::Public, None) } else { let def_map = crate_def_map(db, krate); - let module = def_map.module_id(Self::ROOT); + let module = def_map.root; cov_mark::hit!(macro_dollar_crate_other); PerNs::types(module.into(), Visibility::Public, None) } } - PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public, None), + PathKind::Crate => PerNs::types(self.crate_root(db).into(), Visibility::Public, None), // plain import or absolute path in 2015: crate-relative with // fallback to extern prelude (with the simplification in // rust-lang/rust#57745) @@ -306,14 +306,10 @@ impl DefMap { } PathKind::Super(lvl) => { let mut local_id = original_module; - let mut ext; let mut def_map = self; // Adjust `local_id` to `self`, i.e. the nearest non-block module. - if def_map.module_id(local_id).is_block_module() { - (ext, local_id) = adjust_to_nearest_non_block_module(db, def_map, local_id); - def_map = ext; - } + (def_map, local_id) = adjust_to_nearest_non_block_module(db, def_map, local_id); // Go up the module tree but skip block modules as `super` always refers to the // nearest non-block module. @@ -321,12 +317,8 @@ impl DefMap { // Loop invariant: at the beginning of each loop, `local_id` must refer to a // non-block module. if let Some(parent) = def_map.modules[local_id].parent { - local_id = parent; - if def_map.module_id(local_id).is_block_module() { - (ext, local_id) = - adjust_to_nearest_non_block_module(db, def_map, local_id); - def_map = ext; - } + (def_map, local_id) = + adjust_to_nearest_non_block_module(db, def_map, parent); } else { stdx::always!(def_map.block.is_none()); tracing::debug!("super path in root module"); @@ -334,9 +326,6 @@ impl DefMap { } } - let module = def_map.module_id(local_id); - stdx::never!(module.is_block_module()); - if self.block != def_map.block { // If we have a different `DefMap` from `self` (the original `DefMap` we started // with), resolve the remaining path segments in that `DefMap`. @@ -354,7 +343,7 @@ impl DefMap { ); } - PerNs::types(module.into(), Visibility::Public, None) + PerNs::types(local_id.into(), Visibility::Public, None) } PathKind::Abs => match self.resolve_path_abs(local_def_map, &mut segments, path) { Either::Left(it) => it, @@ -381,7 +370,7 @@ impl DefMap { local_def_map: &LocalDefMap, db: &dyn DefDatabase, mode: ResolveMode, - original_module: LocalModuleId, + original_module: ModuleId, path: &ModPath, shadow: BuiltinShadowMode, ) -> ResolvePathResult { @@ -463,7 +452,7 @@ impl DefMap { mut curr_per_ns: PerNs, path: &ModPath, shadow: BuiltinShadowMode, - original_module: LocalModuleId, + original_module: ModuleId, ) -> ResolvePathResult { while let Some((i, segment)) = segments.next() { let curr = match curr_per_ns.take_types_full() { @@ -481,7 +470,7 @@ impl DefMap { curr_per_ns = match curr.def { ModuleDefId::ModuleId(module) => { - if module.krate != self.krate { + if module.krate(db) != self.krate { // FIXME: Inefficient let path = ModPath::from_segments( PathKind::SELF, @@ -497,7 +486,7 @@ impl DefMap { LocalDefMap::EMPTY, db, mode, - module.local_id, + module, &path, shadow, None, @@ -514,11 +503,11 @@ impl DefMap { } let def_map; - let module_data = if module.block == self.block_id() { - &self[module.local_id] + let module_data = if module.block(db) == self.block_id() { + &self[module] } else { def_map = module.def_map(db); - &def_map[module.local_id] + &def_map[module] }; // Since it is a qualified path here, it should not contains legacy macros @@ -642,7 +631,7 @@ impl DefMap { &self, local_def_map: &LocalDefMap, db: &dyn DefDatabase, - module: LocalModuleId, + module: ModuleId, name: &Name, shadow: BuiltinShadowMode, expected_macro_subns: Option, @@ -679,7 +668,7 @@ impl DefMap { }; let extern_prelude = || { - if self.block.is_some() && module == DefMap::ROOT { + if self.block.is_some() && module == self.root { // Don't resolve extern prelude in pseudo-modules of blocks, because // they might been shadowed by local names. return PerNs::none(); @@ -688,7 +677,7 @@ impl DefMap { }; let macro_use_prelude = || self.resolve_in_macro_use_prelude(name); let prelude = || { - if self.block.is_some() && module == DefMap::ROOT { + if self.block.is_some() && module == self.root { return PerNs::none(); } self.resolve_in_prelude(db, name) @@ -741,18 +730,18 @@ impl DefMap { &self, local_def_map: &LocalDefMap, db: &dyn DefDatabase, - module: LocalModuleId, + module: ModuleId, name: &Name, ) -> PerNs { let from_crate_root = match self.block { Some(_) => { - let def_map = self.crate_root().def_map(db); - def_map[Self::ROOT].scope.get(name) + let def_map = self.crate_root(db).def_map(db); + def_map[def_map.root].scope.get(name) } - None => self[Self::ROOT].scope.get(name), + None => self[self.root].scope.get(name), }; let from_extern_prelude = || { - if self.block.is_some() && module == DefMap::ROOT { + if self.block.is_some() && module == self.root { // Don't resolve extern prelude in pseudo-module of a block. return PerNs::none(); } @@ -765,14 +754,14 @@ impl DefMap { fn resolve_in_prelude(&self, db: &dyn DefDatabase, name: &Name) -> PerNs { if let Some((prelude, _use)) = self.prelude { let keep; - let def_map = if prelude.krate == self.krate { + let def_map = if prelude.krate(db) == self.krate { self } else { // Extend lifetime keep = prelude.def_map(db); keep }; - def_map[prelude.local_id].scope.get(name) + def_map[prelude].scope.get(name) } else { PerNs::none() } @@ -780,23 +769,23 @@ impl DefMap { } /// Given a block module, returns its nearest non-block module and the `DefMap` it belongs to. +#[inline] fn adjust_to_nearest_non_block_module<'db>( db: &'db dyn DefDatabase, - def_map: &'db DefMap, - mut local_id: LocalModuleId, -) -> (&'db DefMap, LocalModuleId) { - // INVARIANT: `local_id` in `def_map` must be a block module. - stdx::always!(def_map.module_id(local_id).is_block_module()); - - // This needs to be a local variable due to our mighty lifetime. - let mut def_map = def_map; - loop { - let BlockInfo { parent, .. } = def_map.block.expect("block module without parent module"); - - def_map = parent.def_map(db, def_map.krate); - local_id = parent.local_id; - if !parent.is_block_module() { + mut def_map: &'db DefMap, + mut local_id: ModuleId, +) -> (&'db DefMap, ModuleId) { + if def_map.root_module_id() != local_id { + // if we aren't the root, we are either not a block module, or a non-block module inside a + // block def map. + return (def_map, local_id); + } + while let Some(BlockInfo { parent, .. }) = def_map.block { + def_map = parent.def_map(db); + local_id = parent; + if def_map.root_module_id() != local_id { return (def_map, local_id); } } + (def_map, local_id) } diff --git a/crates/hir-def/src/nameres/tests/incremental.rs b/crates/hir-def/src/nameres/tests/incremental.rs index 7a4ea62f12ac..52c52648a72d 100644 --- a/crates/hir-def/src/nameres/tests/incremental.rs +++ b/crates/hir-def/src/nameres/tests/incremental.rs @@ -63,7 +63,7 @@ pub const BAZ: u32 = 0; let all_crates_before = db.all_crates(); { - // Add a dependency a -> b. + // Add dependencies: c -> b, b -> a. let mut new_crate_graph = CrateGraphBuilder::default(); let mut add_crate = |crate_name, root_file_idx: usize| { @@ -112,7 +112,10 @@ pub const BAZ: u32 = 0; }); let invalidated_def_maps = events.iter().filter(|event| event.contains("crate_local_def_map")).count(); - assert_eq!(invalidated_def_maps, 1, "{events:#?}") + + // `c` gets invalidated as its dependency `b` changed + // `b` gets invalidated due to its new dependency edge to `a` + assert_eq!(invalidated_def_maps, 2, "{events:#?}") } #[test] @@ -344,7 +347,8 @@ m!(Z); { let events = db.log_executed(|| { let crate_def_map = crate_def_map(&db, krate); - let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); + let module_data = &crate_def_map + [crate_def_map.modules_for_file(&db, pos.file_id.file_id(&db)).next().unwrap()]; assert_eq!(module_data.scope.resolutions().count(), 4); }); let n_recalculated_item_trees = @@ -366,7 +370,8 @@ m!(Z); { let events = db.log_executed(|| { let crate_def_map = crate_def_map(&db, krate); - let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); + let module_data = &crate_def_map + [crate_def_map.modules_for_file(&db, pos.file_id.file_id(&db)).next().unwrap()]; assert_eq!(module_data.scope.resolutions().count(), 4); }); let n_recalculated_item_trees = @@ -417,7 +422,8 @@ pub type Ty = (); { let events = db.log_executed(|| { let crate_def_map = crate_def_map(&db, krate); - let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); + let module_data = &crate_def_map + [crate_def_map.modules_for_file(&db, pos.file_id.file_id(&db)).next().unwrap()]; assert_eq!(module_data.scope.resolutions().count(), 8); assert_eq!(module_data.scope.impls().count(), 1); diff --git a/crates/hir-def/src/nameres/tests/macros.rs b/crates/hir-def/src/nameres/tests/macros.rs index 3cba88ec2f17..1ce6daa2d3f1 100644 --- a/crates/hir-def/src/nameres/tests/macros.rs +++ b/crates/hir-def/src/nameres/tests/macros.rs @@ -753,7 +753,7 @@ macro_rules! foo { pub use core::clone::Clone; "#, - |map| assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1), + |map| assert_eq!(map.modules[map.root].scope.impls().len(), 1), ); } @@ -775,7 +775,7 @@ pub macro Copy {} #[rustc_builtin_macro] pub macro Clone {} "#, - |map| assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 2), + |map| assert_eq!(map.modules[map.root].scope.impls().len(), 2), ); } @@ -818,7 +818,7 @@ pub macro derive($item:item) {} #[rustc_builtin_macro] pub macro Clone {} "#, - |map| assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1), + |map| assert_eq!(map.modules[map.root].scope.impls().len(), 1), ); } @@ -1448,7 +1448,7 @@ fn proc_attr(a: TokenStream, b: TokenStream) -> TokenStream { a } let krate = *db.all_crates().last().expect("no crate graph present"); let def_map = crate_def_map(&db, krate); - let root_module = &def_map[DefMap::ROOT].scope; + let root_module = &def_map[def_map.root].scope; assert!( root_module.legacy_macros().count() == 0, "`#[macro_use]` shouldn't bring macros into textual macro scope", @@ -1553,7 +1553,7 @@ macro_rules! derive { () => {} } #[derive(Clone)] struct S; "#, - |map| assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1), + |map| assert_eq!(map.modules[map.root].scope.impls().len(), 1), ); } diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index 491b6204bce2..e6cfb8054f47 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -16,11 +16,11 @@ use syntax::ast::HasName; use triomphe::Arc; use crate::{ - AdtId, AstIdLoc, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, - EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, - GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, - Macro2Id, MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, - TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UseId, VariantId, + AdtId, AstIdLoc, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, + ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule, ImplId, + ItemContainerId, LifetimeParamId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId, + ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, + TypeOrConstParamId, TypeParamId, UseId, VariantId, builtin_type::BuiltinType, db::DefDatabase, expr_store::{ @@ -55,7 +55,7 @@ pub struct Resolver<'db> { struct ModuleItemMap<'db> { def_map: &'db DefMap, local_def_map: &'db LocalDefMap, - module_id: LocalModuleId, + module_id: ModuleId, } impl fmt::Debug for ModuleItemMap<'_> { @@ -604,14 +604,14 @@ impl<'db> Resolver<'db> { }, ); local_def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| { - res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def.into()))); + res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def))); }); BUILTIN_SCOPE.iter().for_each(|(name, &def)| { res.add_per_ns(name, def); }); if let Some((prelude, _use)) = def_map.prelude() { let prelude_def_map = prelude.def_map(db); - for (name, def) in prelude_def_map[prelude.local_id].scope.entries() { + for (name, def) in prelude_def_map[prelude].scope.entries() { res.add_per_ns(name, def) } } @@ -643,7 +643,7 @@ impl<'db> Resolver<'db> { self.module_scope .local_def_map .extern_prelude() - .map(|(name, module_id)| (name.clone(), module_id.0.into())) + .map(|(name, module_id)| (name.clone(), module_id.0)) } pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet { @@ -671,7 +671,7 @@ impl<'db> Resolver<'db> { // Fill in the prelude traits if let Some((prelude, _use)) = self.module_scope.def_map.prelude() { let prelude_def_map = prelude.def_map(db); - traits.extend(prelude_def_map[prelude.local_id].scope.traits()); + traits.extend(prelude_def_map[prelude].scope.traits()); } // Fill in module visible traits traits.extend(self.module_scope.def_map[self.module_scope.module_id].scope.traits()); @@ -688,8 +688,7 @@ impl<'db> Resolver<'db> { } pub fn module(&self) -> ModuleId { - let (def_map, _, local_id) = self.item_scope_(); - def_map.module_id(local_id) + self.item_scope_().2 } pub fn item_scope(&self) -> &ItemScope { @@ -869,7 +868,7 @@ impl<'db> Resolver<'db> { resolver.scopes.push(Scope::BlockScope(ModuleItemMap { def_map, local_def_map, - module_id: DefMap::ROOT, + module_id: def_map.root, })); // FIXME: This adds as many module scopes as there are blocks, but resolving in each // already traverses all parents, so this is O(n²). I think we could only store the @@ -968,7 +967,7 @@ impl<'db> Resolver<'db> { } /// The innermost block scope that contains items or the module scope that contains this resolver. - fn item_scope_(&self) -> (&DefMap, &LocalDefMap, LocalModuleId) { + fn item_scope_(&self) -> (&DefMap, &LocalDefMap, ModuleId) { self.scopes() .find_map(|scope| match scope { Scope::BlockScope(m) => Some((m.def_map, m.local_def_map, m.module_id)), @@ -1120,7 +1119,7 @@ impl<'db> Resolver<'db> { self.push_scope(Scope::BlockScope(ModuleItemMap { def_map, local_def_map, - module_id: DefMap::ROOT, + module_id: def_map.root, })) } @@ -1282,9 +1281,9 @@ pub trait HasResolver: Copy { impl HasResolver for ModuleId { fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { let (mut def_map, local_def_map) = self.local_def_map(db); - let mut module_id = self.local_id; + let mut module_id = self; - if !self.is_block_module() { + if !self.is_block_module(db) { return Resolver { scopes: vec![], module_scope: ModuleItemMap { def_map, local_def_map, module_id }, @@ -1295,8 +1294,8 @@ impl HasResolver for ModuleId { while let Some(parent) = def_map.parent() { let block_def_map = mem::replace(&mut def_map, parent.def_map(db)); modules.push(block_def_map); - if !parent.is_block_module() { - module_id = parent.local_id; + if !parent.is_block_module(db) { + module_id = parent; break; } } @@ -1311,16 +1310,6 @@ impl HasResolver for ModuleId { } } -impl HasResolver for CrateRootModuleId { - fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { - let (def_map, local_def_map) = self.local_def_map(db); - Resolver { - scopes: vec![], - module_scope: ModuleItemMap { def_map, local_def_map, module_id: DefMap::ROOT }, - } - } -} - impl HasResolver for TraitId { fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { lookup_resolver(db, self).push_generic_params_scope(db, self.into()) diff --git a/crates/hir-def/src/signatures.rs b/crates/hir-def/src/signatures.rs index b7d29f54d08e..772d4f31cd3b 100644 --- a/crates/hir-def/src/signatures.rs +++ b/crates/hir-def/src/signatures.rs @@ -834,7 +834,7 @@ fn lower_fields( override_visibility: Option, ) -> (Arena, ExpressionStore, ExpressionStoreSourceMap) { let mut arena = Arena::new(); - let cfg_options = module.krate.cfg_options(db); + let cfg_options = module.krate(db).cfg_options(db); let mut col = ExprCollector::new(db, module, fields.file_id); let mut idx = 0; for (ty, field) in fields.value { @@ -895,7 +895,7 @@ impl EnumVariants { let span_map = db.span_map(source.file_id); let mut diagnostics = ThinVec::new(); - let cfg_options = loc.container.krate.cfg_options(db); + let cfg_options = loc.container.krate(db).cfg_options(db); let mut index = 0; let Some(variants) = source.value.variant_list() else { return (Arc::new(EnumVariants { variants: Box::default() }), None); diff --git a/crates/hir-def/src/src.rs b/crates/hir-def/src/src.rs index aa373a27b0d5..4e69cf04decd 100644 --- a/crates/hir-def/src/src.rs +++ b/crates/hir-def/src/src.rs @@ -154,7 +154,7 @@ impl HasChildSource for VariantId { let mut map = ArenaMap::new(); match &src.value { ast::StructKind::Tuple(fl) => { - let cfg_options = container.krate.cfg_options(db); + let cfg_options = container.krate(db).cfg_options(db); let mut idx = 0; for fd in fl.fields() { let enabled = @@ -170,7 +170,7 @@ impl HasChildSource for VariantId { } } ast::StructKind::Record(fl) => { - let cfg_options = container.krate.cfg_options(db); + let cfg_options = container.krate(db).cfg_options(db); let mut idx = 0; for fd in fl.fields() { let enabled = diff --git a/crates/hir-def/src/test_db.rs b/crates/hir-def/src/test_db.rs index e30a5b65a1f7..56e65cfa26f7 100644 --- a/crates/hir-def/src/test_db.rs +++ b/crates/hir-def/src/test_db.rs @@ -7,13 +7,13 @@ use base_db::{ SourceDatabase, SourceRoot, SourceRootId, SourceRootInput, }; use hir_expand::{InFile, files::FilePosition}; -use salsa::{AsDynDatabase, Durability}; +use salsa::Durability; use span::FileId; use syntax::{AstNode, algo, ast}; use triomphe::Arc; use crate::{ - LocalModuleId, Lookup, ModuleDefId, ModuleId, + Lookup, ModuleDefId, ModuleId, db::DefDatabase, nameres::{DefMap, ModuleSource, block_def_map, crate_def_map}, src::HasSource, @@ -137,7 +137,7 @@ impl TestDB { let crate_def_map = crate_def_map(self, krate); for (local_id, data) in crate_def_map.modules() { if data.origin.file_id().map(|file_id| file_id.file_id(self)) == Some(file_id) { - return crate_def_map.module_id(local_id); + return local_id; } } } @@ -151,7 +151,7 @@ impl TestDB { def_map = match self.block_at_position(def_map, position) { Some(it) => it, - None => return def_map.module_id(module), + None => return module, }; loop { let new_map = self.block_at_position(def_map, position); @@ -161,16 +161,16 @@ impl TestDB { } _ => { // FIXME: handle `mod` inside block expression - return def_map.module_id(DefMap::ROOT); + return def_map.root; } } } } /// Finds the smallest/innermost module in `def_map` containing `position`. - fn mod_at_position(&self, def_map: &DefMap, position: FilePosition) -> LocalModuleId { + fn mod_at_position(&self, def_map: &DefMap, position: FilePosition) -> ModuleId { let mut size = None; - let mut res = DefMap::ROOT; + let mut res = def_map.root; for (module, data) in def_map.modules() { let src = data.definition_source(self); if src.file_id != position.file_id { @@ -280,19 +280,19 @@ impl TestDB { pub(crate) fn log_executed(&self, f: impl FnOnce()) -> Vec { let events = self.log(f); - events - .into_iter() - .filter_map(|e| match e.kind { - // This is pretty horrible, but `Debug` is the only way to inspect - // QueryDescriptor at the moment. - salsa::EventKind::WillExecute { database_key } => { - let ingredient = self - .as_dyn_database() - .ingredient_debug_name(database_key.ingredient_index()); - Some(ingredient.to_string()) - } - _ => None, - }) - .collect() + + salsa::plumbing::attach(self, || { + events + .into_iter() + .filter_map(|e| match e.kind { + // This is pretty horrible, but `Debug` is the only way to inspect + // QueryDescriptor at the moment. + salsa::EventKind::WillExecute { database_key } => { + salsa::plumbing::attach(self, || Some(format!("{database_key:?}"))) + } + _ => None, + }) + .collect() + }) } } diff --git a/crates/hir-def/src/visibility.rs b/crates/hir-def/src/visibility.rs index 14d67ea804ff..fb387aaa5dd2 100644 --- a/crates/hir-def/src/visibility.rs +++ b/crates/hir-def/src/visibility.rs @@ -8,8 +8,8 @@ use syntax::ast::{self, HasVisibility}; use triomphe::Arc; use crate::{ - ConstId, FunctionId, HasModule, ItemContainerId, LocalFieldId, LocalModuleId, ModuleId, - TraitId, TypeAliasId, VariantId, + ConstId, FunctionId, HasModule, ItemContainerId, LocalFieldId, ModuleId, TraitId, TypeAliasId, + VariantId, db::DefDatabase, nameres::DefMap, resolver::{HasResolver, Resolver}, @@ -48,25 +48,28 @@ impl Visibility { Visibility::Public => return true, }; // if they're not in the same crate, it can't be visible - if from_module.krate != to_module.krate { + if from_module.krate(db) != to_module.krate(db) { return false; } let def_map = from_module.def_map(db); - Self::is_visible_from_def_map_(db, def_map, to_module, from_module.local_id) + Self::is_visible_from_def_map_(db, def_map, to_module, from_module) } pub(crate) fn is_visible_from_def_map( self, db: &dyn DefDatabase, def_map: &DefMap, - from_module: LocalModuleId, + from_module: ModuleId, ) -> bool { + if cfg!(debug_assertions) { + _ = def_map.modules[from_module]; + } let to_module = match self { Visibility::Module(m, _) => m, Visibility::Public => return true, }; // if they're not in the same crate, it can't be visible - if def_map.krate() != to_module.krate { + if def_map.krate() != to_module.krate(db) { return false; } Self::is_visible_from_def_map_(db, def_map, to_module, from_module) @@ -76,9 +79,9 @@ impl Visibility { db: &dyn DefDatabase, def_map: &DefMap, mut to_module: ModuleId, - mut from_module: LocalModuleId, + mut from_module: ModuleId, ) -> bool { - debug_assert_eq!(to_module.krate, def_map.krate()); + debug_assert_eq!(to_module.krate(db), def_map.krate()); // `to_module` might be the root module of a block expression. Those have the same // visibility as the containing module (even though no items are directly nameable from // there, getting this right is important for method resolution). @@ -88,12 +91,12 @@ impl Visibility { // currently computing, so we must not call the `def_map` query for it. let def_map_block = def_map.block_id(); loop { - match (to_module.block, def_map_block) { + match (to_module.block(db), def_map_block) { // `to_module` is not a block, so there is no parent def map to use. (None, _) => (), // `to_module` is at `def_map`'s block, no need to move further. (Some(a), Some(b)) if a == b => { - cov_mark::hit!(is_visible_from_same_block_def_map); + cov_mark::hit!(nested_module_scoping); } _ => { if let Some(parent) = to_module.def_map(db).parent() { @@ -109,7 +112,7 @@ impl Visibility { let mut def_map = def_map; let mut parent_arc; loop { - if def_map.module_id(from_module) == to_module { + if from_module == to_module { return true; } match def_map[from_module].parent { @@ -119,7 +122,7 @@ impl Visibility { Some(module) => { parent_arc = module.def_map(db); def_map = parent_arc; - from_module = module.local_id; + from_module = module; } // Reached the root module, nothing left to check. None => return false, @@ -133,30 +136,33 @@ impl Visibility { /// /// If there is no subset relation between `self` and `other`, returns `None` (ie. they're only /// visible in unrelated modules). - pub(crate) fn max(self, other: Visibility, def_map: &DefMap) -> Option { + pub(crate) fn max( + self, + db: &dyn DefDatabase, + other: Visibility, + def_map: &DefMap, + ) -> Option { match (self, other) { (_, Visibility::Public) | (Visibility::Public, _) => Some(Visibility::Public), (Visibility::Module(mod_a, expl_a), Visibility::Module(mod_b, expl_b)) => { - if mod_a.krate != mod_b.krate { + if mod_a.krate(db) != mod_b.krate(db) { return None; } let def_block = def_map.block_id(); - if (mod_a.containing_block(), mod_b.containing_block()) != (def_block, def_block) { + if (mod_a.block(db), mod_b.block(db)) != (def_block, def_block) { return None; } - let mut a_ancestors = - iter::successors(Some(mod_a.local_id), |&m| def_map[m].parent); - let mut b_ancestors = - iter::successors(Some(mod_b.local_id), |&m| def_map[m].parent); + let mut a_ancestors = iter::successors(Some(mod_a), |&m| def_map[m].parent); + let mut b_ancestors = iter::successors(Some(mod_b), |&m| def_map[m].parent); - if a_ancestors.any(|m| m == mod_b.local_id) { + if a_ancestors.any(|m| m == mod_b) { // B is above A return Some(Visibility::Module(mod_b, expl_b)); } - if b_ancestors.any(|m| m == mod_a.local_id) { + if b_ancestors.any(|m| m == mod_a) { // A is above B return Some(Visibility::Module(mod_a, expl_a)); } @@ -170,30 +176,33 @@ impl Visibility { /// /// If there is no subset relation between `self` and `other`, returns `None` (ie. they're only /// visible in unrelated modules). - pub(crate) fn min(self, other: Visibility, def_map: &DefMap) -> Option { + pub(crate) fn min( + self, + db: &dyn DefDatabase, + other: Visibility, + def_map: &DefMap, + ) -> Option { match (self, other) { (vis, Visibility::Public) | (Visibility::Public, vis) => Some(vis), (Visibility::Module(mod_a, expl_a), Visibility::Module(mod_b, expl_b)) => { - if mod_a.krate != mod_b.krate { + if mod_a.krate(db) != mod_b.krate(db) { return None; } let def_block = def_map.block_id(); - if (mod_a.containing_block(), mod_b.containing_block()) != (def_block, def_block) { + if (mod_a.block(db), mod_b.block(db)) != (def_block, def_block) { return None; } - let mut a_ancestors = - iter::successors(Some(mod_a.local_id), |&m| def_map[m].parent); - let mut b_ancestors = - iter::successors(Some(mod_b.local_id), |&m| def_map[m].parent); + let mut a_ancestors = iter::successors(Some(mod_a), |&m| def_map[m].parent); + let mut b_ancestors = iter::successors(Some(mod_b), |&m| def_map[m].parent); - if a_ancestors.any(|m| m == mod_b.local_id) { + if a_ancestors.any(|m| m == mod_b) { // B is above A return Some(Visibility::Module(mod_a, expl_a)); } - if b_ancestors.any(|m| m == mod_a.local_id) { + if b_ancestors.any(|m| m == mod_a) { // A is above B return Some(Visibility::Module(mod_b, expl_b)); } diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs index f658e2366589..9943c4e1d68e 100644 --- a/crates/hir-ty/src/chalk_db.rs +++ b/crates/hir-ty/src/chalk_db.rs @@ -568,11 +568,11 @@ impl ChalkContext<'_> { }; let mut def_blocks = - [trait_module.containing_block(), type_module.and_then(|it| it.containing_block())]; + [trait_module.block(self.db), type_module.and_then(|it| it.block(self.db))]; let block_impls = iter::successors(self.block, |&block_id| { cov_mark::hit!(block_local_impls); - block_id.loc(self.db).module.containing_block() + block_id.loc(self.db).module.block(self.db) }) .inspect(|&block_id| { // make sure we don't search the same block twice @@ -702,7 +702,7 @@ pub(crate) fn trait_datum_query( let bound_vars = generic_params.bound_vars_subst(db, DebruijnIndex::INNERMOST); let flags = rust_ir::TraitFlags { auto: trait_data.flags.contains(TraitFlags::AUTO), - upstream: trait_.lookup(db).container.krate() != krate, + upstream: trait_.lookup(db).container.krate(db) != krate, non_enumerable: true, coinductive: false, // only relevant for Chalk testing // FIXME: set these flags correctly @@ -795,7 +795,7 @@ pub(crate) fn adt_datum_query( hir_def::AdtId::EnumId(_) => (false, false), }; let flags = rust_ir::AdtFlags { - upstream: adt_id.module(db).krate() != krate, + upstream: adt_id.module(db).krate(db) != krate, fundamental, phantom_data, }; @@ -869,7 +869,7 @@ fn impl_def_datum(db: &dyn HirDatabase, krate: Crate, impl_id: hir_def::ImplId) let generic_params = generics(db, impl_id.into()); let bound_vars = generic_params.bound_vars_subst(db, DebruijnIndex::INNERMOST); let trait_ = trait_ref.hir_trait_id(); - let impl_type = if impl_id.lookup(db).container.krate() == krate { + let impl_type = if impl_id.lookup(db).container.krate(db) == krate { rust_ir::ImplType::Local } else { rust_ir::ImplType::External diff --git a/crates/hir-ty/src/chalk_ext.rs b/crates/hir-ty/src/chalk_ext.rs index 836cc96233eb..8c33cd0e4b88 100644 --- a/crates/hir-ty/src/chalk_ext.rs +++ b/crates/hir-ty/src/chalk_ext.rs @@ -250,7 +250,7 @@ impl TyExt for Ty { TyKind::OpaqueType(opaque_ty_id, subst) => { match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => { - let krate = def.module(db).krate(); + let krate = def.module(db).krate(db); if let Some(future_trait) = LangItem::Future.resolve_trait(db, krate) { // This is only used by type walking. // Parameters will be walked outside, and projection predicate is not used. @@ -361,7 +361,7 @@ impl TyExt for Ty { } fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool { - let crate_id = owner.module(db).krate(); + let crate_id = owner.module(db).krate(db); let Some(copy_trait) = LangItem::Copy.resolve_trait(db, crate_id) else { return false; }; diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index f903b06d65e7..5fc779e2f393 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -253,7 +253,7 @@ pub(crate) fn const_eval_query( db.monomorphized_mir_body(c.into(), subst, db.trait_environment(c.into()))? } GeneralConstId::StaticId(s) => { - let krate = s.module(db).krate(); + let krate = s.module(db).krate(db); db.monomorphized_mir_body(s.into(), subst, TraitEnvironment::empty(krate))? } }; diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs index 6449a4dc7e8c..ef99799e5c70 100644 --- a/crates/hir-ty/src/consteval/tests.rs +++ b/crates/hir-ty/src/consteval/tests.rs @@ -118,7 +118,7 @@ fn pretty_print_err(e: ConstEvalError, db: TestDB) -> String { fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result { let module_id = db.module_for_file(file_id.file_id(db)); let def_map = module_id.def_map(db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; let const_id = scope .declarations() .find_map(|x| match x { diff --git a/crates/hir-ty/src/diagnostics/decl_check.rs b/crates/hir-ty/src/diagnostics/decl_check.rs index fae129fddbfe..d30c2d38a306 100644 --- a/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/crates/hir-ty/src/diagnostics/decl_check.rs @@ -164,7 +164,7 @@ impl<'a> DeclValidator<'a> { else { return; }; - let module_data = &module_id.def_map(self.db)[module_id.local_id]; + let module_data = &module_id.def_map(self.db)[module_id]; let Some(module_src) = module_data.declaration_source(self.db) else { return; }; diff --git a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index 0914b5aac507..e319c6f59767 100644 --- a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -112,7 +112,7 @@ impl<'db> MatchCheckCtx<'db> { /// Returns whether the given ADT is from another crate declared `#[non_exhaustive]`. fn is_foreign_non_exhaustive(&self, adt: hir_def::AdtId) -> bool { - let is_local = adt.krate(self.db) == self.module.krate(); + let is_local = adt.krate(self.db) == self.module.krate(self.db); !is_local && self.db.attrs(adt.into()).by_key(sym::non_exhaustive).exists() } diff --git a/crates/hir-ty/src/diagnostics/unsafe_check.rs b/crates/hir-ty/src/diagnostics/unsafe_check.rs index 20cf3c781151..eebaedbdec1b 100644 --- a/crates/hir-ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir-ty/src/diagnostics/unsafe_check.rs @@ -159,7 +159,7 @@ impl<'db> UnsafeVisitor<'db> { DefWithBodyId::FunctionId(func) => TargetFeatures::from_attrs(&db.attrs(func.into())), _ => TargetFeatures::default(), }; - let edition = resolver.module().krate().data(db).edition; + let edition = resolver.module().krate(db).data(db).edition; Self { db, infer, diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index f210dd8799f9..405732489398 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -20,7 +20,6 @@ use hir_def::{ item_scope::ItemInNs, item_tree::FieldsShape, lang_item::LangItem, - nameres::DefMap, signatures::VariantFields, type_ref::{ ConstRef, LifetimeRef, LifetimeRefId, TraitBoundModifier, TypeBound, TypeRef, TypeRefId, @@ -315,7 +314,7 @@ pub trait HirDisplay { entity_limit: None, omit_verbose_types: false, closure_style: ClosureStyle::ImplFn, - display_target: DisplayTarget::from_crate(db, module_id.krate()), + display_target: DisplayTarget::from_crate(db, module_id.krate(db)), display_kind: DisplayKind::SourceCode { target_module_id: module_id, allow_opaque }, show_container_bounds: false, display_lifetimes: DisplayLifetime::OnlyNamedOrStatic, @@ -1392,7 +1391,7 @@ impl HirDisplay for Ty { } ImplTraitId::AsyncBlockTypeImplTrait(body, ..) => { let future_trait = - LangItem::Future.resolve_trait(db, body.module(db).krate()); + LangItem::Future.resolve_trait(db, body.module(db).krate(db)); let output = future_trait.and_then(|t| { db.trait_items(t) .associated_type_by_name(&Name::new_symbol_root(sym::Output)) @@ -1506,7 +1505,7 @@ impl HirDisplay for Ty { WhereClause::LifetimeOutlives(_) => false, }) .collect::>(); - let krate = id.parent.module(db).krate(); + let krate = id.parent.module(db).krate(db); write_bounds_like_dyn_trait_with_prefix( f, "impl", @@ -1768,7 +1767,7 @@ impl HirDisplay for CallableSig { } fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator + '_ { - let krate = trait_.lookup(db).container.krate(); + let krate = trait_.lookup(db).container.krate(db); utils::fn_traits(db, krate) } @@ -2084,7 +2083,7 @@ pub fn write_visibility( Visibility::Public => write!(f, "pub "), Visibility::Module(vis_id, _) => { let def_map = module_id.def_map(f.db); - let root_module_id = def_map.module_id(DefMap::ROOT); + let root_module_id = def_map.root_module_id(); if vis_id == module_id { // pub(self) or omitted Ok(()) diff --git a/crates/hir-ty/src/drop.rs b/crates/hir-ty/src/drop.rs index b9b0f9828661..655ebdbe9c37 100644 --- a/crates/hir-ty/src/drop.rs +++ b/crates/hir-ty/src/drop.rs @@ -19,15 +19,15 @@ fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool { AdtId::StructId(id) => db.lookup_intern_struct(id).container, AdtId::UnionId(id) => db.lookup_intern_union(id).container, }; - let Some(drop_trait) = LangItem::Drop.resolve_trait(db, module.krate()) else { + let Some(drop_trait) = LangItem::Drop.resolve_trait(db, module.krate(db)) else { return false; }; - let impls = match module.containing_block() { + let impls = match module.block(db) { Some(block) => match db.trait_impls_in_block(block) { Some(it) => it, None => return false, }, - None => db.trait_impls_in_crate(module.krate()), + None => db.trait_impls_in_crate(module.krate(db)), }; impls.for_trait_and_self_ty(drop_trait, TyFingerprint::Adt(adt)).next().is_some() } diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs index 48094945c114..28464820fd4e 100644 --- a/crates/hir-ty/src/dyn_compatibility.rs +++ b/crates/hir-ty/src/dyn_compatibility.rs @@ -9,8 +9,8 @@ use chalk_ir::{ }; use chalk_solve::rust_ir::InlineBound; use hir_def::{ - AssocItemId, ConstId, CrateRootModuleId, FunctionId, GenericDefId, HasModule, TraitId, - TypeAliasId, lang_item::LangItem, signatures::TraitFlags, + AssocItemId, ConstId, FunctionId, GenericDefId, HasModule, TraitId, TypeAliasId, + lang_item::LangItem, nameres::crate_def_map, signatures::TraitFlags, }; use rustc_hash::FxHashSet; use smallvec::SmallVec; @@ -123,7 +123,7 @@ pub fn dyn_compatibility_of_trait_query( } pub fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool { - let krate = def.module(db).krate(); + let krate = def.module(db).krate(db); let Some(sized) = LangItem::Sized.resolve_trait(db, krate) else { return false; }; @@ -343,7 +343,7 @@ where }) } AssocItemId::TypeAliasId(it) => { - let def_map = CrateRootModuleId::from(trait_.krate(db)).def_map(db); + let def_map = crate_def_map(db, trait_.krate(db)); if def_map.is_unstable_feature_enabled(&intern::sym::generic_associated_type_extended) { ControlFlow::Continue(()) } else { @@ -489,7 +489,7 @@ fn receiver_is_dispatchable( return false; }; - let krate = func.module(db).krate(); + let krate = func.module(db).krate(db); let traits = ( LangItem::Unsize.resolve_trait(db, krate), LangItem::DispatchFromDyn.resolve_trait(db, krate), diff --git a/crates/hir-ty/src/dyn_compatibility/tests.rs b/crates/hir-ty/src/dyn_compatibility/tests.rs index 5078e8cfaa8b..3f35dfb48113 100644 --- a/crates/hir-ty/src/dyn_compatibility/tests.rs +++ b/crates/hir-ty/src/dyn_compatibility/tests.rs @@ -35,7 +35,7 @@ fn check_dyn_compatibility<'a>( for (trait_id, name) in file_ids.into_iter().flat_map(|file_id| { let module_id = db.module_for_file(file_id.file_id(&db)); let def_map = module_id.def_map(&db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; scope .declarations() .filter_map(|def| { diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs index bd57ca891620..20b6b59a900a 100644 --- a/crates/hir-ty/src/infer/closure.rs +++ b/crates/hir-ty/src/infer/closure.rs @@ -333,7 +333,7 @@ impl InferenceContext<'_> { // Search for a predicate like `<$self as FnX>::Output == Ret` let fn_traits: SmallVec<[ChalkTraitId; 3]> = - utils::fn_traits(self.db, self.owner.module(self.db).krate()) + utils::fn_traits(self.db, self.owner.module(self.db).krate(self.db)) .map(to_chalk_trait_id) .collect(); @@ -603,7 +603,7 @@ impl HirPlace { |_, _, _| { unreachable!("Closure field only happens in MIR"); }, - ctx.owner.module(ctx.db).krate(), + ctx.owner.module(ctx.db).krate(ctx.db), ); } ty @@ -704,7 +704,7 @@ impl CapturedItem { } } } - if is_raw_identifier(&result, owner.module(db).krate().data(db).edition) { + if is_raw_identifier(&result, owner.module(db).krate(db).data(db).edition) { result.insert_str(0, "r#"); } result @@ -1449,7 +1449,7 @@ impl InferenceContext<'_> { |_, _, _| { unreachable!("Closure field only happens in MIR"); }, - self.owner.module(self.db).krate(), + self.owner.module(self.db).krate(self.db), ); if ty.as_raw_ptr().is_some() || ty.is_union() { capture.kind = CaptureKind::ByRef(BorrowKind::Shared); diff --git a/crates/hir-ty/src/layout/tests.rs b/crates/hir-ty/src/layout/tests.rs index cc7d74f4fb0a..9744b2f19a65 100644 --- a/crates/hir-ty/src/layout/tests.rs +++ b/crates/hir-ty/src/layout/tests.rs @@ -40,7 +40,7 @@ fn eval_goal( .find_map(|file_id| { let module_id = db.module_for_file(file_id.file_id(&db)); let def_map = module_id.def_map(&db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; let adt_or_type_alias_id = scope.declarations().find_map(|x| match x { hir_def::ModuleDefId::AdtId(x) => { let name = match x { @@ -105,7 +105,7 @@ fn eval_expr( let (db, file_id) = TestDB::with_single_file(&ra_fixture); let module_id = db.module_for_file(file_id.file_id(&db)); let def_map = module_id.def_map(&db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; let function_id = scope .declarations() .find_map(|x| match x { diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 0a546768dab4..1b3e5e5610d4 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -1014,7 +1014,7 @@ pub(crate) fn trait_environment_for_body_query( def: DefWithBodyId, ) -> Arc { let Some(def) = def.as_generic_def_id(db) else { - let krate = def.module(db).krate(); + let krate = def.module(db).krate(db); return TraitEnvironment::empty(krate); }; db.trait_environment(def) diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index 3b295d41e6e3..8e1cf718b564 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -399,7 +399,7 @@ pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option { @@ -412,7 +412,7 @@ pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option Option = - [trait_module.containing_block(), type_module.and_then(|it| it.containing_block())] + [trait_module.block(db), type_module.and_then(|it| it.block(db))] .into_iter() .flatten() .filter_map(|block_id| db.trait_impls_in_block(block_id)) @@ -834,9 +834,9 @@ fn is_inherent_impl_coherent( | TyKind::Str | TyKind::Scalar(_) => def_map.is_rustc_coherence_is_core(), - &TyKind::Adt(AdtId(adt), _) => adt.module(db).krate() == def_map.krate(), + &TyKind::Adt(AdtId(adt), _) => adt.module(db).krate(db) == def_map.krate(), TyKind::Dyn(it) => it.principal_id().is_some_and(|trait_id| { - from_chalk_trait_id(trait_id).module(db).krate() == def_map.krate() + from_chalk_trait_id(trait_id).module(db).krate(db) == def_map.krate() }), _ => true, @@ -907,12 +907,12 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool { return true; }; - let local_crate = impl_.lookup(db).container.krate(); + let local_crate = impl_.lookup(db).container.krate(db); let is_local = |tgt_crate| tgt_crate == local_crate; let trait_ref = impl_trait.substitute(Interner, &substs); let trait_id = from_chalk_trait_id(trait_ref.trait_id); - if is_local(trait_id.module(db).krate()) { + if is_local(trait_id.module(db).krate(db)) { // trait to be implemented is local return true; } @@ -944,11 +944,11 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool { // - No uncovered type parameters `P1..=Pn` may appear in `T0..Ti`` (excluding `Ti`) let is_not_orphan = trait_ref.substitution.type_parameters(Interner).any(|ty| { match unwrap_fundamental(ty).kind(Interner) { - &TyKind::Adt(AdtId(id), _) => is_local(id.module(db).krate()), + &TyKind::Adt(AdtId(id), _) => is_local(id.module(db).krate(db)), TyKind::Error => true, - TyKind::Dyn(it) => it - .principal_id() - .is_some_and(|trait_id| is_local(from_chalk_trait_id(trait_id).module(db).krate())), + TyKind::Dyn(it) => it.principal_id().is_some_and(|trait_id| { + is_local(from_chalk_trait_id(trait_id).module(db).krate(db)) + }), _ => false, } }); @@ -1380,7 +1380,7 @@ fn iterate_inherent_methods( }; let (module, mut block) = match visible_from_module { - VisibleFromModule::Filter(module) => (Some(module), module.containing_block()), + VisibleFromModule::Filter(module) => (Some(module), module.block(db)), VisibleFromModule::IncludeBlock(block) => (None, Some(block)), VisibleFromModule::None => (None, None), }; @@ -1399,7 +1399,7 @@ fn iterate_inherent_methods( )?; } - block = block_def_map(db, block_id).parent().and_then(|module| module.containing_block()); + block = block_def_map(db, block_id).parent().and_then(|module| module.block(db)); } for krate in def_crates { diff --git a/crates/hir-ty/src/mir/borrowck.rs b/crates/hir-ty/src/mir/borrowck.rs index fb0c0dee095f..d937d57421ea 100644 --- a/crates/hir-ty/src/mir/borrowck.rs +++ b/crates/hir-ty/src/mir/borrowck.rs @@ -132,7 +132,7 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec ty, db, make_fetch_closure_field(db), - body.owner.module(db).krate(), + body.owner.module(db).krate(db), ); } if is_dereference_of_ref @@ -223,7 +223,7 @@ fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec ty, db, make_fetch_closure_field(db), - body.owner.module(db).krate(), + body.owner.module(db).krate(db), ); } if !ty.clone().is_copy(db, body.owner) @@ -369,7 +369,12 @@ fn place_case(db: &dyn HirDatabase, body: &MirBody, lvalue: &Place) -> Projectio } ProjectionElem::OpaqueCast(_) => (), } - ty = proj.projected_ty(ty, db, make_fetch_closure_field(db), body.owner.module(db).krate()); + ty = proj.projected_ty( + ty, + db, + make_fetch_closure_field(db), + body.owner.module(db).krate(db), + ); } if is_part_of { ProjectionCase::DirectPart } else { ProjectionCase::Direct } } diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index da6e4e5d8a15..54f25191b8cf 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -625,7 +625,7 @@ impl Evaluator<'_> { assert_placeholder_ty_is_unused: bool, trait_env: Option>, ) -> Result> { - let crate_id = owner.module(db).krate(); + let crate_id = owner.module(db).krate(db); let target_data_layout = match db.target_data_layout(crate_id) { Ok(target_data_layout) => target_data_layout, Err(e) => return Err(MirEvalError::TargetDataLayoutNotAvailable(e)), diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs index 8d428dd6d049..bcd42b738648 100644 --- a/crates/hir-ty/src/mir/eval/shim.rs +++ b/crates/hir-ty/src/mir/eval/shim.rs @@ -5,8 +5,8 @@ use std::cmp::{self, Ordering}; use chalk_ir::TyKind; use hir_def::{ - CrateRootModuleId, builtin_type::{BuiltinInt, BuiltinUint}, + nameres::crate_def_map, resolver::HasResolver, }; use hir_expand::name::Name; @@ -151,7 +151,7 @@ impl Evaluator<'_> { ) -> Result> { // `PanicFmt` is redirected to `ConstPanicFmt` if let Some(LangItem::PanicFmt) = self.db.lang_attr(def.into()) { - let resolver = CrateRootModuleId::from(self.crate_id).resolver(self.db); + let resolver = crate_def_map(self.db, self.crate_id).root_module_id().resolver(self.db); let Some(const_panic_fmt) = LangItem::ConstPanicFmt.resolve_function(self.db, resolver.krate()) diff --git a/crates/hir-ty/src/mir/eval/tests.rs b/crates/hir-ty/src/mir/eval/tests.rs index 3abbbe45e6f8..548d78b3ea04 100644 --- a/crates/hir-ty/src/mir/eval/tests.rs +++ b/crates/hir-ty/src/mir/eval/tests.rs @@ -12,7 +12,7 @@ use super::{MirEvalError, interpret_mir}; fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), MirEvalError> { let module_id = db.module_for_file(file_id.file_id(db)); let def_map = module_id.def_map(db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; let func_id = scope .declarations() .find_map(|x| match x { @@ -70,7 +70,7 @@ fn check_pass_and_stdio( let span_formatter = |file, range: TextRange| { format!("{:?} {:?}..{:?}", file, line_index(range.start()), line_index(range.end())) }; - let krate = db.module_for_file(file_id.file_id(&db)).krate(); + let krate = db.module_for_file(file_id.file_id(&db)).krate(&db); e.pretty_print(&mut err, &db, span_formatter, DisplayTarget::from_crate(&db, krate)) .unwrap(); panic!("Error in interpreting: {err}"); diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index ef1f215500c2..c8f6670561b7 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -1747,7 +1747,7 @@ impl<'ctx> MirLowerCtx<'ctx> { } fn resolve_lang_item(&self, item: LangItem) -> Result { - let crate_id = self.owner.module(self.db).krate(); + let crate_id = self.owner.module(self.db).krate(self.db); lang_item(self.db, crate_id, item).ok_or(MirLowerError::LangItemNotFound(item)) } diff --git a/crates/hir-ty/src/test_db.rs b/crates/hir-ty/src/test_db.rs index d049c678e2db..906e8774303a 100644 --- a/crates/hir-ty/src/test_db.rs +++ b/crates/hir-ty/src/test_db.rs @@ -123,7 +123,7 @@ impl TestDB { let crate_def_map = crate_def_map(self, krate); for (local_id, data) in crate_def_map.modules() { if data.origin.file_id().map(|file_id| file_id.file_id(self)) == Some(file_id) { - return Some(crate_def_map.module_id(local_id)); + return Some(local_id); } } } diff --git a/crates/hir-ty/src/tests.rs b/crates/hir-ty/src/tests.rs index 48af7b2e32a2..2f2af1932532 100644 --- a/crates/hir-ty/src/tests.rs +++ b/crates/hir-ty/src/tests.rs @@ -18,7 +18,7 @@ use std::sync::LazyLock; use base_db::{Crate, SourceDatabase}; use expect_test::Expect; use hir_def::{ - AssocItemId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleDefId, SyntheticSyntax, + AssocItemId, DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId, SyntheticSyntax, db::DefDatabase, expr_store::{Body, BodySourceMap}, hir::{ExprId, Pat, PatId}, @@ -132,7 +132,7 @@ fn check_impl( None => continue, }; let def_map = module.def_map(&db); - visit_module(&db, def_map, module.local_id, &mut |it| { + visit_module(&db, def_map, module, &mut |it| { let def = match it { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::EnumVariantId(it) => it.into(), @@ -140,7 +140,7 @@ fn check_impl( ModuleDefId::StaticId(it) => it.into(), _ => return, }; - defs.push((def, module.krate())) + defs.push((def, module.krate(&db))) }); } defs.sort_by_key(|(def, _)| match def { @@ -391,7 +391,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { let def_map = module.def_map(&db); let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new(); - visit_module(&db, def_map, module.local_id, &mut |it| { + visit_module(&db, def_map, module, &mut |it| { let def = match it { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::EnumVariantId(it) => it.into(), @@ -399,7 +399,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { ModuleDefId::StaticId(it) => it.into(), _ => return, }; - defs.push((def, module.krate())) + defs.push((def, module.krate(&db))) }); defs.sort_by_key(|(def, _)| match def { DefWithBodyId::FunctionId(it) => { @@ -432,7 +432,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { pub(crate) fn visit_module( db: &TestDB, crate_def_map: &DefMap, - module_id: LocalModuleId, + module_id: ModuleId, cb: &mut dyn FnMut(ModuleDefId), ) { visit_scope(db, crate_def_map, &crate_def_map[module_id].scope, cb); @@ -495,7 +495,7 @@ pub(crate) fn visit_module( } } } - ModuleDefId::ModuleId(it) => visit_module(db, crate_def_map, it.local_id, cb), + ModuleDefId::ModuleId(it) => visit_module(db, crate_def_map, it, cb), _ => (), } } @@ -570,7 +570,7 @@ fn salsa_bug() { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); - visit_module(&db, crate_def_map, module.local_id, &mut |def| { + visit_module(&db, crate_def_map, module, &mut |def| { db.infer(match def { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::EnumVariantId(it) => it.into(), @@ -609,7 +609,7 @@ fn salsa_bug() { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); - visit_module(&db, crate_def_map, module.local_id, &mut |def| { + visit_module(&db, crate_def_map, module, &mut |def| { db.infer(match def { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::EnumVariantId(it) => it.into(), diff --git a/crates/hir-ty/src/tests/closure_captures.rs b/crates/hir-ty/src/tests/closure_captures.rs index 88d21be81ea6..9d2ea3bfe90f 100644 --- a/crates/hir-ty/src/tests/closure_captures.rs +++ b/crates/hir-ty/src/tests/closure_captures.rs @@ -20,7 +20,7 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec let def_map = module.def_map(&db); let mut defs = Vec::new(); - visit_module(&db, def_map, module.local_id, &mut |it| defs.push(it)); + visit_module(&db, def_map, module, &mut |it| defs.push(it)); let mut captures_info = Vec::new(); for def in defs { @@ -69,7 +69,7 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec let capture_ty = capture .ty .skip_binders() - .display_test(db, DisplayTarget::from_crate(db, module.krate())) + .display_test(db, DisplayTarget::from_crate(db, module.krate(db))) .to_string(); let spans = capture .spans() diff --git a/crates/hir-ty/src/tests/incremental.rs b/crates/hir-ty/src/tests/incremental.rs index 74f6bbb03089..0e61a1a71a25 100644 --- a/crates/hir-ty/src/tests/incremental.rs +++ b/crates/hir-ty/src/tests/incremental.rs @@ -19,7 +19,7 @@ fn foo() -> i32 { let events = db.log_executed(|| { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); - visit_module(&db, crate_def_map, module.local_id, &mut |def| { + visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { db.infer(it.into()); } @@ -41,7 +41,7 @@ fn foo() -> i32 { let events = db.log_executed(|| { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); - visit_module(&db, crate_def_map, module.local_id, &mut |def| { + visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { db.infer(it.into()); } @@ -70,7 +70,7 @@ fn baz() -> i32 { let events = db.log_executed(|| { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); - visit_module(&db, crate_def_map, module.local_id, &mut |def| { + visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { db.infer(it.into()); } @@ -97,7 +97,7 @@ fn baz() -> i32 { let events = db.log_executed(|| { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); - visit_module(&db, crate_def_map, module.local_id, &mut |def| { + visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { db.infer(it.into()); } @@ -125,7 +125,7 @@ $0", let events = db.log_executed(|| { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - db.trait_impls_in_crate(module.krate()); + db.trait_impls_in_crate(module.krate(&db)); }); assert!(format!("{events:?}").contains("trait_impls_in_crate_shim")) } @@ -150,7 +150,7 @@ pub struct NewStruct { let actual = db.log_executed(|| { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - db.trait_impls_in_crate(module.krate()); + db.trait_impls_in_crate(module.krate(&db)); }); let expected = vec![ @@ -184,7 +184,7 @@ $0", let events = db.log_executed(|| { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - db.trait_impls_in_crate(module.krate()); + db.trait_impls_in_crate(module.krate(&db)); }); assert!(format!("{events:?}").contains("trait_impls_in_crate_shim")) } @@ -210,7 +210,7 @@ pub enum SomeEnum { let actual = db.log_executed(|| { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - db.trait_impls_in_crate(module.krate()); + db.trait_impls_in_crate(module.krate(&db)); }); let expected = vec![ @@ -244,7 +244,7 @@ $0", let events = db.log_executed(|| { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - db.trait_impls_in_crate(module.krate()); + db.trait_impls_in_crate(module.krate(&db)); }); assert!(format!("{events:?}").contains("trait_impls_in_crate_shim")) } @@ -267,7 +267,7 @@ fn bar() -> f32 { let actual = db.log_executed(|| { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - db.trait_impls_in_crate(module.krate()); + db.trait_impls_in_crate(module.krate(&db)); }); let expected = vec![ @@ -305,7 +305,7 @@ $0", let events = db.log_executed(|| { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - db.trait_impls_in_crate(module.krate()); + db.trait_impls_in_crate(module.krate(&db)); }); assert!(format!("{events:?}").contains("trait_impls_in_crate_shim")) } @@ -336,7 +336,7 @@ impl SomeStruct { let actual = db.log_executed(|| { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - db.trait_impls_in_crate(module.krate()); + db.trait_impls_in_crate(module.krate(&db)); }); let expected = vec![ @@ -385,7 +385,7 @@ fn main() { let module = db.module_for_file(file_id.file_id(&db)); let crate_def_map = module.def_map(&db); let mut defs: Vec = vec![]; - visit_module(&db, crate_def_map, module.local_id, &mut |it| { + visit_module(&db, crate_def_map, module, &mut |it| { let def = match it { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::EnumVariantId(it) => it.into(), @@ -428,7 +428,7 @@ fn main() { let crate_def_map = module.def_map(&db); let mut defs: Vec = vec![]; - visit_module(&db, crate_def_map, module.local_id, &mut |it| { + visit_module(&db, crate_def_map, module, &mut |it| { let def = match it { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::EnumVariantId(it) => it.into(), diff --git a/crates/hir-ty/src/variance.rs b/crates/hir-ty/src/variance.rs index 62478d4fd86c..fe2e5fd1ddcf 100644 --- a/crates/hir-ty/src/variance.rs +++ b/crates/hir-ty/src/variance.rs @@ -984,7 +984,7 @@ struct FixedPoint(&'static FixedPoint<(), T, U>, V); let mut defs: Vec = Vec::new(); let module = db.module_for_file_opt(file_id.file_id(&db)).unwrap(); let def_map = module.def_map(&db); - crate::tests::visit_module(&db, def_map, module.local_id, &mut |it| { + crate::tests::visit_module(&db, def_map, module, &mut |it| { defs.push(match it { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::AdtId(it) => it.into(), diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs index b1cf30b98f5b..3a0c519b7fb1 100644 --- a/crates/hir/src/attrs.rs +++ b/crates/hir/src/attrs.rs @@ -25,7 +25,7 @@ use crate::{ pub trait HasAttrs { fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner; #[doc(hidden)] - fn attr_id(self) -> AttrDefId; + fn attr_id(self, db: &dyn HirDatabase) -> AttrDefId; } macro_rules! impl_has_attrs { @@ -35,7 +35,7 @@ macro_rules! impl_has_attrs { let def = AttrDefId::$def_id(self.into()); AttrsWithOwner::new(db, def) } - fn attr_id(self) -> AttrDefId { + fn attr_id(self, _: &dyn HirDatabase) -> AttrDefId { AttrDefId::$def_id(self.into()) } } @@ -65,8 +65,8 @@ macro_rules! impl_has_attrs_enum { fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner { $enum::$variant(self).attrs(db) } - fn attr_id(self) -> AttrDefId { - $enum::$variant(self).attr_id() + fn attr_id(self, db: &dyn HirDatabase) -> AttrDefId { + $enum::$variant(self).attr_id(db) } } )*}; @@ -83,22 +83,22 @@ impl HasAttrs for AssocItem { AssocItem::TypeAlias(it) => it.attrs(db), } } - fn attr_id(self) -> AttrDefId { + fn attr_id(self, db: &dyn HirDatabase) -> AttrDefId { match self { - AssocItem::Function(it) => it.attr_id(), - AssocItem::Const(it) => it.attr_id(), - AssocItem::TypeAlias(it) => it.attr_id(), + AssocItem::Function(it) => it.attr_id(db), + AssocItem::Const(it) => it.attr_id(db), + AssocItem::TypeAlias(it) => it.attr_id(db), } } } impl HasAttrs for crate::Crate { fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner { - let def = AttrDefId::ModuleId(self.root_module().id); + let def = AttrDefId::ModuleId(self.root_module(db).id); AttrsWithOwner::new(db, def) } - fn attr_id(self) -> AttrDefId { - AttrDefId::ModuleId(self.root_module().id) + fn attr_id(self, db: &dyn HirDatabase) -> AttrDefId { + AttrDefId::ModuleId(self.root_module(db).id) } } @@ -110,7 +110,7 @@ pub fn resolve_doc_path_on( ns: Option, is_inner_doc: bool, ) -> Option { - resolve_doc_path_on_(db, link, def.attr_id(), ns, is_inner_doc) + resolve_doc_path_on_(db, link, def.attr_id(db), ns, is_inner_doc) } fn resolve_doc_path_on_( diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index fe7429c86725..5f346286d30a 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs @@ -36,23 +36,23 @@ impl Module { /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. pub fn definition_source(self, db: &dyn HirDatabase) -> InFile { let def_map = self.id.def_map(db); - def_map[self.id.local_id].definition_source(db) + def_map[self.id].definition_source(db) } /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. pub fn definition_source_range(self, db: &dyn HirDatabase) -> InFile { let def_map = self.id.def_map(db); - def_map[self.id.local_id].definition_source_range(db) + def_map[self.id].definition_source_range(db) } pub fn definition_source_file_id(self, db: &dyn HirDatabase) -> HirFileId { let def_map = self.id.def_map(db); - def_map[self.id.local_id].definition_source_file_id() + def_map[self.id].definition_source_file_id() } pub fn is_mod_rs(self, db: &dyn HirDatabase) -> bool { let def_map = self.id.def_map(db); - match def_map[self.id.local_id].origin { + match def_map[self.id].origin { ModuleOrigin::File { is_mod_rs, .. } => is_mod_rs, _ => false, } @@ -60,7 +60,7 @@ impl Module { pub fn as_source_file_id(self, db: &dyn HirDatabase) -> Option { let def_map = self.id.def_map(db); - match def_map[self.id.local_id].origin { + match def_map[self.id].origin { ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition, .. } => { Some(definition) } @@ -70,21 +70,21 @@ impl Module { pub fn is_inline(self, db: &dyn HirDatabase) -> bool { let def_map = self.id.def_map(db); - def_map[self.id.local_id].origin.is_inline() + def_map[self.id].origin.is_inline() } /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. /// `None` for the crate root. pub fn declaration_source(self, db: &dyn HirDatabase) -> Option> { let def_map = self.id.def_map(db); - def_map[self.id.local_id].declaration_source(db) + def_map[self.id].declaration_source(db) } /// Returns a text range which declares this module, either a `mod foo;` or a `mod foo {}`. /// `None` for the crate root. pub fn declaration_source_range(self, db: &dyn HirDatabase) -> Option> { let def_map = self.id.def_map(db); - def_map[self.id.local_id].declaration_source_range(db) + def_map[self.id].declaration_source_range(db) } } diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index c746b88c5b11..671e9f1dcd1a 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -43,10 +43,10 @@ use base_db::{CrateDisplayName, CrateOrigin, LangCrateOrigin}; use either::Either; use hir_def::{ AdtId, AssocItemId, AssocItemLoc, AttrDefId, CallableDefId, ConstId, ConstParamId, - CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, - FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, - LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId, SyntheticSyntax, - TraitAliasId, TupleId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, + DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, + GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, + MacroExpander, MacroId, ModuleId, StaticId, StructId, SyntheticSyntax, TraitAliasId, TupleId, + TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, expr_store::{ExpressionStoreDiagnostics, ExpressionStoreSourceMap}, hir::{ BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat, @@ -225,13 +225,13 @@ impl Crate { db.transitive_rev_deps(self.id).into_iter().map(|id| Crate { id }) } - pub fn root_module(self) -> Module { - Module { id: CrateRootModuleId::from(self.id).into() } + pub fn root_module(self, db: &dyn HirDatabase) -> Module { + Module { id: crate_def_map(db, self.id).root_module_id() } } pub fn modules(self, db: &dyn HirDatabase) -> Vec { let def_map = crate_def_map(db, self.id); - def_map.modules().map(|(id, _)| def_map.module_id(id).into()).collect() + def_map.modules().map(|(id, _)| id.into()).collect() } pub fn root_file(self, db: &dyn HirDatabase) -> FileId { @@ -274,7 +274,7 @@ impl Crate { /// Try to get the root URL of the documentation of a crate. pub fn get_html_root_url(self: &Crate, db: &dyn HirDatabase) -> Option { // Look for #![doc(html_root_url = "...")] - let attrs = db.attrs(AttrDefId::ModuleId(self.root_module().into())); + let attrs = db.attrs(AttrDefId::ModuleId(self.root_module(db).into())); let doc_url = attrs.by_key(sym::doc).find_string_value_in_tt(sym::html_root_url); doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/") } @@ -492,7 +492,7 @@ impl ModuleDef { impl HasCrate for ModuleDef { fn krate(&self, db: &dyn HirDatabase) -> Crate { match self.module(db) { - Some(module) => module.krate(), + Some(module) => module.krate(db), None => Crate::core(db).unwrap_or_else(|| db.all_crates()[0].into()), } } @@ -523,29 +523,29 @@ impl Module { } /// Returns the crate this module is part of. - pub fn krate(self) -> Crate { - Crate { id: self.id.krate() } + pub fn krate(self, db: &dyn HirDatabase) -> Crate { + Crate { id: self.id.krate(db) } } /// Topmost parent of this module. Every module has a `crate_root`, but some /// might be missing `krate`. This can happen if a module's file is not included /// in the module tree of any target in `Cargo.toml`. pub fn crate_root(self, db: &dyn HirDatabase) -> Module { - let def_map = crate_def_map(db, self.id.krate()); - Module { id: def_map.crate_root().into() } + let def_map = crate_def_map(db, self.id.krate(db)); + Module { id: def_map.crate_root(db) } } - pub fn is_crate_root(self) -> bool { - DefMap::ROOT == self.id.local_id + pub fn is_crate_root(self, db: &dyn HirDatabase) -> bool { + self.crate_root(db) == self } /// Iterates over all child modules. pub fn children(self, db: &dyn HirDatabase) -> impl Iterator { let def_map = self.id.def_map(db); - let children = def_map[self.id.local_id] + let children = def_map[self.id] .children .values() - .map(|module_id| Module { id: def_map.module_id(*module_id) }) + .map(|module_id| Module { id: *module_id }) .collect::>(); children.into_iter() } @@ -553,14 +553,14 @@ impl Module { /// Finds a parent module. pub fn parent(self, db: &dyn HirDatabase) -> Option { let def_map = self.id.def_map(db); - let parent_id = def_map.containing_module(self.id.local_id)?; + let parent_id = def_map.containing_module(self.id)?; Some(Module { id: parent_id }) } /// Finds nearest non-block ancestor `Module` (`self` included). pub fn nearest_non_block_module(self, db: &dyn HirDatabase) -> Module { let mut id = self.id; - while id.is_block_module() { + while id.is_block_module(db) { id = id.containing_module(db).expect("block without parent module"); } Module { id } @@ -582,7 +582,7 @@ impl Module { db: &dyn HirDatabase, visible_from: Option, ) -> Vec<(Name, ScopeDef)> { - self.id.def_map(db)[self.id.local_id] + self.id.def_map(db)[self.id] .scope .entries() .filter_map(|(name, def)| { @@ -619,19 +619,19 @@ impl Module { style_lints: bool, ) { let _p = tracing::info_span!("diagnostics", name = ?self.name(db)).entered(); - let edition = self.id.krate().data(db).edition; + let edition = self.id.krate(db).data(db).edition; let def_map = self.id.def_map(db); for diag in def_map.diagnostics() { - if diag.in_module != self.id.local_id { + if diag.in_module != self.id { // FIXME: This is accidentally quadratic. continue; } emit_def_diagnostic(db, acc, diag, edition); } - if !self.id.is_block_module() { + if !self.id.is_block_module(db) { // These are reported by the body of block modules - let scope = &def_map[self.id.local_id].scope; + let scope = &def_map[self.id].scope; scope.all_macro_calls().for_each(|it| macro_call_diagnostics(db, it, acc)); } @@ -639,7 +639,7 @@ impl Module { match def { ModuleDef::Module(m) => { // Only add diagnostics from inline modules - if def_map[m.id.local_id].origin.is_inline() { + if def_map[m.id].origin.is_inline() { m.diagnostics(db, acc, style_lints) } acc.extend(def.diagnostics(db, style_lints)) @@ -737,7 +737,7 @@ impl Module { } self.legacy_macros(db).into_iter().for_each(|m| emit_macro_def_diagnostics(db, acc, m)); - let inherent_impls = db.inherent_impls_in_crate(self.id.krate()); + let inherent_impls = db.inherent_impls_in_crate(self.id.krate(db)); let mut impl_assoc_items_scratch = vec![]; for impl_def in self.impl_defs(db) { @@ -780,7 +780,7 @@ impl Module { let drop_maybe_dangle = (|| { // FIXME: This can be simplified a lot by exposing hir-ty's utils.rs::Generics helper let trait_ = trait_?; - let drop_trait = LangItem::Drop.resolve_trait(db, self.krate().into())?; + let drop_trait = LangItem::Drop.resolve_trait(db, self.krate(db).into())?; if drop_trait != trait_.into() { return None; } @@ -920,7 +920,7 @@ impl Module { pub fn declarations(self, db: &dyn HirDatabase) -> Vec { let def_map = self.id.def_map(db); - let scope = &def_map[self.id.local_id].scope; + let scope = &def_map[self.id].scope; scope .declarations() .map(ModuleDef::from) @@ -930,13 +930,13 @@ impl Module { pub fn legacy_macros(self, db: &dyn HirDatabase) -> Vec { let def_map = self.id.def_map(db); - let scope = &def_map[self.id.local_id].scope; + let scope = &def_map[self.id].scope; scope.legacy_macros().flat_map(|(_, it)| it).map(|&it| it.into()).collect() } pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec { let def_map = self.id.def_map(db); - def_map[self.id.local_id].scope.impls().map(Impl::from).collect() + def_map[self.id].scope.impls().map(Impl::from).collect() } /// Finds a path that can be used to refer to the given item from within @@ -1228,7 +1228,7 @@ fn precise_macro_call_location( impl HasVisibility for Module { fn visibility(&self, db: &dyn HirDatabase) -> Visibility { let def_map = self.id.def_map(db); - let module_data = &def_map[self.id.local_id]; + let module_data = &def_map[self.id]; module_data.visibility } } @@ -1526,7 +1526,7 @@ impl Enum { /// The type of the enum variant bodies. pub fn variant_body_ty(self, db: &dyn HirDatabase) -> Type { Type::new_for_crate( - self.id.lookup(db).container.krate(), + self.id.lookup(db).container.krate(db), TyBuilder::builtin(match db.enum_signature(self.id).variant_body_type() { layout::IntegerType::Pointer(sign) => match sign { true => hir_def::builtin_type::BuiltinType::Int( @@ -1869,7 +1869,7 @@ impl DefWithBody { pub fn debug_mir(self, db: &dyn HirDatabase) -> String { let body = db.mir_body(self.id()); match body { - Ok(body) => body.pretty_print(db, self.module(db).krate().to_display_target(db)), + Ok(body) => body.pretty_print(db, self.module(db).krate(db).to_display_target(db)), Err(e) => format!("error:\n{e:?}"), } } @@ -1880,7 +1880,7 @@ impl DefWithBody { acc: &mut Vec, style_lints: bool, ) { - let krate = self.module(db).id.krate(); + let krate = self.module(db).id.krate(db); let (body, source_map) = db.body_with_source_map(self.into()); let sig_source_map = match self { @@ -1894,7 +1894,7 @@ impl DefWithBody { }; for (_, def_map) in body.blocks(db) { - Module { id: def_map.module_id(DefMap::ROOT) }.diagnostics(db, acc, style_lints); + Module { id: def_map.root_module_id() }.diagnostics(db, acc, style_lints); } source_map @@ -2387,7 +2387,7 @@ impl Function { /// is this a `fn main` or a function with an `export_name` of `main`? pub fn is_main(self, db: &dyn HirDatabase) -> bool { db.attrs(self.id.into()).export_name() == Some(&sym::main) - || self.module(db).is_crate_root() && db.function_signature(self.id).name == sym::main + || self.module(db).is_crate_root(db) && db.function_signature(self.id).name == sym::main } /// Is this a function with an `export_name` of `main`? @@ -2648,7 +2648,7 @@ impl ExternCrateDecl { pub fn resolved_crate(self, db: &dyn HirDatabase) -> Option { let loc = self.id.lookup(db); - let krate = loc.container.krate(); + let krate = loc.container.krate(db); let name = self.name(db); if name == sym::self_ { Some(krate.into()) @@ -3244,8 +3244,8 @@ impl ItemInNs { /// Returns the crate defining this item (or `None` if `self` is built-in). pub fn krate(&self, db: &dyn HirDatabase) -> Option { match self { - ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate()), - ItemInNs::Macros(id) => Some(id.module(db).krate()), + ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate(db)), + ItemInNs::Macros(id) => Some(id.module(db).krate(db)), } } @@ -4310,7 +4310,7 @@ impl Impl { } pub fn all_in_module(db: &dyn HirDatabase, module: Module) -> Vec { - module.id.def_map(db)[module.id.local_id].scope.impls().map(Into::into).collect() + module.id.def_map(db)[module.id].scope.impls().map(Into::into).collect() } pub fn all_for_type(db: &dyn HirDatabase, Type { ty, env }: Type) -> Vec { @@ -4356,8 +4356,7 @@ impl Impl { ); } - if let Some(block) = ty.adt_id(Interner).and_then(|def| def.0.module(db).containing_block()) - { + if let Some(block) = ty.adt_id(Interner).and_then(|def| def.0.module(db).block(db)) { if let Some(inherent_impls) = db.inherent_impls_in_block(block) { all.extend( inherent_impls.for_self_ty(&ty).iter().cloned().map(Self::from).filter(filter), @@ -4378,13 +4377,13 @@ impl Impl { pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec { let module = trait_.module(db); - let krate = module.krate(); + let krate = module.krate(db); let mut all = Vec::new(); for Crate { id } in krate.transitive_reverse_dependencies(db) { let impls = db.trait_impls_in_crate(id); all.extend(impls.for_trait(trait_.id).map(Self::from)) } - if let Some(block) = module.id.containing_block() { + if let Some(block) = module.id.block(db) { if let Some(trait_impls) = db.trait_impls_in_block(block) { all.extend(trait_impls.for_trait(trait_.id).map(Self::from)); } @@ -4437,7 +4436,7 @@ impl Impl { MacroCallKind::Derive { ast_id, derive_attr_index, derive_index, .. } => { let module_id = self.id.lookup(db).container; ( - crate_def_map(db, module_id.krate())[module_id.local_id] + module_id.def_map(db)[module_id] .scope .derive_macro_invoc(ast_id, derive_attr_index)?, derive_index, @@ -5476,7 +5475,7 @@ impl Type { db, environment, traits_in_scope, - with_local_impls.and_then(|b| b.id.containing_block()).into(), + with_local_impls.and_then(|b| b.id.block(db)).into(), name, method_resolution::LookupMode::MethodCall, &mut Callback(callback), @@ -5563,7 +5562,7 @@ impl Type { db, environment, traits_in_scope, - with_local_impls.and_then(|b| b.id.containing_block()).into(), + with_local_impls.and_then(|b| b.id.block(db)).into(), name, &mut Callback(callback), ); @@ -6048,12 +6047,12 @@ impl ScopeDef { pub fn krate(&self, db: &dyn HirDatabase) -> Option { match self { - ScopeDef::ModuleDef(it) => it.module(db).map(|m| m.krate()), - ScopeDef::GenericParam(it) => Some(it.module(db).krate()), + ScopeDef::ModuleDef(it) => it.module(db).map(|m| m.krate(db)), + ScopeDef::GenericParam(it) => Some(it.module(db).krate(db)), ScopeDef::ImplSelfType(_) => None, - ScopeDef::AdtSelfType(it) => Some(it.module(db).krate()), - ScopeDef::Local(it) => Some(it.module(db).krate()), - ScopeDef::Label(it) => Some(it.module(db).krate()), + ScopeDef::AdtSelfType(it) => Some(it.module(db).krate(db)), + ScopeDef::Local(it) => Some(it.module(db).krate(db)), + ScopeDef::Label(it) => Some(it.module(db).krate(db)), ScopeDef::Unknown => None, } } @@ -6113,61 +6112,61 @@ pub trait HasCrate { impl HasCrate for T { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate().into() + self.module(db).krate(db).into() } } impl HasCrate for AssocItem { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Struct { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Union { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Enum { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Field { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.parent_def(db).module(db).krate() + self.parent_def(db).module(db).krate(db) } } impl HasCrate for Variant { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Function { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Const { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for TypeAlias { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } @@ -6179,43 +6178,43 @@ impl HasCrate for Type { impl HasCrate for Macro { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Trait { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for TraitAlias { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Static { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Adt { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Impl { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Module { - fn krate(&self, _: &dyn HirDatabase) -> Crate { - Module::krate(*self) + fn krate(&self, db: &dyn HirDatabase) -> Crate { + Module::krate(*self, db) } } @@ -6233,8 +6232,8 @@ impl HasContainer for Module { fn container(&self, db: &dyn HirDatabase) -> ItemContainer { // FIXME: handle block expressions as modules (their parent is in a different DefMap) let def_map = self.id.def_map(db); - match def_map[self.id.local_id].parent { - Some(parent_id) => ItemContainer::Module(Module { id: def_map.module_id(parent_id) }), + match def_map[self.id].parent { + Some(parent_id) => ItemContainer::Module(Module { id: parent_id }), None => ItemContainer::Crate(def_map.krate().into()), } } @@ -6399,7 +6398,7 @@ pub fn resolve_absolute_path<'a, I: Iterator + Clone + 'a>( .filter_map(|&krate| { let segments = segments.clone(); let mut def_map = crate_def_map(db, krate); - let mut module = &def_map[DefMap::ROOT]; + let mut module = &def_map[def_map.root]; let mut segments = segments.with_position().peekable(); while let Some((_, segment)) = segments.next_if(|&(position, _)| { !matches!(position, itertools::Position::Last | itertools::Position::Only) @@ -6413,7 +6412,7 @@ pub fn resolve_absolute_path<'a, I: Iterator + Clone + 'a>( _ => None, })?; def_map = res.def_map(db); - module = &def_map[res.local_id]; + module = &def_map[res]; } let (_, item_name) = segments.next()?; let res = module.scope.get(&Name::new_symbol_root(item_name)); diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 10498958242a..533fd4384187 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -375,7 +375,7 @@ impl<'db> SemanticsImpl<'db> { /// If not crate is found for the file, try to return the last crate in topological order. pub fn first_crate(&self, file: FileId) -> Option { match self.file_to_module_defs(file).next() { - Some(module) => Some(module.krate()), + Some(module) => Some(module.krate(self.db)), None => self.db.all_crates().last().copied().map(Into::into), } } @@ -384,7 +384,7 @@ impl<'db> SemanticsImpl<'db> { Some(EditionedFileId::new( self.db, file, - self.file_to_module_defs(file).next()?.krate().edition(self.db), + self.file_to_module_defs(file).next()?.krate(self.db).edition(self.db), )) } @@ -411,8 +411,8 @@ impl<'db> SemanticsImpl<'db> { match file_id { HirFileId::FileId(file_id) => { let module = self.file_to_module_defs(file_id.file_id(self.db)).next()?; - let def_map = crate_def_map(self.db, module.krate().id); - match def_map[module.id.local_id].origin { + let def_map = crate_def_map(self.db, module.krate(self.db).id); + match def_map[module.id].origin { ModuleOrigin::CrateRoot { .. } => None, ModuleOrigin::File { declaration, declaration_tree_id, .. } => { let file_id = declaration_tree_id.file_id(); @@ -438,7 +438,7 @@ impl<'db> SemanticsImpl<'db> { /// the `SyntaxNode` of the *definition* file, not of the *declaration*. pub fn module_definition_node(&self, module: Module) -> InFile { let def_map = module.id.def_map(self.db); - let definition = def_map[module.id.local_id].origin.definition_source(self.db); + let definition = def_map[module.id].origin.definition_source(self.db); let definition = definition.map(|it| it.node()); let root_node = find_root(&definition.value); self.cache(root_node, definition.file_id); @@ -467,7 +467,7 @@ impl<'db> SemanticsImpl<'db> { let file_id = self.find_file(attr.syntax()).file_id; let krate = match file_id { HirFileId::FileId(file_id) => { - self.file_to_module_defs(file_id.file_id(self.db)).next()?.krate().id + self.file_to_module_defs(file_id.file_id(self.db)).next()?.krate(self.db).id } HirFileId::MacroFile(macro_file) => self.db.lookup_intern_macro_call(macro_file).krate, }; diff --git a/crates/hir/src/semantics/child_by_source.rs b/crates/hir/src/semantics/child_by_source.rs index ea44451a8ee4..474d6d7a93e6 100644 --- a/crates/hir/src/semantics/child_by_source.rs +++ b/crates/hir/src/semantics/child_by_source.rs @@ -20,7 +20,6 @@ use hir_def::{ }, hir::generics::GenericParams, item_scope::ItemScope, - nameres::DefMap, src::{HasChildSource, HasSource}, }; @@ -87,7 +86,7 @@ impl ChildBySource for ImplId { impl ChildBySource for ModuleId { fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) { let def_map = self.def_map(db); - let module_data = &def_map[self.local_id]; + let module_data = &def_map[*self]; module_data.scope.child_by_source_to(db, res, file_id); } } @@ -230,7 +229,7 @@ impl ChildBySource for DefWithBodyId { for (block, def_map) in body.blocks(db) { // All block expressions are merged into the same map, because they logically all add // inner items to the containing `DefWithBodyId`. - def_map[DefMap::ROOT].scope.child_by_source_to(db, res, file_id); + def_map[def_map.root].scope.child_by_source_to(db, res, file_id); res[keys::BLOCK].insert(block.lookup(db).ast_id.to_ptr(db), block); } } diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 71ee0f693896..be53f394d5bc 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs @@ -183,11 +183,7 @@ impl SourceToDefCtx<'_, '_> { // Note: `mod` declarations in block modules cannot be supported here let crate_def_map = crate_def_map(self.db, crate_id); let n_mods = mods.len(); - let modules = |file| { - crate_def_map - .modules_for_file(self.db, file) - .map(|local_id| crate_def_map.module_id(local_id)) - }; + let modules = |file| crate_def_map.modules_for_file(self.db, file); mods.extend(modules(file)); if mods.len() == n_mods { mods.extend( @@ -239,8 +235,8 @@ impl SourceToDefCtx<'_, '_> { let child_name = src.value.name()?.as_name(); let def_map = parent_module.def_map(self.db); - let &child_id = def_map[parent_module.local_id].children.get(&child_name)?; - Some(def_map.module_id(child_id)) + let &child_id = def_map[parent_module].children.get(&child_name)?; + Some(child_id) } pub(super) fn source_file_to_def(&mut self, src: InFile<&ast::SourceFile>) -> Option { diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs index a0815c3131b1..92c2a112541a 100644 --- a/crates/hir/src/symbols.rs +++ b/crates/hir/src/symbols.rs @@ -231,7 +231,7 @@ impl<'a> SymbolCollector<'a> { }; let def_map = module_id.def_map(self.db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; for impl_id in scope.impls() { self.collect_from_impl(impl_id); @@ -302,10 +302,7 @@ impl<'a> SymbolCollector<'a> { // Descend into the blocks and enqueue collection of all modules within. for (_, def_map) in body.blocks(self.db) { for (id, _) in def_map.modules() { - self.work.push(SymbolCollectorWork { - module_id: def_map.module_id(id), - parent: name.clone(), - }); + self.work.push(SymbolCollectorWork { module_id: id, parent: name.clone() }); } } } @@ -417,7 +414,7 @@ impl<'a> SymbolCollector<'a> { fn push_module(&mut self, module_id: ModuleId, name: &Name) { let def_map = module_id.def_map(self.db); - let module_data = &def_map[module_id.local_id]; + let module_data = &def_map[module_id]; let Some(declaration) = module_data.origin.declaration() else { return }; let module = declaration.to_node(self.db); let Some(name_node) = module.name() else { return }; diff --git a/crates/hir/src/term_search/tactics.rs b/crates/hir/src/term_search/tactics.rs index bcff44fcd016..1f9adc2942be 100644 --- a/crates/hir/src/term_search/tactics.rs +++ b/crates/hir/src/term_search/tactics.rs @@ -758,7 +758,7 @@ pub(super) fn make_tuple<'a, DB: HirDatabase>( .filter(|_| should_continue()) .map(|params| { let tys: Vec = params.iter().map(|it| it.ty(db)).collect(); - let tuple_ty = Type::new_tuple(module.krate().into(), &tys); + let tuple_ty = Type::new_tuple(module.krate(db).into(), &tys); let expr = Expr::Tuple { ty: tuple_ty.clone(), params }; lookup.insert(tuple_ty, iter::once(expr.clone())); diff --git a/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/crates/ide-assists/src/handlers/add_missing_impl_members.rs index 6a55f39e6934..2979a1549c9e 100644 --- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs @@ -129,7 +129,7 @@ fn add_missing_impl_members_inner( if let IgnoreAssocItems::DocHiddenAttrPresent = ignore_items { // Relax condition for local crates. let db = ctx.db(); - if trait_.module(db).krate().origin(db).is_local() { + if trait_.module(db).krate(db).origin(db).is_local() { ign_item = IgnoreAssocItems::No; } } diff --git a/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 858d4369914a..dfdeec5a0c33 100644 --- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -85,24 +85,26 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) bool, bool, ) = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr) { - let is_non_exhaustive = enum_def.is_non_exhaustive(ctx.db(), module.krate()); + let is_non_exhaustive = enum_def.is_non_exhaustive(ctx.db(), module.krate(ctx.db())); let variants = enum_def.variants(ctx.db()); - let has_hidden_variants = - variants.iter().any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); + let has_hidden_variants = variants + .iter() + .any(|variant| variant.should_be_hidden(ctx.db(), module.krate(ctx.db()))); let missing_pats = variants .into_iter() .filter_map(|variant| { Some(( build_pat(ctx, &make, module, variant, cfg)?, - variant.should_be_hidden(ctx.db(), module.krate()), + variant.should_be_hidden(ctx.db(), module.krate(ctx.db())), )) }) .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat)); - let option_enum = FamousDefs(&ctx.sema, module.krate()).core_option_Option().map(lift_enum); + let option_enum = + FamousDefs(&ctx.sema, module.krate(ctx.db())).core_option_Option().map(lift_enum); let missing_pats: Box> = if Some(enum_def) == option_enum { // Match `Some` variant first. cov_mark::hit!(option_order); @@ -112,8 +114,9 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) }; (missing_pats.peekable(), is_non_exhaustive, has_hidden_variants) } else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) { - let is_non_exhaustive = - enum_defs.iter().any(|enum_def| enum_def.is_non_exhaustive(ctx.db(), module.krate())); + let is_non_exhaustive = enum_defs + .iter() + .any(|enum_def| enum_def.is_non_exhaustive(ctx.db(), module.krate(ctx.db()))); let mut n_arms = 1; let variants_of_enums: Vec> = enum_defs @@ -137,7 +140,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let has_hidden_variants = variants_of_enums .iter() .flatten() - .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); + .any(|variant| variant.should_be_hidden(ctx.db(), module.krate(ctx.db()))); let missing_pats = variants_of_enums .into_iter() @@ -146,7 +149,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .map(|variants| { let is_hidden = variants .iter() - .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); + .any(|variant| variant.should_be_hidden(ctx.db(), module.krate(ctx.db()))); let patterns = variants .into_iter() .filter_map(|variant| build_pat(ctx, &make, module, variant, cfg)); @@ -160,15 +163,16 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) has_hidden_variants, ) } else if let Some((enum_def, len)) = resolve_array_of_enum_def(&ctx.sema, &expr) { - let is_non_exhaustive = enum_def.is_non_exhaustive(ctx.db(), module.krate()); + let is_non_exhaustive = enum_def.is_non_exhaustive(ctx.db(), module.krate(ctx.db())); let variants = enum_def.variants(ctx.db()); if len.pow(variants.len() as u32) > 256 { return None; } - let has_hidden_variants = - variants.iter().any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); + let has_hidden_variants = variants + .iter() + .any(|variant| variant.should_be_hidden(ctx.db(), module.krate(ctx.db()))); let variants_of_enums = vec![variants; len]; @@ -179,7 +183,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .map(|variants| { let is_hidden = variants .iter() - .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); + .any(|variant| variant.should_be_hidden(ctx.db(), module.krate(ctx.db()))); let patterns = variants .into_iter() .filter_map(|variant| build_pat(ctx, &make, module, variant, cfg)); @@ -390,7 +394,7 @@ impl ExtendedVariant { fn should_be_hidden(self, db: &RootDatabase, krate: Crate) -> bool { match self { ExtendedVariant::Variant(var) => { - var.attrs(db).has_doc_hidden() && var.module(db).krate() != krate + var.attrs(db).has_doc_hidden() && var.module(db).krate(db) != krate } _ => false, } @@ -405,7 +409,7 @@ impl ExtendedEnum { fn is_non_exhaustive(self, db: &RootDatabase, krate: Crate) -> bool { match self { ExtendedEnum::Enum(e) => { - e.attrs(db).by_key(sym::non_exhaustive).exists() && e.module(db).krate() != krate + e.attrs(db).by_key(sym::non_exhaustive).exists() && e.module(db).krate(db) != krate } _ => false, } @@ -475,7 +479,7 @@ fn build_pat( let db = ctx.db(); match var { ExtendedVariant::Variant(var) => { - let edition = module.krate().edition(db); + let edition = module.krate(ctx.db()).edition(db); let path = mod_path_to_ast(&module.find_path(db, ModuleDef::from(var), cfg)?, edition); let fields = var.fields(db); let pat: ast::Pat = match var.kind(db) { diff --git a/crates/ide-assists/src/handlers/apply_demorgan.rs b/crates/ide-assists/src/handlers/apply_demorgan.rs index 3b447d1f6d57..d1d24dba5ec1 100644 --- a/crates/ide-assists/src/handlers/apply_demorgan.rs +++ b/crates/ide-assists/src/handlers/apply_demorgan.rs @@ -251,7 +251,7 @@ fn validate_method_call_expr( let receiver = method_call.receiver()?; let it_type = sema.type_of_expr(&receiver)?.adjusted(); let module = sema.scope(receiver.syntax())?.module(); - let krate = module.krate(); + let krate = module.krate(ctx.db()); let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; it_type.impls_trait(sema.db, iter_trait, &[]).then_some((name_ref, arg_expr)) diff --git a/crates/ide-assists/src/handlers/auto_import.rs b/crates/ide-assists/src/handlers/auto_import.rs index f3243d369a0b..141bd5eaca71 100644 --- a/crates/ide-assists/src/handlers/auto_import.rs +++ b/crates/ide-assists/src/handlers/auto_import.rs @@ -114,7 +114,8 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< proposed_imports.sort_by_key(|import| { Reverse(relevance_score(ctx, import, expected.as_ref(), current_module.as_ref())) }); - let edition = current_module.map(|it| it.krate().edition(ctx.db())).unwrap_or(Edition::CURRENT); + let edition = + current_module.map(|it| it.krate(ctx.db()).edition(ctx.db())).unwrap_or(Edition::CURRENT); let group_label = group_label(import_assets.import_candidate()); for import in proposed_imports { @@ -316,11 +317,11 @@ fn module_distance_heuristic(db: &dyn HirDatabase, current: &Module, item: &Modu let distinct_length = current_path.len() + item_path.len() - 2 * prefix_length; // cost of importing from another crate - let crate_boundary_cost = if current.krate() == item.krate() { + let crate_boundary_cost = if current.krate(db) == item.krate(db) { 0 - } else if item.krate().origin(db).is_local() { + } else if item.krate(db).origin(db).is_local() { 2 - } else if item.krate().is_builtin(db) { + } else if item.krate(db).is_builtin(db) { 3 } else { 4 diff --git a/crates/ide-assists/src/handlers/convert_bool_to_enum.rs b/crates/ide-assists/src/handlers/convert_bool_to_enum.rs index f73b8c4fd0f1..ded4ff04a838 100644 --- a/crates/ide-assists/src/handlers/convert_bool_to_enum.rs +++ b/crates/ide-assists/src/handlers/convert_bool_to_enum.rs @@ -336,7 +336,7 @@ fn augment_references_with_imports( let cfg = ctx.config.import_path_config(); - let edition = target_module.krate().edition(ctx.db()); + let edition = target_module.krate(ctx.db()).edition(ctx.db()); references .into_iter() .filter_map(|FileReference { range, name, .. }| { diff --git a/crates/ide-assists/src/handlers/convert_for_to_while_let.rs b/crates/ide-assists/src/handlers/convert_for_to_while_let.rs index 2d6a59a7c365..1ab53f1ea20b 100644 --- a/crates/ide-assists/src/handlers/convert_for_to_while_let.rs +++ b/crates/ide-assists/src/handlers/convert_for_to_while_let.rs @@ -150,7 +150,7 @@ fn impls_core_iter(sema: &hir::Semantics<'_, ide_db::RootDatabase>, iterable: &a let module = sema.scope(iterable.syntax())?.module(); - let krate = module.krate(); + let krate = module.krate(sema.db); let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; cov_mark::hit!(test_already_impls_iterator); Some(it_typ.impls_trait(sema.db, iter_trait, &[])) diff --git a/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs b/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs index db41927f1df2..dd46f9014609 100644 --- a/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs +++ b/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs @@ -65,7 +65,7 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_> let tail_expr = from_fn.body()?.tail_expr()?; if resolve_target_trait(&ctx.sema, &impl_)? - != FamousDefs(&ctx.sema, module.krate()).core_convert_From()? + != FamousDefs(&ctx.sema, module.krate(ctx.db())).core_convert_From()? { return None; } diff --git a/crates/ide-assists/src/handlers/convert_into_to_from.rs b/crates/ide-assists/src/handlers/convert_into_to_from.rs index b80276a95fbf..087b536421ff 100644 --- a/crates/ide-assists/src/handlers/convert_into_to_from.rs +++ b/crates/ide-assists/src/handlers/convert_into_to_from.rs @@ -39,7 +39,7 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) - let module = ctx.sema.scope(impl_.syntax())?.module(); let trait_ = resolve_target_trait(&ctx.sema, &impl_)?; - if trait_ != FamousDefs(&ctx.sema, module.krate()).core_convert_Into()? { + if trait_ != FamousDefs(&ctx.sema, module.krate(ctx.db())).core_convert_Into()? { return None; } @@ -53,7 +53,7 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) - }; mod_path_to_ast( &module.find_path(ctx.db(), src_type_def, cfg)?, - module.krate().edition(ctx.db()), + module.krate(ctx.db()).edition(ctx.db()), ) }; diff --git a/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs b/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs index 3917ca197bb8..f3b2bed2e6a3 100644 --- a/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs +++ b/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs @@ -186,7 +186,7 @@ fn impls_core_iter(sema: &hir::Semantics<'_, ide_db::RootDatabase>, iterable: &a let module = sema.scope(iterable.syntax())?.module(); - let krate = module.krate(); + let krate = module.krate(sema.db); let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; cov_mark::hit!(test_already_impls_iterator); Some(it_typ.impls_trait(sema.db, iter_trait, &[])) @@ -214,7 +214,7 @@ fn validate_method_call_expr( let it_type = sema.type_of_expr(&receiver)?.adjusted(); let module = sema.scope(receiver.syntax())?.module(); - let krate = module.krate(); + let krate = module.krate(ctx.db()); let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; it_type.impls_trait(sema.db, iter_trait, &[]).then_some((expr, receiver)) diff --git a/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs b/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs index cca4cb9d8f77..b9a0098448bd 100644 --- a/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs +++ b/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs @@ -212,7 +212,10 @@ fn augment_references_with_imports( ) .map(|mod_path| { make::path_concat( - mod_path_to_ast(&mod_path, target_module.krate().edition(ctx.db())), + mod_path_to_ast( + &mod_path, + target_module.krate(ctx.db()).edition(ctx.db()), + ), make::path_from_text(struct_name), ) }); diff --git a/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/crates/ide-assists/src/handlers/destructure_struct_binding.rs index b8c647ac8b71..0bdcf868b855 100644 --- a/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/crates/ide-assists/src/handlers/destructure_struct_binding.rs @@ -94,7 +94,8 @@ fn collect_data(ident_pat: ast::IdentPat, ctx: &AssistContext<'_>) -> Option) -> Option (true, current_module.krate().root_module()), - VisibilityKind::PubCrate => (false, current_module.krate().root_module()), + VisibilityKind::Pub => (true, current_module.krate(ctx.db()).root_module(ctx.db())), + VisibilityKind::PubCrate => { + (false, current_module.krate(ctx.db()).root_module(ctx.db())) + } _ => (false, current_module), } }; @@ -170,7 +172,7 @@ fn build_expanded_import( let names_to_import = find_names_to_import(filtered_defs, imported_defs); let expanded = make::use_tree_list(names_to_import.iter().map(|n| { let path = make::ext::ident_path( - &n.display(ctx.db(), current_module.krate().edition(ctx.db())).to_string(), + &n.display(ctx.db(), current_module.krate(ctx.db()).edition(ctx.db())).to_string(), ); make::use_tree(path, None, None, false) })) diff --git a/crates/ide-assists/src/handlers/extract_function.rs b/crates/ide-assists/src/handlers/extract_function.rs index cf45ea0a30d0..a8e6e2b4e095 100644 --- a/crates/ide-assists/src/handlers/extract_function.rs +++ b/crates/ide-assists/src/handlers/extract_function.rs @@ -206,7 +206,7 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op { let scope = builder.make_import_scope_mut(scope); let control_flow_enum = - FamousDefs(&ctx.sema, module.krate()).core_ops_ControlFlow(); + FamousDefs(&ctx.sema, module.krate(ctx.db())).core_ops_ControlFlow(); if let Some(control_flow_enum) = control_flow_enum { let mod_path = module.find_use_path( diff --git a/crates/ide-assists/src/handlers/fix_visibility.rs b/crates/ide-assists/src/handlers/fix_visibility.rs index 3badc17d01af..2077adc6f58a 100644 --- a/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/crates/ide-assists/src/handlers/fix_visibility.rs @@ -59,7 +59,7 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) let (vis_owner, target, target_file, target_name) = target_data_for_def(ctx.db(), def)?; - let missing_visibility = if current_module.krate() == target_module.krate() { + let missing_visibility = if current_module.krate(ctx.db()) == target_module.krate(ctx.db()) { make::visibility_pub_crate() } else { make::visibility_pub() @@ -70,7 +70,7 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) Some(name) => { format!( "Change visibility of {} to {missing_visibility}", - name.display(ctx.db(), current_module.krate().edition(ctx.db())) + name.display(ctx.db(), current_module.krate(ctx.db()).edition(ctx.db())) ) } }; diff --git a/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs b/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs index 6198dbc4ed99..d6ac0fa15364 100644 --- a/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs +++ b/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs @@ -72,7 +72,7 @@ fn existing_default_impl( ) -> Option<()> { let variant = sema.to_def(variant)?; let enum_ = variant.parent_enum(sema.db); - let krate = enum_.module(sema.db).krate(); + let krate = enum_.module(sema.db).krate(sema.db); let default_trait = FamousDefs(sema, krate).core_default_Default()?; let enum_type = enum_.ty(sema.db); diff --git a/crates/ide-assists/src/handlers/generate_default_from_new.rs b/crates/ide-assists/src/handlers/generate_default_from_new.rs index 79a78ab3698b..e7d4bc55a93d 100644 --- a/crates/ide-assists/src/handlers/generate_default_from_new.rs +++ b/crates/ide-assists/src/handlers/generate_default_from_new.rs @@ -138,7 +138,7 @@ fn is_default_implemented(ctx: &AssistContext<'_>, impl_: &Impl) -> bool { }; let ty = impl_def.self_ty(db); - let krate = impl_def.module(db).krate(); + let krate = impl_def.module(db).krate(ctx.db()); let default = FamousDefs(&ctx.sema, krate).core_default_Default(); let default_trait = match default { Some(value) => value, diff --git a/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/crates/ide-assists/src/handlers/generate_delegate_methods.rs index ca66cb69dcc0..0c74a234d023 100644 --- a/crates/ide-assists/src/handlers/generate_delegate_methods.rs +++ b/crates/ide-assists/src/handlers/generate_delegate_methods.rs @@ -55,7 +55,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' let strukt = ctx.find_node_at_offset::()?; let strukt_name = strukt.name()?; let current_module = ctx.sema.scope(strukt.syntax())?.module(); - let current_edition = current_module.krate().edition(ctx.db()); + let current_edition = current_module.krate(ctx.db()).edition(ctx.db()); let (field_name, field_ty, target) = match ctx.find_node_at_offset::() { Some(field) => { diff --git a/crates/ide-assists/src/handlers/generate_delegate_trait.rs b/crates/ide-assists/src/handlers/generate_delegate_trait.rs index 848c63810a4b..4ece6015a0c2 100644 --- a/crates/ide-assists/src/handlers/generate_delegate_trait.rs +++ b/crates/ide-assists/src/handlers/generate_delegate_trait.rs @@ -125,7 +125,7 @@ impl Field { let db = ctx.sema.db; let module = ctx.sema.file_to_module_def(ctx.vfs_file_id())?; - let edition = module.krate().edition(ctx.db()); + let edition = module.krate(ctx.db()).edition(ctx.db()); let (name, range, ty) = match f { Either::Left(f) => { diff --git a/crates/ide-assists/src/handlers/generate_deref.rs b/crates/ide-assists/src/handlers/generate_deref.rs index c7b97dcd231d..cd1cccce5b09 100644 --- a/crates/ide-assists/src/handlers/generate_deref.rs +++ b/crates/ide-assists/src/handlers/generate_deref.rs @@ -57,7 +57,7 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( }; let module = ctx.sema.to_def(&strukt)?.module(ctx.db()); - let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate())?; + let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate(ctx.db()))?; let trait_path = module.find_path(ctx.db(), ModuleDef::Trait(trait_), ctx.config.import_path_config())?; @@ -77,7 +77,7 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( field_name.syntax(), deref_type_to_generate, trait_path, - module.krate().edition(ctx.db()), + module.krate(ctx.db()).edition(ctx.db()), ) }, ) @@ -99,7 +99,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() }; let module = ctx.sema.to_def(&strukt)?.module(ctx.db()); - let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate())?; + let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate(ctx.db()))?; let trait_path = module.find_path(ctx.db(), ModuleDef::Trait(trait_), ctx.config.import_path_config())?; @@ -118,7 +118,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() field_list_index, deref_type_to_generate, trait_path, - module.krate().edition(ctx.db()), + module.krate(ctx.db()).edition(ctx.db()), ) }, ) @@ -163,7 +163,7 @@ fn existing_deref_impl( strukt: &ast::Struct, ) -> Option { let strukt = sema.to_def(strukt)?; - let krate = strukt.module(sema.db).krate(); + let krate = strukt.module(sema.db).krate(sema.db); let deref_trait = FamousDefs(sema, krate).core_ops_Deref()?; let deref_mut_trait = FamousDefs(sema, krate).core_ops_DerefMut()?; diff --git a/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs b/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs index af949a064989..f1038b9a89ae 100644 --- a/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs +++ b/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs @@ -82,7 +82,7 @@ fn existing_from_impl( ) -> Option<()> { let variant = sema.to_def(variant)?; let enum_ = variant.parent_enum(sema.db); - let krate = enum_.module(sema.db).krate(); + let krate = enum_.module(sema.db).krate(sema.db); let from_trait = FamousDefs(sema, krate).core_convert_From()?; diff --git a/crates/ide-assists/src/handlers/generate_function.rs b/crates/ide-assists/src/handlers/generate_function.rs index 30084d23d1fb..9dfbf4a658aa 100644 --- a/crates/ide-assists/src/handlers/generate_function.rs +++ b/crates/ide-assists/src/handlers/generate_function.rs @@ -71,7 +71,7 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { fn_target_info(ctx, path, &call, fn_name)?; if let Some(m) = target_module { - if !is_editable_crate(m.krate(), ctx.db()) { + if !is_editable_crate(m.krate(ctx.db()), ctx.db()) { return None; } } @@ -143,7 +143,7 @@ fn gen_method(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let adt = receiver_ty.as_adt()?; let target_module = adt.module(ctx.sema.db); - if !is_editable_crate(target_module.krate(), ctx.db()) { + if !is_editable_crate(target_module.krate(ctx.db()), ctx.db()) { return None; } @@ -241,7 +241,7 @@ impl FunctionBuilder { ) -> Option { let target_module = target_module.or_else(|| ctx.sema.scope(target.syntax()).map(|it| it.module()))?; - let target_edition = target_module.krate().edition(ctx.db()); + let target_edition = target_module.krate(ctx.db()).edition(ctx.db()); let current_module = ctx.sema.scope(call.syntax())?.module(); let visibility = calculate_necessary_visibility(current_module, target_module, ctx); @@ -311,7 +311,7 @@ impl FunctionBuilder { target_module: Module, target: GeneratedFunctionTarget, ) -> Option { - let target_edition = target_module.krate().edition(ctx.db()); + let target_edition = target_module.krate(ctx.db()).edition(ctx.db()); let current_module = ctx.sema.scope(call.syntax())?.module(); let visibility = calculate_necessary_visibility(current_module, target_module, ctx); @@ -543,7 +543,7 @@ fn assoc_fn_target_info( let current_module = ctx.sema.scope(call.syntax())?.module(); let module = adt.module(ctx.sema.db); let target_module = if current_module == module { None } else { Some(module) }; - if current_module.krate() != module.krate() { + if current_module.krate(ctx.db()) != module.krate(ctx.db()) { return None; } let (impl_, file) = get_adt_source(ctx, &adt, fn_name)?; @@ -1133,7 +1133,10 @@ fn fn_arg_type( convert_reference_type(ty.strip_references(), ctx.db(), famous_defs) .map(|conversion| { conversion - .convert_type(ctx.db(), target_module.krate().to_display_target(ctx.db())) + .convert_type( + ctx.db(), + target_module.krate(ctx.db()).to_display_target(ctx.db()), + ) .to_string() }) .or_else(|| ty.display_source_code(ctx.db(), target_module.into(), true).ok()) @@ -1219,7 +1222,7 @@ fn calculate_necessary_visibility( let current_module = current_module.nearest_non_block_module(db); let target_module = target_module.nearest_non_block_module(db); - if target_module.krate() != current_module.krate() { + if target_module.krate(ctx.db()) != current_module.krate(ctx.db()) { Visibility::Pub } else if current_module.path_to_root(db).contains(&target_module) { Visibility::None diff --git a/crates/ide-assists/src/handlers/generate_new.rs b/crates/ide-assists/src/handlers/generate_new.rs index 4837f92f9345..aa41d922f9b1 100644 --- a/crates/ide-assists/src/handlers/generate_new.rs +++ b/crates/ide-assists/src/handlers/generate_new.rs @@ -64,7 +64,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option ctx.config.import_path_config(), )?; - let edition = current_module.krate().edition(ctx.db()); + let edition = current_module.krate(ctx.db()).edition(ctx.db()); let expr = use_trivial_constructor( ctx.sema.db, diff --git a/crates/ide-assists/src/handlers/inline_call.rs b/crates/ide-assists/src/handlers/inline_call.rs index 6f028e58d0cd..340ab1f986f7 100644 --- a/crates/ide-assists/src/handlers/inline_call.rs +++ b/crates/ide-assists/src/handlers/inline_call.rs @@ -110,7 +110,7 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) -> let mut inline_refs_for_file = |file_id: EditionedFileId, refs: Vec| { let file_id = file_id.file_id(ctx.db()); builder.edit_file(file_id); - let call_krate = ctx.sema.file_to_module_def(file_id).map(|it| it.krate()); + let call_krate = ctx.sema.file_to_module_def(file_id).map(|it| it.krate(ctx.db())); let count = refs.len(); // The collects are required as we are otherwise iterating while mutating 🙅‍♀️🙅‍♂️ let (name_refs, name_refs_use) = split_refs_and_uses(builder, refs, Some); @@ -196,7 +196,7 @@ pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< let name_ref: ast::NameRef = ctx.find_node_at_offset()?; let call_info = CallInfo::from_name_ref( name_ref.clone(), - ctx.sema.file_to_module_def(ctx.vfs_file_id())?.krate().into(), + ctx.sema.file_to_module_def(ctx.vfs_file_id())?.krate(ctx.db()).into(), )?; let (function, label) = match &call_info.node { ast::CallableExpr::Call(call) => { diff --git a/crates/ide-assists/src/handlers/inline_macro.rs b/crates/ide-assists/src/handlers/inline_macro.rs index b09bef36ae15..280bd7f2ca9a 100644 --- a/crates/ide-assists/src/handlers/inline_macro.rs +++ b/crates/ide-assists/src/handlers/inline_macro.rs @@ -38,7 +38,7 @@ use crate::{AssistContext, AssistId, Assists}; pub(crate) fn inline_macro(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let unexpanded = ctx.find_node_at_offset::()?; let macro_call = ctx.sema.to_def(&unexpanded)?; - let target_crate_id = ctx.sema.file_to_module_def(ctx.vfs_file_id())?.krate().into(); + let target_crate_id = ctx.sema.file_to_module_def(ctx.vfs_file_id())?.krate(ctx.db()).into(); let text_range = unexpanded.syntax().text_range(); acc.add( diff --git a/crates/ide-assists/src/handlers/qualify_method_call.rs b/crates/ide-assists/src/handlers/qualify_method_call.rs index 985121780b1a..0c86a392ffd6 100644 --- a/crates/ide-assists/src/handlers/qualify_method_call.rs +++ b/crates/ide-assists/src/handlers/qualify_method_call.rs @@ -42,7 +42,7 @@ pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> let resolved_call = ctx.sema.resolve_method_call(&call)?; let current_module = ctx.sema.scope(call.syntax())?.module(); - let current_edition = current_module.krate().edition(ctx.db()); + let current_edition = current_module.krate(ctx.db()).edition(ctx.db()); let target_module_def = ModuleDef::from(resolved_call); let item_in_ns = ItemInNs::from(target_module_def); let receiver_path = current_module.find_path( diff --git a/crates/ide-assists/src/handlers/qualify_path.rs b/crates/ide-assists/src/handlers/qualify_path.rs index 07d2f52a34ee..9431f93ede71 100644 --- a/crates/ide-assists/src/handlers/qualify_path.rs +++ b/crates/ide-assists/src/handlers/qualify_path.rs @@ -82,7 +82,7 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option proposed_imports.dedup_by(|a, b| a.import_path == b.import_path); let current_edition = - current_module.map(|it| it.krate().edition(ctx.db())).unwrap_or(Edition::CURRENT); + current_module.map(|it| it.krate(ctx.db()).edition(ctx.db())).unwrap_or(Edition::CURRENT); // prioritize more relevant imports proposed_imports.sort_by_key(|import| { Reverse(super::auto_import::relevance_score( diff --git a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 806c8fba9ea4..9e223fcd4715 100644 --- a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -69,7 +69,7 @@ pub(crate) fn replace_derive_with_manual_impl( let args = attr.token_tree()?; let current_module = ctx.sema.scope(adt.syntax())?.module(); - let current_crate = current_module.krate(); + let current_crate = current_module.krate(ctx.db()); let current_edition = current_crate.edition(ctx.db()); let found_traits = items_locator::items_with_name( @@ -233,7 +233,7 @@ fn impl_def_from_trait( let target_scope = sema.scope(annotated_name.syntax())?; // Keep assoc items of local crates even if they have #[doc(hidden)] attr. - let ignore_items = if trait_.module(sema.db).krate().origin(sema.db).is_local() { + let ignore_items = if trait_.module(sema.db).krate(sema.db).origin(sema.db).is_local() { IgnoreAssocItems::No } else { IgnoreAssocItems::DocHiddenAttrPresent diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index 5d68aca9e615..3b15ff788121 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -173,7 +173,7 @@ impl Completions { path_ctx: &PathCompletionCtx, ) { ctx.process_all_names(&mut |name, res, doc_aliases| match res { - ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root() => { + ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root(ctx.db) => { self.add_module(ctx, path_ctx, m, name, doc_aliases); } _ => (), diff --git a/crates/ide-completion/src/completions/attribute/derive.rs b/crates/ide-completion/src/completions/attribute/derive.rs index 2fc07e013828..d7b1fd4b444f 100644 --- a/crates/ide-completion/src/completions/attribute/derive.rs +++ b/crates/ide-completion/src/completions/attribute/derive.rs @@ -56,7 +56,7 @@ pub(crate) fn complete_derive_path( _ => return, }; - match (core, mac.module(ctx.db).krate()) { + match (core, mac.module(ctx.db).krate(ctx.db)) { // show derive dependencies for `core`/`std` derives (Some(core), mac_krate) if core == mac_krate => {} _ => return acc.add_macro(ctx, path_ctx, mac, name), diff --git a/crates/ide-completion/src/completions/attribute/macro_use.rs b/crates/ide-completion/src/completions/attribute/macro_use.rs index 0641a4f6c3fe..136315c61f58 100644 --- a/crates/ide-completion/src/completions/attribute/macro_use.rs +++ b/crates/ide-completion/src/completions/attribute/macro_use.rs @@ -15,7 +15,7 @@ pub(super) fn complete_macro_use( let Some(extern_crate) = ctx.sema.to_def(extern_crate) else { return }; let Some(krate) = extern_crate.resolved_crate(ctx.db) else { return }; - for mod_def in krate.root_module().declarations(ctx.db) { + for mod_def in krate.root_module(ctx.db).declarations(ctx.db) { if let ModuleDef::Macro(mac) = mod_def { let mac_name = mac.name(ctx.db); let mac_name = mac_name.as_str(); diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs index 1fdd4cdb1c6b..6937d1bb89b5 100644 --- a/crates/ide-completion/src/lib.rs +++ b/crates/ide-completion/src/lib.rs @@ -284,7 +284,7 @@ pub fn resolve_completion_edits( let scope = ImportScope::find_insert_use_container(position_for_import, &sema)?; let current_module = sema.scope(position_for_import)?.module(); - let current_crate = current_module.krate(); + let current_crate = current_module.krate(db); let current_edition = current_crate.edition(db); let new_ast = scope.clone_for_update(); let mut import_insert = TextEdit::builder(); diff --git a/crates/ide-completion/src/render/variant.rs b/crates/ide-completion/src/render/variant.rs index 42324b4290a7..3828059ade18 100644 --- a/crates/ide-completion/src/render/variant.rs +++ b/crates/ide-completion/src/render/variant.rs @@ -97,7 +97,7 @@ pub(crate) fn visible_fields( .collect::>(); let has_invisible_field = n_fields - fields.len() > 0; let is_foreign_non_exhaustive = item.attrs(ctx.db).by_key(sym::non_exhaustive).exists() - && item.krate(ctx.db) != module.krate(); + && item.krate(ctx.db) != module.krate(ctx.db); let fields_omitted = has_invisible_field || is_foreign_non_exhaustive; Some((fields, fields_omitted)) } diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs index d5db1c481b69..9e389dbcb790 100644 --- a/crates/ide-db/src/defs.rs +++ b/crates/ide-db/src/defs.rs @@ -63,9 +63,9 @@ impl Definition { pub fn krate(&self, db: &RootDatabase) -> Option { Some(match self { - Definition::Module(m) => m.krate(), + Definition::Module(m) => m.krate(db), &Definition::Crate(it) => it, - _ => self.module(db)?.krate(), + _ => self.module(db)?.krate(db), }) } @@ -93,7 +93,7 @@ impl Definition { Definition::ExternCrateDecl(it) => it.module(db), Definition::DeriveHelper(it) => it.derive().module(db), Definition::InlineAsmOperand(it) => it.parent(db).module(db), - Definition::ToolModule(t) => t.krate().root_module(), + Definition::ToolModule(t) => t.krate().root_module(db), Definition::BuiltinAttr(_) | Definition::BuiltinType(_) | Definition::BuiltinLifetime(_) @@ -377,7 +377,7 @@ fn find_std_module( ) -> Option { let db = famous_defs.0.db; let std_crate = famous_defs.std()?; - let std_root_module = std_crate.root_module(); + let std_root_module = std_crate.root_module(famous_defs.0.db); std_root_module.children(db).find(|module| { module.name(db).is_some_and(|module| module.display(db, edition).to_string() == name) }) diff --git a/crates/ide-db/src/documentation.rs b/crates/ide-db/src/documentation.rs index 30c355f8b3f9..7fb64e4f707e 100644 --- a/crates/ide-db/src/documentation.rs +++ b/crates/ide-db/src/documentation.rs @@ -261,7 +261,7 @@ impl HasDocs for hir::AssocItem { impl HasDocs for hir::ExternCrateDecl { fn docs(self, db: &dyn HirDatabase) -> Option { - let crate_docs = docs_from_attrs(&self.resolved_crate(db)?.root_module().attrs(db)); + let crate_docs = docs_from_attrs(&self.resolved_crate(db)?.root_module(db).attrs(db)); let decl_docs = docs_from_attrs(&self.attrs(db)); match (decl_docs, crate_docs) { (None, None) => None, @@ -278,7 +278,8 @@ impl HasDocs for hir::ExternCrateDecl { } fn docs_with_rangemap(self, db: &dyn HirDatabase) -> Option<(Documentation, DocsRangeMap)> { - let crate_docs = docs_with_rangemap(db, &self.resolved_crate(db)?.root_module().attrs(db)); + let crate_docs = + docs_with_rangemap(db, &self.resolved_crate(db)?.root_module(db).attrs(db)); let decl_docs = docs_with_rangemap(db, &self.attrs(db)); match (decl_docs, crate_docs) { (None, None) => None, diff --git a/crates/ide-db/src/famous_defs.rs b/crates/ide-db/src/famous_defs.rs index 994150b1ac4c..fe9e211f7473 100644 --- a/crates/ide-db/src/famous_defs.rs +++ b/crates/ide-db/src/famous_defs.rs @@ -216,7 +216,7 @@ impl FamousDefs<'_, '_> { lang_crate => lang_crate, }; let std_crate = self.find_lang_crate(lang_crate)?; - let mut module = std_crate.root_module(); + let mut module = std_crate.root_module(db); for segment in path { module = module.children(db).find_map(|child| { let name = child.name(db)?; diff --git a/crates/ide-db/src/helpers.rs b/crates/ide-db/src/helpers.rs index 340429037e67..309ad9a33022 100644 --- a/crates/ide-db/src/helpers.rs +++ b/crates/ide-db/src/helpers.rs @@ -80,7 +80,7 @@ pub fn visit_file_defs( } module.impl_defs(db).into_iter().for_each(|impl_| cb(impl_.into())); - let is_root = module.is_crate_root(); + let is_root = module.is_crate_root(db); module .legacy_macros(db) .into_iter() diff --git a/crates/ide-db/src/imports/import_assets.rs b/crates/ide-db/src/imports/import_assets.rs index ac592dfe93cf..7a7717597973 100644 --- a/crates/ide-db/src/imports/import_assets.rs +++ b/crates/ide-db/src/imports/import_assets.rs @@ -297,7 +297,7 @@ impl ImportAssets { None => return >::default().into_iter(), }; let db = sema.db; - let krate = self.module_with_candidate.krate(); + let krate = self.module_with_candidate.krate(sema.db); let scope_definitions = self.scope_definitions(sema); let mod_path = |item| { get_mod_path( diff --git a/crates/ide-db/src/path_transform.rs b/crates/ide-db/src/path_transform.rs index 232648af661f..3e7a3d986392 100644 --- a/crates/ide-db/src/path_transform.rs +++ b/crates/ide-db/src/path_transform.rs @@ -148,7 +148,7 @@ impl<'a> PathTransform<'a> { let mut type_substs: FxHashMap = Default::default(); let mut const_substs: FxHashMap = Default::default(); let mut defaulted_params: Vec = Default::default(); - let target_edition = target_module.krate().edition(self.source_scope.db); + let target_edition = target_module.krate(db).edition(self.source_scope.db); self.generic_def .into_iter() .flat_map(|it| it.type_or_const_params(db)) @@ -194,7 +194,7 @@ impl<'a> PathTransform<'a> { } (Either::Left(k), None) => { if let Some(default) = - k.default(db, target_module.krate().to_display_target(db)) + k.default(db, target_module.krate(db).to_display_target(db)) { if let Some(default) = default.expr() { const_substs.insert(k, default.syntax().clone_for_update()); diff --git a/crates/ide-db/src/rename.rs b/crates/ide-db/src/rename.rs index 4e737e27f050..e22e61d88771 100644 --- a/crates/ide-db/src/rename.rs +++ b/crates/ide-db/src/rename.rs @@ -247,7 +247,7 @@ fn rename_mod( ) -> Result { let mut source_change = SourceChange::default(); - if module.is_crate_root() { + if module.is_crate_root(sema.db) { return Ok(source_change); } diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs index c5ad64ed5941..91f0a4f3f662 100644 --- a/crates/ide-db/src/search.rs +++ b/crates/ide-db/src/search.rs @@ -296,8 +296,8 @@ impl Definition { // def is crate root if let &Definition::Module(module) = self { - if module.is_crate_root() { - return SearchScope::reverse_dependencies(db, module.krate()); + if module.is_crate_root(db) { + return SearchScope::reverse_dependencies(db, module.krate(db)); } } @@ -370,27 +370,27 @@ impl Definition { return match macro_def.kind(db) { hir::MacroKind::Declarative => { if macro_def.attrs(db).by_key(sym::macro_export).exists() { - SearchScope::reverse_dependencies(db, module.krate()) + SearchScope::reverse_dependencies(db, module.krate(db)) } else { - SearchScope::krate(db, module.krate()) + SearchScope::krate(db, module.krate(db)) } } hir::MacroKind::AttrBuiltIn | hir::MacroKind::DeriveBuiltIn | hir::MacroKind::DeclarativeBuiltIn => SearchScope::crate_graph(db), hir::MacroKind::Derive | hir::MacroKind::Attr | hir::MacroKind::ProcMacro => { - SearchScope::reverse_dependencies(db, module.krate()) + SearchScope::reverse_dependencies(db, module.krate(db)) } }; } if let Definition::DeriveHelper(_) = self { - return SearchScope::reverse_dependencies(db, module.krate()); + return SearchScope::reverse_dependencies(db, module.krate(db)); } let vis = self.visibility(db); if let Some(Visibility::Public) = vis { - return SearchScope::reverse_dependencies(db, module.krate()); + return SearchScope::reverse_dependencies(db, module.krate(db)); } if let Some(Visibility::Module(module, _)) = vis { return SearchScope::module_and_children(db, module.into()); @@ -919,13 +919,13 @@ impl<'a> FindUsages<'a> { } } // special case crate modules as these do not have a proper name - (_, Definition::Module(module)) if module.is_crate_root() => { + (_, Definition::Module(module)) if module.is_crate_root(self.sema.db) => { // FIXME: This assumes the crate name is always equal to its display name when it // really isn't // we should instead look at the dependency edge name and recursively search our way // up the ancestors module - .krate() + .krate(self.sema.db) .display_name(self.sema.db) .map(|crate_name| crate_name.crate_name().symbol().as_str().into()) } @@ -1009,7 +1009,7 @@ impl<'a> FindUsages<'a> { let scope = search_scope.intersection(&SearchScope::module_and_children(self.sema.db, module)); - let is_crate_root = module.is_crate_root().then(|| Finder::new("crate")); + let is_crate_root = module.is_crate_root(self.sema.db).then(|| Finder::new("crate")); let finder = &Finder::new("super"); for (text, file_id, search_range) in Self::scope_files(sema.db, &scope) { diff --git a/crates/ide-db/src/test_data/test_doc_alias.txt b/crates/ide-db/src/test_data/test_doc_alias.txt index 455a6805907c..4126b9823f39 100644 --- a/crates/ide-db/src/test_data/test_doc_alias.txt +++ b/crates/ide-db/src/test_data/test_doc_alias.txt @@ -1,12 +1,8 @@ [ ( Module { - id: ModuleId { - krate: Crate( - Id(3000), - ), - block: None, - local_id: Idx::(0), + id: ModuleIdLt { + [salsa id]: Id(3400), }, }, [ @@ -16,7 +12,7 @@ Struct( Struct { id: StructId( - 3401, + 3801, ), }, ), @@ -49,7 +45,7 @@ Struct( Struct { id: StructId( - 3400, + 3800, ), }, ), @@ -82,7 +78,7 @@ Struct( Struct { id: StructId( - 3400, + 3800, ), }, ), @@ -115,7 +111,7 @@ Struct( Struct { id: StructId( - 3400, + 3800, ), }, ), @@ -148,7 +144,7 @@ Struct( Struct { id: StructId( - 3400, + 3800, ), }, ), @@ -181,7 +177,7 @@ Struct( Struct { id: StructId( - 3401, + 3801, ), }, ), @@ -214,7 +210,7 @@ Struct( Struct { id: StructId( - 3400, + 3800, ), }, ), diff --git a/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/crates/ide-db/src/test_data/test_symbol_index_collection.txt index 5e5ae1d168e7..3345ab3729ad 100644 --- a/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/crates/ide-db/src/test_data/test_symbol_index_collection.txt @@ -1,12 +1,8 @@ [ ( Module { - id: ModuleId { - krate: Crate( - Id(3000), - ), - block: None, - local_id: Idx::(0), + id: ModuleIdLt { + [salsa id]: Id(3400), }, }, [ @@ -15,7 +11,7 @@ def: TypeAlias( TypeAlias { id: TypeAliasId( - 6800, + 6c00, ), }, ), @@ -46,7 +42,7 @@ def: Const( Const { id: ConstId( - 6000, + 6400, ), }, ), @@ -77,7 +73,7 @@ def: Const( Const { id: ConstId( - 6002, + 6402, ), }, ), @@ -109,7 +105,7 @@ Enum( Enum { id: EnumId( - 4c00, + 5000, ), }, ), @@ -142,7 +138,7 @@ Macro { id: Macro2Id( Macro2Id( - 4800, + 4c00, ), ), }, @@ -175,7 +171,7 @@ Macro { id: Macro2Id( Macro2Id( - 4800, + 4c00, ), ), }, @@ -207,7 +203,7 @@ def: Static( Static { id: StaticId( - 6400, + 6800, ), }, ), @@ -239,7 +235,7 @@ Struct( Struct { id: StructId( - 4401, + 4801, ), }, ), @@ -272,7 +268,7 @@ Struct( Struct { id: StructId( - 4400, + 4800, ), }, ), @@ -280,7 +276,7 @@ loc: DeclarationLocation { hir_file_id: MacroFile( MacroCallId( - Id(3800), + Id(3c00), ), ), ptr: SyntaxNodePtr { @@ -305,7 +301,7 @@ Struct( Struct { id: StructId( - 4405, + 4805, ), }, ), @@ -340,7 +336,7 @@ Struct( Struct { id: StructId( - 4406, + 4806, ), }, ), @@ -375,7 +371,7 @@ Struct( Struct { id: StructId( - 4407, + 4807, ), }, ), @@ -408,7 +404,7 @@ Struct( Struct { id: StructId( - 4402, + 4802, ), }, ), @@ -440,7 +436,7 @@ def: Trait( Trait { id: TraitId( - 5800, + 5c00, ), }, ), @@ -472,7 +468,7 @@ Macro { id: Macro2Id( Macro2Id( - 4800, + 4c00, ), ), }, @@ -505,7 +501,7 @@ Union( Union { id: UnionId( - 5000, + 5400, ), }, ), @@ -536,12 +532,8 @@ name: "a_mod", def: Module( Module { - id: ModuleId { - krate: Crate( - Id(3000), - ), - block: None, - local_id: Idx::(1), + id: ModuleIdLt { + [salsa id]: Id(3401), }, }, ), @@ -571,12 +563,8 @@ name: "b_mod", def: Module( Module { - id: ModuleId { - krate: Crate( - Id(3000), - ), - block: None, - local_id: Idx::(2), + id: ModuleIdLt { + [salsa id]: Id(3402), }, }, ), @@ -608,7 +596,7 @@ Macro { id: MacroRulesId( MacroRulesId( - 3401, + 3801, ), ), }, @@ -640,7 +628,7 @@ def: Function( Function { id: FunctionId( - 5c02, + 6002, ), }, ), @@ -673,7 +661,7 @@ def: Function( Function { id: FunctionId( - 5c01, + 6001, ), }, ), @@ -707,7 +695,7 @@ Macro { id: MacroRulesId( MacroRulesId( - 3400, + 3800, ), ), }, @@ -739,7 +727,7 @@ def: Function( Function { id: FunctionId( - 5c00, + 6000, ), }, ), @@ -771,7 +759,7 @@ Macro { id: MacroRulesId( MacroRulesId( - 3401, + 3801, ), ), }, @@ -803,7 +791,7 @@ def: Function( Function { id: FunctionId( - 5c03, + 6003, ), }, ), @@ -835,12 +823,8 @@ ), ( Module { - id: ModuleId { - krate: Crate( - Id(3000), - ), - block: None, - local_id: Idx::(1), + id: ModuleIdLt { + [salsa id]: Id(3401), }, }, [ @@ -850,7 +834,7 @@ Struct( Struct { id: StructId( - 4403, + 4803, ), }, ), @@ -881,12 +865,8 @@ ), ( Module { - id: ModuleId { - krate: Crate( - Id(3000), - ), - block: None, - local_id: Idx::(2), + id: ModuleIdLt { + [salsa id]: Id(3402), }, }, [ @@ -895,7 +875,7 @@ def: Trait( Trait { id: TraitId( - 5800, + 5c00, ), }, ), @@ -927,7 +907,7 @@ Macro { id: Macro2Id( Macro2Id( - 4800, + 4c00, ), ), }, @@ -960,7 +940,7 @@ Struct( Struct { id: StructId( - 4404, + 4804, ), }, ), @@ -993,7 +973,7 @@ Macro { id: Macro2Id( Macro2Id( - 4800, + 4c00, ), ), }, @@ -1026,7 +1006,7 @@ Struct( Struct { id: StructId( - 4404, + 4804, ), }, ), diff --git a/crates/ide-db/src/traits.rs b/crates/ide-db/src/traits.rs index 61e28386d072..5c06a5dec809 100644 --- a/crates/ide-db/src/traits.rs +++ b/crates/ide-db/src/traits.rs @@ -34,7 +34,7 @@ pub fn get_missing_assoc_items( // may share the same name as a function or constant. let mut impl_fns_consts = FxHashSet::default(); let mut impl_type = FxHashSet::default(); - let edition = imp.module(sema.db).krate().edition(sema.db); + let edition = imp.module(sema.db).krate(sema.db).edition(sema.db); for item in imp.items(sema.db) { match item { diff --git a/crates/ide-diagnostics/src/handlers/missing_fields.rs b/crates/ide-diagnostics/src/handlers/missing_fields.rs index 2b76efb1965b..e300d38ecad2 100644 --- a/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -221,8 +221,8 @@ fn get_default_constructor( let krate = ctx .sema .file_to_module_def(d.file.original_file(ctx.sema.db).file_id(ctx.sema.db))? - .krate(); - let module = krate.root_module(); + .krate(ctx.sema.db); + let module = krate.root_module(ctx.sema.db); // Look for a ::new() associated function let has_new_func = ty diff --git a/crates/ide-diagnostics/src/handlers/no_such_field.rs b/crates/ide-diagnostics/src/handlers/no_such_field.rs index ef42f2dc7448..83c0ef9db43f 100644 --- a/crates/ide-diagnostics/src/handlers/no_such_field.rs +++ b/crates/ide-diagnostics/src/handlers/no_such_field.rs @@ -59,7 +59,7 @@ fn field_is_private_fixes( private_field: Field, ) -> Option> { let def_crate = private_field.krate(sema.db); - let usage_crate = sema.file_to_module_def(usage_file_id.file_id(sema.db))?.krate(); + let usage_crate = sema.file_to_module_def(usage_file_id.file_id(sema.db))?.krate(sema.db); let visibility = if usage_crate == def_crate { "pub(crate) " } else { "pub " }; let source = private_field.source(sema.db)?; diff --git a/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs b/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs index 4327b12dce70..439ca135e5e4 100644 --- a/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs +++ b/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs @@ -82,7 +82,7 @@ fn quickfix_for_redundant_assoc_item( let root = db.parse_or_expand(d.file_id); // don't modify trait def in outer crate let current_crate = ctx.sema.scope(&d.impl_.syntax_node_ptr().to_node(&root))?.krate(); - let trait_def_crate = d.trait_.module(db).krate(); + let trait_def_crate = d.trait_.module(db).krate(db); if trait_def_crate != current_crate { return None; } diff --git a/crates/ide-diagnostics/src/handlers/unlinked_file.rs b/crates/ide-diagnostics/src/handlers/unlinked_file.rs index d96c658d7b04..ade5da09973e 100644 --- a/crates/ide-diagnostics/src/handlers/unlinked_file.rs +++ b/crates/ide-diagnostics/src/handlers/unlinked_file.rs @@ -3,7 +3,7 @@ use std::iter; use hir::crate_def_map; -use hir::{DefMap, InFile, ModuleSource}; +use hir::{InFile, ModuleSource}; use ide_db::base_db::RootQueryDb; use ide_db::text_edit::TextEdit; use ide_db::{ @@ -106,7 +106,7 @@ fn fixes( // FIXME: This shouldnt need to access the crate def map directly let crate_def_map = crate_def_map(ctx.sema.db, krate); - let root_module = &crate_def_map[DefMap::ROOT]; + let root_module = &crate_def_map[crate_def_map.root_module_id()]; let Some(root_file_id) = root_module.origin.file_id() else { continue }; let Some(crate_root_path) = source_root.path_for_file(&root_file_id.file_id(ctx.sema.db)) else { diff --git a/crates/ide-diagnostics/src/handlers/unresolved_field.rs b/crates/ide-diagnostics/src/handlers/unresolved_field.rs index 0649c97f8205..50338b968046 100644 --- a/crates/ide-diagnostics/src/handlers/unresolved_field.rs +++ b/crates/ide-diagnostics/src/handlers/unresolved_field.rs @@ -85,7 +85,7 @@ fn field_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField) -> Option module.krate(), + Some(module) => module.krate(db), None => { match db.all_crates().last() { Some(last) => (*last).into(), diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index f31886b96976..fe890d1b5aa9 100644 --- a/crates/ide/src/expand_macro.rs +++ b/crates/ide/src/expand_macro.rs @@ -28,7 +28,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< let sema = Semantics::new(db); let file_id = sema.attach_first_edition(position.file_id)?; let file = sema.parse(file_id); - let krate = sema.file_to_module_def(file_id.file_id(db))?.krate().into(); + let krate = sema.file_to_module_def(file_id.file_id(db))?.krate(db).into(); let tok = pick_best_token(file.syntax().token_at_offset(position.offset), |kind| match kind { SyntaxKind::IDENT => 1, diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 574803fb9e88..df710d1cfc84 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -116,7 +116,7 @@ pub(crate) fn goto_definition( if let Definition::ExternCrateDecl(crate_def) = def { return crate_def .resolved_crate(db) - .map(|it| it.root_module().to_nav(sema.db)) + .map(|it| it.root_module(sema.db).to_nav(sema.db)) .into_iter() .flatten() .collect(); @@ -244,7 +244,7 @@ fn try_lookup_macro_def_in_macro_use( let extern_crate = sema.to_def(&extern_crate)?; let krate = extern_crate.resolved_crate(sema.db)?; - for mod_def in krate.root_module().declarations(sema.db) { + for mod_def in krate.root_module(sema.db).declarations(sema.db) { if let ModuleDef::Macro(mac) = mod_def { if mac.name(sema.db).as_str() == token.text() { if let Some(nav) = mac.try_to_nav(sema.db) { diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs index 1bc28f28b6f5..db8cabcd7428 100644 --- a/crates/ide/src/goto_implementation.rs +++ b/crates/ide/src/goto_implementation.rs @@ -355,7 +355,7 @@ trait Bar {} fn test() { #[derive(Copy)] - //^^^^^^^^^^^^^^^ + // ^^^^ struct Foo$0; impl Foo {} diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index c24864a18bdf..f6aa7ca9d670 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -463,7 +463,7 @@ pub(super) fn path( item_name: Option, edition: Edition, ) -> String { - let crate_name = module.krate().display_name(db).as_ref().map(|it| it.to_string()); + let crate_name = module.krate(db).display_name(db).as_ref().map(|it| it.to_string()); let module_path = module .path_to_root(db) .into_iter() @@ -1166,7 +1166,7 @@ fn find_std_module( ) -> Option { let db = famous_defs.0.db; let std_crate = famous_defs.std()?; - let std_root_module = std_crate.root_module(); + let std_root_module = std_crate.root_module(db); std_root_module.children(db).find(|module| { module.name(db).is_some_and(|module| module.display(db, edition).to_string() == name) }) diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index b094b098462f..5c67876e9784 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -795,7 +795,7 @@ fn hint_iterator( ) -> Option<(hir::Trait, hir::TypeAlias, hir::Type)> { let db = sema.db; let strukt = ty.strip_references().as_adt()?; - let krate = strukt.module(db).krate(); + let krate = strukt.module(db).krate(db); if krate != famous_defs.core()? { return None; } diff --git a/crates/ide/src/interpret.rs b/crates/ide/src/interpret.rs index 8f9d2d6bf111..3741822547e4 100644 --- a/crates/ide/src/interpret.rs +++ b/crates/ide/src/interpret.rs @@ -45,7 +45,7 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<(Dura None => format!("file://{path} range {text_range:?}"), } }; - let display_target = def.module(db).krate().to_display_target(db); + let display_target = def.module(db).krate(db).to_display_target(db); let start_time = Instant::now(); let res = match def { DefWithBody::Function(it) => it.eval(db, span_formatter), diff --git a/crates/ide/src/moniker.rs b/crates/ide/src/moniker.rs index 795c1f2ca3c0..6acf4f363cb4 100644 --- a/crates/ide/src/moniker.rs +++ b/crates/ide/src/moniker.rs @@ -285,10 +285,10 @@ fn def_to_non_local_moniker( from_crate: Crate, ) -> Option { let module = match definition { - Definition::Module(module) if module.is_crate_root() => module, + Definition::Module(module) if module.is_crate_root(db) => module, _ => definition.module(db)?, }; - let krate = module.krate(); + let krate = module.krate(db); let edition = krate.edition(db); // Add descriptors for this definition and every enclosing definition. @@ -322,7 +322,7 @@ fn def_to_non_local_moniker( }); } else { match def { - Definition::Module(module) if module.is_crate_root() => { + Definition::Module(module) if module.is_crate_root(db) => { // only include `crate` namespace by itself because we prefer // `rust-analyzer cargo foo . bar/` over `rust-analyzer cargo foo . crate/bar/` if reverse_description.is_empty() { @@ -390,7 +390,8 @@ fn display(db: &RootDatabase, module: hir::Module, it: T) -> Stri Ok(result) => result, // Fallback on display variant that always succeeds Err(_) => { - let fallback_result = it.display(db, module.krate().to_display_target(db)).to_string(); + let fallback_result = + it.display(db, module.krate(db).to_display_target(db)).to_string(); tracing::error!( display = %fallback_result, "`display_source_code` failed; falling back to using display" ); diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs index 4c7c597e684e..feb5ea22e3c0 100644 --- a/crates/ide/src/navigation_target.rs +++ b/crates/ide/src/navigation_target.rs @@ -102,7 +102,7 @@ impl NavigationTarget { db: &RootDatabase, module: hir::Module, ) -> UpmappingResult { - let edition = module.krate().edition(db); + let edition = module.krate(db).edition(db); let name = module.name(db).map(|it| it.display_no_db(edition).to_smolstr()).unwrap_or_default(); match module.declaration_source(db) { @@ -118,7 +118,7 @@ impl NavigationTarget { ); res.docs = module.docs(db); res.description = Some( - module.display(db, module.krate().to_display_target(db)).to_string(), + module.display(db, module.krate(db).to_display_target(db)).to_string(), ); res }, @@ -185,7 +185,7 @@ impl NavigationTarget { impl TryToNav for FileSymbol { fn try_to_nav(&self, db: &RootDatabase) -> Option> { let edition = - self.def.module(db).map(|it| it.krate().edition(db)).unwrap_or(Edition::CURRENT); + self.def.module(db).map(|it| it.krate(db).edition(db)).unwrap_or(Edition::CURRENT); let display_target = self.def.krate(db).to_display_target(db); Some( orig_range_with_focus_r( @@ -426,7 +426,7 @@ impl ToNav for hir::Module { impl ToNav for hir::Crate { fn to_nav(&self, db: &RootDatabase) -> UpmappingResult { - self.root_module().to_nav(db) + self.root_module(db).to_nav(db) } } @@ -461,7 +461,7 @@ impl TryToNav for hir::ExternCrateDecl { let focus = value .rename() .map_or_else(|| value.name_ref().map(Either::Left), |it| it.name().map(Either::Right)); - let krate = self.module(db).krate(); + let krate = self.module(db).krate(db); let edition = krate.edition(db); Some(orig_range_with_focus(db, file_id, value.syntax(), focus).map( @@ -489,7 +489,7 @@ impl TryToNav for hir::ExternCrateDecl { impl TryToNav for hir::Field { fn try_to_nav(&self, db: &RootDatabase) -> Option> { let src = self.source(db)?; - let krate = self.parent_def(db).module(db).krate(); + let krate = self.parent_def(db).module(db).krate(db); let field_source = match &src.value { FieldSource::Named(it) => { @@ -578,7 +578,7 @@ impl ToNav for LocalSource { Either::Left(bind_pat) => (bind_pat.syntax(), bind_pat.name()), Either::Right(it) => (it.syntax(), it.name()), }; - let edition = self.local.parent(db).module(db).krate().edition(db); + let edition = self.local.parent(db).module(db).krate(db).edition(db); orig_range_with_focus(db, file_id, node, name).map( |(FileRange { file_id, range: full_range }, focus_range)| { @@ -637,7 +637,7 @@ impl TryToNav for hir::Label { impl TryToNav for hir::TypeParam { fn try_to_nav(&self, db: &RootDatabase) -> Option> { let InFile { file_id, value } = self.merge().source(db)?; - let edition = self.module(db).krate().edition(db); + let edition = self.module(db).krate(db).edition(db); let name = self.name(db).display_no_db(edition).to_smolstr(); let value = match value { @@ -702,7 +702,7 @@ impl TryToNav for hir::LifetimeParam { impl TryToNav for hir::ConstParam { fn try_to_nav(&self, db: &RootDatabase) -> Option> { let InFile { file_id, value } = self.merge().source(db)?; - let edition = self.module(db).krate().edition(db); + let edition = self.module(db).krate(db).edition(db); let name = self.name(db).display_no_db(edition).to_smolstr(); let value = match value { @@ -735,7 +735,7 @@ impl TryToNav for hir::InlineAsmOperand { let file_id = *file_id; Some(orig_range_with_focus(db, file_id, value.syntax(), value.name()).map( |(FileRange { file_id, range: full_range }, focus_range)| { - let edition = self.parent(db).module(db).krate().edition(db); + let edition = self.parent(db).module(db).krate(db).edition(db); NavigationTarget { file_id, name: self diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index f48150b369f2..a64f27b4b83d 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -373,7 +373,7 @@ pub(crate) fn runnable_mod( .rev() .filter_map(|module| { module.name(sema.db).map(|mod_name| { - mod_name.display(sema.db, module.krate().edition(sema.db)).to_string() + mod_name.display(sema.db, module.krate(sema.db).edition(sema.db)).to_string() }) }) .join("::"); @@ -403,7 +403,7 @@ pub(crate) fn runnable_impl( sema: &Semantics<'_, RootDatabase>, def: &hir::Impl, ) -> Option { - let display_target = def.module(sema.db).krate().to_display_target(sema.db); + let display_target = def.module(sema.db).krate(sema.db).to_display_target(sema.db); let edition = display_target.edition; let attrs = def.attrs(sema.db); if !has_runnable_doc_test(&attrs) { @@ -459,7 +459,7 @@ fn runnable_mod_outline_definition( .rev() .filter_map(|module| { module.name(sema.db).map(|mod_name| { - mod_name.display(sema.db, module.krate().edition(sema.db)).to_string() + mod_name.display(sema.db, module.krate(sema.db).edition(sema.db)).to_string() }) }) .join("::"); diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs index efee39c13db9..d5d2801771f3 100644 --- a/crates/ide/src/static_index.rs +++ b/crates/ide/src/static_index.rs @@ -94,7 +94,7 @@ pub struct StaticIndexedFile { fn all_modules(db: &dyn HirDatabase) -> Vec { let mut worklist: Vec<_> = - Crate::all(db).into_iter().map(|krate| krate.root_module()).collect(); + Crate::all(db).into_iter().map(|krate| krate.root_module(db)).collect(); let mut modules = Vec::new(); while let Some(module) = worklist.pop() { diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 87db0cd7dc53..e731bde5ad84 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -493,7 +493,7 @@ pub(super) fn highlight_def( } Definition::Module(module) => { let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module)); - if module.is_crate_root() { + if module.is_crate_root(db) { h |= HlMod::CrateRoot; } h @@ -718,7 +718,7 @@ fn highlight_method_call( h |= HlMod::Trait; } - let def_crate = func.module(sema.db).krate(); + let def_crate = func.module(sema.db).krate(sema.db); let is_from_other_crate = krate.as_ref().map_or(false, |krate| def_crate != *krate); let is_from_builtin_crate = def_crate.is_builtin(sema.db); let is_public = func.visibility(sema.db) == hir::Visibility::Public; diff --git a/crates/ide/src/test_explorer.rs b/crates/ide/src/test_explorer.rs index 06cbd50e946a..8c98f469b524 100644 --- a/crates/ide/src/test_explorer.rs +++ b/crates/ide/src/test_explorer.rs @@ -135,11 +135,11 @@ fn find_module_id_and_test_parents( module: Module, ) -> Option<(Vec, String)> { let Some(parent) = module.parent(sema.db) else { - let name = module.krate().display_name(sema.db)?.to_string(); + let name = module.krate(sema.db).display_name(sema.db)?.to_string(); return Some(( vec![TestItem { id: name.clone(), - kind: TestItemKind::Crate(module.krate().into()), + kind: TestItemKind::Crate(module.krate(sema.db).into()), label: name.clone(), parent: None, file: None, @@ -181,7 +181,7 @@ pub(crate) fn discover_tests_in_crate( let kind = TestItemKind::Crate(crate_id); let crate_test_id = crate_test_id.to_string(); let crate_id: Crate = crate_id.into(); - let module = crate_id.root_module(); + let module = crate_id.root_module(db); let mut r = vec![TestItem { id: crate_test_id.clone(), kind, diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 12b393b80c0d..0a3c4b5a92f8 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -203,7 +203,7 @@ impl flags::AnalysisStats { let mut visited_modules = FxHashSet::default(); let mut visit_queue = Vec::new(); for krate in krates { - let module = krate.root_module(); + let module = krate.root_module(db); let file_id = module.definition_source_file_id(db); let file_id = file_id.original_file(db); @@ -726,10 +726,10 @@ impl flags::AnalysisStats { for &body_id in bodies { let name = body_id.name(db).unwrap_or_else(Name::missing); let module = body_id.module(db); - let display_target = module.krate().to_display_target(db); + let display_target = module.krate(db).to_display_target(db); let full_name = move || { module - .krate() + .krate(db) .display_name(db) .map(|it| it.canonical_name().as_str().to_owned()) .into_iter() @@ -1051,7 +1051,7 @@ impl flags::AnalysisStats { let module = body_id.module(db); let full_name = move || { module - .krate() + .krate(db) .display_name(db) .map(|it| it.canonical_name().as_str().to_owned()) .into_iter() diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs index 7b12cb14009f..82216614f245 100644 --- a/crates/rust-analyzer/src/cli/diagnostics.rs +++ b/crates/rust-analyzer/src/cli/diagnostics.rs @@ -61,8 +61,12 @@ impl flags::Diagnostics { for module in work { let file_id = module.definition_source_file_id(db).original_file(db); if !visited_files.contains(&file_id) { - let crate_name = - module.krate().display_name(db).as_deref().unwrap_or(&sym::unknown).to_owned(); + let crate_name = module + .krate(db) + .display_name(db) + .as_deref() + .unwrap_or(&sym::unknown) + .to_owned(); println!( "processing crate: {crate_name}, module: {}", _vfs.file_path(file_id.file_id(db)) @@ -104,7 +108,7 @@ impl flags::Diagnostics { fn all_modules(db: &dyn HirDatabase) -> Vec { let mut worklist: Vec<_> = - Crate::all(db).into_iter().map(|krate| krate.root_module()).collect(); + Crate::all(db).into_iter().map(|krate| krate.root_module(db)).collect(); let mut modules = Vec::new(); while let Some(module) = worklist.pop() { diff --git a/crates/rust-analyzer/src/cli/run_tests.rs b/crates/rust-analyzer/src/cli/run_tests.rs index 60b33f0a3086..82ace8c8b315 100644 --- a/crates/rust-analyzer/src/cli/run_tests.rs +++ b/crates/rust-analyzer/src/cli/run_tests.rs @@ -78,7 +78,7 @@ fn all_modules(db: &dyn HirDatabase) -> Vec { let mut worklist: Vec<_> = Crate::all(db) .into_iter() .filter(|x| x.origin(db).is_local()) - .map(|krate| krate.root_module()) + .map(|krate| krate.root_module(db)) .collect(); let mut modules = Vec::new(); diff --git a/crates/rust-analyzer/src/cli/unresolved_references.rs b/crates/rust-analyzer/src/cli/unresolved_references.rs index 0362e13b88b7..78de9c51e1ec 100644 --- a/crates/rust-analyzer/src/cli/unresolved_references.rs +++ b/crates/rust-analyzer/src/cli/unresolved_references.rs @@ -66,8 +66,12 @@ impl flags::UnresolvedReferences { let file_id = module.definition_source_file_id(db).original_file(db); let file_id = file_id.file_id(db); if !visited_files.contains(&file_id) { - let crate_name = - module.krate().display_name(db).as_deref().unwrap_or(&sym::unknown).to_owned(); + let crate_name = module + .krate(db) + .display_name(db) + .as_deref() + .unwrap_or(&sym::unknown) + .to_owned(); let file_path = vfs.file_path(file_id); eprintln!("processing crate: {crate_name}, module: {file_path}",); @@ -95,7 +99,7 @@ impl flags::UnresolvedReferences { fn all_modules(db: &dyn HirDatabase) -> Vec { let mut worklist: Vec<_> = - Crate::all(db).into_iter().map(|krate| krate.root_module()).collect(); + Crate::all(db).into_iter().map(|krate| krate.root_module(db)).collect(); let mut modules = Vec::new(); while let Some(module) = worklist.pop() { From 623b67007a257c392433ba9d55f631979a7f9010 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 14 Jun 2025 14:25:13 +0200 Subject: [PATCH 2/4] optimize some stuff --- crates/hir-def/src/attr.rs | 24 ++++++++----------- crates/hir-def/src/expr_store/lower.rs | 5 ++-- crates/hir-def/src/import_map.rs | 4 +--- crates/hir-def/src/item_scope.rs | 15 ++++-------- crates/hir-def/src/item_tree.rs | 4 ++-- crates/hir-def/src/nameres.rs | 5 ++-- crates/hir-def/src/nameres/collector.rs | 3 +-- crates/hir-def/src/resolver.rs | 13 +++++----- crates/hir-expand/src/attrs.rs | 9 ++++--- .../test_data/highlight_block_mod_items.html | 2 +- crates/ide/src/syntax_highlighting/tests.rs | 2 +- 11 files changed, 38 insertions(+), 48 deletions(-) diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs index 086c7aa18937..28235f161743 100644 --- a/crates/hir-def/src/attr.rs +++ b/crates/hir-def/src/attr.rs @@ -2,7 +2,6 @@ use std::{borrow::Cow, convert::identity, hash::Hash, ops}; -use base_db::Crate; use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ @@ -56,12 +55,12 @@ impl Attrs { (**self).iter().find(|attr| attr.id == id) } - pub(crate) fn expand_cfg_attr( - db: &dyn DefDatabase, - krate: Crate, + pub(crate) fn expand_cfg_attr<'db>( + db: &'db dyn DefDatabase, + cfg_options: impl FnOnce() -> &'db CfgOptions, raw_attrs: RawAttrs, ) -> Attrs { - Attrs(raw_attrs.expand_cfg_attr(db, krate)) + Attrs(raw_attrs.expand_cfg_attr(db, cfg_options)) } pub(crate) fn is_cfg_enabled_for( @@ -105,27 +104,24 @@ impl Attrs { ) -> Arc> { let _p = tracing::info_span!("fields_attrs_query").entered(); let mut res = ArenaMap::default(); - let (fields, file_id, krate) = match v { + let (fields, file_id, module) = match v { VariantId::EnumVariantId(it) => { let loc = it.lookup(db); - let krate = loc.parent.lookup(db).container.krate(db); let source = loc.source(db); - (source.value.field_list(), source.file_id, krate) + (source.value.field_list(), source.file_id, loc.parent.lookup(db).container) } VariantId::StructId(it) => { let loc = it.lookup(db); - let krate = loc.container.krate(db); let source = loc.source(db); - (source.value.field_list(), source.file_id, krate) + (source.value.field_list(), source.file_id, loc.container) } VariantId::UnionId(it) => { let loc = it.lookup(db); - let krate = loc.container.krate(db); let source = loc.source(db); ( source.value.record_field_list().map(ast::FieldList::RecordFieldList), source.file_id, - krate, + loc.container, ) } }; @@ -133,7 +129,7 @@ impl Attrs { return Arc::new(res); }; - let cfg_options = krate.cfg_options(db); + let cfg_options = module.krate(db).cfg_options(db); let span_map = db.span_map(file_id); match fields { @@ -544,7 +540,7 @@ impl AttrsWithOwner { tree.top_level_raw_attrs().clone() } }; - Attrs::expand_cfg_attr(db, module.krate(db), raw_attrs) + Attrs::expand_cfg_attr(db, || module.krate(db).cfg_options(db), raw_attrs) } AttrDefId::FieldId(it) => db.fields_attrs(it.parent)[it.local_id].clone(), AttrDefId::EnumVariantId(it) => attrs_from_ast_id_loc(db, it), diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs index 7b88501a7380..f12681acd066 100644 --- a/crates/hir-def/src/expr_store/lower.rs +++ b/crates/hir-def/src/expr_store/lower.rs @@ -546,9 +546,10 @@ impl ExprCollector<'_> { ) -> ExprCollector<'_> { let (def_map, local_def_map) = module.local_def_map(db); let expander = Expander::new(db, current_file_id, def_map); + let krate = module.krate(db); ExprCollector { db, - cfg_options: module.krate(db).cfg_options(db), + cfg_options: krate.cfg_options(db), module, def_map, local_def_map, @@ -562,7 +563,7 @@ impl ExprCollector<'_> { awaitable_context: None, current_block_legacy_macro_defs_count: FxHashMap::default(), outer_impl_trait: false, - krate: module.krate(db), + krate, } } diff --git a/crates/hir-def/src/import_map.rs b/crates/hir-def/src/import_map.rs index a0e9430577c7..7d4eb4de2243 100644 --- a/crates/hir-def/src/import_map.rs +++ b/crates/hir-def/src/import_map.rs @@ -141,13 +141,11 @@ impl ImportMap { if !visited.insert(module) { continue; } - let ext_def_map; let mod_data = if module.krate(db) == krate { &def_map[module] } else { // The crate might reexport a module defined in another crate. - ext_def_map = module.def_map(db); - &ext_def_map[module] + &module.def_map(db)[module] }; let visible_items = mod_data.scope.entries().filter_map(|(name, per_ns)| { diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs index 583781211ec4..2a3d19d5cf58 100644 --- a/crates/hir-def/src/item_scope.rs +++ b/crates/hir-def/src/item_scope.rs @@ -261,14 +261,12 @@ impl ItemScope { pub fn fully_resolve_import(&self, db: &dyn DefDatabase, mut import: ImportId) -> PerNs { let mut res = PerNs::none(); - let mut def_map; let mut scope = self; while let Some(&m) = scope.use_imports_macros.get(&ImportOrExternCrate::Import(import)) { match m { ImportOrDef::Import(i) => { let module_id = i.use_.lookup(db).container; - def_map = module_id.def_map(db); - scope = &def_map[module_id].scope; + scope = &module_id.def_map(db)[module_id].scope; import = i; } ImportOrDef::Def(ModuleDefId::MacroId(def)) => { @@ -283,8 +281,7 @@ impl ItemScope { match m { ImportOrDef::Import(i) => { let module_id = i.use_.lookup(db).container; - def_map = module_id.def_map(db); - scope = &def_map[module_id].scope; + scope = &module_id.def_map(db)[module_id].scope; import = i; } ImportOrDef::Def(def) => { @@ -299,8 +296,7 @@ impl ItemScope { match m { ImportOrDef::Import(i) => { let module_id = i.use_.lookup(db).container; - def_map = module_id.def_map(db); - scope = &def_map[module_id].scope; + scope = &module_id.def_map(db)[module_id].scope; import = i; } ImportOrDef::Def(def) => { @@ -912,10 +908,7 @@ impl ItemInNs { /// Returns the crate defining this item (or `None` if `self` is built-in). pub fn krate(&self, db: &dyn DefDatabase) -> Option { - match self { - ItemInNs::Types(id) | ItemInNs::Values(id) => id.module(db).map(|m| m.krate(db)), - ItemInNs::Macros(id) => Some(id.module(db).krate(db)), - } + self.module(db).map(|module_id| module_id.krate(db)) } pub fn module(&self, db: &dyn DefDatabase) -> Option { diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index f61b403b84ef..4cb72fa00d77 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -203,7 +203,7 @@ impl ItemTree { /// Returns the inner attributes of the source file. pub(crate) fn top_level_attrs(&self, db: &dyn DefDatabase, krate: Crate) -> Attrs { - Attrs::expand_cfg_attr(db, krate, self.top_attrs.clone()) + Attrs::expand_cfg_attr(db, || krate.cfg_options(db), self.top_attrs.clone()) } pub(crate) fn raw_attrs(&self, of: FileAstId) -> &RawAttrs { @@ -216,7 +216,7 @@ impl ItemTree { krate: Crate, of: FileAstId, ) -> Attrs { - Attrs::expand_cfg_attr(db, krate, self.raw_attrs(of).clone()) + Attrs::expand_cfg_attr(db, || krate.cfg_options(db), self.raw_attrs(of).clone()) } /// Returns a count of a few, expensive items. diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 0419d1c8769d..dd43736ddecc 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -420,10 +420,11 @@ pub fn block_def_map(db: &dyn DefDatabase, block_id: BlockId) -> DefMap { let module_data = ModuleData::new(ModuleOrigin::BlockExpr { block: ast_id, id: block_id }, visibility, None); - let local_def_map = crate_local_def_map(db, module.krate(db)); + let krate = module.krate(db); + let local_def_map = crate_local_def_map(db, krate); let def_map = DefMap::empty( db, - module.krate(db), + krate, local_def_map.def_map(db).data.clone(), module_data, Some(BlockInfo { block: block_id, parent: module }), diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 3d2a246bc66c..eaf2eccee899 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -1074,7 +1074,6 @@ impl<'db> DefCollector<'db> { vis: Visibility, import: Option, ) { - self.db.unwind_if_revision_cancelled(); self.update_recursive(module_id, resolutions, vis, import, 0) } @@ -1706,7 +1705,7 @@ impl ModCollector<'_, '_> { // Prelude module is always considered to be `#[macro_use]`. if let Some((prelude_module, _use)) = self.def_collector.def_map.prelude { // Don't insert macros from the prelude into blocks, as they can be shadowed by other macros. - if prelude_module.krate(self.def_collector.db) != krate && is_crate_root { + if is_crate_root && prelude_module.krate(self.def_collector.db) != krate { cov_mark::hit!(prelude_is_macro_use); self.def_collector.import_macros_from_extern_crate( prelude_module.krate(self.def_collector.db), diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index e6cfb8054f47..9d9367956e23 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -1,5 +1,5 @@ //! Name resolution façade. -use std::{fmt, mem}; +use std::fmt; use base_db::Crate; use hir_expand::{ @@ -1282,8 +1282,7 @@ impl HasResolver for ModuleId { fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { let (mut def_map, local_def_map) = self.local_def_map(db); let mut module_id = self; - - if !self.is_block_module(db) { + if def_map.parent().is_none() || module_id != def_map.root_module_id() { return Resolver { scopes: vec![], module_scope: ModuleItemMap { def_map, local_def_map, module_id }, @@ -1292,10 +1291,10 @@ impl HasResolver for ModuleId { let mut modules: SmallVec<[_; 1]> = smallvec![]; while let Some(parent) = def_map.parent() { - let block_def_map = mem::replace(&mut def_map, parent.def_map(db)); - modules.push(block_def_map); - if !parent.is_block_module(db) { - module_id = parent; + modules.push(def_map); + def_map = parent.def_map(db); + module_id = parent; + if module_id != def_map.root_module_id() { break; } } diff --git a/crates/hir-expand/src/attrs.rs b/crates/hir-expand/src/attrs.rs index 94c97713f065..90e533f0e1e5 100644 --- a/crates/hir-expand/src/attrs.rs +++ b/crates/hir-expand/src/attrs.rs @@ -2,7 +2,6 @@ use std::iter; use std::{borrow::Cow, fmt, ops}; -use base_db::Crate; use cfg::{CfgExpr, CfgOptions}; use either::Either; use intern::{Interned, Symbol, sym}; @@ -141,14 +140,18 @@ impl RawAttrs { } /// Processes `cfg_attr`s - pub fn expand_cfg_attr(self, db: &dyn ExpandDatabase, krate: Crate) -> RawAttrs { + pub fn expand_cfg_attr<'db>( + self, + db: &'db dyn ExpandDatabase, + cfg_options: impl FnOnce() -> &'db CfgOptions, + ) -> RawAttrs { let has_cfg_attrs = self.iter().any(|attr| attr.path.as_ident().is_some_and(|name| *name == sym::cfg_attr)); if !has_cfg_attrs { return self; } - let cfg_options = krate.cfg_options(db); + let cfg_options = cfg_options(); let new_attrs = self .iter() .cloned() diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html b/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html index 3beda396da80..06b78e4f29d8 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html @@ -53,7 +53,7 @@ foo!(Bar); fn func(_: y::Bar) { mod inner { - struct Innerest<const C: usize> { field: [(); {C}] } + struct Innerest<const C: usize> { field: [u32; {C}], field2: &Innerest } } } } diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index dd359326c61d..50cbaa589149 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -1151,7 +1151,7 @@ fn main() { foo!(Bar); fn func(_: y::Bar) { mod inner { - struct Innerest { field: [(); {C}] } + struct Innerest { field: [u32; {C}], field2: &Innerest } } } } From 5bbf8aa2a68cd5bfad49fdcafdea45dfdf1113b1 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 14 Jun 2025 14:33:52 +0200 Subject: [PATCH 3/4] Optimize `pub(crate)` visibility resolution --- crates/hir-def/src/expr_store/pretty.rs | 1 + crates/hir-def/src/find_path.rs | 1 + crates/hir-def/src/item_scope.rs | 22 ++--------- crates/hir-def/src/item_tree.rs | 11 ++---- crates/hir-def/src/item_tree/pretty.rs | 1 + crates/hir-def/src/nameres/collector.rs | 2 +- crates/hir-def/src/nameres/path_resolution.rs | 1 + crates/hir-def/src/resolver.rs | 1 + crates/hir-def/src/visibility.rs | 39 ++++++++++++++++--- crates/hir-ty/src/display.rs | 1 + crates/hir/src/symbols.rs | 1 + 11 files changed, 49 insertions(+), 32 deletions(-) diff --git a/crates/hir-def/src/expr_store/pretty.rs b/crates/hir-def/src/expr_store/pretty.rs index 7b452721dfe2..ae8a959164ca 100644 --- a/crates/hir-def/src/expr_store/pretty.rs +++ b/crates/hir-def/src/expr_store/pretty.rs @@ -144,6 +144,7 @@ pub fn print_variant_body_hir(db: &dyn DefDatabase, owner: VariantId, edition: E w!(p, "{}", interned.display(db, p.edition)) } crate::item_tree::RawVisibility::Public => w!(p, "pub "), + crate::item_tree::RawVisibility::PubCrate => w!(p, "pub(crate) "), } if *is_unsafe { w!(p, "unsafe "); diff --git a/crates/hir-def/src/find_path.rs b/crates/hir-def/src/find_path.rs index 64d4ecc88d49..fc7df663aacf 100644 --- a/crates/hir-def/src/find_path.rs +++ b/crates/hir-def/src/find_path.rs @@ -613,6 +613,7 @@ fn find_local_import_locations( cov_mark::hit!(discount_private_imports); false } + Visibility::PubCrate(_) => true, Visibility::Public => true, }; diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs index 2a3d19d5cf58..2a2135cc87b6 100644 --- a/crates/hir-def/src/item_scope.rs +++ b/crates/hir-def/src/item_scope.rs @@ -20,7 +20,7 @@ use crate::{ Lookup, MacroId, ModuleDefId, ModuleId, TraitId, UseId, db::DefDatabase, per_ns::{Item, MacrosItem, PerNs, TypesItem, ValuesItem}, - visibility::{Visibility, VisibilityExplicitness}, + visibility::Visibility, }; #[derive(Debug, Default)] @@ -716,33 +716,19 @@ impl ItemScope { } /// Marks everything that is not a procedural macro as private to `this_module`. - pub(crate) fn censor_non_proc_macros(&mut self, this_module: ModuleId) { + pub(crate) fn censor_non_proc_macros(&mut self, krate: Crate) { self.types .values_mut() .map(|def| &mut def.vis) .chain(self.values.values_mut().map(|def| &mut def.vis)) .chain(self.unnamed_trait_imports.iter_mut().map(|(_, def)| &mut def.vis)) - .for_each(|vis| match vis { - &mut Visibility::Module(_, visibility_explicitness) => { - *vis = Visibility::Module(this_module, visibility_explicitness) - } - Visibility::Public => { - *vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit) - } - }); + .for_each(|vis| *vis = Visibility::PubCrate(krate)); for mac in self.macros.values_mut() { if matches!(mac.def, MacroId::ProcMacroId(_) if mac.import.is_none()) { continue; } - match mac.vis { - Visibility::Module(_, visibility_explicitness) => { - mac.vis = Visibility::Module(this_module, visibility_explicitness) - } - Visibility::Public => { - mac.vis = Visibility::Module(this_module, VisibilityExplicitness::Implicit) - } - } + mac.vis = Visibility::PubCrate(krate) } } diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 4cb72fa00d77..0ccc857106de 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -416,7 +416,7 @@ impl Index for ItemTree { static VIS_PUB: RawVisibility = RawVisibility::Public; static VIS_PRIV_IMPLICIT: OnceLock = OnceLock::new(); static VIS_PRIV_EXPLICIT: OnceLock = OnceLock::new(); - static VIS_PUB_CRATE: OnceLock = OnceLock::new(); + static VIS_PUB_CRATE: RawVisibility = RawVisibility::PubCrate; match index { RawVisibilityId::PRIV_IMPLICIT => VIS_PRIV_IMPLICIT.get_or_init(|| { @@ -432,12 +432,7 @@ impl Index for ItemTree { ) }), RawVisibilityId::PUB => &VIS_PUB, - RawVisibilityId::PUB_CRATE => VIS_PUB_CRATE.get_or_init(|| { - RawVisibility::Module( - Interned::new(ModPath::from_kind(PathKind::Crate)), - VisibilityExplicitness::Explicit, - ) - }), + RawVisibilityId::PUB_CRATE => &VIS_PUB_CRATE, _ => &self.vis.arena[index.0 as usize], } } @@ -555,6 +550,8 @@ pub enum RawVisibility { /// `pub(in module)`, `pub(crate)` or `pub(super)`. Also private, which is /// equivalent to `pub(self)`. Module(Interned, VisibilityExplicitness), + /// `pub(crate)`. + PubCrate, /// `pub`. Public, } diff --git a/crates/hir-def/src/item_tree/pretty.rs b/crates/hir-def/src/item_tree/pretty.rs index eb97081128ed..a8e816bd3ae9 100644 --- a/crates/hir-def/src/item_tree/pretty.rs +++ b/crates/hir-def/src/item_tree/pretty.rs @@ -111,6 +111,7 @@ impl Printer<'_> { w!(self, "pub({}) ", path.display(self.db, self.edition)) } RawVisibility::Public => w!(self, "pub "), + RawVisibility::PubCrate => w!(self, "pub(crate) "), }; } diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index eaf2eccee899..165f3f6bfdbc 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -446,7 +446,7 @@ impl<'db> DefCollector<'db> { // in the crate root that aren't proc macros. let module_id = self.def_map.root_module_id(); let root = &mut self.def_map.modules[module_id]; - root.scope.censor_non_proc_macros(module_id); + root.scope.censor_non_proc_macros(self.def_map.krate); } } diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs index 74ac47981f24..1ea4b7de6783 100644 --- a/crates/hir-def/src/nameres/path_resolution.rs +++ b/crates/hir-def/src/nameres/path_resolution.rs @@ -129,6 +129,7 @@ impl DefMap { } } RawVisibility::Public => Visibility::Public, + RawVisibility::PubCrate => Visibility::PubCrate(self.krate), }; // In block expressions, `self` normally refers to the containing non-block module, and diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index 9d9367956e23..06454f6bb73a 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -305,6 +305,7 @@ impl<'db> Resolver<'db> { }), ) } + RawVisibility::PubCrate => Some(Visibility::PubCrate(self.krate())), RawVisibility::Public => Some(Visibility::Public), } } diff --git a/crates/hir-def/src/visibility.rs b/crates/hir-def/src/visibility.rs index fb387aaa5dd2..4e7458f7a1c7 100644 --- a/crates/hir-def/src/visibility.rs +++ b/crates/hir-def/src/visibility.rs @@ -2,6 +2,7 @@ use std::iter; +use base_db::Crate; use hir_expand::{InFile, Lookup}; use la_arena::ArenaMap; use syntax::ast::{self, HasVisibility}; @@ -23,6 +24,8 @@ pub use crate::item_tree::{RawVisibility, VisibilityExplicitness}; pub enum Visibility { /// Visibility is restricted to a certain module. Module(ModuleId, VisibilityExplicitness), + /// Visibility is restricted to the crate. + PubCrate(Crate), /// Visibility is unrestricted. Public, } @@ -45,6 +48,7 @@ impl Visibility { pub fn is_visible_from(self, db: &dyn DefDatabase, from_module: ModuleId) -> bool { let to_module = match self { Visibility::Module(m, _) => m, + Visibility::PubCrate(krate) => return from_module.krate(db) == krate, Visibility::Public => return true, }; // if they're not in the same crate, it can't be visible @@ -66,6 +70,7 @@ impl Visibility { } let to_module = match self { Visibility::Module(m, _) => m, + Visibility::PubCrate(krate) => return from_module.krate(db) == krate, Visibility::Public => return true, }; // if they're not in the same crate, it can't be visible @@ -144,24 +149,35 @@ impl Visibility { ) -> Option { match (self, other) { (_, Visibility::Public) | (Visibility::Public, _) => Some(Visibility::Public), + (Visibility::PubCrate(krate), Visibility::PubCrate(krateb)) => { + if krate == krateb { + Some(Visibility::PubCrate(krate)) + } else { + None + } + } + (Visibility::Module(mod_, _), Visibility::PubCrate(krate)) + | (Visibility::PubCrate(krate), Visibility::Module(mod_, _)) => { + if mod_.krate(db) == krate { Some(Visibility::PubCrate(krate)) } else { None } + } (Visibility::Module(mod_a, expl_a), Visibility::Module(mod_b, expl_b)) => { - if mod_a.krate(db) != mod_b.krate(db) { + if mod_a.krate(db) != def_map.krate() || mod_b.krate(db) != def_map.krate() { return None; } let def_block = def_map.block_id(); - if (mod_a.block(db), mod_b.block(db)) != (def_block, def_block) { + if mod_a.block(db) != def_block || mod_b.block(db) != def_block { return None; } let mut a_ancestors = iter::successors(Some(mod_a), |&m| def_map[m].parent); - let mut b_ancestors = iter::successors(Some(mod_b), |&m| def_map[m].parent); if a_ancestors.any(|m| m == mod_b) { // B is above A return Some(Visibility::Module(mod_b, expl_b)); } + let mut b_ancestors = iter::successors(Some(mod_b), |&m| def_map[m].parent); if b_ancestors.any(|m| m == mod_a) { // A is above B return Some(Visibility::Module(mod_a, expl_a)); @@ -184,24 +200,35 @@ impl Visibility { ) -> Option { match (self, other) { (vis, Visibility::Public) | (Visibility::Public, vis) => Some(vis), + (Visibility::PubCrate(krate), Visibility::PubCrate(krateb)) => { + if krate == krateb { + Some(Visibility::PubCrate(krate)) + } else { + None + } + } + (Visibility::Module(mod_, exp), Visibility::PubCrate(krate)) + | (Visibility::PubCrate(krate), Visibility::Module(mod_, exp)) => { + if mod_.krate(db) == krate { Some(Visibility::Module(mod_, exp)) } else { None } + } (Visibility::Module(mod_a, expl_a), Visibility::Module(mod_b, expl_b)) => { - if mod_a.krate(db) != mod_b.krate(db) { + if mod_a.krate(db) != def_map.krate() || mod_b.krate(db) != def_map.krate() { return None; } let def_block = def_map.block_id(); - if (mod_a.block(db), mod_b.block(db)) != (def_block, def_block) { + if mod_a.block(db) != def_block || mod_b.block(db) != def_block { return None; } let mut a_ancestors = iter::successors(Some(mod_a), |&m| def_map[m].parent); - let mut b_ancestors = iter::successors(Some(mod_b), |&m| def_map[m].parent); if a_ancestors.any(|m| m == mod_b) { // B is above A return Some(Visibility::Module(mod_a, expl_a)); } + let mut b_ancestors = iter::successors(Some(mod_b), |&m| def_map[m].parent); if b_ancestors.any(|m| m == mod_a) { // A is above B return Some(Visibility::Module(mod_b, expl_b)); diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index 405732489398..bf5081a6a696 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -2081,6 +2081,7 @@ pub fn write_visibility( ) -> Result<(), HirDisplayError> { match vis { Visibility::Public => write!(f, "pub "), + Visibility::PubCrate(_) => write!(f, "pub(crate) "), Visibility::Module(vis_id, _) => { let def_map = module_id.def_map(f.db); let root_module_id = def_map.root_module_id(); diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs index 92c2a112541a..8a8dd9406886 100644 --- a/crates/hir/src/symbols.rs +++ b/crates/hir/src/symbols.rs @@ -164,6 +164,7 @@ impl<'a> SymbolCollector<'a> { let is_explicit_import = |vis| match vis { Visibility::Public => true, + Visibility::PubCrate(_) => true, Visibility::Module(_, VisibilityExplicitness::Explicit) => true, Visibility::Module(_, VisibilityExplicitness::Implicit) => false, }; From 362ef27f33ecfd1a0827055f98a5b6d9367582b5 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 14 Jun 2025 15:33:48 +0200 Subject: [PATCH 4/4] Optimize private visibility resolution --- crates/hir-def/src/expr_store/pretty.rs | 3 +- .../src/expr_store/tests/body/block.rs | 2 - crates/hir-def/src/find_path.rs | 1 - crates/hir-def/src/item_tree.rs | 22 ++++------ crates/hir-def/src/item_tree/pretty.rs | 3 +- crates/hir-def/src/item_tree/tests.rs | 2 +- crates/hir-def/src/lib.rs | 6 ++- crates/hir-def/src/nameres/path_resolution.rs | 35 +++++++++------- crates/hir-def/src/resolver.rs | 3 ++ crates/hir-def/src/visibility.rs | 42 +++++++++++++++++-- 10 files changed, 81 insertions(+), 38 deletions(-) diff --git a/crates/hir-def/src/expr_store/pretty.rs b/crates/hir-def/src/expr_store/pretty.rs index ae8a959164ca..56c7655f9ea6 100644 --- a/crates/hir-def/src/expr_store/pretty.rs +++ b/crates/hir-def/src/expr_store/pretty.rs @@ -141,10 +141,11 @@ pub fn print_variant_body_hir(db: &dyn DefDatabase, owner: VariantId, edition: E let FieldData { name, type_ref, visibility, is_unsafe } = data; match visibility { crate::item_tree::RawVisibility::Module(interned, _visibility_explicitness) => { - w!(p, "{}", interned.display(db, p.edition)) + w!(p, "pub(in {})", interned.display(db, p.edition)) } crate::item_tree::RawVisibility::Public => w!(p, "pub "), crate::item_tree::RawVisibility::PubCrate => w!(p, "pub(crate) "), + crate::item_tree::RawVisibility::PubSelf(_) => w!(p, "pub(self) "), } if *is_unsafe { w!(p, "unsafe "); diff --git a/crates/hir-def/src/expr_store/tests/body/block.rs b/crates/hir-def/src/expr_store/tests/body/block.rs index 21a618344810..8cda4a8a31b7 100644 --- a/crates/hir-def/src/expr_store/tests/body/block.rs +++ b/crates/hir-def/src/expr_store/tests/body/block.rs @@ -176,7 +176,6 @@ fn outer() { #[test] fn nested_module_scoping() { - cov_mark::check!(nested_module_scoping); check_block_scopes_at( r#" fn f() { @@ -445,7 +444,6 @@ fn main() { fn underscore_import() { // This used to panic, because the default (private) visibility inside block expressions would // point into the containing `DefMap`, which visibilities should never be able to do. - cov_mark::check!(adjust_vis_in_block_def_map); check_at( r#" mod m { diff --git a/crates/hir-def/src/find_path.rs b/crates/hir-def/src/find_path.rs index fc7df663aacf..24548e9c4209 100644 --- a/crates/hir-def/src/find_path.rs +++ b/crates/hir-def/src/find_path.rs @@ -1285,7 +1285,6 @@ $0 #[test] fn explicit_private_imports_crate() { - cov_mark::check!(explicit_private_imports); check_found_path( r#" //- /main.rs diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 0ccc857106de..15f6ce17f81f 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -414,23 +414,15 @@ impl Index for ItemTree { type Output = RawVisibility; fn index(&self, index: RawVisibilityId) -> &Self::Output { static VIS_PUB: RawVisibility = RawVisibility::Public; - static VIS_PRIV_IMPLICIT: OnceLock = OnceLock::new(); - static VIS_PRIV_EXPLICIT: OnceLock = OnceLock::new(); + static VIS_PRIV_IMPLICIT: RawVisibility = + RawVisibility::PubSelf(VisibilityExplicitness::Implicit); + static VIS_PRIV_EXPLICIT: RawVisibility = + RawVisibility::PubSelf(VisibilityExplicitness::Explicit); static VIS_PUB_CRATE: RawVisibility = RawVisibility::PubCrate; match index { - RawVisibilityId::PRIV_IMPLICIT => VIS_PRIV_IMPLICIT.get_or_init(|| { - RawVisibility::Module( - Interned::new(ModPath::from_kind(PathKind::SELF)), - VisibilityExplicitness::Implicit, - ) - }), - RawVisibilityId::PRIV_EXPLICIT => VIS_PRIV_EXPLICIT.get_or_init(|| { - RawVisibility::Module( - Interned::new(ModPath::from_kind(PathKind::SELF)), - VisibilityExplicitness::Explicit, - ) - }), + RawVisibilityId::PRIV_IMPLICIT => &VIS_PRIV_IMPLICIT, + RawVisibilityId::PRIV_EXPLICIT => &VIS_PRIV_EXPLICIT, RawVisibilityId::PUB => &VIS_PUB, RawVisibilityId::PUB_CRATE => &VIS_PUB_CRATE, _ => &self.vis.arena[index.0 as usize], @@ -550,6 +542,8 @@ pub enum RawVisibility { /// `pub(in module)`, `pub(crate)` or `pub(super)`. Also private, which is /// equivalent to `pub(self)`. Module(Interned, VisibilityExplicitness), + /// `pub(self)`. + PubSelf(VisibilityExplicitness), /// `pub(crate)`. PubCrate, /// `pub`. diff --git a/crates/hir-def/src/item_tree/pretty.rs b/crates/hir-def/src/item_tree/pretty.rs index a8e816bd3ae9..696174cb072b 100644 --- a/crates/hir-def/src/item_tree/pretty.rs +++ b/crates/hir-def/src/item_tree/pretty.rs @@ -108,10 +108,11 @@ impl Printer<'_> { fn print_visibility(&mut self, vis: RawVisibilityId) { match &self.tree[vis] { RawVisibility::Module(path, _expl) => { - w!(self, "pub({}) ", path.display(self.db, self.edition)) + w!(self, "pub(in {}) ", path.display(self.db, self.edition)) } RawVisibility::Public => w!(self, "pub "), RawVisibility::PubCrate => w!(self, "pub(crate) "), + RawVisibility::PubSelf(_) => w!(self, "pub(self) "), }; } diff --git a/crates/hir-def/src/item_tree/tests.rs b/crates/hir-def/src/item_tree/tests.rs index e39efd31c6c1..5923b3ea4913 100644 --- a/crates/hir-def/src/item_tree/tests.rs +++ b/crates/hir-def/src/item_tree/tests.rs @@ -39,7 +39,7 @@ use a::{c, d::{e}}; pub(self) extern crate self as renamed; // AstId: ExternCrate[7E1C, 0] - pub(super) extern crate bli; + pub(in super) extern crate bli; // AstId: Use[0000, 0] pub use crate::path::{nested, items as renamed, Trait as _}; diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index ae1ccd948374..bef9b1c98a61 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -144,6 +144,7 @@ impl HasModule for ItemLoc { #[derive(Debug)] pub struct AssocItemLoc { + // FIXME: Store this as an erased `salsa::Id` to save space pub container: ItemContainerId, pub id: AstId, } @@ -445,6 +446,7 @@ impl HasModule for ModuleId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct FieldId { + // FIXME: Store this as an erased `salsa::Id` to save space pub parent: VariantId, pub local_id: LocalFieldId, } @@ -460,6 +462,7 @@ pub struct TupleFieldId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct TypeOrConstParamId { + // FIXME: Store this as an erased `salsa::Id` to save space pub parent: GenericDefId, pub local_id: LocalTypeOrConstParamId, } @@ -518,6 +521,7 @@ impl From for TypeOrConstParamId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct LifetimeParamId { + // FIXME: Store this as an erased `salsa::Id` to save space pub parent: GenericDefId, pub local_id: LocalLifetimeParamId, } @@ -661,7 +665,7 @@ impl DefWithBodyId { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, salsa_macros::Supertype)] pub enum AssocItemId { FunctionId(FunctionId), ConstId(ConstId), diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs index 1ea4b7de6783..a87da5b95ebe 100644 --- a/crates/hir-def/src/nameres/path_resolution.rs +++ b/crates/hir-def/src/nameres/path_resolution.rs @@ -106,7 +106,7 @@ impl DefMap { visibility: &RawVisibility, within_impl: bool, ) -> Option { - let mut vis = match visibility { + let vis = match visibility { RawVisibility::Module(path, explicitness) => { let (result, remaining) = self.resolve_path( local_def_map, @@ -120,30 +120,37 @@ impl DefMap { return None; } let types = result.take_types()?; - match types { + let mut vis = match types { ModuleDefId::ModuleId(m) => Visibility::Module(m, *explicitness), // error: visibility needs to refer to module _ => { return None; } + }; + + // In block expressions, `self` normally refers to the containing non-block module, and + // `super` to its parent (etc.). However, visibilities must only refer to a module in the + // DefMap they're written in, so we restrict them when that happens. + if let Visibility::Module(m, mv) = vis { + // ...unless we're resolving visibility for an associated item in an impl. + if self.block_id() != m.block(db) && !within_impl { + vis = Visibility::Module(self.root, mv); + tracing::debug!( + "visibility {:?} points outside DefMap, adjusting to {:?}", + m, + vis + ); + } } + vis + } + RawVisibility::PubSelf(explicitness) => { + Visibility::Module(original_module, *explicitness) } RawVisibility::Public => Visibility::Public, RawVisibility::PubCrate => Visibility::PubCrate(self.krate), }; - // In block expressions, `self` normally refers to the containing non-block module, and - // `super` to its parent (etc.). However, visibilities must only refer to a module in the - // DefMap they're written in, so we restrict them when that happens. - if let Visibility::Module(m, mv) = vis { - // ...unless we're resolving visibility for an associated item in an impl. - if self.block_id() != m.block(db) && !within_impl { - cov_mark::hit!(adjust_vis_in_block_def_map); - vis = Visibility::Module(self.root, mv); - tracing::debug!("visibility {:?} points outside DefMap, adjusting to {:?}", m, vis); - } - } - Some(vis) } diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index 06454f6bb73a..ee2b60427c2e 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -305,6 +305,9 @@ impl<'db> Resolver<'db> { }), ) } + RawVisibility::PubSelf(explicitness) => { + Some(Visibility::Module(self.module(), *explicitness)) + } RawVisibility::PubCrate => Some(Visibility::PubCrate(self.krate())), RawVisibility::Public => Some(Visibility::Public), } diff --git a/crates/hir-def/src/visibility.rs b/crates/hir-def/src/visibility.rs index 4e7458f7a1c7..9133e47c4575 100644 --- a/crates/hir-def/src/visibility.rs +++ b/crates/hir-def/src/visibility.rs @@ -51,6 +51,10 @@ impl Visibility { Visibility::PubCrate(krate) => return from_module.krate(db) == krate, Visibility::Public => return true, }; + if from_module == to_module { + // if the modules are the same, visibility is trivially satisfied + return true; + } // if they're not in the same crate, it can't be visible if from_module.krate(db) != to_module.krate(db) { return false; @@ -73,6 +77,10 @@ impl Visibility { Visibility::PubCrate(krate) => return from_module.krate(db) == krate, Visibility::Public => return true, }; + if from_module == to_module { + // if the modules are the same, visibility is trivially satisfied + return true; + } // if they're not in the same crate, it can't be visible if def_map.krate() != to_module.krate(db) { return false; @@ -100,9 +108,7 @@ impl Visibility { // `to_module` is not a block, so there is no parent def map to use. (None, _) => (), // `to_module` is at `def_map`'s block, no need to move further. - (Some(a), Some(b)) if a == b => { - cov_mark::hit!(nested_module_scoping); - } + (Some(a), Some(b)) if a == b => {} _ => { if let Some(parent) = to_module.def_map(db).parent() { to_module = parent; @@ -161,6 +167,21 @@ impl Visibility { if mod_.krate(db) == krate { Some(Visibility::PubCrate(krate)) } else { None } } (Visibility::Module(mod_a, expl_a), Visibility::Module(mod_b, expl_b)) => { + if mod_a == mod_b { + // Most module visibilities are `pub(self)`, and assuming no errors + // this will be the common and thus fast path. + return Some(Visibility::Module( + mod_a, + match (expl_a, expl_b) { + (VisibilityExplicitness::Explicit, _) + | (_, VisibilityExplicitness::Explicit) => { + VisibilityExplicitness::Explicit + } + _ => VisibilityExplicitness::Implicit, + }, + )); + } + if mod_a.krate(db) != def_map.krate() || mod_b.krate(db) != def_map.krate() { return None; } @@ -212,6 +233,21 @@ impl Visibility { if mod_.krate(db) == krate { Some(Visibility::Module(mod_, exp)) } else { None } } (Visibility::Module(mod_a, expl_a), Visibility::Module(mod_b, expl_b)) => { + if mod_a == mod_b { + // Most module visibilities are `pub(self)`, and assuming no errors + // this will be the common and thus fast path. + return Some(Visibility::Module( + mod_a, + match (expl_a, expl_b) { + (VisibilityExplicitness::Explicit, _) + | (_, VisibilityExplicitness::Explicit) => { + VisibilityExplicitness::Explicit + } + _ => VisibilityExplicitness::Implicit, + }, + )); + } + if mod_a.krate(db) != def_map.krate() || mod_b.krate(db) != def_map.krate() { return None; }