Unnamed repository; edit this file 'description' to name the repository.
implement inherited_visibility in collector
Hongxu Xu 2022-06-14
parent 3f60e71 · commit ded412d
-rw-r--r--crates/hir-def/src/data.rs52
-rw-r--r--crates/hir-def/src/item_tree/lower.rs2
-rw-r--r--crates/hir-def/src/item_tree/tests.rs72
-rw-r--r--crates/hir-def/src/lib.rs23
-rw-r--r--crates/hir-def/src/nameres/collector.rs36
-rw-r--r--crates/ide-completion/src/tests/special.rs59
6 files changed, 156 insertions, 88 deletions
diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs
index f2d8318f7d..bb2e9a5b29 100644
--- a/crates/hir-def/src/data.rs
+++ b/crates/hir-def/src/data.rs
@@ -15,8 +15,8 @@ use crate::{
type_ref::{TraitRef, TypeBound, TypeRef},
visibility::RawVisibility,
AssocItemId, AstIdWithPath, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
- Intern, ItemContainerId, Lookup, Macro2Id, MacroRulesId, ModuleId, ProcMacroId, StaticId,
- TraitId, TypeAliasId, TypeAliasLoc,
+ InheritedVisibilityLoc, Intern, ItemContainerId, Lookup, Macro2Id, MacroRulesId, ModuleId,
+ ProcMacroId, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
};
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -41,6 +41,12 @@ impl FunctionData {
let item_tree = loc.id.item_tree(db);
let func = &item_tree[loc.id.value];
+ let visibility = if let Some(inherited_vis) = loc.inherited_visibility {
+ inherited_vis.tree_id.item_tree(db)[inherited_vis.raw_visibility_id].clone()
+ } else {
+ item_tree[func.visibility].clone()
+ };
+
let enabled_params = func
.params
.clone()
@@ -93,7 +99,7 @@ impl FunctionData {
ret_type: func.ret_type.clone(),
async_ret_type: func.async_ret_type.clone(),
attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
- visibility: item_tree[func.visibility].clone(),
+ visibility,
abi: func.abi.clone(),
legacy_const_generics_indices,
flags,
@@ -171,11 +177,16 @@ impl TypeAliasData {
let loc = typ.lookup(db);
let item_tree = loc.id.item_tree(db);
let typ = &item_tree[loc.id.value];
+ let visibility = if let Some(inherited_vis) = loc.inherited_visibility {
+ inherited_vis.tree_id.item_tree(db)[inherited_vis.raw_visibility_id].clone()
+ } else {
+ item_tree[typ.visibility].clone()
+ };
Arc::new(TypeAliasData {
name: typ.name.clone(),
type_ref: typ.type_ref.clone(),
- visibility: item_tree[typ.visibility].clone(),
+ visibility,
is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)),
bounds: typ.bounds.to_vec(),
})
@@ -221,6 +232,7 @@ impl TraitData {
module_id,
tr_loc.id.file_id(),
ItemContainerId::TraitId(tr),
+ Some(InheritedVisibilityLoc::new(tr_def.visibility, tr_loc.id.tree_id())),
);
collector.collect(tr_loc.id.tree_id(), &tr_def.items);
@@ -288,6 +300,7 @@ impl ImplData {
module_id,
impl_loc.id.file_id(),
ItemContainerId::ImplId(id),
+ None,
);
collector.collect(impl_loc.id.tree_id(), &impl_def.items);
@@ -385,11 +398,16 @@ impl ConstData {
let loc = konst.lookup(db);
let item_tree = loc.id.item_tree(db);
let konst = &item_tree[loc.id.value];
+ let visibility = if let Some(inherited_vis) = loc.inherited_visibility {
+ inherited_vis.tree_id.item_tree(db)[inherited_vis.raw_visibility_id].clone()
+ } else {
+ item_tree[konst.visibility].clone()
+ };
Arc::new(ConstData {
name: konst.name.clone(),
type_ref: konst.type_ref.clone(),
- visibility: item_tree[konst.visibility].clone(),
+ visibility,
})
}
}
@@ -428,6 +446,8 @@ struct AssocItemCollector<'a> {
items: Vec<(Name, AssocItemId)>,
attr_calls: Vec<(AstId<ast::Item>, MacroCallId)>,
+
+ inherited_visibility: Option<InheritedVisibilityLoc>,
}
impl<'a> AssocItemCollector<'a> {
@@ -436,6 +456,7 @@ impl<'a> AssocItemCollector<'a> {
module_id: ModuleId,
file_id: HirFileId,
container: ItemContainerId,
+ inherited_visibility: Option<InheritedVisibilityLoc>,
) -> Self {
Self {
db,
@@ -446,6 +467,8 @@ impl<'a> AssocItemCollector<'a> {
items: Vec::new(),
attr_calls: Vec::new(),
+
+ inherited_visibility,
}
}
@@ -488,9 +511,12 @@ impl<'a> AssocItemCollector<'a> {
match item {
AssocItem::Function(id) => {
let item = &item_tree[id];
- let def =
- FunctionLoc { container: self.container, id: ItemTreeId::new(tree_id, id) }
- .intern(self.db);
+ let def = FunctionLoc {
+ container: self.container,
+ id: ItemTreeId::new(tree_id, id),
+ inherited_visibility: self.inherited_visibility,
+ }
+ .intern(self.db);
self.items.push((item.name.clone(), def.into()));
}
AssocItem::Const(id) => {
@@ -499,9 +525,12 @@ impl<'a> AssocItemCollector<'a> {
Some(name) => name,
None => continue,
};
- let def =
- ConstLoc { container: self.container, id: ItemTreeId::new(tree_id, id) }
- .intern(self.db);
+ let def = ConstLoc {
+ container: self.container,
+ id: ItemTreeId::new(tree_id, id),
+ inherited_visibility: self.inherited_visibility,
+ }
+ .intern(self.db);
self.items.push((name, def.into()));
}
AssocItem::TypeAlias(id) => {
@@ -509,6 +538,7 @@ impl<'a> AssocItemCollector<'a> {
let def = TypeAliasLoc {
container: self.container,
id: ItemTreeId::new(tree_id, id),
+ inherited_visibility: self.inherited_visibility,
}
.intern(self.db);
self.items.push((item.name.clone(), def.into()));
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index 7ba983fa71..7f2551e941 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -1,6 +1,6 @@
//! AST -> `ItemTree` lowering code.
-use std::{collections::hash_map::Entry, mem, sync::Arc};
+use std::{collections::hash_map::Entry, sync::Arc};
use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, HirFileId};
use syntax::ast::{self, HasModuleItem};
diff --git a/crates/hir-def/src/item_tree/tests.rs b/crates/hir-def/src/item_tree/tests.rs
index fb3811dbd5..bd7c9588b6 100644
--- a/crates/hir-def/src/item_tree/tests.rs
+++ b/crates/hir-def/src/item_tree/tests.rs
@@ -359,39 +359,39 @@ trait Tr<'a, T: 'a>: Super where Self: for<'a> Tr<'a, T> {}
)
}
-#[test]
-fn inherit_visibility() {
- check(
- r#"
-pub(crate) enum En {
- Var1(u8),
- Var2 {
- fld: u8,
- },
-}
-
-pub(crate) trait Tr {
- fn f();
- fn method(&self) {}
-}
- "#,
- expect![[r#"
- pub(crate) enum En {
- Var1(
- pub(crate) 0: u8,
- ),
- Var2 {
- pub(crate) fld: u8,
- },
- }
-
- pub(crate) trait Tr<Self> {
- pub(crate) fn f() -> ();
-
- pub(crate) fn method(
- _: &Self, // self
- ) -> () { ... }
- }
- "#]],
- )
-}
+// #[test]
+// fn inherit_visibility() {
+// check(
+// r#"
+// pub(crate) enum En {
+// Var1(u8),
+// Var2 {
+// fld: u8,
+// },
+// }
+
+// pub(crate) trait Tr {
+// fn f();
+// fn method(&self) {}
+// }
+// "#,
+// expect![[r#"
+// pub(crate) enum En {
+// Var1(
+// pub(crate) 0: u8,
+// ),
+// Var2 {
+// pub(crate) fld: u8,
+// },
+// }
+
+// pub(crate) trait Tr<Self> {
+// pub(crate) fn f() -> ();
+
+// pub(crate) fn method(
+// _: &Self, // self
+// ) -> () { ... }
+// }
+// "#]],
+// )
+// }
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index 4431d1b3c8..e3ac7faa6c 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -70,7 +70,7 @@ use hir_expand::{
AstId, ExpandError, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId,
MacroDefKind, UnresolvedMacro,
};
-use item_tree::ExternBlock;
+use item_tree::{ExternBlock, RawVisibilityId, TreeId};
use la_arena::Idx;
use nameres::DefMap;
use stdx::impl_from;
@@ -156,19 +156,24 @@ impl<N: ItemTreeNode> Hash for ItemLoc<N> {
}
}
-#[derive(Debug)]
-pub struct AssocItemLoc<N: ItemTreeNode> {
- pub container: ItemContainerId,
- pub id: ItemTreeId<N>,
+#[derive(Debug, Clone, Copy)]
+pub struct InheritedVisibilityLoc {
+ pub raw_visibility_id: RawVisibilityId,
+ pub tree_id: TreeId,
}
-impl<N: ItemTreeNode> Clone for AssocItemLoc<N> {
- fn clone(&self) -> Self {
- Self { container: self.container, id: self.id }
+impl InheritedVisibilityLoc {
+ pub fn new(visibility_id: RawVisibilityId, tree_id: TreeId) -> Self {
+ Self { raw_visibility_id: visibility_id, tree_id }
}
}
-impl<N: ItemTreeNode> Copy for AssocItemLoc<N> {}
+#[derive(Debug, Clone, Copy)]
+pub struct AssocItemLoc<N: ItemTreeNode> {
+ pub container: ItemContainerId,
+ pub id: ItemTreeId<N>,
+ pub inherited_visibility: Option<InheritedVisibilityLoc>,
+}
impl<N: ItemTreeNode> PartialEq for AssocItemLoc<N> {
fn eq(&self, other: &Self) -> bool {
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 7fea46bee3..5e3e143bef 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -1549,8 +1549,12 @@ impl ModCollector<'_, '_> {
}
ModItem::Function(id) => {
let it = &self.item_tree[id];
- let fn_id =
- FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) }.intern(db);
+ let fn_id = FunctionLoc {
+ container,
+ id: ItemTreeId::new(self.tree_id, id),
+ inherited_visibility: None,
+ }
+ .intern(db);
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
if self.def_collector.is_proc_macro {
@@ -1613,8 +1617,12 @@ impl ModCollector<'_, '_> {
}
ModItem::Const(id) => {
let it = &self.item_tree[id];
- let const_id =
- ConstLoc { container, id: ItemTreeId::new(self.tree_id, id) }.intern(db);
+ let const_id = ConstLoc {
+ container,
+ id: ItemTreeId::new(self.tree_id, id),
+ inherited_visibility: None,
+ }
+ .intern(db);
match &it.name {
Some(name) => {
@@ -1635,9 +1643,13 @@ impl ModCollector<'_, '_> {
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
update_def(
self.def_collector,
- StaticLoc { container, id: ItemTreeId::new(self.tree_id, id) }
- .intern(db)
- .into(),
+ StaticLoc {
+ container,
+ id: ItemTreeId::new(self.tree_id, id),
+ inherited_visibility: None,
+ }
+ .intern(db)
+ .into(),
&it.name,
vis,
false,
@@ -1663,9 +1675,13 @@ impl ModCollector<'_, '_> {
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
update_def(
self.def_collector,
- TypeAliasLoc { container, id: ItemTreeId::new(self.tree_id, id) }
- .intern(db)
- .into(),
+ TypeAliasLoc {
+ container,
+ id: ItemTreeId::new(self.tree_id, id),
+ inherited_visibility: None,
+ }
+ .intern(db)
+ .into(),
&it.name,
vis,
false,
diff --git a/crates/ide-completion/src/tests/special.rs b/crates/ide-completion/src/tests/special.rs
index 8231336237..2f2351e27b 100644
--- a/crates/ide-completion/src/tests/special.rs
+++ b/crates/ide-completion/src/tests/special.rs
@@ -13,7 +13,7 @@ fn check(ra_fixture: &str, expect: Expect) {
}
fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) {
- let actual = completion_list_with_config(config, ra_fixture, true, None);
+ let actual = completion_list_with_config(config, ra_fixture, false, None);
expect.assert_eq(&actual)
}
@@ -679,20 +679,10 @@ fn main() {
expect![[r#"
me by_macro() (as MyTrait) fn(&self)
me not_by_macro() (as MyTrait) fn(&self)
- sn box Box::new(expr)
- sn call function(expr)
- sn dbg dbg!(expr)
- sn dbgr dbg!(&expr)
- sn let let
- sn letm let mut
- sn match match expr {}
- sn ref &expr
- sn refm &mut expr
"#]],
)
}
-
#[test]
fn completes_fn_in_pub_trait_generated_by_recursive_macro() {
let mut config = TEST_CONFIG.clone();
@@ -733,15 +723,42 @@ fn main() {
expect![[r#"
me by_macro() (as MyTrait) fn(&self)
me not_by_macro() (as MyTrait) fn(&self)
- sn box Box::new(expr)
- sn call function(expr)
- sn dbg dbg!(expr)
- sn dbgr dbg!(&expr)
- sn let let
- sn letm let mut
- sn match match expr {}
- sn ref &expr
- sn refm &mut expr
"#]],
)
-} \ No newline at end of file
+}
+
+#[test]
+fn completes_const_in_pub_trait_generated_by_macro() {
+ let mut config = TEST_CONFIG.clone();
+ config.enable_private_editable = false;
+
+ check_with_config(
+ config,
+ r#"
+mod other_mod {
+ macro_rules! make_const {
+ ($name:ident) => {
+ const $name: u8 = 1;
+ };
+ }
+
+ pub trait MyTrait {
+ make_const! { by_macro }
+ }
+
+ pub struct Foo {}
+
+ impl MyTrait for Foo {}
+}
+
+fn main() {
+ use other_mod::{Foo, MyTrait};
+ let f = Foo {};
+ Foo::$0
+}
+"#,
+ expect![[r#"
+ ct by_macro (as MyTrait) pub const by_macro: u8
+ "#]],
+ )
+}