4421: Find references to a function outside module r=flodiebold a=montekki

Fixes #4188 

Yet again, it looks like although the code in 
da1f316b02/crates/ra_ide_db/src/search.rs (L128-L132)

may be wrong, it is not hit since the `vis` is `None` at this point. The fix is similar to the #4237 case: just add another special case to `Definition::visibility()`.

Co-authored-by: Fedor Sakharov <fedor.sakharov@gmail.com>
This commit is contained in:
bors[bot] 2020-05-11 12:21:08 +00:00 committed by GitHub
commit 05399250d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 10 deletions

View File

@ -148,6 +148,26 @@ impl ModuleDef {
ModuleDef::BuiltinType(_) => None, ModuleDef::BuiltinType(_) => None,
} }
} }
pub fn definition_visibility(&self, db: &dyn HirDatabase) -> Option<Visibility> {
let module = match self {
ModuleDef::Module(it) => it.parent(db)?,
ModuleDef::Function(it) => return Some(it.visibility(db)),
ModuleDef::Adt(it) => it.module(db),
ModuleDef::EnumVariant(it) => {
let parent = it.parent_enum(db);
let module = it.module(db);
return module.visibility_of(db, &ModuleDef::Adt(Adt::Enum(parent)));
}
ModuleDef::Const(it) => return Some(it.visibility(db)),
ModuleDef::Static(it) => it.module(db),
ModuleDef::Trait(it) => it.module(db),
ModuleDef::TypeAlias(it) => return Some(it.visibility(db)),
ModuleDef::BuiltinType(_) => return None,
};
module.visibility_of(db, self)
}
} }
pub use hir_def::{ pub use hir_def::{

View File

@ -593,6 +593,31 @@ mod tests {
check_result(refs, "i BIND_PAT FileId(1) 36..37 Other", &["FileId(1) 51..52 Other Write"]); check_result(refs, "i BIND_PAT FileId(1) 36..37 Other", &["FileId(1) 51..52 Other Write"]);
} }
#[test]
fn test_find_struct_function_refs_outside_module() {
let code = r#"
mod foo {
pub struct Foo;
impl Foo {
pub fn new<|>() -> Foo {
Foo
}
}
}
fn main() {
let _f = foo::Foo::new();
}"#;
let refs = get_all_refs(code);
check_result(
refs,
"new FN_DEF FileId(1) 87..150 94..97 Other",
&["FileId(1) 227..230 StructLiteral"],
);
}
fn get_all_refs(text: &str) -> ReferenceSearchResult { fn get_all_refs(text: &str) -> ReferenceSearchResult {
let (analysis, position) = single_file_with_position(text); let (analysis, position) = single_file_with_position(text);
analysis.find_all_refs(position, None).unwrap().unwrap() analysis.find_all_refs(position, None).unwrap().unwrap()

View File

@ -6,7 +6,7 @@
// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06).
use hir::{ use hir::{
Adt, Field, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, Name, PathResolution, Field, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, Name, PathResolution,
Semantics, TypeParam, Visibility, Semantics, TypeParam, Visibility,
}; };
use ra_prof::profile; use ra_prof::profile;
@ -42,18 +42,10 @@ impl Definition {
} }
pub fn visibility(&self, db: &RootDatabase) -> Option<Visibility> { pub fn visibility(&self, db: &RootDatabase) -> Option<Visibility> {
let module = self.module(db);
match self { match self {
Definition::Macro(_) => None, Definition::Macro(_) => None,
Definition::Field(sf) => Some(sf.visibility(db)), Definition::Field(sf) => Some(sf.visibility(db)),
Definition::ModuleDef(def) => match def { Definition::ModuleDef(def) => def.definition_visibility(db),
ModuleDef::EnumVariant(id) => {
let parent = id.parent_enum(db);
module?.visibility_of(db, &ModuleDef::Adt(Adt::Enum(parent)))
}
_ => module?.visibility_of(db, def),
},
Definition::SelfType(_) => None, Definition::SelfType(_) => None,
Definition::Local(_) => None, Definition::Local(_) => None,
Definition::TypeParam(_) => None, Definition::TypeParam(_) => None,