From 8da50c907754d9af1dc4532938d7d72f34ec96bf Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 5 Mar 2021 14:06:09 +0100 Subject: [PATCH 1/8] Change `ChildBySource` to allow reusing `DynMap` --- crates/hir_def/src/child_by_source.rs | 46 ++++++++++----------------- crates/hir_def/src/generics.rs | 4 +-- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/crates/hir_def/src/child_by_source.rs b/crates/hir_def/src/child_by_source.rs index 75c2d756bf..6dde741382 100644 --- a/crates/hir_def/src/child_by_source.rs +++ b/crates/hir_def/src/child_by_source.rs @@ -17,13 +17,16 @@ use crate::{ }; pub trait ChildBySource { - fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap; + fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { + let mut res = DynMap::default(); + self.child_by_source_to(db, &mut res); + res + } + fn child_by_source_to(&self, db: &dyn DefDatabase, map: &mut DynMap); } impl ChildBySource for TraitId { - fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { - let mut res = DynMap::default(); - + fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) { let data = db.trait_data(*self); for (_name, item) in data.items.iter() { match *item { @@ -41,15 +44,11 @@ impl ChildBySource for TraitId { } } } - - res } } impl ChildBySource for ImplId { - fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { - let mut res = DynMap::default(); - + fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) { let data = db.impl_data(*self); for &item in data.items.iter() { match item { @@ -67,25 +66,21 @@ impl ChildBySource for ImplId { } } } - - res } } impl ChildBySource for ModuleId { - fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { + fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) { let def_map = self.def_map(db); let module_data = &def_map[self.local_id]; - module_data.scope.child_by_source(db) + module_data.scope.child_by_source_to(db, res); } } impl ChildBySource for ItemScope { - fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { - let mut res = DynMap::default(); - self.declarations().for_each(|item| add_module_def(db, &mut res, item)); - self.impls().for_each(|imp| add_impl(db, &mut res, imp)); - return res; + fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) { + self.declarations().for_each(|item| add_module_def(db, res, item)); + self.impls().for_each(|imp| add_impl(db, res, imp)); fn add_module_def(db: &dyn DefDatabase, map: &mut DynMap, item: ModuleDefId) { match item { @@ -134,9 +129,7 @@ impl ChildBySource for ItemScope { } impl ChildBySource for VariantId { - fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { - let mut res = DynMap::default(); - + fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) { let arena_map = self.child_source(db); let arena_map = arena_map.as_ref(); for (local_id, source) in arena_map.value.iter() { @@ -150,28 +143,23 @@ impl ChildBySource for VariantId { } } } - res } } impl ChildBySource for EnumId { - fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { - let mut res = DynMap::default(); - + fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) { let arena_map = self.child_source(db); let arena_map = arena_map.as_ref(); for (local_id, source) in arena_map.value.iter() { let id = EnumVariantId { parent: *self, local_id }; res[keys::VARIANT].insert(arena_map.with_value(source.clone()), id) } - - res } } impl ChildBySource for DefWithBodyId { - fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { + fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) { let body = db.body(*self); - body.item_scope.child_by_source(db) + body.item_scope.child_by_source_to(db, res); } } diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index 3ace3be1fa..a056ab797e 100644 --- a/crates/hir_def/src/generics.rs +++ b/crates/hir_def/src/generics.rs @@ -421,8 +421,7 @@ impl HasChildSource for GenericDefId { } impl ChildBySource for GenericDefId { - fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { - let mut res = DynMap::default(); + fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) { let (_, sm) = GenericParams::new(db, *self); let sm = sm.as_ref(); @@ -440,6 +439,5 @@ impl ChildBySource for GenericDefId { let id = ConstParamId { parent: *self, local_id }; res[keys::CONST_PARAM].insert(sm.with_value(src.clone()), id); } - res } } From 13f4356d2f05c79a01e55b1bdd91d9a2dcf9c6f2 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 5 Mar 2021 14:08:23 +0100 Subject: [PATCH 2/8] Store inner `BlockId`s in `Body` --- crates/hir_def/src/body.rs | 4 +++- crates/hir_def/src/body/lower.rs | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index b1a3fe1cb8..9dbe717e50 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs @@ -32,7 +32,7 @@ use crate::{ nameres::DefMap, path::{ModPath, Path}, src::HasSource, - AsMacroCall, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleId, + AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleId, }; /// A subset of Expander that only deals with cfg attributes. We only need it to @@ -226,6 +226,8 @@ pub struct Body { pub params: Vec, /// The `ExprId` of the actual body expression. pub body_expr: ExprId, + /// Block expressions in this body that may contain inner items. + pub block_scopes: Vec, pub item_scope: ItemScope, _c: Count, } diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index d4abe819d3..c3aa1dc37c 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs @@ -76,6 +76,7 @@ pub(super) fn lower( labels: Arena::default(), params: Vec::new(), body_expr: dummy_expr_id(), + block_scopes: Vec::new(), item_scope: Default::default(), _c: Count::new(), }, @@ -700,6 +701,8 @@ impl ExprCollector<'_> { let block_loc = BlockLoc { ast_id, module: self.expander.def_map.module_id(self.expander.module) }; let block_id = self.db.intern_block(block_loc); + self.body.block_scopes.push(block_id); + let opt_def_map = self.db.block_def_map(block_id); let has_def_map = opt_def_map.is_some(); let def_map = opt_def_map.unwrap_or_else(|| self.expander.def_map.clone()); From c12f7be8d33f9ddfd69f72fb75acc5b12d149527 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 5 Mar 2021 14:08:36 +0100 Subject: [PATCH 3/8] Use `body.block_scopes` in `ChildBySource` --- crates/hir_def/src/child_by_source.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/hir_def/src/child_by_source.rs b/crates/hir_def/src/child_by_source.rs index 6dde741382..2a331dcaf9 100644 --- a/crates/hir_def/src/child_by_source.rs +++ b/crates/hir_def/src/child_by_source.rs @@ -160,6 +160,10 @@ impl ChildBySource for EnumId { impl ChildBySource for DefWithBodyId { fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) { let body = db.body(*self); - body.item_scope.child_by_source_to(db, res); + for def_map in body.block_scopes.iter().filter_map(|block| db.block_def_map(*block)) { + // All block expressions are merged into the same map, because they logically all add + // inner items to the containing `DefWithBodyId`. + def_map[def_map.root()].scope.child_by_source_to(db, res); + } } } From 0cb46a9e8d20a5f843e3a7fa6387779d1ff68c3b Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 5 Mar 2021 14:15:26 +0100 Subject: [PATCH 4/8] Use `body.block_scopes` to validate inner items --- crates/hir_ty/src/diagnostics/decl_check.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs index e230f97656..3605ca5816 100644 --- a/crates/hir_ty/src/diagnostics/decl_check.rs +++ b/crates/hir_ty/src/diagnostics/decl_check.rs @@ -99,9 +99,14 @@ impl<'a, 'b> DeclValidator<'a, 'b> { let body = self.db.body(func.into()); // Recursively validate inner scope items, such as static variables and constants. - for (item_id, _) in body.item_scope.values() { - let mut validator = DeclValidator::new(self.db, self.krate, self.sink); - validator.validate_item(item_id); + let db = self.db; + for block_def_map in body.block_scopes.iter().filter_map(|block| db.block_def_map(*block)) { + for (_, module) in block_def_map.modules() { + for (def_id, _) in module.scope.values() { + let mut validator = DeclValidator::new(self.db, self.krate, self.sink); + validator.validate_item(def_id); + } + } } // Check whether non-snake case identifiers are allowed for this function. From 1da0a27626559eb74d2398db314df2edca18de70 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 5 Mar 2021 14:53:32 +0100 Subject: [PATCH 5/8] Use `body.block_scopes` in `hir_ty` tests --- crates/hir_ty/src/tests.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs index 7386a4e7ba..fc770ea600 100644 --- a/crates/hir_ty/src/tests.rs +++ b/crates/hir_ty/src/tests.rs @@ -13,7 +13,7 @@ use std::{env, sync::Arc}; use base_db::{fixture::WithFixture, FileRange, SourceDatabase, SourceDatabaseExt}; use expect_test::Expect; use hir_def::{ - body::{BodySourceMap, SyntheticSyntax}, + body::{Body, BodySourceMap, SyntheticSyntax}, child_by_source::ChildBySource, db::DefDatabase, item_scope::ItemScope, @@ -234,13 +234,13 @@ fn visit_module( let def = it.into(); cb(def); let body = db.body(def); - visit_scope(db, crate_def_map, &body.item_scope, cb); + visit_body(db, &body, cb); } AssocItemId::ConstId(it) => { let def = it.into(); cb(def); let body = db.body(def); - visit_scope(db, crate_def_map, &body.item_scope, cb); + visit_body(db, &body, cb); } AssocItemId::TypeAliasId(_) => (), } @@ -259,19 +259,19 @@ fn visit_module( let def = it.into(); cb(def); let body = db.body(def); - visit_scope(db, crate_def_map, &body.item_scope, cb); + visit_body(db, &body, cb); } ModuleDefId::ConstId(it) => { let def = it.into(); cb(def); let body = db.body(def); - visit_scope(db, crate_def_map, &body.item_scope, cb); + visit_body(db, &body, cb); } ModuleDefId::StaticId(it) => { let def = it.into(); cb(def); let body = db.body(def); - visit_scope(db, crate_def_map, &body.item_scope, cb); + visit_body(db, &body, cb); } ModuleDefId::TraitId(it) => { let trait_data = db.trait_data(it); @@ -288,6 +288,14 @@ fn visit_module( } } } + + fn visit_body(db: &TestDB, body: &Body, cb: &mut dyn FnMut(DefWithBodyId)) { + for def_map in body.block_scopes.iter().filter_map(|block| db.block_def_map(*block)) { + for (mod_id, _) in def_map.modules() { + visit_module(db, &def_map, mod_id, cb); + } + } + } } fn ellipsize(mut text: String, max_len: usize) -> String { From 6be4f30cae93479c19dfe313ab13b8ffd3f7a27f Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 5 Mar 2021 14:53:54 +0100 Subject: [PATCH 6/8] Remove `item_scope` field from `Body` --- crates/hir_def/src/body.rs | 7 +- crates/hir_def/src/body/lower.rs | 143 +------------------------------ crates/hir_def/src/item_scope.rs | 31 ------- 3 files changed, 6 insertions(+), 175 deletions(-) diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index 9dbe717e50..19c4eb521d 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs @@ -28,7 +28,6 @@ use crate::{ db::DefDatabase, expr::{Expr, ExprId, Label, LabelId, Pat, PatId}, item_scope::BuiltinShadowMode, - item_scope::ItemScope, nameres::DefMap, path::{ModPath, Path}, src::HasSource, @@ -228,7 +227,6 @@ pub struct Body { pub body_expr: ExprId, /// Block expressions in this body that may contain inner items. pub block_scopes: Vec, - pub item_scope: ItemScope, _c: Count, } @@ -297,7 +295,7 @@ impl Body { } }; let expander = Expander::new(db, file_id, module); - let (body, source_map) = Body::new(db, def, expander, params, body); + let (body, source_map) = Body::new(db, expander, params, body); (Arc::new(body), Arc::new(source_map)) } @@ -307,12 +305,11 @@ impl Body { fn new( db: &dyn DefDatabase, - def: DefWithBodyId, expander: Expander, params: Option, body: Option, ) -> (Body, BodySourceMap) { - lower::lower(db, def, expander, params, body) + lower::lower(db, expander, params, body) } } diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index c3aa1dc37c..4d79ab72cd 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs @@ -1,13 +1,13 @@ //! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr` //! representation. -use std::{any::type_name, mem, sync::Arc}; +use std::{mem, sync::Arc}; use either::Either; use hir_expand::{ hygiene::Hygiene, name::{name, AsName, Name}, - ExpandError, HirFileId, MacroDefId, MacroDefKind, + ExpandError, HirFileId, }; use la_arena::Arena; use profile::Count; @@ -32,11 +32,10 @@ use crate::{ Statement, }, item_scope::BuiltinShadowMode, - item_tree::{ItemTree, ItemTreeId, ItemTreeNode}, + item_tree::ItemTree, path::{GenericArgs, Path}, type_ref::{Mutability, Rawness, TypeRef}, - AdtId, BlockLoc, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, - ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, + AdtId, BlockLoc, ModuleDefId, }; use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource}; @@ -60,7 +59,6 @@ impl LowerCtx { pub(super) fn lower( db: &dyn DefDatabase, - def: DefWithBodyId, expander: Expander, params: Option, body: Option, @@ -68,7 +66,6 @@ pub(super) fn lower( let item_tree = db.item_tree(expander.current_file_id); ExprCollector { db, - def, source_map: BodySourceMap::default(), body: Body { exprs: Arena::default(), @@ -77,7 +74,6 @@ pub(super) fn lower( params: Vec::new(), body_expr: dummy_expr_id(), block_scopes: Vec::new(), - item_scope: Default::default(), _c: Count::new(), }, item_trees: { @@ -92,7 +88,6 @@ pub(super) fn lower( struct ExprCollector<'a> { db: &'a dyn DefDatabase, - def: DefWithBodyId, expander: Expander, body: Body, source_map: BodySourceMap, @@ -606,32 +601,6 @@ impl ExprCollector<'_> { } } - fn find_inner_item(&self, ast: &N::Source) -> Option> { - let id = self.expander.ast_id(ast); - let tree = &self.item_trees[&id.file_id]; - - // FIXME: This probably breaks with `use` items, since they produce multiple item tree nodes - - // Root file (non-macro). - let item_tree_id = tree - .all_inner_items() - .chain(tree.top_level_items().iter().copied()) - .filter_map(|mod_item| mod_item.downcast::()) - .find(|tree_id| tree[*tree_id].ast_id().upcast() == id.value.upcast()) - .or_else(|| { - log::debug!( - "couldn't find inner {} item for {:?} (AST: `{}` - {:?})", - type_name::(), - id, - ast.syntax(), - ast.syntax(), - ); - None - })?; - - Some(ItemTreeId::new(id.file_id, item_tree_id)) - } - fn collect_expr_opt(&mut self, expr: Option) -> ExprId { if let Some(expr) = expr { self.collect_expr(expr) @@ -663,7 +632,6 @@ impl ExprCollector<'_> { match expansion { Some(expansion) => { let statements: ast::MacroStmts = expansion; - this.collect_stmts_items(statements.statements()); statements.statements().for_each(|stmt| { if let Some(mut r) = this.collect_stmt(stmt) { @@ -710,7 +678,6 @@ impl ExprCollector<'_> { let prev_def_map = mem::replace(&mut self.expander.def_map, def_map); let prev_local_module = mem::replace(&mut self.expander.module, module); - self.collect_stmts_items(block.statements()); let statements = block.statements().filter_map(|s| self.collect_stmt(s)).flatten().collect(); let tail = block.tail_expr().map(|e| self.collect_expr(e)); @@ -725,108 +692,6 @@ impl ExprCollector<'_> { expr_id } - fn collect_stmts_items(&mut self, stmts: ast::AstChildren) { - let container = ContainerId::DefWithBodyId(self.def); - - let items = stmts - .filter_map(|stmt| match stmt { - ast::Stmt::Item(it) => Some(it), - ast::Stmt::LetStmt(_) | ast::Stmt::ExprStmt(_) => None, - }) - .filter_map(|item| { - let (def, name): (ModuleDefId, Option) = match item { - ast::Item::Fn(def) => { - let id = self.find_inner_item(&def)?; - ( - FunctionLoc { container: container.into(), id }.intern(self.db).into(), - def.name(), - ) - } - ast::Item::TypeAlias(def) => { - let id = self.find_inner_item(&def)?; - ( - TypeAliasLoc { container: container.into(), id }.intern(self.db).into(), - def.name(), - ) - } - ast::Item::Const(def) => { - let id = self.find_inner_item(&def)?; - ( - ConstLoc { container: container.into(), id }.intern(self.db).into(), - def.name(), - ) - } - ast::Item::Static(def) => { - let id = self.find_inner_item(&def)?; - (StaticLoc { container, id }.intern(self.db).into(), def.name()) - } - ast::Item::Struct(def) => { - let id = self.find_inner_item(&def)?; - (StructLoc { container, id }.intern(self.db).into(), def.name()) - } - ast::Item::Enum(def) => { - let id = self.find_inner_item(&def)?; - (EnumLoc { container, id }.intern(self.db).into(), def.name()) - } - ast::Item::Union(def) => { - let id = self.find_inner_item(&def)?; - (UnionLoc { container, id }.intern(self.db).into(), def.name()) - } - ast::Item::Trait(def) => { - let id = self.find_inner_item(&def)?; - (TraitLoc { container, id }.intern(self.db).into(), def.name()) - } - ast::Item::ExternBlock(_) => return None, // FIXME: collect from extern blocks - ast::Item::Impl(_) - | ast::Item::Use(_) - | ast::Item::ExternCrate(_) - | ast::Item::Module(_) - | ast::Item::MacroCall(_) => return None, - ast::Item::MacroRules(def) => { - return Some(Either::Right(ast::Macro::from(def))); - } - ast::Item::MacroDef(def) => { - return Some(Either::Right(ast::Macro::from(def))); - } - }; - - Some(Either::Left((def, name))) - }) - .collect::>(); - - for either in items { - match either { - Either::Left((def, name)) => { - self.body.item_scope.define_def(def); - if let Some(name) = name { - let vis = crate::visibility::Visibility::Public; // FIXME determine correctly - let has_constructor = match def { - ModuleDefId::AdtId(AdtId::StructId(s)) => { - self.db.struct_data(s).variant_data.kind() != StructKind::Record - } - _ => true, - }; - self.body.item_scope.push_res( - name.as_name(), - crate::per_ns::PerNs::from_def(def, vis, has_constructor), - ); - } - } - Either::Right(e) => { - let mac = MacroDefId { - krate: self.expander.def_map.krate(), - ast_id: Some(self.expander.ast_id(&e)), - kind: MacroDefKind::Declarative, - local_inner: false, - }; - if let Some(name) = e.name() { - self.body.item_scope.define_legacy_macro(name.as_name(), mac); - } - } - } - } - } - fn collect_block_opt(&mut self, expr: Option) -> ExprId { if let Some(block) = expr { self.collect_block(block) diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs index 9199338139..aafd73b606 100644 --- a/crates/hir_def/src/item_scope.rs +++ b/crates/hir_def/src/item_scope.rs @@ -168,37 +168,6 @@ impl ItemScope { self.unnamed_trait_imports.insert(tr, vis); } - pub(crate) fn push_res(&mut self, name: Name, def: PerNs) -> bool { - let mut changed = false; - - if let Some(types) = def.types { - self.types.entry(name.clone()).or_insert_with(|| { - changed = true; - types - }); - } - if let Some(values) = def.values { - self.values.entry(name.clone()).or_insert_with(|| { - changed = true; - values - }); - } - if let Some(macros) = def.macros { - self.macros.entry(name.clone()).or_insert_with(|| { - changed = true; - macros - }); - } - - if def.is_none() { - if self.unresolved.insert(name) { - changed = true; - } - } - - changed - } - pub(crate) fn push_res_with_import( &mut self, glob_imports: &mut PerNsGlobImports, From 12f6bdcfd9fe1393887b3be0d0329fcf11492e75 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 9 Mar 2021 18:18:35 +0100 Subject: [PATCH 7/8] Check ancestor maps when computing traits in scope --- crates/hir_def/src/resolver.rs | 10 ++++++++++ crates/hir_ty/src/tests/traits.rs | 33 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs index 77ff21739d..28b184f7cf 100644 --- a/crates/hir_def/src/resolver.rs +++ b/crates/hir_def/src/resolver.rs @@ -342,6 +342,16 @@ impl Resolver { traits.extend(prelude_def_map[prelude.local_id].scope.traits()); } traits.extend(m.def_map[m.module_id].scope.traits()); + + // Add all traits that are in scope because of the containing DefMaps + m.def_map.with_ancestor_maps(db, m.module_id, &mut |def_map, module| { + if let Some(prelude) = def_map.prelude() { + let prelude_def_map = prelude.def_map(db); + traits.extend(prelude_def_map[prelude.local_id].scope.traits()); + } + traits.extend(def_map[module].scope.traits()); + None::<()> + }); } } traits diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index 5280920825..e185b1c0a1 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs @@ -3173,6 +3173,39 @@ fn f() { ); } +#[test] +fn trait_in_scope_with_inner_item() { + check_infer( + r#" +mod m { + pub trait Tr { + fn method(&self) -> u8 { 0 } + } + + impl Tr for () {} +} + +use m::Tr; + +fn f() { + fn inner() { + ().method(); + //^^^^^^^^^^^ u8 + } +} + "#, + expect![[r#" + 46..50 'self': &Self + 58..63 '{ 0 }': u8 + 60..61 '0': u8 + 115..185 '{ ... } }': () + 132..183 '{ ... }': () + 142..144 '()': () + 142..153 '().method()': u8 + "#]], + ); +} + #[test] fn inner_use_in_block() { check_types( From a430549aa6cb78e3a6c9258305b348743c4d7449 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 9 Mar 2021 18:27:16 +0100 Subject: [PATCH 8/8] Stop using `ContainerId` in `AssocContainerId` --- crates/hir/src/lib.rs | 4 ++-- crates/hir_def/src/lib.rs | 6 +++--- crates/hir_def/src/nameres/collector.rs | 6 +++--- crates/hir_def/src/resolver.rs | 2 +- crates/hir_ty/src/infer/path.rs | 2 +- crates/hir_ty/src/method_resolution.rs | 2 +- crates/hir_ty/src/utils.rs | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 638398e292..c6d424c487 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -1157,7 +1157,7 @@ where { match id.lookup(db.upcast()).container { AssocContainerId::TraitId(_) | AssocContainerId::ImplId(_) => Some(ctor(DEF::from(id))), - AssocContainerId::ContainerId(_) => None, + AssocContainerId::ModuleId(_) => None, } } @@ -1185,7 +1185,7 @@ impl AssocItem { match container { AssocContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()), AssocContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()), - AssocContainerId::ContainerId(_) => panic!("invalid AssocItem"), + AssocContainerId::ModuleId(_) => panic!("invalid AssocItem"), } } diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 4498d94bb2..ab3b17f6cd 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs @@ -286,11 +286,11 @@ pub enum ContainerId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum AssocContainerId { - ContainerId(ContainerId), + ModuleId(ModuleId), ImplId(ImplId), TraitId(TraitId), } -impl_from!(ContainerId for AssocContainerId); +impl_from!(ModuleId for AssocContainerId); /// A Data Type #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] @@ -459,7 +459,7 @@ impl HasModule for ContainerId { impl HasModule for AssocContainerId { fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { match *self { - AssocContainerId::ContainerId(it) => it.module(db), + AssocContainerId::ModuleId(it) => it, AssocContainerId::ImplId(it) => it.lookup(db).container.module(db), AssocContainerId::TraitId(it) => it.lookup(db).container.module(db), } diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 3bb69d935f..5bf2ba721b 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -1121,7 +1121,7 @@ impl ModCollector<'_, '_> { def = Some(DefData { id: FunctionLoc { - container: container.into(), + container: module.into(), id: ItemTreeId::new(self.file_id, id), } .intern(self.def_collector.db) @@ -1188,7 +1188,7 @@ impl ModCollector<'_, '_> { if let Some(name) = &it.name { def = Some(DefData { id: ConstLoc { - container: container.into(), + container: module.into(), id: ItemTreeId::new(self.file_id, id), } .intern(self.def_collector.db) @@ -1228,7 +1228,7 @@ impl ModCollector<'_, '_> { def = Some(DefData { id: TypeAliasLoc { - container: container.into(), + container: module.into(), id: ItemTreeId::new(self.file_id, id), } .intern(self.def_collector.db) diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs index 28b184f7cf..6f036c8c42 100644 --- a/crates/hir_def/src/resolver.rs +++ b/crates/hir_def/src/resolver.rs @@ -700,7 +700,7 @@ impl HasResolver for ContainerId { impl HasResolver for AssocContainerId { fn resolver(self, db: &dyn DefDatabase) -> Resolver { match self { - AssocContainerId::ContainerId(it) => it.resolver(db), + AssocContainerId::ModuleId(it) => it.resolver(db), AssocContainerId::TraitId(it) => it.resolver(db), AssocContainerId::ImplId(it) => it.resolver(db), } diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index 5d541104e2..ae3554bac8 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs @@ -260,7 +260,7 @@ impl<'a> InferenceContext<'a> { })); Some(trait_substs) } - AssocContainerId::ContainerId(_) => None, + AssocContainerId::ModuleId(_) => None, }; self.write_assoc_resolution(id, item); diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 24db33c491..2483672674 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -715,7 +715,7 @@ fn transform_receiver_ty( .fill_with_unknown() .build() } - AssocContainerId::ContainerId(_) => unreachable!(), + AssocContainerId::ModuleId(_) => unreachable!(), }; let sig = db.callable_item_signature(function_id.into()); Some(sig.value.params()[0].clone().subst_bound_vars(&substs)) diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs index 65b79df0d5..7351e4e54a 100644 --- a/crates/hir_ty/src/utils.rs +++ b/crates/hir_ty/src/utils.rs @@ -259,6 +259,6 @@ fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option Some(it.into()), AssocContainerId::TraitId(it) => Some(it.into()), - AssocContainerId::ContainerId(_) => None, + AssocContainerId::ModuleId(_) => None, } }