From 7776aad166760480726ee9d4692d2597dd2fa399 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 10 Nov 2021 22:02:50 +0100 Subject: [PATCH] internal: Flatten `Definition::ModuleDef` variant --- crates/hir/src/display.rs | 5 +- crates/hir/src/lib.rs | 25 +- crates/hir_def/src/data.rs | 4 +- crates/hir_ty/src/db.rs | 4 +- crates/hir_ty/src/diagnostics/decl_check.rs | 5 +- crates/ide/src/call_hierarchy.rs | 8 +- crates/ide/src/display/navigation_target.rs | 14 +- crates/ide/src/doc_links.rs | 254 ++++++++--------- crates/ide/src/goto_declaration.rs | 2 +- crates/ide/src/goto_definition.rs | 9 +- crates/ide/src/goto_implementation.rs | 104 ++++--- crates/ide/src/goto_type_definition.rs | 4 +- crates/ide/src/highlight_related.rs | 2 +- crates/ide/src/hover.rs | 45 ++- crates/ide/src/hover/render.rs | 41 ++- crates/ide/src/references.rs | 6 +- crates/ide/src/rename.rs | 2 +- .../ide/src/syntax_highlighting/highlight.rs | 174 ++++++------ crates/ide/src/syntax_highlighting/inject.rs | 39 ++- .../src/handlers/add_turbo_fish.rs | 2 +- .../convert_tuple_struct_to_named_struct.rs | 4 +- .../src/handlers/expand_glob_import.rs | 58 ++-- .../src/handlers/extract_module.rs | 256 +++++++++--------- .../extract_struct_from_enum_variant.rs | 3 +- .../src/handlers/fix_visibility.rs | 2 +- .../src/handlers/generate_function.rs | 7 +- .../ide_assists/src/handlers/inline_call.rs | 2 +- .../src/handlers/remove_unused_param.rs | 2 +- crates/ide_db/src/defs.rs | 187 +++++++++---- crates/ide_db/src/items_locator.rs | 3 +- crates/ide_db/src/rename.rs | 73 ++--- crates/ide_db/src/search.rs | 65 ++--- 32 files changed, 709 insertions(+), 702 deletions(-) diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index a541cbd5e18..e9ace855fc3 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -421,10 +421,7 @@ impl HirDisplay for Static { if data.mutable { write!(f, "mut ")?; } - match &data.name { - Some(name) => write!(f, "{}: ", name)?, - None => write!(f, "_: ")?, - } + write!(f, "{}: ", &data.name)?; data.type_ref.hir_fmt(f)?; Ok(()) } diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 2096c485e46..c46324f988c 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -316,17 +316,18 @@ impl ModuleDef { } pub fn name(self, db: &dyn HirDatabase) -> Option { - match self { - ModuleDef::Adt(it) => Some(it.name(db)), - ModuleDef::Trait(it) => Some(it.name(db)), - ModuleDef::Function(it) => Some(it.name(db)), - ModuleDef::Variant(it) => Some(it.name(db)), - ModuleDef::TypeAlias(it) => Some(it.name(db)), - ModuleDef::Module(it) => it.name(db), - ModuleDef::Const(it) => it.name(db), + let name = match self { + ModuleDef::Module(it) => it.name(db)?, + ModuleDef::Const(it) => it.name(db)?, + ModuleDef::Adt(it) => it.name(db), + ModuleDef::Trait(it) => it.name(db), + ModuleDef::Function(it) => it.name(db), + ModuleDef::Variant(it) => it.name(db), + ModuleDef::TypeAlias(it) => it.name(db), ModuleDef::Static(it) => it.name(db), - ModuleDef::BuiltinType(it) => Some(it.name()), - } + ModuleDef::BuiltinType(it) => it.name(), + }; + Some(name) } pub fn diagnostics(self, db: &dyn HirDatabase) -> Vec { @@ -1036,7 +1037,7 @@ impl DefWithBody { pub fn name(self, db: &dyn HirDatabase) -> Option { match self { DefWithBody::Function(f) => Some(f.name(db)), - DefWithBody::Static(s) => s.name(db), + DefWithBody::Static(s) => Some(s.name(db)), DefWithBody::Const(c) => c.name(db), } } @@ -1484,7 +1485,7 @@ impl Static { Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } } - pub fn name(self, db: &dyn HirDatabase) -> Option { + pub fn name(self, db: &dyn HirDatabase) -> Name { db.static_data(self.id).name.clone() } diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index 435073f6753..f4d0c3af90b 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs @@ -273,7 +273,7 @@ impl ConstData { #[derive(Debug, Clone, PartialEq, Eq)] pub struct StaticData { - pub name: Option, + pub name: Name, pub type_ref: Interned, pub visibility: RawVisibility, pub mutable: bool, @@ -287,7 +287,7 @@ impl StaticData { let statik = &item_tree[node.id.value]; Arc::new(StaticData { - name: Some(statik.name.clone()), + name: statik.name.clone(), type_ref: statik.type_ref.clone(), visibility: item_tree[statik.visibility].clone(), mutable: statik.mutable, diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs index 98a58490012..63aa6b91daf 100644 --- a/crates/hir_ty/src/db.rs +++ b/crates/hir_ty/src/db.rs @@ -159,9 +159,7 @@ pub trait HirDatabase: DefDatabase + Upcast { fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc { let _p = profile::span("infer:wait").detail(|| match def { DefWithBodyId::FunctionId(it) => db.function_data(it).name.to_string(), - DefWithBodyId::StaticId(it) => { - db.static_data(it).name.clone().unwrap_or_else(Name::missing).to_string() - } + DefWithBodyId::StaticId(it) => db.static_data(it).name.clone().to_string(), DefWithBodyId::ConstId(it) => { db.const_data(it).name.clone().unwrap_or_else(Name::missing).to_string() } diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs index 6fbb9c93b49..4f4a92447ff 100644 --- a/crates/hir_ty/src/diagnostics/decl_check.rs +++ b/crates/hir_ty/src/diagnostics/decl_check.rs @@ -581,10 +581,7 @@ impl<'a> DeclValidator<'a> { return; } - let name = match &data.name { - Some(name) => name, - None => return, - }; + let name = &data.name; let static_name = name.to_string(); let replacement = if let Some(new_name) = to_upper_snake_case(&static_name) { diff --git a/crates/ide/src/call_hierarchy.rs b/crates/ide/src/call_hierarchy.rs index 7268478191c..23bffd56489 100644 --- a/crates/ide/src/call_hierarchy.rs +++ b/crates/ide/src/call_hierarchy.rs @@ -47,15 +47,11 @@ pub(crate) fn incoming_calls( .find_nodes_at_offset_with_descend(file, offset) .filter_map(move |node| match node { ast::NameLike::NameRef(name_ref) => match NameRefClass::classify(sema, &name_ref)? { - NameRefClass::Definition( - def @ Definition::ModuleDef(hir::ModuleDef::Function(_)), - ) => Some(def), + NameRefClass::Definition(def @ Definition::Function(_)) => Some(def), _ => None, }, ast::NameLike::Name(name) => match NameClass::classify(sema, &name)? { - NameClass::Definition(def @ Definition::ModuleDef(hir::ModuleDef::Function(_))) => { - Some(def) - } + NameClass::Definition(def @ Definition::Function(_)) => Some(def), _ => None, }, ast::NameLike::Lifetime(_) => None, diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index b21998e0d22..3121cdd4a23 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs @@ -196,13 +196,21 @@ impl ToNav for FileSymbol { impl TryToNav for Definition { fn try_to_nav(&self, db: &RootDatabase) -> Option { match self { + Definition::Local(it) => Some(it.to_nav(db)), + Definition::Label(it) => Some(it.to_nav(db)), + Definition::Module(it) => Some(it.to_nav(db)), Definition::Macro(it) => it.try_to_nav(db), Definition::Field(it) => it.try_to_nav(db), - Definition::ModuleDef(it) => it.try_to_nav(db), Definition::SelfType(it) => it.try_to_nav(db), - Definition::Local(it) => Some(it.to_nav(db)), Definition::GenericParam(it) => it.try_to_nav(db), - Definition::Label(it) => Some(it.to_nav(db)), + Definition::Function(it) => it.try_to_nav(db), + Definition::Adt(it) => it.try_to_nav(db), + Definition::Variant(it) => it.try_to_nav(db), + Definition::Const(it) => it.try_to_nav(db), + Definition::Static(it) => it.try_to_nav(db), + Definition::Trait(it) => it.try_to_nav(db), + Definition::TypeAlias(it) => it.try_to_nav(db), + Definition::BuiltinType(_) => None, } } } diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index 703449fe404..075c9172257 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs @@ -8,10 +8,7 @@ use pulldown_cmark_to_cmark::{cmark_with_options, Options as CMarkOptions}; use stdx::format_to; use url::Url; -use hir::{ - db::HirDatabase, Adt, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasAttrs, MacroDef, - ModuleDef, -}; +use hir::{db::HirDatabase, Adt, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasAttrs}; use ide_db::{ defs::{Definition, NameClass, NameRefClass}, helpers::pick_best_token, @@ -53,10 +50,8 @@ pub(crate) fn rewrite_links(db: &RootDatabase, markdown: &str, definition: Defin if let Some(rewritten) = rewrite_intra_doc_link(db, definition, target, title) { return rewritten; } - if let Definition::ModuleDef(def) = definition { - if let Some(target) = rewrite_url_link(db, Either::Left(def), target) { - return (target, title.to_string()); - } + if let Some(target) = rewrite_url_link(db, definition, target) { + return (target, title.to_string()); } (target.to_string(), title.to_string()) @@ -174,25 +169,27 @@ pub(crate) fn resolve_doc_path_for_def( def: Definition, link: &str, ns: Option, -) -> Option> { - match def { - Definition::ModuleDef(def) => match def { - hir::ModuleDef::Module(it) => it.resolve_doc_path(db, link, ns), - hir::ModuleDef::Function(it) => it.resolve_doc_path(db, link, ns), - hir::ModuleDef::Adt(it) => it.resolve_doc_path(db, link, ns), - hir::ModuleDef::Variant(it) => it.resolve_doc_path(db, link, ns), - hir::ModuleDef::Const(it) => it.resolve_doc_path(db, link, ns), - hir::ModuleDef::Static(it) => it.resolve_doc_path(db, link, ns), - hir::ModuleDef::Trait(it) => it.resolve_doc_path(db, link, ns), - hir::ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, link, ns), - hir::ModuleDef::BuiltinType(_) => None, - }, +) -> Option { + let def = match def { + Definition::Module(it) => it.resolve_doc_path(db, link, ns), + Definition::Function(it) => it.resolve_doc_path(db, link, ns), + Definition::Adt(it) => it.resolve_doc_path(db, link, ns), + Definition::Variant(it) => it.resolve_doc_path(db, link, ns), + Definition::Const(it) => it.resolve_doc_path(db, link, ns), + Definition::Static(it) => it.resolve_doc_path(db, link, ns), + Definition::Trait(it) => it.resolve_doc_path(db, link, ns), + Definition::TypeAlias(it) => it.resolve_doc_path(db, link, ns), Definition::Macro(it) => it.resolve_doc_path(db, link, ns), Definition::Field(it) => it.resolve_doc_path(db, link, ns), - Definition::SelfType(_) + Definition::BuiltinType(_) + | Definition::SelfType(_) | Definition::Local(_) | Definition::GenericParam(_) | Definition::Label(_) => None, + }?; + match def { + Either::Left(def) => Some(Definition::from(def)), + Either::Right(def) => Some(Definition::Macro(def)), } } @@ -202,17 +199,17 @@ pub(crate) fn doc_attributes( ) -> Option<(hir::AttrsWithOwner, Definition)> { match_ast! { match node { - ast::SourceFile(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Module(def)))), - ast::Module(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Module(def)))), - ast::Fn(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Function(def)))), - ast::Struct(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Struct(def))))), - ast::Union(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Union(def))))), - ast::Enum(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(def))))), - ast::Variant(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Variant(def)))), - ast::Trait(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Trait(def)))), - ast::Static(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Static(def)))), - ast::Const(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Const(def)))), - ast::TypeAlias(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::TypeAlias(def)))), + ast::SourceFile(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Module(def))), + ast::Module(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Module(def))), + ast::Fn(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Function(def))), + ast::Struct(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Adt(hir::Adt::Struct(def)))), + ast::Union(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Adt(hir::Adt::Union(def)))), + ast::Enum(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Adt(hir::Adt::Enum(def)))), + ast::Variant(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Variant(def))), + ast::Trait(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Trait(def))), + ast::Static(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Static(def))), + ast::Const(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Const(def))), + ast::TypeAlias(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::TypeAlias(def))), ast::Impl(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::SelfType(def))), ast::RecordField(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Field(def))), ast::TupleField(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Field(def))), @@ -274,10 +271,7 @@ impl DocCommentToken { let in_expansion_relative_range = in_expansion_range - descended_prefix_len - token_start; // Apply relative range to the original input comment let absolute_range = in_expansion_relative_range + original_start + prefix_len; - let def = match resolve_doc_path_for_def(sema.db, def, &link, ns)? { - Either::Left(it) => Definition::ModuleDef(it), - Either::Right(it) => Definition::Macro(it), - }; + let def = resolve_doc_path_for_def(sema.db, def, &link, ns)?; cb(def, node, absolute_range) }) } @@ -299,33 +293,8 @@ fn broken_link_clone_cb<'a, 'b>(link: BrokenLink<'a>) -> Option<(CowStr<'b>, Cow // // This should cease to be a problem if RFC2988 (Stable Rustdoc URLs) is implemented // https://github.com/rust-lang/rfcs/pull/2988 -fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option { - let (target, frag) = match definition { - Definition::ModuleDef(def) => { - if let Some(assoc_item) = def.as_assoc_item(db) { - let def = match assoc_item.container(db) { - AssocItemContainer::Trait(t) => t.into(), - AssocItemContainer::Impl(i) => i.self_ty(db).as_adt()?.into(), - }; - let frag = get_assoc_item_fragment(db, assoc_item)?; - (Either::Left(def), Some(frag)) - } else { - (Either::Left(def), None) - } - } - Definition::Field(field) => { - let def = match field.parent_def(db) { - hir::VariantDef::Struct(it) => it.into(), - hir::VariantDef::Union(it) => it.into(), - hir::VariantDef::Variant(it) => it.into(), - }; - (Either::Left(def), Some(format!("structfield.{}", field.name(db)))) - } - Definition::Macro(makro) => (Either::Right(makro), None), - // FIXME impls - Definition::SelfType(_) => return None, - Definition::Local(_) | Definition::GenericParam(_) | Definition::Label(_) => return None, - }; +fn get_doc_link(db: &RootDatabase, def: Definition) -> Option { + let (target, file, frag) = filename_and_frag_for_def(db, def)?; let krate = crate_of_def(db, target)?; let mut url = get_doc_base_url(db, &krate)?; @@ -334,7 +303,7 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option { url = url.join(&path).ok()?; } - url = url.join(&get_symbol_filename(db, target)?).ok()?; + url = url.join(&file).ok()?; url.set_fragment(frag.as_deref()); Some(url.into()) @@ -352,73 +321,51 @@ fn rewrite_intra_doc_link( let krate = crate_of_def(db, resolved)?; let mut url = get_doc_base_url(db, &krate)?; + let (_, file, frag) = filename_and_frag_for_def(db, resolved)?; if let Some(path) = mod_path_of_def(db, resolved) { url = url.join(&path).ok()?; } - let (resolved, frag) = - if let Some(assoc_item) = resolved.left().and_then(|it| it.as_assoc_item(db)) { - let resolved = match assoc_item.container(db) { - AssocItemContainer::Trait(t) => t.into(), - AssocItemContainer::Impl(i) => i.self_ty(db).as_adt()?.into(), - }; - let frag = get_assoc_item_fragment(db, assoc_item)?; - (Either::Left(resolved), Some(frag)) - } else { - (resolved, None) - }; - url = url.join(&get_symbol_filename(db, resolved)?).ok()?; + url = url.join(&file).ok()?; url.set_fragment(frag.as_deref()); Some((url.into(), strip_prefixes_suffixes(title).to_string())) } /// Try to resolve path to local documentation via path-based links (i.e. `../gateway/struct.Shard.html`). -fn rewrite_url_link( - db: &RootDatabase, - def: Either, - target: &str, -) -> Option { +fn rewrite_url_link(db: &RootDatabase, def: Definition, target: &str) -> Option { if !(target.contains('#') || target.contains(".html")) { return None; } let krate = crate_of_def(db, def)?; let mut url = get_doc_base_url(db, &krate)?; + let (def, file, frag) = filename_and_frag_for_def(db, def)?; if let Some(path) = mod_path_of_def(db, def) { url = url.join(&path).ok()?; } - url = url.join(&get_symbol_filename(db, def)?).ok()?; + url = url.join(&file).ok()?; + url.set_fragment(frag.as_deref()); url.join(target).ok().map(Into::into) } -fn crate_of_def(db: &RootDatabase, def: Either) -> Option { +fn crate_of_def(db: &RootDatabase, def: Definition) -> Option { let krate = match def { // Definition::module gives back the parent module, we don't want that as it fails for root modules - Either::Left(ModuleDef::Module(module)) => module.krate(), - Either::Left(def) => def.module(db)?.krate(), - Either::Right(def) => def.module(db)?.krate(), + Definition::Module(module) => module.krate(), + def => def.module(db)?.krate(), }; Some(krate) } -fn mod_path_of_def(db: &RootDatabase, def: Either) -> Option { - match def { - Either::Left(def) => def.canonical_module_path(db).map(|it| { - let mut path = String::new(); - it.flat_map(|it| it.name(db)).for_each(|name| format_to!(path, "{}/", name)); - path - }), - Either::Right(def) => { - def.module(db).map(|it| it.path_to_root(db).into_iter().rev()).map(|it| { - let mut path = String::new(); - it.flat_map(|it| it.name(db)).for_each(|name| format_to!(path, "{}/", name)); - path - }) - } - } +fn mod_path_of_def(db: &RootDatabase, def: Definition) -> Option { + def.canonical_module_path(db).map(|it| { + let mut path = String::new(); + it.flat_map(|it| it.name(db)).for_each(|name| format_to!(path, "{}/", name)); + path + }) } /// Rewrites a markdown document, applying 'callback' to each link. @@ -496,34 +443,61 @@ fn get_doc_base_url(db: &RootDatabase, krate: &Crate) -> Option { /// https://doc.rust-lang.org/std/iter/trait.Iterator.html#tymethod.next /// ^^^^^^^^^^^^^^^^^^^ /// ``` -fn get_symbol_filename( +fn filename_and_frag_for_def( db: &dyn HirDatabase, - definition: Either, -) -> Option { - let res = match definition { - Either::Left(definition) => match definition { - ModuleDef::Adt(adt) => match adt { - Adt::Struct(s) => format!("struct.{}.html", s.name(db)), - Adt::Enum(e) => format!("enum.{}.html", e.name(db)), - Adt::Union(u) => format!("union.{}.html", u.name(db)), - }, - ModuleDef::Module(m) => match m.name(db) { - Some(name) => format!("{}/index.html", name), - None => String::from("index.html"), - }, - ModuleDef::Trait(t) => format!("trait.{}.html", t.name(db)), - ModuleDef::TypeAlias(t) => format!("type.{}.html", t.name(db)), - ModuleDef::BuiltinType(t) => format!("primitive.{}.html", t.name()), - ModuleDef::Function(f) => format!("fn.{}.html", f.name(db)), - ModuleDef::Variant(ev) => { - format!("enum.{}.html#variant.{}", ev.parent_enum(db).name(db), ev.name(db)) - } - ModuleDef::Const(c) => format!("const.{}.html", c.name(db)?), - ModuleDef::Static(s) => format!("static.{}.html", s.name(db)?), + def: Definition, +) -> Option<(Definition, String, Option)> { + if let Some(assoc_item) = def.as_assoc_item(db) { + let def = match assoc_item.container(db) { + AssocItemContainer::Trait(t) => t.into(), + AssocItemContainer::Impl(i) => i.self_ty(db).as_adt()?.into(), + }; + let (_, file, _) = filename_and_frag_for_def(db, def)?; + let frag = get_assoc_item_fragment(db, assoc_item)?; + return Some((def, file, Some(frag))); + } + + let res = match def { + Definition::Adt(adt) => match adt { + Adt::Struct(s) => format!("struct.{}.html", s.name(db)), + Adt::Enum(e) => format!("enum.{}.html", e.name(db)), + Adt::Union(u) => format!("union.{}.html", u.name(db)), }, - Either::Right(mac) => format!("macro.{}.html", mac.name(db)?), + Definition::Module(m) => match m.name(db) { + Some(name) => format!("{}/index.html", name), + None => String::from("index.html"), + }, + Definition::Trait(t) => format!("trait.{}.html", t.name(db)), + Definition::TypeAlias(t) => format!("type.{}.html", t.name(db)), + Definition::BuiltinType(t) => format!("primitive.{}.html", t.name()), + Definition::Function(f) => format!("fn.{}.html", f.name(db)), + Definition::Variant(ev) => { + format!("enum.{}.html#variant.{}", ev.parent_enum(db).name(db), ev.name(db)) + } + Definition::Const(c) => format!("const.{}.html", c.name(db)?), + Definition::Static(s) => format!("static.{}.html", s.name(db)), + Definition::Macro(mac) => format!("macro.{}.html", mac.name(db)?), + Definition::Field(field) => { + let def = match field.parent_def(db) { + hir::VariantDef::Struct(it) => Definition::Adt(it.into()), + hir::VariantDef::Union(it) => Definition::Adt(it.into()), + hir::VariantDef::Variant(it) => Definition::Variant(it), + }; + let (_, file, _) = filename_and_frag_for_def(db, def)?; + return Some((def, file, Some(format!("structfield.{}", field.name(db))))); + } + Definition::SelfType(impl_) => { + let adt = impl_.self_ty(db).as_adt()?.into(); + let (_, file, _) = filename_and_frag_for_def(db, adt)?; + // FIXME fragment numbering + return Some((adt, file, Some(String::from("impl")))); + } + Definition::Local(_) => return None, + Definition::GenericParam(_) => return None, + Definition::Label(_) => return None, }; - Some(res) + + Some((def, res, None)) } /// Get the fragment required to link to a specific field, method, associated type, or associated constant. @@ -803,8 +777,6 @@ pub struct B$0ar #[test] fn rewrite_on_field() { - // FIXME: Should be - // [Foo](https://docs.rs/test/*/test/struct.Foo.html) check_rewrite( r#" //- /main.rs crate:foo @@ -813,7 +785,7 @@ pub struct Foo { fie$0ld: () } "#, - expect![[r#"[Foo](struct.Foo.html)"#]], + expect![[r#"[Foo](https://docs.rs/foo/*/foo/struct.Foo.html)"#]], ); } @@ -927,17 +899,17 @@ pub struct $0Foo; ) -> Option, Definition)>> { Some(match_ast! { match node { - ast::SourceFile(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Module(def)))), - ast::Module(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Module(def)))), - ast::Fn(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Function(def)))), - ast::Struct(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Struct(def))))), - ast::Union(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Union(def))))), - ast::Enum(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(def))))), - ast::Variant(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Variant(def)))), - ast::Trait(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Trait(def)))), - ast::Static(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Static(def)))), - ast::Const(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Const(def)))), - ast::TypeAlias(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::TypeAlias(def)))), + ast::SourceFile(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Module(def))), + ast::Module(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Module(def))), + ast::Fn(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Function(def))), + ast::Struct(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Adt(hir::Adt::Struct(def)))), + ast::Union(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Adt(hir::Adt::Union(def)))), + ast::Enum(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Adt(hir::Adt::Enum(def)))), + ast::Variant(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Variant(def))), + ast::Trait(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Trait(def))), + ast::Static(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Static(def))), + ast::Const(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Const(def))), + ast::TypeAlias(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::TypeAlias(def))), ast::Impl(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::SelfType(def))), ast::RecordField(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Field(def))), ast::TupleField(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Field(def))), diff --git a/crates/ide/src/goto_declaration.rs b/crates/ide/src/goto_declaration.rs index c79015c7160..e62daf03f98 100644 --- a/crates/ide/src/goto_declaration.rs +++ b/crates/ide/src/goto_declaration.rs @@ -39,7 +39,7 @@ pub(crate) fn goto_declaration( } }; match def? { - Definition::ModuleDef(hir::ModuleDef::Module(module)) => { + Definition::Module(module) => { Some(NavigationTarget::from_module_to_decl(db, module)) } _ => None, diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 1edb17739b5..77f90eee194 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use crate::{ display::TryToNav, doc_links::token_as_doc_comment, FilePosition, NavigationTarget, RangeInfo, }; -use hir::{AsAssocItem, ModuleDef, Semantics}; +use hir::{AsAssocItem, Semantics}; use ide_db::{ base_db::{AnchoredPath, FileId, FileLoader}, defs::Definition, @@ -110,12 +110,7 @@ fn try_find_trait_item_definition( def: &Definition, ) -> Option> { let name = def.name(db)?; - let assoc = match def { - Definition::ModuleDef(ModuleDef::Function(f)) => f.as_assoc_item(db), - Definition::ModuleDef(ModuleDef::Const(c)) => c.as_assoc_item(db), - Definition::ModuleDef(ModuleDef::TypeAlias(ty)) => ty.as_assoc_item(db), - _ => None, - }?; + let assoc = def.as_assoc_item(db)?; let imp = match assoc.container(db) { hir::AssocItemContainer::Impl(imp) => imp, diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs index 9b0e42d8cff..c9c7e232f29 100644 --- a/crates/ide/src/goto_implementation.rs +++ b/crates/ide/src/goto_implementation.rs @@ -34,63 +34,57 @@ pub(crate) fn goto_implementation( _ => 0, })?; let range = original_token.text_range(); - let navs = - sema.descend_into_macros(original_token) - .into_iter() - .filter_map(|token| token.parent().and_then(ast::NameLike::cast)) - .filter_map(|node| { - let def = match &node { - ast::NameLike::Name(name) => { - NameClass::classify(&sema, name).map(|class| match class { - NameClass::Definition(it) | NameClass::ConstReference(it) => it, - NameClass::PatFieldShorthand { local_def, field_ref: _ } => { - Definition::Local(local_def) - } - }) + let navs = sema + .descend_into_macros(original_token) + .into_iter() + .filter_map(|token| token.parent().and_then(ast::NameLike::cast)) + .filter_map(|node| match &node { + ast::NameLike::Name(name) => { + NameClass::classify(&sema, name).map(|class| match class { + NameClass::Definition(it) | NameClass::ConstReference(it) => it, + NameClass::PatFieldShorthand { local_def, field_ref: _ } => { + Definition::Local(local_def) } - ast::NameLike::NameRef(name_ref) => NameRefClass::classify(&sema, name_ref) - .map(|class| match class { - NameRefClass::Definition(def) => def, - NameRefClass::FieldShorthand { local_ref, field_ref: _ } => { - Definition::Local(local_ref) - } - }), - ast::NameLike::Lifetime(_) => None, - }?; - - match def { - Definition::ModuleDef(def) => Some(def), - _ => None, + }) + } + ast::NameLike::NameRef(name_ref) => { + NameRefClass::classify(&sema, name_ref).map(|class| match class { + NameRefClass::Definition(def) => def, + NameRefClass::FieldShorthand { local_ref, field_ref: _ } => { + Definition::Local(local_ref) + } + }) + } + ast::NameLike::Lifetime(_) => None, + }) + .unique() + .filter_map(|def| { + let navs = match def { + Definition::Trait(trait_) => impls_for_trait(&sema, trait_), + Definition::Adt(adt) => impls_for_ty(&sema, adt.ty(sema.db)), + Definition::TypeAlias(alias) => impls_for_ty(&sema, alias.ty(sema.db)), + Definition::BuiltinType(builtin) => { + let module = sema.to_module_def(position.file_id)?; + impls_for_ty(&sema, builtin.ty(sema.db, module)) } - }) - .unique() - .filter_map(|def| { - let navs = match def { - hir::ModuleDef::Trait(trait_) => impls_for_trait(&sema, trait_), - hir::ModuleDef::Adt(adt) => impls_for_ty(&sema, adt.ty(sema.db)), - hir::ModuleDef::TypeAlias(alias) => impls_for_ty(&sema, alias.ty(sema.db)), - hir::ModuleDef::BuiltinType(builtin) => { - let module = sema.to_module_def(position.file_id)?; - impls_for_ty(&sema, builtin.ty(sema.db, module)) - } - hir::ModuleDef::Function(f) => { - let assoc = f.as_assoc_item(sema.db)?; - let name = assoc.name(sema.db)?; - let trait_ = assoc.containing_trait_or_trait_impl(sema.db)?; - impls_for_trait_item(&sema, trait_, name) - } - hir::ModuleDef::Const(c) => { - let assoc = c.as_assoc_item(sema.db)?; - let name = assoc.name(sema.db)?; - let trait_ = assoc.containing_trait_or_trait_impl(sema.db)?; - impls_for_trait_item(&sema, trait_, name) - } - _ => return None, - }; - Some(navs) - }) - .flatten() - .collect(); + Definition::Function(f) => { + let assoc = f.as_assoc_item(sema.db)?; + let name = assoc.name(sema.db)?; + let trait_ = assoc.containing_trait_or_trait_impl(sema.db)?; + impls_for_trait_item(&sema, trait_, name) + } + Definition::Const(c) => { + let assoc = c.as_assoc_item(sema.db)?; + let name = assoc.name(sema.db)?; + let trait_ = assoc.containing_trait_or_trait_impl(sema.db)?; + impls_for_trait_item(&sema, trait_, name) + } + _ => return None, + }; + Some(navs) + }) + .flatten() + .collect(); Some(RangeInfo { range, info: navs }) } diff --git a/crates/ide/src/goto_type_definition.rs b/crates/ide/src/goto_type_definition.rs index 693098e3f29..ce58f72a775 100644 --- a/crates/ide/src/goto_type_definition.rs +++ b/crates/ide/src/goto_type_definition.rs @@ -1,4 +1,4 @@ -use ide_db::{base_db::Upcast, helpers::pick_best_token, RootDatabase}; +use ide_db::{base_db::Upcast, defs::Definition, helpers::pick_best_token, RootDatabase}; use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, T}; use crate::{display::TryToNav, FilePosition, NavigationTarget, RangeInfo}; @@ -29,7 +29,7 @@ pub(crate) fn goto_type_definition( })?; let mut res = Vec::new(); - let mut push = |def: hir::ModuleDef| { + let mut push = |def: Definition| { if let Some(nav) = def.try_to_nav(db) { if !res.contains(&nav) { res.push(nav); diff --git a/crates/ide/src/highlight_related.rs b/crates/ide/src/highlight_related.rs index e452f8c9386..5ff6fd10bc8 100644 --- a/crates/ide/src/highlight_related.rs +++ b/crates/ide/src/highlight_related.rs @@ -97,7 +97,7 @@ fn highlight_references( let declarations = defs.iter().flat_map(|def| { match def { - &Definition::ModuleDef(hir::ModuleDef::Module(module)) => { + &Definition::Module(module) => { Some(NavigationTarget::from_module_to_decl(sema.db, module)) } def => def.try_to_nav(sema.db), diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index d4244628787..f4fb52647e7 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -163,9 +163,7 @@ pub(crate) fn hover_for_definition( config: &HoverConfig, ) -> Option { let famous_defs = match &definition { - Definition::ModuleDef(hir::ModuleDef::BuiltinType(_)) => { - Some(FamousDefs(sema, sema.scope(node).krate())) - } + Definition::BuiltinType(_) => Some(FamousDefs(sema, sema.scope(node).krate())), _ => None, }; if let Some(markup) = render::definition(sema.db, definition, famous_defs.as_ref(), config) { @@ -260,10 +258,8 @@ fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option { - return it.try_to_nav(db).map(to_action) - } - Definition::ModuleDef(hir::ModuleDef::Adt(it)) => Some(it), + Definition::Trait(it) => return it.try_to_nav(db).map(to_action), + Definition::Adt(it) => Some(it), Definition::SelfType(it) => it.self_ty(db).as_adt(), _ => None, }?; @@ -272,14 +268,12 @@ fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option Option { match def { - Definition::ModuleDef(hir::ModuleDef::Function(it)) => { - it.try_to_nav(db).map(|nav_target| { - HoverAction::Reference(FilePosition { - file_id: nav_target.file_id, - offset: nav_target.focus_or_full_range().start(), - }) + Definition::Function(it) => it.try_to_nav(db).map(|nav_target| { + HoverAction::Reference(FilePosition { + file_id: nav_target.file_id, + offset: nav_target.focus_or_full_range().start(), }) - } + }), _ => None, } } @@ -290,20 +284,17 @@ fn runnable_action( file_id: FileId, ) -> Option { match def { - Definition::ModuleDef(it) => match it { - hir::ModuleDef::Module(it) => runnable_mod(sema, it).map(HoverAction::Runnable), - hir::ModuleDef::Function(func) => { - let src = func.source(sema.db)?; - if src.file_id != file_id.into() { - cov_mark::hit!(hover_macro_generated_struct_fn_doc_comment); - cov_mark::hit!(hover_macro_generated_struct_fn_doc_attr); - return None; - } - - runnable_fn(sema, func).map(HoverAction::Runnable) + Definition::Module(it) => runnable_mod(sema, it).map(HoverAction::Runnable), + Definition::Function(func) => { + let src = func.source(sema.db)?; + if src.file_id != file_id.into() { + cov_mark::hit!(hover_macro_generated_struct_fn_doc_comment); + cov_mark::hit!(hover_macro_generated_struct_fn_doc_attr); + return None; } - _ => None, - }, + + runnable_fn(sema, func).map(HoverAction::Runnable) + } _ => None, } } diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index 7f9a91286a4..59068028ed9 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -242,7 +242,7 @@ pub(super) fn keyword( let docs = doc_owner.attrs(sema.db).docs()?; let markup = process_markup( sema.db, - Definition::ModuleDef(doc_owner.into()), + Definition::Module(doc_owner), &markup(Some(docs.into()), token.text().into(), None)?, config, ); @@ -311,14 +311,11 @@ fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option match def { Definition::Field(f) => Some(f.parent_def(db).name(db)), Definition::Local(l) => l.parent(db).name(db), - Definition::ModuleDef(md) => match md { - hir::ModuleDef::Function(f) => match f.as_assoc_item(db)?.container(db) { - hir::AssocItemContainer::Trait(t) => Some(t.name(db)), - hir::AssocItemContainer::Impl(i) => i.self_ty(db).as_adt().map(|adt| adt.name(db)), - }, - hir::ModuleDef::Variant(e) => Some(e.parent_enum(db).name(db)), - _ => None, + Definition::Function(f) => match f.as_assoc_item(db)?.container(db) { + hir::AssocItemContainer::Trait(t) => Some(t.name(db)), + hir::AssocItemContainer::Impl(i) => i.self_ty(db).as_adt().map(|adt| adt.name(db)), }, + Definition::Variant(e) => Some(e.parent_enum(db).name(db)), _ => None, } .map(|name| name.to_string()) @@ -351,21 +348,19 @@ pub(super) fn definition( it.attrs(db).docs(), ), Definition::Field(def) => label_and_docs(db, def), - Definition::ModuleDef(it) => match it { - hir::ModuleDef::Module(it) => label_and_docs(db, it), - hir::ModuleDef::Function(it) => label_and_docs(db, it), - hir::ModuleDef::Adt(it) => label_and_docs(db, it), - hir::ModuleDef::Variant(it) => label_and_docs(db, it), - hir::ModuleDef::Const(it) => label_and_docs(db, it), - hir::ModuleDef::Static(it) => label_and_docs(db, it), - hir::ModuleDef::Trait(it) => label_and_docs(db, it), - hir::ModuleDef::TypeAlias(it) => label_and_docs(db, it), - hir::ModuleDef::BuiltinType(it) => { - return famous_defs - .and_then(|fd| builtin(fd, it)) - .or_else(|| Some(Markup::fenced_block(&it.name()))) - } - }, + Definition::Module(it) => label_and_docs(db, it), + Definition::Function(it) => label_and_docs(db, it), + Definition::Adt(it) => label_and_docs(db, it), + Definition::Variant(it) => label_and_docs(db, it), + Definition::Const(it) => label_and_docs(db, it), + Definition::Static(it) => label_and_docs(db, it), + Definition::Trait(it) => label_and_docs(db, it), + Definition::TypeAlias(it) => label_and_docs(db, it), + Definition::BuiltinType(it) => { + return famous_defs + .and_then(|fd| builtin(fd, it)) + .or_else(|| Some(Markup::fenced_block(&it.name()))) + } Definition::Local(it) => return local(db, it), Definition::SelfType(impl_def) => { impl_def.self_ty(db).as_adt().map(|adt| label_and_docs(db, adt))? diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index fd36cfc44de..d1219044fe5 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs @@ -80,7 +80,7 @@ pub(crate) fn find_all_refs( let mut usages = def.usages(sema).set_scope(search_scope.clone()).include_self_refs().all(); let declaration = match def { - Definition::ModuleDef(hir::ModuleDef::Module(module)) => { + Definition::Module(module) => { Some(NavigationTarget::from_module_to_decl(sema.db, module)) } def => def.try_to_nav(sema.db), @@ -168,7 +168,7 @@ fn retain_adt_literal_usages( ) { let refs = usages.references.values_mut(); match def { - Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(enum_))) => { + Definition::Adt(hir::Adt::Enum(enum_)) => { refs.for_each(|it| { it.retain(|reference| { reference @@ -179,7 +179,7 @@ fn retain_adt_literal_usages( }); usages.references.retain(|_, it| !it.is_empty()); } - Definition::ModuleDef(hir::ModuleDef::Adt(_) | hir::ModuleDef::Variant(_)) => { + Definition::Adt(_) | Definition::Variant(_) => { refs.for_each(|it| { it.retain(|reference| reference.name.as_name_ref().map_or(false, is_lit_name_ref)) }); diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index a7ebba82b03..f9f9c0832cd 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -113,7 +113,7 @@ pub(crate) fn will_rename_file( ) -> Option { let sema = Semantics::new(db); let module = sema.to_module_def(file_id)?; - let def = Definition::ModuleDef(module.into()); + let def = Definition::Module(module); let mut change = def.rename(&sema, new_name_stem).ok()?; change.file_system_edits.clear(); Some(change) diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 2bf83da4dfa..d63b0c87a90 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -246,7 +246,7 @@ fn node( fn highlight_name_ref_in_attr(sema: &Semantics, name_ref: ast::NameRef) -> Highlight { match NameRefClass::classify(sema, &name_ref) { Some(name_class) => match name_class { - NameRefClass::Definition(Definition::ModuleDef(hir::ModuleDef::Module(_))) + NameRefClass::Definition(Definition::Module(_)) if name_ref .syntax() .ancestors() @@ -302,9 +302,7 @@ fn highlight_name_ref( { h |= HlMod::Consuming; } - Definition::ModuleDef(hir::ModuleDef::Trait(trait_)) - if trait_.is_unsafe(db) => - { + Definition::Trait(trait_) if trait_.is_unsafe(db) => { if ast::Impl::for_trait_name_ref(&name_ref) .map_or(false, |impl_| impl_.unsafe_token().is_some()) { @@ -358,7 +356,7 @@ fn highlight_name( match name_kind { Some(NameClass::Definition(def)) => { let mut h = highlight_def(sema, krate, def) | HlMod::Definition; - if let Definition::ModuleDef(hir::ModuleDef::Trait(trait_)) = &def { + if let Definition::Trait(trait_) = &def { if trait_.is_unsafe(db) { h |= HlMod::Unsafe; } @@ -398,112 +396,110 @@ fn highlight_def( let mut h = match def { Definition::Macro(_) => Highlight::new(HlTag::Symbol(SymbolKind::Macro)), Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)), - Definition::ModuleDef(def) => match def { - hir::ModuleDef::Module(module) => { - let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module)); - if module.parent(db).is_none() { - h |= HlMod::CrateRoot - } - h + Definition::Module(module) => { + let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module)); + if module.parent(db).is_none() { + h |= HlMod::CrateRoot } - hir::ModuleDef::Function(func) => { - let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function)); - if let Some(item) = func.as_assoc_item(db) { - h |= HlMod::Associated; - match func.self_param(db) { - Some(sp) => match sp.access(db) { - hir::Access::Exclusive => { - h |= HlMod::Mutable; - h |= HlMod::Reference; - } - hir::Access::Shared => h |= HlMod::Reference, - hir::Access::Owned => h |= HlMod::Consuming, - }, - None => h |= HlMod::Static, - } - - match item.container(db) { - hir::AssocItemContainer::Impl(i) => { - if i.trait_(db).is_some() { - h |= HlMod::Trait; - } + h + } + Definition::Function(func) => { + let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function)); + if let Some(item) = func.as_assoc_item(db) { + h |= HlMod::Associated; + match func.self_param(db) { + Some(sp) => match sp.access(db) { + hir::Access::Exclusive => { + h |= HlMod::Mutable; + h |= HlMod::Reference; } - hir::AssocItemContainer::Trait(_t) => { + hir::Access::Shared => h |= HlMod::Reference, + hir::Access::Owned => h |= HlMod::Consuming, + }, + None => h |= HlMod::Static, + } + + match item.container(db) { + hir::AssocItemContainer::Impl(i) => { + if i.trait_(db).is_some() { h |= HlMod::Trait; } } + hir::AssocItemContainer::Trait(_t) => { + h |= HlMod::Trait; + } } - - if func.is_unsafe(db) { - h |= HlMod::Unsafe; - } - if func.is_async(db) { - h |= HlMod::Async; - } - - h } - hir::ModuleDef::Adt(adt) => { - let h = match adt { - hir::Adt::Struct(_) => HlTag::Symbol(SymbolKind::Struct), - hir::Adt::Enum(_) => HlTag::Symbol(SymbolKind::Enum), - hir::Adt::Union(_) => HlTag::Symbol(SymbolKind::Union), - }; - Highlight::new(h) + if func.is_unsafe(db) { + h |= HlMod::Unsafe; + } + if func.is_async(db) { + h |= HlMod::Async; } - hir::ModuleDef::Variant(_) => Highlight::new(HlTag::Symbol(SymbolKind::Variant)), - hir::ModuleDef::Const(konst) => { - let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const)); - if let Some(item) = konst.as_assoc_item(db) { - h |= HlMod::Associated; - match item.container(db) { - hir::AssocItemContainer::Impl(i) => { - if i.trait_(db).is_some() { - h |= HlMod::Trait; - } - } - hir::AssocItemContainer::Trait(_t) => { + h + } + Definition::Adt(adt) => { + let h = match adt { + hir::Adt::Struct(_) => HlTag::Symbol(SymbolKind::Struct), + hir::Adt::Enum(_) => HlTag::Symbol(SymbolKind::Enum), + hir::Adt::Union(_) => HlTag::Symbol(SymbolKind::Union), + }; + + Highlight::new(h) + } + Definition::Variant(_) => Highlight::new(HlTag::Symbol(SymbolKind::Variant)), + Definition::Const(konst) => { + let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const)); + + if let Some(item) = konst.as_assoc_item(db) { + h |= HlMod::Associated; + match item.container(db) { + hir::AssocItemContainer::Impl(i) => { + if i.trait_(db).is_some() { h |= HlMod::Trait; } } + hir::AssocItemContainer::Trait(_t) => { + h |= HlMod::Trait; + } } - - h } - hir::ModuleDef::Trait(_) => Highlight::new(HlTag::Symbol(SymbolKind::Trait)), - hir::ModuleDef::TypeAlias(type_) => { - let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias)); - if let Some(item) = type_.as_assoc_item(db) { - h |= HlMod::Associated; - match item.container(db) { - hir::AssocItemContainer::Impl(i) => { - if i.trait_(db).is_some() { - h |= HlMod::Trait; - } - } - hir::AssocItemContainer::Trait(_t) => { + h + } + Definition::Trait(_) => Highlight::new(HlTag::Symbol(SymbolKind::Trait)), + Definition::TypeAlias(type_) => { + let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias)); + + if let Some(item) = type_.as_assoc_item(db) { + h |= HlMod::Associated; + match item.container(db) { + hir::AssocItemContainer::Impl(i) => { + if i.trait_(db).is_some() { h |= HlMod::Trait; } } + hir::AssocItemContainer::Trait(_t) => { + h |= HlMod::Trait; + } } - - h } - hir::ModuleDef::BuiltinType(_) => Highlight::new(HlTag::BuiltinType), - hir::ModuleDef::Static(s) => { - let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static)); - if s.is_mut(db) { - h |= HlMod::Mutable; - h |= HlMod::Unsafe; - } + h + } + Definition::BuiltinType(_) => Highlight::new(HlTag::BuiltinType), + Definition::Static(s) => { + let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static)); - h + if s.is_mut(db) { + h |= HlMod::Mutable; + h |= HlMod::Unsafe; } - }, + + h + } Definition::SelfType(_) => Highlight::new(HlTag::Symbol(SymbolKind::Impl)), Definition::GenericParam(it) => match it { hir::GenericParam::TypeParam(_) => Highlight::new(HlTag::Symbol(SymbolKind::TypeParam)), @@ -540,13 +536,13 @@ fn highlight_def( let famous_defs = FamousDefs(sema, krate); let def_crate = def.module(db).map(hir::Module::krate).or_else(|| match def { - Definition::ModuleDef(hir::ModuleDef::Module(module)) => Some(module.krate()), + Definition::Module(module) => Some(module.krate()), _ => None, }); let is_from_other_crate = def_crate != krate; let is_from_builtin_crate = def_crate.map_or(false, |def_crate| famous_defs.builtin_crates().any(|it| def_crate == it)); - let is_builtin_type = matches!(def, Definition::ModuleDef(hir::ModuleDef::BuiltinType(_))); + let is_builtin_type = matches!(def, Definition::BuiltinType(_)); let is_public = def.visibility(db) == Some(hir::Visibility::Public); match (is_from_other_crate, is_builtin_type, is_public) { diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs index 91587b11f53..b7a3fb62cb4 100644 --- a/crates/ide/src/syntax_highlighting/inject.rs +++ b/crates/ide/src/syntax_highlighting/inject.rs @@ -4,7 +4,9 @@ use std::mem; use either::Either; use hir::{InFile, Semantics}; -use ide_db::{call_info::ActiveParameter, helpers::rust_doc::is_rust_fence, SymbolKind}; +use ide_db::{ + call_info::ActiveParameter, defs::Definition, helpers::rust_doc::is_rust_fence, SymbolKind, +}; use syntax::{ ast::{self, AstNode, IsString}, AstToken, NodeOrToken, SyntaxNode, SyntaxToken, TextRange, TextSize, @@ -237,22 +239,29 @@ fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option) -> HlTag { +fn module_def_to_hl_tag(def: Definition) -> HlTag { let symbol = match def { - Either::Left(def) => match def { - hir::ModuleDef::Module(_) => SymbolKind::Module, - hir::ModuleDef::Function(_) => SymbolKind::Function, - hir::ModuleDef::Adt(hir::Adt::Struct(_)) => SymbolKind::Struct, - hir::ModuleDef::Adt(hir::Adt::Enum(_)) => SymbolKind::Enum, - hir::ModuleDef::Adt(hir::Adt::Union(_)) => SymbolKind::Union, - hir::ModuleDef::Variant(_) => SymbolKind::Variant, - hir::ModuleDef::Const(_) => SymbolKind::Const, - hir::ModuleDef::Static(_) => SymbolKind::Static, - hir::ModuleDef::Trait(_) => SymbolKind::Trait, - hir::ModuleDef::TypeAlias(_) => SymbolKind::TypeAlias, - hir::ModuleDef::BuiltinType(_) => return HlTag::BuiltinType, + Definition::Module(_) => SymbolKind::Module, + Definition::Function(_) => SymbolKind::Function, + Definition::Adt(hir::Adt::Struct(_)) => SymbolKind::Struct, + Definition::Adt(hir::Adt::Enum(_)) => SymbolKind::Enum, + Definition::Adt(hir::Adt::Union(_)) => SymbolKind::Union, + Definition::Variant(_) => SymbolKind::Variant, + Definition::Const(_) => SymbolKind::Const, + Definition::Static(_) => SymbolKind::Static, + Definition::Trait(_) => SymbolKind::Trait, + Definition::TypeAlias(_) => SymbolKind::TypeAlias, + Definition::BuiltinType(_) => return HlTag::BuiltinType, + Definition::Macro(_) => SymbolKind::Macro, + Definition::Field(_) => SymbolKind::Field, + Definition::SelfType(_) => SymbolKind::Impl, + Definition::Local(_) => SymbolKind::Local, + Definition::GenericParam(gp) => match gp { + hir::GenericParam::TypeParam(_) => SymbolKind::TypeParam, + hir::GenericParam::LifetimeParam(_) => SymbolKind::LifetimeParam, + hir::GenericParam::ConstParam(_) => SymbolKind::ConstParam, }, - Either::Right(_) => SymbolKind::Macro, + Definition::Label(_) => SymbolKind::Label, }; HlTag::Symbol(symbol) } diff --git a/crates/ide_assists/src/handlers/add_turbo_fish.rs b/crates/ide_assists/src/handlers/add_turbo_fish.rs index d08111a90da..64f9eb9586a 100644 --- a/crates/ide_assists/src/handlers/add_turbo_fish.rs +++ b/crates/ide_assists/src/handlers/add_turbo_fish.rs @@ -44,7 +44,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<( NameRefClass::FieldShorthand { .. } => return None, }; let fun = match def { - Definition::ModuleDef(hir::ModuleDef::Function(it)) => it, + Definition::Function(it) => it, _ => return None, }; let generics = hir::GenericDef::Function(fun).params(ctx.sema.db); diff --git a/crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs index 9ff4ab90c8f..8093ba2560c 100644 --- a/crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs +++ b/crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs @@ -127,8 +127,8 @@ fn edit_struct_references( names: &[ast::Name], ) { let strukt_def = match strukt { - Either::Left(s) => Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Struct(s))), - Either::Right(v) => Definition::ModuleDef(hir::ModuleDef::Variant(v)), + Either::Left(s) => Definition::Adt(hir::Adt::Struct(s)), + Either::Right(v) => Definition::Variant(v), }; let usages = strukt_def.usages(&ctx.sema).include_self_refs().all(); diff --git a/crates/ide_assists/src/handlers/expand_glob_import.rs b/crates/ide_assists/src/handlers/expand_glob_import.rs index 3abf06d5887..72c17b674c4 100644 --- a/crates/ide_assists/src/handlers/expand_glob_import.rs +++ b/crates/ide_assists/src/handlers/expand_glob_import.rs @@ -1,5 +1,5 @@ use either::Either; -use hir::{AssocItem, HasVisibility, MacroDef, Module, ModuleDef, Name, PathResolution, ScopeDef}; +use hir::{AssocItem, HasVisibility, Module, ModuleDef, Name, PathResolution, ScopeDef}; use ide_db::{ defs::{Definition, NameRefClass}, search::SearchScope, @@ -112,36 +112,27 @@ fn find_parent_and_path( } } -#[derive(Debug, PartialEq, Clone)] -enum Def { - ModuleDef(ModuleDef), - MacroDef(MacroDef), -} - -impl Def { - fn is_referenced_in(&self, ctx: &AssistContext) -> bool { - let def = match self { - Def::ModuleDef(def) => Definition::ModuleDef(*def), - Def::MacroDef(def) => Definition::Macro(*def), - }; - - let search_scope = SearchScope::single_file(ctx.file_id()); - def.usages(&ctx.sema).in_scope(search_scope).at_least_one() - } +fn def_is_referenced_in(def: Definition, ctx: &AssistContext) -> bool { + let search_scope = SearchScope::single_file(ctx.file_id()); + def.usages(&ctx.sema).in_scope(search_scope).at_least_one() } #[derive(Debug, Clone)] struct Ref { // could be alias visible_name: Name, - def: Def, + def: Definition, } impl Ref { fn from_scope_def(name: Name, scope_def: ScopeDef) -> Option { match scope_def { - ScopeDef::ModuleDef(def) => Some(Ref { visible_name: name, def: Def::ModuleDef(def) }), - ScopeDef::MacroDef(def) => Some(Ref { visible_name: name, def: Def::MacroDef(def) }), + ScopeDef::ModuleDef(def) => { + Some(Ref { visible_name: name, def: Definition::from(def) }) + } + ScopeDef::MacroDef(def) => { + Some(Ref { visible_name: name, def: Definition::Macro(def) }) + } _ => None, } } @@ -157,10 +148,10 @@ impl Refs { .clone() .into_iter() .filter(|r| { - if let Def::ModuleDef(ModuleDef::Trait(tr)) = r.def { + if let Definition::Trait(tr) = r.def { if tr.items(ctx.db()).into_iter().any(|ai| { if let AssocItem::Function(f) = ai { - Def::ModuleDef(ModuleDef::Function(f)).is_referenced_in(ctx) + def_is_referenced_in(Definition::Function(f), ctx) } else { false } @@ -169,13 +160,13 @@ impl Refs { } } - r.def.is_referenced_in(ctx) + def_is_referenced_in(r.def, ctx) }) .collect(), ) } - fn filter_out_by_defs(&self, defs: Vec) -> Refs { + fn filter_out_by_defs(&self, defs: Vec) -> Refs { Refs(self.0.clone().into_iter().filter(|r| !defs.contains(&r.def)).collect()) } } @@ -220,7 +211,7 @@ fn is_mod_visible_from(ctx: &AssistContext, module: Module, from: Module) -> boo // use foo::*$0; // use baz::Baz; // ↑ --------------- -fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option> { +fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option> { let parent_use_item_syntax = star.ancestors().find_map(|n| if ast::Use::can_cast(n.kind()) { Some(n) } else { None })?; @@ -234,8 +225,19 @@ fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option }) .flat_map(|n| n.descendants().filter_map(ast::NameRef::cast)) .filter_map(|r| match NameRefClass::classify(&ctx.sema, &r)? { - NameRefClass::Definition(Definition::ModuleDef(def)) => Some(Def::ModuleDef(def)), - NameRefClass::Definition(Definition::Macro(def)) => Some(Def::MacroDef(def)), + NameRefClass::Definition( + def + @ + (Definition::Macro(_) + | Definition::Module(_) + | Definition::Function(_) + | Definition::Adt(_) + | Definition::Variant(_) + | Definition::Const(_) + | Definition::Static(_) + | Definition::Trait(_) + | Definition::TypeAlias(_)), + ) => Some(def), _ => None, }) .collect(), @@ -245,7 +247,7 @@ fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option fn find_names_to_import( ctx: &AssistContext, refs_in_target: Refs, - imported_defs: Vec, + imported_defs: Vec, ) -> Vec { let used_refs = refs_in_target.used_refs(ctx).filter_out_by_defs(imported_defs); used_refs.0.iter().map(|r| r.visible_name.clone()).collect() diff --git a/crates/ide_assists/src/handlers/extract_module.rs b/crates/ide_assists/src/handlers/extract_module.rs index dc0683866c2..80fc7946ce3 100644 --- a/crates/ide_assists/src/handlers/extract_module.rs +++ b/crates/ide_assists/src/handlers/extract_module.rs @@ -1,6 +1,6 @@ use std::collections::{HashMap, HashSet}; -use hir::{HasSource, ModuleDef, ModuleSource}; +use hir::{HasSource, ModuleSource}; use ide_db::{ assists::{AssistId, AssistKind}, base_db::FileId, @@ -184,7 +184,7 @@ impl Module { match (item.syntax()) { ast::Adt(it) => { if let Some( nod ) = ctx.sema.to_def(&it) { - let node_def = Definition::ModuleDef(nod.into()); + let node_def = Definition::Adt(nod.into()); self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs); //Enum Fields are not allowed to explicitly specify pub, it is implied @@ -218,25 +218,25 @@ impl Module { }, ast::TypeAlias(it) => { if let Some( nod ) = ctx.sema.to_def(&it) { - let node_def = Definition::ModuleDef(nod.into()); + let node_def = Definition::TypeAlias(nod.into()); self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs); } }, ast::Const(it) => { if let Some( nod ) = ctx.sema.to_def(&it) { - let node_def = Definition::ModuleDef(nod.into()); + let node_def = Definition::Const(nod.into()); self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs); } }, ast::Static(it) => { if let Some( nod ) = ctx.sema.to_def(&it) { - let node_def = Definition::ModuleDef(nod.into()); + let node_def = Definition::Static(nod.into()); self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs); } }, ast::Fn(it) => { if let Some( nod ) = ctx.sema.to_def(&it) { - let node_def = Definition::ModuleDef(nod.into()); + let node_def = Definition::Function(nod.into()); self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs); } }, @@ -603,161 +603,151 @@ fn does_source_exists_outside_sel_in_same_mod( ) -> bool { let mut source_exists_outside_sel_in_same_mod = false; match def { - Definition::ModuleDef(it) => match it { - ModuleDef::Module(x) => { - let source = x.definition_source(ctx.db()); + Definition::Module(x) => { + let source = x.definition_source(ctx.db()); + let have_same_parent; + if let Some(ast_module) = &curr_parent_module { + if let Some(hir_module) = x.parent(ctx.db()) { + have_same_parent = + compare_hir_and_ast_module(&ast_module, hir_module, ctx).is_some(); + } else { + let source_file_id = source.file_id.original_file(ctx.db()); + have_same_parent = source_file_id == curr_file_id; + } + } else { + let source_file_id = source.file_id.original_file(ctx.db()); + have_same_parent = source_file_id == curr_file_id; + } + + if have_same_parent { + match source.value { + ModuleSource::Module(module_) => { + source_exists_outside_sel_in_same_mod = + !selection_range.contains_range(module_.syntax().text_range()); + } + _ => {} + } + } + } + Definition::Function(x) => { + if let Some(source) = x.source(ctx.db()) { let have_same_parent; if let Some(ast_module) = &curr_parent_module { - if let Some(hir_module) = x.parent(ctx.db()) { - have_same_parent = - compare_hir_and_ast_module(&ast_module, hir_module, ctx).is_some(); - } else { - let source_file_id = source.file_id.original_file(ctx.db()); - have_same_parent = source_file_id == curr_file_id; - } + have_same_parent = + compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some(); } else { let source_file_id = source.file_id.original_file(ctx.db()); have_same_parent = source_file_id == curr_file_id; } if have_same_parent { - match source.value { - ModuleSource::Module(module_) => { - source_exists_outside_sel_in_same_mod = - !selection_range.contains_range(module_.syntax().text_range()); - } - _ => {} - } + source_exists_outside_sel_in_same_mod = + !selection_range.contains_range(source.value.syntax().text_range()); } } - ModuleDef::Function(x) => { - if let Some(source) = x.source(ctx.db()) { - let have_same_parent; - if let Some(ast_module) = &curr_parent_module { - have_same_parent = - compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx) - .is_some(); - } else { - let source_file_id = source.file_id.original_file(ctx.db()); - have_same_parent = source_file_id == curr_file_id; - } + } + Definition::Adt(x) => { + if let Some(source) = x.source(ctx.db()) { + let have_same_parent; + if let Some(ast_module) = &curr_parent_module { + have_same_parent = + compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some(); + } else { + let source_file_id = source.file_id.original_file(ctx.db()); + have_same_parent = source_file_id == curr_file_id; + } - if have_same_parent { - source_exists_outside_sel_in_same_mod = - !selection_range.contains_range(source.value.syntax().text_range()); - } + if have_same_parent { + source_exists_outside_sel_in_same_mod = + !selection_range.contains_range(source.value.syntax().text_range()); } } - ModuleDef::Adt(x) => { - if let Some(source) = x.source(ctx.db()) { - let have_same_parent; - if let Some(ast_module) = &curr_parent_module { - have_same_parent = - compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx) - .is_some(); - } else { - let source_file_id = source.file_id.original_file(ctx.db()); - have_same_parent = source_file_id == curr_file_id; - } + } + Definition::Variant(x) => { + if let Some(source) = x.source(ctx.db()) { + let have_same_parent; + if let Some(ast_module) = &curr_parent_module { + have_same_parent = + compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some(); + } else { + let source_file_id = source.file_id.original_file(ctx.db()); + have_same_parent = source_file_id == curr_file_id; + } - if have_same_parent { - source_exists_outside_sel_in_same_mod = - !selection_range.contains_range(source.value.syntax().text_range()); - } + if have_same_parent { + source_exists_outside_sel_in_same_mod = + !selection_range.contains_range(source.value.syntax().text_range()); } } - ModuleDef::Variant(x) => { - if let Some(source) = x.source(ctx.db()) { - let have_same_parent; - if let Some(ast_module) = &curr_parent_module { - have_same_parent = - compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx) - .is_some(); - } else { - let source_file_id = source.file_id.original_file(ctx.db()); - have_same_parent = source_file_id == curr_file_id; - } + } + Definition::Const(x) => { + if let Some(source) = x.source(ctx.db()) { + let have_same_parent; + if let Some(ast_module) = &curr_parent_module { + have_same_parent = + compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some(); + } else { + let source_file_id = source.file_id.original_file(ctx.db()); + have_same_parent = source_file_id == curr_file_id; + } - if have_same_parent { - source_exists_outside_sel_in_same_mod = - !selection_range.contains_range(source.value.syntax().text_range()); - } + if have_same_parent { + source_exists_outside_sel_in_same_mod = + !selection_range.contains_range(source.value.syntax().text_range()); } } - ModuleDef::Const(x) => { - if let Some(source) = x.source(ctx.db()) { - let have_same_parent; - if let Some(ast_module) = &curr_parent_module { - have_same_parent = - compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx) - .is_some(); - } else { - let source_file_id = source.file_id.original_file(ctx.db()); - have_same_parent = source_file_id == curr_file_id; - } + } + Definition::Static(x) => { + if let Some(source) = x.source(ctx.db()) { + let have_same_parent; + if let Some(ast_module) = &curr_parent_module { + have_same_parent = + compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some(); + } else { + let source_file_id = source.file_id.original_file(ctx.db()); + have_same_parent = source_file_id == curr_file_id; + } - if have_same_parent { - source_exists_outside_sel_in_same_mod = - !selection_range.contains_range(source.value.syntax().text_range()); - } + if have_same_parent { + source_exists_outside_sel_in_same_mod = + !selection_range.contains_range(source.value.syntax().text_range()); } } - ModuleDef::Static(x) => { - if let Some(source) = x.source(ctx.db()) { - let have_same_parent; - if let Some(ast_module) = &curr_parent_module { - have_same_parent = - compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx) - .is_some(); - } else { - let source_file_id = source.file_id.original_file(ctx.db()); - have_same_parent = source_file_id == curr_file_id; - } + } + Definition::Trait(x) => { + if let Some(source) = x.source(ctx.db()) { + let have_same_parent; + if let Some(ast_module) = &curr_parent_module { + have_same_parent = + compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some(); + } else { + let source_file_id = source.file_id.original_file(ctx.db()); + have_same_parent = source_file_id == curr_file_id; + } - if have_same_parent { - source_exists_outside_sel_in_same_mod = - !selection_range.contains_range(source.value.syntax().text_range()); - } + if have_same_parent { + source_exists_outside_sel_in_same_mod = + !selection_range.contains_range(source.value.syntax().text_range()); } } - ModuleDef::Trait(x) => { - if let Some(source) = x.source(ctx.db()) { - let have_same_parent; - if let Some(ast_module) = &curr_parent_module { - have_same_parent = - compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx) - .is_some(); - } else { - let source_file_id = source.file_id.original_file(ctx.db()); - have_same_parent = source_file_id == curr_file_id; - } + } + Definition::TypeAlias(x) => { + if let Some(source) = x.source(ctx.db()) { + let have_same_parent; + if let Some(ast_module) = &curr_parent_module { + have_same_parent = + compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some(); + } else { + let source_file_id = source.file_id.original_file(ctx.db()); + have_same_parent = source_file_id == curr_file_id; + } - if have_same_parent { - source_exists_outside_sel_in_same_mod = - !selection_range.contains_range(source.value.syntax().text_range()); - } + if have_same_parent { + source_exists_outside_sel_in_same_mod = + !selection_range.contains_range(source.value.syntax().text_range()); } } - ModuleDef::TypeAlias(x) => { - if let Some(source) = x.source(ctx.db()) { - let have_same_parent; - if let Some(ast_module) = &curr_parent_module { - have_same_parent = - compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx) - .is_some(); - } else { - let source_file_id = source.file_id.original_file(ctx.db()); - have_same_parent = source_file_id == curr_file_id; - } - - if have_same_parent { - source_exists_outside_sel_in_same_mod = - !selection_range.contains_range(source.value.syntax().text_range()); - } - } - } - _ => {} - }, + } _ => {} } diff --git a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs index 8e28f0443d6..82e0970cc4b 100644 --- a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs @@ -63,8 +63,7 @@ pub(crate) fn extract_struct_from_enum_variant( |builder| { let variant_hir_name = variant_hir.name(ctx.db()); let enum_module_def = ModuleDef::from(enum_hir); - let usages = - Definition::ModuleDef(ModuleDef::Variant(variant_hir)).usages(&ctx.sema).all(); + let usages = Definition::Variant(variant_hir).usages(&ctx.sema).all(); let mut visited_modules_set = FxHashSet::default(); let current_module = enum_hir.module(ctx.db()); diff --git a/crates/ide_assists/src/handlers/fix_visibility.rs b/crates/ide_assists/src/handlers/fix_visibility.rs index 80da4a35ad8..0b743307486 100644 --- a/crates/ide_assists/src/handlers/fix_visibility.rs +++ b/crates/ide_assists/src/handlers/fix_visibility.rs @@ -181,7 +181,7 @@ fn target_data_for_def( offset_target_and_file_id(db, c)? } hir::ModuleDef::Static(s) => { - target_name = s.name(db); + target_name = Some(s.name(db)); offset_target_and_file_id(db, s)? } hir::ModuleDef::Trait(t) => { diff --git a/crates/ide_assists/src/handlers/generate_function.rs b/crates/ide_assists/src/handlers/generate_function.rs index edc4697f2ca..db3379abf4c 100644 --- a/crates/ide_assists/src/handlers/generate_function.rs +++ b/crates/ide_assists/src/handlers/generate_function.rs @@ -1,6 +1,6 @@ use rustc_hash::{FxHashMap, FxHashSet}; -use hir::{HasSource, HirDisplay, Module, ModuleDef, Semantics, TypeInfo}; +use hir::{HasSource, HirDisplay, Module, Semantics, TypeInfo}; use ide_db::helpers::FamousDefs; use ide_db::{ base_db::FileId, @@ -482,9 +482,8 @@ fn fn_arg_name(sema: &Semantics, arg_expr: &ast::Expr) -> String { ast::Expr::CastExpr(cast_expr) => Some(fn_arg_name(sema, &cast_expr.expr()?)), expr => { let name_ref = expr.syntax().descendants().filter_map(ast::NameRef::cast).last()?; - if let Some(NameRefClass::Definition(Definition::ModuleDef( - ModuleDef::Const(_) | ModuleDef::Static(_), - ))) = NameRefClass::classify(sema, &name_ref) + if let Some(NameRefClass::Definition(Definition::Const(_) | Definition::Static(_))) = + NameRefClass::classify(sema, &name_ref) { return Some(name_ref.to_string().to_lowercase()); }; diff --git a/crates/ide_assists/src/handlers/inline_call.rs b/crates/ide_assists/src/handlers/inline_call.rs index ae7707667e0..cd4f0464116 100644 --- a/crates/ide_assists/src/handlers/inline_call.rs +++ b/crates/ide_assists/src/handlers/inline_call.rs @@ -69,7 +69,7 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext) -> Opt let params = get_fn_params(ctx.sema.db, function, ¶m_list)?; - let usages = Definition::ModuleDef(hir::ModuleDef::Function(function)).usages(&ctx.sema); + let usages = Definition::Function(function).usages(&ctx.sema); if !usages.at_least_one() { return None; } diff --git a/crates/ide_assists/src/handlers/remove_unused_param.rs b/crates/ide_assists/src/handlers/remove_unused_param.rs index 5210166738a..80e2ca918b9 100644 --- a/crates/ide_assists/src/handlers/remove_unused_param.rs +++ b/crates/ide_assists/src/handlers/remove_unused_param.rs @@ -62,7 +62,7 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext) -> Opt } let fn_def = { let func = ctx.sema.to_def(&func)?; - Definition::ModuleDef(func.into()) + Definition::Function(func) }; let param_def = { diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index e4874c7c482..5fdbb600814 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs @@ -7,9 +7,11 @@ use arrayvec::ArrayVec; use hir::{ - Field, GenericParam, HasVisibility, Impl, Label, Local, MacroDef, Module, ModuleDef, Name, - PathResolution, Semantics, Visibility, + Adt, AsAssocItem, AssocItem, BuiltinType, Const, Field, Function, GenericParam, HasVisibility, + Impl, ItemInNs, Label, Local, MacroDef, Module, ModuleDef, Name, PathResolution, Semantics, + Static, Trait, TypeAlias, Variant, Visibility, }; +use stdx::impl_from; use syntax::{ ast::{self, AstNode}, match_ast, AstToken, SyntaxKind, SyntaxNode, SyntaxToken, @@ -22,7 +24,15 @@ use crate::{helpers::try_resolve_derive_input, RootDatabase}; pub enum Definition { Macro(MacroDef), Field(Field), - ModuleDef(ModuleDef), + Module(Module), + Function(Function), + Adt(Adt), + Variant(Variant), + Const(Const), + Static(Static), + Trait(Trait), + TypeAlias(TypeAlias), + BuiltinType(BuiltinType), SelfType(Impl), Local(Local), GenericParam(GenericParam), @@ -98,49 +108,65 @@ impl Definition { res } + pub fn canonical_module_path(&self, db: &RootDatabase) -> Option> { + self.module(db).map(|it| it.path_to_root(db).into_iter().rev()) + } + pub fn module(&self, db: &RootDatabase) -> Option { - match self { - Definition::Macro(it) => it.module(db), - Definition::Field(it) => Some(it.parent_def(db).module(db)), - Definition::ModuleDef(it) => it.module(db), - Definition::SelfType(it) => Some(it.module(db)), - Definition::Local(it) => Some(it.module(db)), - Definition::GenericParam(it) => Some(it.module(db)), - Definition::Label(it) => Some(it.module(db)), - } + let module = match self { + Definition::Macro(it) => it.module(db)?, + Definition::Module(it) => it.parent(db)?, + Definition::Field(it) => it.parent_def(db).module(db), + Definition::Function(it) => it.module(db), + Definition::Adt(it) => it.module(db), + Definition::Const(it) => it.module(db), + Definition::Static(it) => it.module(db), + Definition::Trait(it) => it.module(db), + Definition::TypeAlias(it) => it.module(db), + Definition::Variant(it) => it.module(db), + Definition::SelfType(it) => it.module(db), + Definition::Local(it) => it.module(db), + Definition::GenericParam(it) => it.module(db), + Definition::Label(it) => it.module(db), + Definition::BuiltinType(_) => return None, + }; + Some(module) } pub fn visibility(&self, db: &RootDatabase) -> Option { - match self { - Definition::Field(sf) => Some(sf.visibility(db)), - Definition::ModuleDef(def) => Some(def.visibility(db)), - Definition::Macro(_) - | Definition::SelfType(_) + let vis = match self { + Definition::Field(sf) => sf.visibility(db), + Definition::Module(it) => it.visibility(db), + Definition::Function(it) => it.visibility(db), + Definition::Adt(it) => it.visibility(db), + Definition::Const(it) => it.visibility(db), + Definition::Static(it) => it.visibility(db), + Definition::Trait(it) => it.visibility(db), + Definition::TypeAlias(it) => it.visibility(db), + Definition::Variant(it) => it.visibility(db), + Definition::BuiltinType(_) => Visibility::Public, + Definition::Macro(_) => return None, + Definition::SelfType(_) | Definition::Local(_) | Definition::GenericParam(_) - | Definition::Label(_) => None, - } + | Definition::Label(_) => return None, + }; + Some(vis) } pub fn name(&self, db: &RootDatabase) -> Option { let name = match self { Definition::Macro(it) => it.name(db)?, Definition::Field(it) => it.name(db), - Definition::ModuleDef(def) => match def { - hir::ModuleDef::Module(it) => it.name(db)?, - hir::ModuleDef::Function(it) => it.name(db), - hir::ModuleDef::Adt(def) => match def { - hir::Adt::Struct(it) => it.name(db), - hir::Adt::Union(it) => it.name(db), - hir::Adt::Enum(it) => it.name(db), - }, - hir::ModuleDef::Variant(it) => it.name(db), - hir::ModuleDef::Const(it) => it.name(db)?, - hir::ModuleDef::Static(it) => it.name(db)?, - hir::ModuleDef::Trait(it) => it.name(db), - hir::ModuleDef::TypeAlias(it) => it.name(db), - hir::ModuleDef::BuiltinType(it) => it.name(), - }, + Definition::Module(it) => it.name(db)?, + Definition::Function(it) => it.name(db), + Definition::Adt(it) => it.name(db), + Definition::Variant(it) => it.name(db), + Definition::Const(it) => it.name(db)?, + Definition::Static(it) => it.name(db), + Definition::Trait(it) => it.name(db), + Definition::TypeAlias(it) => it.name(db), + Definition::BuiltinType(it) => it.name(), Definition::SelfType(_) => return None, Definition::Local(it) => it.name(db)?, Definition::GenericParam(it) => it.name(db), @@ -193,7 +219,7 @@ impl NameClass { if let Some(bind_pat) = ast::IdentPat::cast(parent.clone()) { if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) { - return Some(NameClass::ConstReference(Definition::ModuleDef(def))); + return Some(NameClass::ConstReference(Definition::from(def))); } } @@ -231,7 +257,7 @@ impl NameClass { let extern_crate = it.syntax().parent().and_then(ast::ExternCrate::cast)?; let krate = sema.resolve_extern_crate(&extern_crate)?; let root_module = krate.root_module(sema.db); - Some(NameClass::Definition(Definition::ModuleDef(root_module.into()))) + Some(NameClass::Definition(Definition::Module(root_module))) } }, ast::IdentPat(it) => { @@ -257,43 +283,43 @@ impl NameClass { }, ast::Module(it) => { let def = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::ModuleDef(def.into()))) + Some(NameClass::Definition(Definition::Module(def))) }, ast::Struct(it) => { let def: hir::Struct = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::ModuleDef(def.into()))) + Some(NameClass::Definition(Definition::Adt(def.into()))) }, ast::Union(it) => { let def: hir::Union = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::ModuleDef(def.into()))) + Some(NameClass::Definition(Definition::Adt(def.into()))) }, ast::Enum(it) => { let def: hir::Enum = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::ModuleDef(def.into()))) + Some(NameClass::Definition(Definition::Adt(def.into()))) }, ast::Trait(it) => { let def: hir::Trait = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::ModuleDef(def.into()))) + Some(NameClass::Definition(Definition::Trait(def))) }, ast::Static(it) => { let def: hir::Static = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::ModuleDef(def.into()))) + Some(NameClass::Definition(Definition::Static(def))) }, ast::Variant(it) => { let def: hir::Variant = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::ModuleDef(def.into()))) + Some(NameClass::Definition(Definition::Variant(def))) }, ast::Fn(it) => { let def: hir::Function = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::ModuleDef(def.into()))) + Some(NameClass::Definition(Definition::Function(def))) }, ast::Const(it) => { let def: hir::Const = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::ModuleDef(def.into()))) + Some(NameClass::Definition(Definition::Const(def))) }, ast::TypeAlias(it) => { let def: hir::TypeAlias = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::ModuleDef(def.into()))) + Some(NameClass::Definition(Definition::TypeAlias(def))) }, ast::Macro(it) => { let def = sema.to_def(&it)?; @@ -360,7 +386,7 @@ impl NameRefClass { if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { if let Some(func) = sema.resolve_method_call(&method_call) { - return Some(NameRefClass::Definition(Definition::ModuleDef(func.into()))); + return Some(NameRefClass::Definition(Definition::Function(func))); } } @@ -406,9 +432,7 @@ impl NameRefClass { }) .find(|alias| alias.name(sema.db).to_smol_str() == name_ref.text().as_str()) { - return Some(NameRefClass::Definition(Definition::ModuleDef( - ModuleDef::TypeAlias(ty), - ))); + return Some(NameRefClass::Definition(Definition::TypeAlias(ty))); } } @@ -440,9 +464,9 @@ impl NameRefClass { .map(NameRefClass::Definition), // in case of the path being a qualifier, don't resolve to anything but a module Some(true) => match sema.resolve_path(&path)? { - PathResolution::Def(module @ ModuleDef::Module(_)) => { + PathResolution::Def(ModuleDef::Module(module)) => { cov_mark::hit!(name_ref_classify_attr_path_qualifier); - Some(NameRefClass::Definition(Definition::ModuleDef(module))) + Some(NameRefClass::Definition(Definition::Module(module))) } _ => None, }, @@ -455,7 +479,7 @@ impl NameRefClass { let extern_crate = ast::ExternCrate::cast(parent)?; let krate = sema.resolve_extern_crate(&extern_crate)?; let root_module = krate.root_module(sema.db); - Some(NameRefClass::Definition(Definition::ModuleDef(root_module.into()))) + Some(NameRefClass::Definition(Definition::Module(root_module))) } pub fn classify_lifetime( @@ -492,17 +516,34 @@ impl NameRefClass { } } +impl AsAssocItem for Definition { + fn as_assoc_item(self, db: &dyn hir::db::HirDatabase) -> Option { + match self { + Definition::Function(it) => it.as_assoc_item(db), + Definition::Const(it) => it.as_assoc_item(db), + Definition::TypeAlias(it) => it.as_assoc_item(db), + _ => None, + } + } +} + +impl_from!( + Field, Module, Function, Adt, Variant, Const, Static, Trait, TypeAlias, BuiltinType, Local, + GenericParam, Label + for Definition +); + impl From for Definition { fn from(path_resolution: PathResolution) -> Self { match path_resolution { - PathResolution::Def(def) => Definition::ModuleDef(def), + PathResolution::Def(def) => def.into(), PathResolution::AssocItem(item) => { - let def = match item { + let def: ModuleDef = match item { hir::AssocItem::Function(it) => it.into(), hir::AssocItem::Const(it) => it.into(), hir::AssocItem::TypeAlias(it) => it.into(), }; - Definition::ModuleDef(def) + def.into() } PathResolution::Local(local) => Definition::Local(local), PathResolution::TypeParam(par) => Definition::GenericParam(par.into()), @@ -512,3 +553,37 @@ impl From for Definition { } } } + +impl From for Definition { + fn from(def: ModuleDef) -> Self { + match def { + ModuleDef::Module(it) => Definition::Module(it), + ModuleDef::Function(it) => Definition::Function(it), + ModuleDef::Adt(it) => Definition::Adt(it), + ModuleDef::Variant(it) => Definition::Variant(it), + ModuleDef::Const(it) => Definition::Const(it), + ModuleDef::Static(it) => Definition::Static(it), + ModuleDef::Trait(it) => Definition::Trait(it), + ModuleDef::TypeAlias(it) => Definition::TypeAlias(it), + ModuleDef::BuiltinType(it) => Definition::BuiltinType(it), + } + } +} + +impl From for Option { + fn from(def: Definition) -> Self { + let item = match def { + Definition::Module(it) => ModuleDef::Module(it), + Definition::Function(it) => ModuleDef::Function(it), + Definition::Adt(it) => ModuleDef::Adt(it), + Definition::Variant(it) => ModuleDef::Variant(it), + Definition::Const(it) => ModuleDef::Const(it), + Definition::Static(it) => ModuleDef::Static(it), + Definition::Trait(it) => ModuleDef::Trait(it), + Definition::TypeAlias(it) => ModuleDef::TypeAlias(it), + Definition::BuiltinType(it) => ModuleDef::BuiltinType(it), + _ => return None, + }; + Some(ItemInNs::from(item)) + } +} diff --git a/crates/ide_db/src/items_locator.rs b/crates/ide_db/src/items_locator.rs index 6a326eb4ca3..a3ea3edc977 100644 --- a/crates/ide_db/src/items_locator.rs +++ b/crates/ide_db/src/items_locator.rs @@ -117,9 +117,8 @@ fn find_items<'a>( .into_iter() .filter_map(move |local_candidate| get_name_definition(sema, &local_candidate)) .filter_map(|name_definition_to_import| match name_definition_to_import { - Definition::ModuleDef(module_def) => Some(ItemInNs::from(module_def)), Definition::Macro(macro_def) => Some(ItemInNs::from(macro_def)), - _ => None, + def => >::from(def), }); external_importables.chain(local_results).filter(move |&item| match assoc_item_search { diff --git a/crates/ide_db/src/rename.rs b/crates/ide_db/src/rename.rs index 4fb5c770e52..678153c6e1d 100644 --- a/crates/ide_db/src/rename.rs +++ b/crates/ide_db/src/rename.rs @@ -67,10 +67,8 @@ pub use _bail as bail; impl Definition { pub fn rename(&self, sema: &Semantics, new_name: &str) -> Result { match *self { - Definition::ModuleDef(hir::ModuleDef::Module(module)) => { - rename_mod(sema, module, new_name) - } - Definition::ModuleDef(hir::ModuleDef::BuiltinType(_)) => { + Definition::Module(module) => rename_mod(sema, module, new_name), + Definition::BuiltinType(_) => { bail!("Cannot rename builtin type") } Definition::SelfType(_) => bail!("Cannot rename `Self`"), @@ -101,25 +99,23 @@ impl Definition { FieldSource::Pos(_) => None, } } - Definition::ModuleDef(module_def) => match module_def { - hir::ModuleDef::Module(module) => { - let src = module.declaration_source(sema.db)?; - let name = src.value.name()?; - src.with_value(name.syntax()).original_file_range_opt(sema.db) - } - hir::ModuleDef::Function(it) => name_range(it, sema), - hir::ModuleDef::Adt(adt) => match adt { - hir::Adt::Struct(it) => name_range(it, sema), - hir::Adt::Union(it) => name_range(it, sema), - hir::Adt::Enum(it) => name_range(it, sema), - }, - hir::ModuleDef::Variant(it) => name_range(it, sema), - hir::ModuleDef::Const(it) => name_range(it, sema), - hir::ModuleDef::Static(it) => name_range(it, sema), - hir::ModuleDef::Trait(it) => name_range(it, sema), - hir::ModuleDef::TypeAlias(it) => name_range(it, sema), - hir::ModuleDef::BuiltinType(_) => return None, + Definition::Module(module) => { + let src = module.declaration_source(sema.db)?; + let name = src.value.name()?; + src.with_value(name.syntax()).original_file_range_opt(sema.db) + } + Definition::Function(it) => name_range(it, sema), + Definition::Adt(adt) => match adt { + hir::Adt::Struct(it) => name_range(it, sema), + hir::Adt::Union(it) => name_range(it, sema), + hir::Adt::Enum(it) => name_range(it, sema), }, + Definition::Variant(it) => name_range(it, sema), + Definition::Const(it) => name_range(it, sema), + Definition::Static(it) => name_range(it, sema), + Definition::Trait(it) => name_range(it, sema), + Definition::TypeAlias(it) => name_range(it, sema), + Definition::BuiltinType(_) => return None, Definition::SelfType(_) => return None, Definition::Local(local) => { let src = local.source(sema.db); @@ -200,7 +196,7 @@ fn rename_mod( _ => never!("Module source node is missing a name"), } } - let def = Definition::ModuleDef(hir::ModuleDef::Module(module)); + let def = Definition::Module(module); let usages = def.usages(sema).all(); let ref_edits = usages.iter().map(|(&file_id, references)| { (file_id, source_edit_from_references(references, def, new_name)) @@ -239,35 +235,40 @@ fn rename_reference( } } - def = match def { + let assoc_item = match def { // HACK: resolve trait impl items to the item def of the trait definition // so that we properly resolve all trait item references - Definition::ModuleDef(mod_def) => mod_def - .as_assoc_item(sema.db) - .and_then(|it| it.containing_trait_impl(sema.db)) - .and_then(|it| { - it.items(sema.db).into_iter().find_map(|it| match (it, mod_def) { - (hir::AssocItem::Function(trait_func), hir::ModuleDef::Function(func)) + Definition::Function(it) => it.as_assoc_item(sema.db), + Definition::TypeAlias(it) => it.as_assoc_item(sema.db), + Definition::Const(it) => it.as_assoc_item(sema.db), + _ => None, + }; + def = match assoc_item { + Some(assoc) => assoc + .containing_trait_impl(sema.db) + .and_then(|trait_| { + trait_.items(sema.db).into_iter().find_map(|it| match (it, assoc) { + (hir::AssocItem::Function(trait_func), hir::AssocItem::Function(func)) if trait_func.name(sema.db) == func.name(sema.db) => { - Some(Definition::ModuleDef(hir::ModuleDef::Function(trait_func))) + Some(Definition::Function(trait_func)) } - (hir::AssocItem::Const(trait_konst), hir::ModuleDef::Const(konst)) + (hir::AssocItem::Const(trait_konst), hir::AssocItem::Const(konst)) if trait_konst.name(sema.db) == konst.name(sema.db) => { - Some(Definition::ModuleDef(hir::ModuleDef::Const(trait_konst))) + Some(Definition::Const(trait_konst)) } ( hir::AssocItem::TypeAlias(trait_type_alias), - hir::ModuleDef::TypeAlias(type_alias), + hir::AssocItem::TypeAlias(type_alias), ) if trait_type_alias.name(sema.db) == type_alias.name(sema.db) => { - Some(Definition::ModuleDef(hir::ModuleDef::TypeAlias(trait_type_alias))) + Some(Definition::TypeAlias(trait_type_alias)) } _ => None, }) }) .unwrap_or(def), - _ => def, + None => def, }; let usages = def.usages(sema).all(); diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index 65deaf4d7df..c23a9ee2572 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs @@ -8,8 +8,7 @@ use std::{convert::TryInto, mem}; use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt}; use hir::{ - AsAssocItem, DefWithBody, HasAttrs, HasSource, InFile, ModuleDef, ModuleSource, Semantics, - Visibility, + AsAssocItem, DefWithBody, HasAttrs, HasSource, InFile, ModuleSource, Semantics, Visibility, }; use once_cell::unsync::Lazy; use rustc_hash::FxHashMap; @@ -217,13 +216,13 @@ impl Definition { fn search_scope(&self, db: &RootDatabase) -> SearchScope { let _p = profile::span("search_scope"); - if let Definition::ModuleDef(hir::ModuleDef::BuiltinType(_)) = self { + if let Definition::BuiltinType(_) = self { return SearchScope::crate_graph(db); } // def is crate root // FIXME: We don't do searches for crates currently, as a crate does not actually have a single name - if let &Definition::ModuleDef(hir::ModuleDef::Module(module)) = self { + if let &Definition::Module(module) = self { if module.crate_root(db) == module { return SearchScope::reverse_dependencies(db, module.krate()); } @@ -431,7 +430,7 @@ impl<'a> FindUsages<'a> { // search for module `self` references in our module's definition source match self.def { - Definition::ModuleDef(hir::ModuleDef::Module(module)) if self.search_self_mod => { + Definition::Module(module) if self.search_self_mod => { let src = module.definition_source(sema.db); let file_id = src.file_id.original_file(sema.db); let (file_id, search_range) = match src.value { @@ -491,7 +490,7 @@ impl<'a> FindUsages<'a> { sink: &mut dyn FnMut(FileId, FileReference) -> bool, ) -> bool { match NameRefClass::classify(self.sema, name_ref) { - Some(NameRefClass::Definition(def @ Definition::ModuleDef(_))) if def == self.def => { + Some(NameRefClass::Definition(def @ Definition::Module(_))) if def == self.def => { let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax()); let reference = FileReference { range, @@ -604,30 +603,27 @@ impl<'a> FindUsages<'a> { sink(file_id, reference) } // Resolve trait impl function definitions to the trait definition's version if self.def is the trait definition's - Some(NameClass::Definition(Definition::ModuleDef(mod_def))) => { + Some(NameClass::Definition(def)) if def != self.def => { /* poor man's try block */ (|| { - let this = match self.def { - Definition::ModuleDef(this) if this != mod_def => this, - _ => return None, - }; - let this_trait = this + let this_trait = self + .def .as_assoc_item(self.sema.db)? .containing_trait_or_trait_impl(self.sema.db)?; - let trait_ = mod_def + let trait_ = def .as_assoc_item(self.sema.db)? .containing_trait_or_trait_impl(self.sema.db)?; - (trait_ == this_trait - && self.def.name(self.sema.db) == mod_def.name(self.sema.db)) - .then(|| { - let FileRange { file_id, range } = self.sema.original_range(name.syntax()); - let reference = FileReference { - range, - name: ast::NameLike::Name(name.clone()), - category: None, - }; - sink(file_id, reference) - }) + (trait_ == this_trait && self.def.name(self.sema.db) == def.name(self.sema.db)) + .then(|| { + let FileRange { file_id, range } = + self.sema.original_range(name.syntax()); + let reference = FileReference { + range, + name: ast::NameLike::Name(name.clone()), + category: None, + }; + sink(file_id, reference) + }) })() .unwrap_or(false) } @@ -638,18 +634,15 @@ impl<'a> FindUsages<'a> { fn def_to_ty(sema: &Semantics, def: &Definition) -> Option { match def { - Definition::ModuleDef(def) => match def { - ModuleDef::Adt(adt) => Some(adt.ty(sema.db)), - ModuleDef::TypeAlias(it) => Some(it.ty(sema.db)), - ModuleDef::BuiltinType(it) => { - let graph = sema.db.crate_graph(); - let krate = graph.iter().next()?; - let root_file = graph[krate].root_file_id; - let module = sema.to_module_def(root_file)?; - Some(it.ty(sema.db, module)) - } - _ => None, - }, + Definition::Adt(adt) => Some(adt.ty(sema.db)), + Definition::TypeAlias(it) => Some(it.ty(sema.db)), + Definition::BuiltinType(it) => { + let graph = sema.db.crate_graph(); + let krate = graph.iter().next()?; + let root_file = graph[krate].root_file_id; + let module = sema.to_module_def(root_file)?; + Some(it.ty(sema.db, module)) + } Definition::SelfType(it) => Some(it.self_ty(sema.db)), _ => None, }