diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index cc19383339..6cbf5cecfa 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -1263,6 +1263,24 @@ pub enum GenericParam { } impl_from!(TypeParam, LifetimeParam, ConstParam for GenericParam); +impl GenericParam { + pub fn module(self, db: &dyn HirDatabase) -> Module { + match self { + GenericParam::TypeParam(it) => it.module(db), + GenericParam::LifetimeParam(it) => it.module(db), + GenericParam::ConstParam(it) => it.module(db), + } + } + + pub fn name(self, db: &dyn HirDatabase) -> Name { + match self { + GenericParam::TypeParam(it) => it.name(db), + GenericParam::LifetimeParam(it) => it.name(db), + GenericParam::ConstParam(it) => it.name(db), + } + } +} + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct TypeParam { pub(crate) id: TypeParamId, diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index e24c783017..4eecae6975 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs @@ -215,10 +215,8 @@ impl TryToNav for Definition { 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::TypeParam(it) => it.try_to_nav(db), - Definition::LifetimeParam(it) => it.try_to_nav(db), + Definition::GenericParam(it) => it.try_to_nav(db), Definition::Label(it) => Some(it.to_nav(db)), - Definition::ConstParam(it) => it.try_to_nav(db), } } } @@ -389,6 +387,16 @@ impl TryToNav for hir::AssocItem { } } +impl TryToNav for hir::GenericParam { + fn try_to_nav(&self, db: &RootDatabase) -> Option { + match self { + hir::GenericParam::TypeParam(it) => it.try_to_nav(db), + hir::GenericParam::ConstParam(it) => it.try_to_nav(db), + hir::GenericParam::LifetimeParam(it) => it.try_to_nav(db), + } + } +} + impl ToNav for hir::Local { fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { let src = self.source(db); diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index 678d22d03f..91f4241f94 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs @@ -216,9 +216,7 @@ fn rewrite_intra_doc_link( Definition::Field(it) => it.resolve_doc_path(db, link, ns), Definition::SelfType(_) | Definition::Local(_) - | Definition::TypeParam(_) - | Definition::ConstParam(_) - | Definition::LifetimeParam(_) + | Definition::GenericParam(_) | Definition::Label(_) => return None, }?; let krate = resolved.module(db)?.krate(); diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 227f209433..c20185b164 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -111,9 +111,7 @@ fn def_for_doc_comment( Definition::Field(it) => it.resolve_doc_path(db, link, ns), Definition::SelfType(_) | Definition::Local(_) - | Definition::TypeParam(_) - | Definition::LifetimeParam(_) - | Definition::ConstParam(_) + | Definition::GenericParam(_) | Definition::Label(_) => return None, } } diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 939efa43ff..e331f8886c 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -1,6 +1,6 @@ use hir::{ - Adt, AsAssocItem, AssocItemContainer, FieldSource, HasAttrs, HasSource, HirDisplay, Module, - ModuleDef, ModuleSource, Semantics, + Adt, AsAssocItem, AssocItemContainer, FieldSource, GenericParam, HasAttrs, HasSource, + HirDisplay, Module, ModuleDef, ModuleSource, Semantics, }; use ide_db::base_db::SourceDatabase; use ide_db::{ @@ -220,12 +220,12 @@ fn goto_type_action(db: &RootDatabase, def: Definition) -> Option { } }; - if let Definition::TypeParam(it) = def { + if let Definition::GenericParam(GenericParam::TypeParam(it)) = def { it.trait_bounds(db).into_iter().for_each(|it| push_new_def(it.into())); } else { let ty = match def { Definition::Local(it) => it.ty(db), - Definition::ConstParam(it) => it.ty(db), + Definition::GenericParam(GenericParam::ConstParam(it)) => it.ty(db), _ => return None, }; @@ -357,9 +357,11 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option { }) } Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), - Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), - Definition::TypeParam(type_param) => Some(Markup::fenced_block(&type_param.display(db))), - Definition::ConstParam(it) => from_def_source(db, it, None), + Definition::GenericParam(it) => match it { + GenericParam::TypeParam(it) => Some(Markup::fenced_block(&it.display(db))), + GenericParam::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), + GenericParam::ConstParam(it) => from_def_source(db, it, None), + }, }; fn from_def_source(db: &RootDatabase, def: D, mod_path: Option) -> Option diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index c95ed669c4..0d5cd5f9a9 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs @@ -130,7 +130,10 @@ pub(crate) fn find_all_refs( kind = ReferenceKind::FieldShorthandForLocal; } } - } else if matches!(def, Definition::LifetimeParam(_) | Definition::Label(_)) { + } else if matches!( + def, + Definition::GenericParam(hir::GenericParam::LifetimeParam(_)) | Definition::Label(_) + ) { kind = ReferenceKind::Lifetime; }; diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 1a88975d2c..20eccf3c60 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -328,8 +328,11 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { } }, Definition::SelfType(_) => HlTag::Symbol(SymbolKind::Impl), - Definition::TypeParam(_) => HlTag::Symbol(SymbolKind::TypeParam), - Definition::ConstParam(_) => HlTag::Symbol(SymbolKind::ConstParam), + Definition::GenericParam(it) => match it { + hir::GenericParam::TypeParam(_) => HlTag::Symbol(SymbolKind::TypeParam), + hir::GenericParam::ConstParam(_) => HlTag::Symbol(SymbolKind::ConstParam), + hir::GenericParam::LifetimeParam(_) => HlTag::Symbol(SymbolKind::LifetimeParam), + }, Definition::Local(local) => { let tag = if local.is_param(db) { HlTag::Symbol(SymbolKind::ValueParam) @@ -345,7 +348,6 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { } return h; } - Definition::LifetimeParam(_) => HlTag::Symbol(SymbolKind::LifetimeParam), Definition::Label(_) => HlTag::Symbol(SymbolKind::Label), } .into() diff --git a/crates/ide/src/syntax_highlighting/highlights.rs b/crates/ide/src/syntax_highlighting/highlights.rs index 11c11ed288..c6f0417ecb 100644 --- a/crates/ide/src/syntax_highlighting/highlights.rs +++ b/crates/ide/src/syntax_highlighting/highlights.rs @@ -51,18 +51,20 @@ impl Node { } } - let (start, len) = + let overlapping = equal_range_by(&self.nested, |n| ordering(n.hl_range.range, hl_range.range)); - if len == 1 && self.nested[start].hl_range.range.contains_range(hl_range.range) { - return self.nested[start].add(hl_range); + if overlapping.len() == 1 + && self.nested[overlapping.start].hl_range.range.contains_range(hl_range.range) + { + return self.nested[overlapping.start].add(hl_range); } let nested = self .nested - .splice(start..start + len, iter::once(Node::new(hl_range))) + .splice(overlapping.clone(), iter::once(Node::new(hl_range))) .collect::>(); - self.nested[start].nested = nested; + self.nested[overlapping.start].nested = nested; } fn flatten(&self, acc: &mut Vec) { diff --git a/crates/ide/src/syntax_highlighting/injector.rs b/crates/ide/src/syntax_highlighting/injector.rs index e8f17eb69f..fd40256942 100644 --- a/crates/ide/src/syntax_highlighting/injector.rs +++ b/crates/ide/src/syntax_highlighting/injector.rs @@ -33,8 +33,7 @@ impl Injector { &self.buf } pub(super) fn map_range_up(&self, range: TextRange) -> impl Iterator + '_ { - let (start, len) = equal_range_by(&self.ranges, |&(r, _)| ordering(r, range)); - (start..start + len).filter_map(move |i| { + equal_range_by(&self.ranges, |&(r, _)| ordering(r, range)).filter_map(move |i| { let (target_range, delta) = self.ranges[i]; let intersection = target_range.intersect(range).unwrap(); Some(intersection + delta?) diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index be1c64b03b..d68fe42b02 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs @@ -6,8 +6,8 @@ // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). use hir::{ - db::HirDatabase, ConstParam, Crate, Field, HasVisibility, Impl, Label, LifetimeParam, Local, - MacroDef, Module, ModuleDef, Name, PathResolution, Semantics, TypeParam, Visibility, + db::HirDatabase, Crate, Field, GenericParam, HasVisibility, Impl, Label, Local, MacroDef, + Module, ModuleDef, Name, PathResolution, Semantics, Visibility, }; use syntax::{ ast::{self, AstNode}, @@ -24,9 +24,7 @@ pub enum Definition { ModuleDef(ModuleDef), SelfType(Impl), Local(Local), - TypeParam(TypeParam), - LifetimeParam(LifetimeParam), - ConstParam(ConstParam), + GenericParam(GenericParam), Label(Label), } @@ -38,9 +36,7 @@ impl Definition { Definition::ModuleDef(it) => it.module(db), Definition::SelfType(it) => Some(it.module(db)), Definition::Local(it) => Some(it.module(db)), - Definition::TypeParam(it) => Some(it.module(db)), - Definition::LifetimeParam(it) => Some(it.module(db)), - Definition::ConstParam(it) => Some(it.module(db)), + Definition::GenericParam(it) => Some(it.module(db)), Definition::Label(it) => Some(it.module(db)), } } @@ -52,9 +48,7 @@ impl Definition { Definition::ModuleDef(def) => def.definition_visibility(db), Definition::SelfType(_) => None, Definition::Local(_) => None, - Definition::TypeParam(_) => None, - Definition::LifetimeParam(_) => None, - Definition::ConstParam(_) => None, + Definition::GenericParam(_) => None, Definition::Label(_) => None, } } @@ -80,9 +74,7 @@ impl Definition { }, Definition::SelfType(_) => return None, Definition::Local(it) => it.name(db)?, - Definition::TypeParam(it) => it.name(db), - Definition::LifetimeParam(it) => it.name(db), - Definition::ConstParam(it) => it.name(db), + Definition::GenericParam(it) => it.name(db), Definition::Label(it) => it.name(db), }; Some(name) @@ -235,11 +227,11 @@ impl NameClass { }, ast::TypeParam(it) => { let def = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::TypeParam(def))) + Some(NameClass::Definition(Definition::GenericParam(def.into()))) }, ast::ConstParam(it) => { let def = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::ConstParam(def))) + Some(NameClass::Definition(Definition::GenericParam(def.into()))) }, _ => None, } @@ -257,7 +249,7 @@ impl NameClass { match parent { ast::LifetimeParam(it) => { let def = sema.to_def(&it)?; - Some(NameClass::Definition(Definition::LifetimeParam(def))) + Some(NameClass::Definition(Definition::GenericParam(def.into()))) }, ast::Label(it) => { let def = sema.to_def(&it)?; @@ -393,7 +385,8 @@ impl NameRefClass { | SyntaxKind::WHERE_PRED | SyntaxKind::REF_TYPE => sema .resolve_lifetime_param(lifetime) - .map(Definition::LifetimeParam) + .map(GenericParam::LifetimeParam) + .map(Definition::GenericParam) .map(NameRefClass::Definition), // lifetime bounds, as in the 'b in 'a: 'b aren't wrapped in TypeBound nodes so we gotta check // if our lifetime is in a LifetimeParam without being the constrained lifetime @@ -401,7 +394,8 @@ impl NameRefClass { != Some(lifetime) => { sema.resolve_lifetime_param(lifetime) - .map(Definition::LifetimeParam) + .map(GenericParam::LifetimeParam) + .map(Definition::GenericParam) .map(NameRefClass::Definition) } _ => None, @@ -422,10 +416,10 @@ impl From for Definition { Definition::ModuleDef(def) } PathResolution::Local(local) => Definition::Local(local), - PathResolution::TypeParam(par) => Definition::TypeParam(par), + PathResolution::TypeParam(par) => Definition::GenericParam(par.into()), PathResolution::Macro(def) => Definition::Macro(def), PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def), - PathResolution::ConstParam(par) => Definition::ConstParam(par), + PathResolution::ConstParam(par) => Definition::GenericParam(par.into()), } } } diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index 37b06027c7..773bfbc2c6 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs @@ -136,7 +136,7 @@ impl Definition { return SearchScope::new(res); } - if let Definition::LifetimeParam(param) = self { + if let Definition::GenericParam(hir::GenericParam::LifetimeParam(param)) = self { let range = match param.parent(db) { hir::GenericDef::Function(it) => { it.source(db).and_then(|src| Some(src.value.syntax().text_range())) diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index 5aacdb16ed..13aab1451e 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs @@ -152,13 +152,13 @@ where left } -pub fn equal_range_by(slice: &[T], mut key: F) -> (usize, usize) +pub fn equal_range_by(slice: &[T], mut key: F) -> ops::Range where F: FnMut(&T) -> Ordering, { let start = partition_point(slice, |it| key(it) == Ordering::Less); let len = partition_point(&slice[start..], |it| key(it) == Ordering::Equal); - (start, len) + start..start + len } pub struct JodChild(pub process::Child);