aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-06-22 19:22:36 +0100
committerAleksey Kladov <[email protected]>2021-06-22 19:26:07 +0100
commit7be2d2f008595114e19aad0aa0608ddedfe3edf7 (patch)
tree61b75baa49f6b88c24fbda5f44ac734fed1f7d98
parent9239943b84ec2bd687c4c80d2c3a0df4f8caf31c (diff)
internal: remove one more accidentally quadratic code-path
Definition::visibility was implemented in a rather roundabout way -- by asking the parent module about the effective visibility. This is problematic for a couple of reasons: * first, it doesn't work for local items * second, asking module about visibility of a child is a linear operation (that's a problem in itself, tracked in #9378) Instead, lets ask the declared visibility directly, we have all the code for it, and need only to actually us it.
-rw-r--r--crates/hir/src/lib.rs30
-rw-r--r--crates/ide_db/src/defs.rs28
2 files changed, 32 insertions, 26 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 9c56fe1a6..3f0000889 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -303,26 +303,6 @@ impl ModuleDef {
303 Some(segments.join("::")) 303 Some(segments.join("::"))
304 } 304 }
305 305
306 pub fn definition_visibility(&self, db: &dyn HirDatabase) -> Option<Visibility> {
307 let module = match self {
308 ModuleDef::Module(it) => it.parent(db)?,
309 ModuleDef::Function(it) => return Some(it.visibility(db)),
310 ModuleDef::Adt(it) => it.module(db),
311 ModuleDef::Variant(it) => {
312 let parent = it.parent_enum(db);
313 let module = it.module(db);
314 return module.visibility_of(db, &ModuleDef::Adt(Adt::Enum(parent)));
315 }
316 ModuleDef::Const(it) => return Some(it.visibility(db)),
317 ModuleDef::Static(it) => it.module(db),
318 ModuleDef::Trait(it) => it.module(db),
319 ModuleDef::TypeAlias(it) => return Some(it.visibility(db)),
320 ModuleDef::BuiltinType(_) => return None,
321 };
322
323 module.visibility_of(db, self)
324 }
325
326 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 306 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
327 match self { 307 match self {
328 ModuleDef::Adt(it) => Some(it.name(db)), 308 ModuleDef::Adt(it) => Some(it.name(db)),
@@ -893,6 +873,16 @@ impl Adt {
893 } 873 }
894} 874}
895 875
876impl HasVisibility for Adt {
877 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
878 match self {
879 Adt::Struct(it) => it.visibility(db),
880 Adt::Union(it) => it.visibility(db),
881 Adt::Enum(it) => it.visibility(db),
882 }
883 }
884}
885
896#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 886#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
897pub enum VariantDef { 887pub enum VariantDef {
898 Struct(Struct), 888 Struct(Struct),
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs
index a54f2c323..fddd1fc2d 100644
--- a/crates/ide_db/src/defs.rs
+++ b/crates/ide_db/src/defs.rs
@@ -43,13 +43,29 @@ impl Definition {
43 43
44 pub fn visibility(&self, db: &RootDatabase) -> Option<Visibility> { 44 pub fn visibility(&self, db: &RootDatabase) -> Option<Visibility> {
45 match self { 45 match self {
46 Definition::Macro(_) => None,
47 Definition::Field(sf) => Some(sf.visibility(db)), 46 Definition::Field(sf) => Some(sf.visibility(db)),
48 Definition::ModuleDef(def) => def.definition_visibility(db), 47 Definition::ModuleDef(def) => match def {
49 Definition::SelfType(_) => None, 48 ModuleDef::Module(it) => {
50 Definition::Local(_) => None, 49 // FIXME: should work like other cases here.
51 Definition::GenericParam(_) => None, 50 let parent = it.parent(db)?;
52 Definition::Label(_) => None, 51 parent.visibility_of(db, def)
52 }
53 ModuleDef::Function(it) => Some(it.visibility(db)),
54 ModuleDef::Adt(it) => Some(it.visibility(db)),
55 ModuleDef::Const(it) => Some(it.visibility(db)),
56 ModuleDef::Static(it) => Some(it.visibility(db)),
57 ModuleDef::Trait(it) => Some(it.visibility(db)),
58 ModuleDef::TypeAlias(it) => Some(it.visibility(db)),
59 // NB: Variants don't have their own visibility, and just inherit
60 // one from the parent. Not sure if that's the right thing to do.
61 ModuleDef::Variant(it) => Some(it.parent_enum(db).visibility(db)),
62 ModuleDef::BuiltinType(_) => None,
63 },
64 Definition::Macro(_)
65 | Definition::SelfType(_)
66 | Definition::Local(_)
67 | Definition::GenericParam(_)
68 | Definition::Label(_) => None,
53 } 69 }
54 } 70 }
55 71