diff options
28 files changed, 238 insertions, 41 deletions
diff --git a/crates/assists/src/ast_transform.rs b/crates/assists/src/ast_transform.rs index da94e9987..4a3ed7783 100644 --- a/crates/assists/src/ast_transform.rs +++ b/crates/assists/src/ast_transform.rs | |||
@@ -204,7 +204,8 @@ impl<'a> AstTransform<'a> for QualifyPaths<'a> { | |||
204 | } | 204 | } |
205 | PathResolution::Local(_) | 205 | PathResolution::Local(_) |
206 | | PathResolution::TypeParam(_) | 206 | | PathResolution::TypeParam(_) |
207 | | PathResolution::SelfType(_) => None, | 207 | | PathResolution::SelfType(_) |
208 | | PathResolution::ConstParam(_) => None, | ||
208 | PathResolution::Macro(_) => None, | 209 | PathResolution::Macro(_) => None, |
209 | PathResolution::AssocItem(_) => None, | 210 | PathResolution::AssocItem(_) => None, |
210 | } | 211 | } |
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index b7ded3478..97b7a8b5f 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -18,10 +18,10 @@ use hir_def::{ | |||
18 | resolver::{HasResolver, Resolver}, | 18 | resolver::{HasResolver, Resolver}, |
19 | src::HasSource as _, | 19 | src::HasSource as _, |
20 | type_ref::{Mutability, TypeRef}, | 20 | type_ref::{Mutability, TypeRef}, |
21 | AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, DefWithBodyId, EnumId, | 21 | AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, |
22 | FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId, | 22 | DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, |
23 | LocalModuleId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, | 23 | LocalEnumVariantId, LocalFieldId, LocalModuleId, Lookup, ModuleId, StaticId, StructId, TraitId, |
24 | UnionId, | 24 | TypeAliasId, TypeParamId, UnionId, |
25 | }; | 25 | }; |
26 | use hir_def::{find_path::PrefixKind, item_scope::ItemInNs, visibility::Visibility}; | 26 | use hir_def::{find_path::PrefixKind, item_scope::ItemInNs, visibility::Visibility}; |
27 | use hir_expand::{ | 27 | use hir_expand::{ |
@@ -1125,7 +1125,12 @@ impl GenericDef { | |||
1125 | id: LifetimeParamId { parent: self.into(), local_id }, | 1125 | id: LifetimeParamId { parent: self.into(), local_id }, |
1126 | }) | 1126 | }) |
1127 | .map(GenericParam::LifetimeParam); | 1127 | .map(GenericParam::LifetimeParam); |
1128 | ty_params.chain(lt_params).collect() | 1128 | let const_params = generics |
1129 | .consts | ||
1130 | .iter() | ||
1131 | .map(|(local_id, _)| ConstParam { id: ConstParamId { parent: self.into(), local_id } }) | ||
1132 | .map(GenericParam::ConstParam); | ||
1133 | ty_params.chain(lt_params).chain(const_params).collect() | ||
1129 | } | 1134 | } |
1130 | 1135 | ||
1131 | pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeParam> { | 1136 | pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeParam> { |
@@ -1237,8 +1242,9 @@ impl Label { | |||
1237 | pub enum GenericParam { | 1242 | pub enum GenericParam { |
1238 | TypeParam(TypeParam), | 1243 | TypeParam(TypeParam), |
1239 | LifetimeParam(LifetimeParam), | 1244 | LifetimeParam(LifetimeParam), |
1245 | ConstParam(ConstParam), | ||
1240 | } | 1246 | } |
1241 | impl_from!(TypeParam, LifetimeParam for GenericParam); | 1247 | impl_from!(TypeParam, LifetimeParam, ConstParam for GenericParam); |
1242 | 1248 | ||
1243 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 1249 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
1244 | pub struct TypeParam { | 1250 | pub struct TypeParam { |
@@ -1300,6 +1306,26 @@ impl LifetimeParam { | |||
1300 | } | 1306 | } |
1301 | } | 1307 | } |
1302 | 1308 | ||
1309 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
1310 | pub struct ConstParam { | ||
1311 | pub(crate) id: ConstParamId, | ||
1312 | } | ||
1313 | |||
1314 | impl ConstParam { | ||
1315 | pub fn name(self, db: &dyn HirDatabase) -> Name { | ||
1316 | let params = db.generic_params(self.id.parent); | ||
1317 | params.consts[self.id.local_id].name.clone() | ||
1318 | } | ||
1319 | |||
1320 | pub fn module(self, db: &dyn HirDatabase) -> Module { | ||
1321 | self.id.parent.module(db.upcast()).into() | ||
1322 | } | ||
1323 | |||
1324 | pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef { | ||
1325 | self.id.parent.into() | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1303 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 1329 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
1304 | pub struct Impl { | 1330 | pub struct Impl { |
1305 | pub(crate) id: ImplId, | 1331 | pub(crate) id: ImplId, |
diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs index a0792b9a6..2422887e3 100644 --- a/crates/hir/src/from_id.rs +++ b/crates/hir/src/from_id.rs | |||
@@ -44,6 +44,7 @@ from_id![ | |||
44 | (hir_def::ImplId, crate::Impl), | 44 | (hir_def::ImplId, crate::Impl), |
45 | (hir_def::TypeParamId, crate::TypeParam), | 45 | (hir_def::TypeParamId, crate::TypeParam), |
46 | (hir_def::LifetimeParamId, crate::LifetimeParam), | 46 | (hir_def::LifetimeParamId, crate::LifetimeParam), |
47 | (hir_def::ConstParamId, crate::ConstParam), | ||
47 | (hir_expand::MacroDefId, crate::MacroDef) | 48 | (hir_expand::MacroDefId, crate::MacroDef) |
48 | ]; | 49 | ]; |
49 | 50 | ||
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index 0dc07c33e..dd7c0c570 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs | |||
@@ -10,8 +10,8 @@ use hir_expand::InFile; | |||
10 | use syntax::ast; | 10 | use syntax::ast; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | db::HirDatabase, Const, Enum, Field, FieldSource, Function, Impl, LifetimeParam, MacroDef, | 13 | db::HirDatabase, Const, ConstParam, Enum, Field, FieldSource, Function, Impl, LifetimeParam, |
14 | Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant, | 14 | MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | pub trait HasSource { | 17 | pub trait HasSource { |
@@ -140,3 +140,11 @@ impl HasSource for LifetimeParam { | |||
140 | child_source.map(|it| it[self.id.local_id].clone()) | 140 | child_source.map(|it| it[self.id.local_id].clone()) |
141 | } | 141 | } |
142 | } | 142 | } |
143 | |||
144 | impl HasSource for ConstParam { | ||
145 | type Ast = ast::ConstParam; | ||
146 | fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> { | ||
147 | let child_source = self.id.parent.child_source(db.upcast()); | ||
148 | child_source.map(|it| it[self.id.local_id].clone()) | ||
149 | } | ||
150 | } | ||
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 7ac9fd507..8ac27e2dd 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -34,9 +34,9 @@ pub use crate::{ | |||
34 | attrs::{HasAttrs, Namespace}, | 34 | attrs::{HasAttrs, Namespace}, |
35 | code_model::{ | 35 | code_model::{ |
36 | Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const, | 36 | Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const, |
37 | Crate, CrateDependency, DefWithBody, Enum, Field, FieldSource, Function, GenericDef, | 37 | ConstParam, Crate, CrateDependency, DefWithBody, Enum, Field, FieldSource, Function, |
38 | HasVisibility, Impl, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, ScopeDef, | 38 | GenericDef, HasVisibility, Impl, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, |
39 | Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, | 39 | ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, |
40 | }, | 40 | }, |
41 | has_source::HasSource, | 41 | has_source::HasSource, |
42 | semantics::{PathResolution, Semantics, SemanticsScope}, | 42 | semantics::{PathResolution, Semantics, SemanticsScope}, |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 67cd16e31..cd689c869 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -25,9 +25,9 @@ use crate::{ | |||
25 | diagnostics::Diagnostic, | 25 | diagnostics::Diagnostic, |
26 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, | 26 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, |
27 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, | 27 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, |
28 | AssocItem, Callable, Crate, Field, Function, HirFileId, Impl, InFile, Label, LifetimeParam, | 28 | AssocItem, Callable, ConstParam, Crate, Field, Function, HirFileId, Impl, InFile, Label, |
29 | Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, | 29 | LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, |
30 | VariantDef, | 30 | TypeAlias, TypeParam, VariantDef, |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #[derive(Debug, Clone, PartialEq, Eq)] | 33 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -38,6 +38,7 @@ pub enum PathResolution { | |||
38 | Local(Local), | 38 | Local(Local), |
39 | /// A generic parameter | 39 | /// A generic parameter |
40 | TypeParam(TypeParam), | 40 | TypeParam(TypeParam), |
41 | ConstParam(ConstParam), | ||
41 | SelfType(Impl), | 42 | SelfType(Impl), |
42 | Macro(MacroDef), | 43 | Macro(MacroDef), |
43 | AssocItem(AssocItem), | 44 | AssocItem(AssocItem), |
@@ -59,7 +60,9 @@ impl PathResolution { | |||
59 | PathResolution::Def(ModuleDef::TypeAlias(alias)) => { | 60 | PathResolution::Def(ModuleDef::TypeAlias(alias)) => { |
60 | Some(TypeNs::TypeAliasId((*alias).into())) | 61 | Some(TypeNs::TypeAliasId((*alias).into())) |
61 | } | 62 | } |
62 | PathResolution::Local(_) | PathResolution::Macro(_) => None, | 63 | PathResolution::Local(_) | PathResolution::Macro(_) | PathResolution::ConstParam(_) => { |
64 | None | ||
65 | } | ||
63 | PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())), | 66 | PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())), |
64 | PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())), | 67 | PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())), |
65 | PathResolution::AssocItem(AssocItem::Const(_)) | 68 | PathResolution::AssocItem(AssocItem::Const(_)) |
@@ -744,6 +747,7 @@ to_def_impls![ | |||
744 | (crate::Variant, ast::Variant, enum_variant_to_def), | 747 | (crate::Variant, ast::Variant, enum_variant_to_def), |
745 | (crate::TypeParam, ast::TypeParam, type_param_to_def), | 748 | (crate::TypeParam, ast::TypeParam, type_param_to_def), |
746 | (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), | 749 | (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), |
750 | (crate::ConstParam, ast::ConstParam, const_param_to_def), | ||
747 | (crate::MacroDef, ast::MacroRules, macro_rules_to_def), | 751 | (crate::MacroDef, ast::MacroRules, macro_rules_to_def), |
748 | (crate::Local, ast::IdentPat, bind_pat_to_def), | 752 | (crate::Local, ast::IdentPat, bind_pat_to_def), |
749 | (crate::Label, ast::Label, label_to_def), | 753 | (crate::Label, ast::Label, label_to_def), |
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 424e6e8a9..4b9ebff72 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs | |||
@@ -6,9 +6,9 @@ use hir_def::{ | |||
6 | dyn_map::DynMap, | 6 | dyn_map::DynMap, |
7 | expr::{LabelId, PatId}, | 7 | expr::{LabelId, PatId}, |
8 | keys::{self, Key}, | 8 | keys::{self, Key}, |
9 | ConstId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId, GenericDefId, ImplId, | 9 | ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId, GenericDefId, |
10 | LifetimeParamId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, | 10 | ImplId, LifetimeParamId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, |
11 | VariantId, | 11 | UnionId, VariantId, |
12 | }; | 12 | }; |
13 | use hir_expand::{name::AsName, AstId, MacroDefKind}; | 13 | use hir_expand::{name::AsName, AstId, MacroDefKind}; |
14 | use rustc_hash::FxHashMap; | 14 | use rustc_hash::FxHashMap; |
@@ -157,6 +157,18 @@ impl SourceToDefCtx<'_, '_> { | |||
157 | dyn_map[keys::LIFETIME_PARAM].get(&src).copied() | 157 | dyn_map[keys::LIFETIME_PARAM].get(&src).copied() |
158 | } | 158 | } |
159 | 159 | ||
160 | pub(super) fn const_param_to_def( | ||
161 | &mut self, | ||
162 | src: InFile<ast::ConstParam>, | ||
163 | ) -> Option<ConstParamId> { | ||
164 | let container: ChildContainer = | ||
165 | self.find_generic_param_container(src.as_ref().map(|it| it.syntax()))?.into(); | ||
166 | let db = self.db; | ||
167 | let dyn_map = | ||
168 | &*self.cache.entry(container).or_insert_with(|| container.child_by_source(db)); | ||
169 | dyn_map[keys::CONST_PARAM].get(&src).copied() | ||
170 | } | ||
171 | |||
160 | // FIXME: use DynMap as well? | 172 | // FIXME: use DynMap as well? |
161 | pub(super) fn macro_rules_to_def( | 173 | pub(super) fn macro_rules_to_def( |
162 | &mut self, | 174 | &mut self, |
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index bddc49c05..30a8e513d 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs | |||
@@ -479,6 +479,7 @@ pub(crate) fn resolve_hir_path( | |||
479 | ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), | 479 | ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), |
480 | ValueNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()), | 480 | ValueNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()), |
481 | ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()), | 481 | ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()), |
482 | ValueNs::GenericParam(it) => PathResolution::ConstParam(it.into()), | ||
482 | }; | 483 | }; |
483 | Some(res) | 484 | Some(res) |
484 | }); | 485 | }); |
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index bb8fca009..9b5b886c2 100644 --- a/crates/hir_def/src/generics.rs +++ b/crates/hir_def/src/generics.rs | |||
@@ -21,11 +21,11 @@ use crate::{ | |||
21 | keys, | 21 | keys, |
22 | src::{HasChildSource, HasSource}, | 22 | src::{HasChildSource, HasSource}, |
23 | type_ref::{LifetimeRef, TypeBound, TypeRef}, | 23 | type_ref::{LifetimeRef, TypeBound, TypeRef}, |
24 | AdtId, GenericDefId, LifetimeParamId, LocalLifetimeParamId, LocalTypeParamId, Lookup, | 24 | AdtId, ConstParamId, GenericDefId, LifetimeParamId, LocalConstParamId, LocalLifetimeParamId, |
25 | TypeParamId, | 25 | LocalTypeParamId, Lookup, TypeParamId, |
26 | }; | 26 | }; |
27 | 27 | ||
28 | /// Data about a generic parameter (to a function, struct, impl, ...). | 28 | /// Data about a generic type parameter (to a function, struct, impl, ...). |
29 | #[derive(Clone, PartialEq, Eq, Debug)] | 29 | #[derive(Clone, PartialEq, Eq, Debug)] |
30 | pub struct TypeParamData { | 30 | pub struct TypeParamData { |
31 | pub name: Option<Name>, | 31 | pub name: Option<Name>, |
@@ -33,12 +33,19 @@ pub struct TypeParamData { | |||
33 | pub provenance: TypeParamProvenance, | 33 | pub provenance: TypeParamProvenance, |
34 | } | 34 | } |
35 | 35 | ||
36 | /// Data about a generic parameter (to a function, struct, impl, ...). | 36 | /// Data about a generic lifetime parameter (to a function, struct, impl, ...). |
37 | #[derive(Clone, PartialEq, Eq, Debug)] | 37 | #[derive(Clone, PartialEq, Eq, Debug)] |
38 | pub struct LifetimeParamData { | 38 | pub struct LifetimeParamData { |
39 | pub name: Name, | 39 | pub name: Name, |
40 | } | 40 | } |
41 | 41 | ||
42 | /// Data about a generic const parameter (to a function, struct, impl, ...). | ||
43 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
44 | pub struct ConstParamData { | ||
45 | pub name: Name, | ||
46 | pub ty: TypeRef, | ||
47 | } | ||
48 | |||
42 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] | 49 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] |
43 | pub enum TypeParamProvenance { | 50 | pub enum TypeParamProvenance { |
44 | TypeParamList, | 51 | TypeParamList, |
@@ -51,6 +58,7 @@ pub enum TypeParamProvenance { | |||
51 | pub struct GenericParams { | 58 | pub struct GenericParams { |
52 | pub types: Arena<TypeParamData>, | 59 | pub types: Arena<TypeParamData>, |
53 | pub lifetimes: Arena<LifetimeParamData>, | 60 | pub lifetimes: Arena<LifetimeParamData>, |
61 | pub consts: Arena<ConstParamData>, | ||
54 | pub where_predicates: Vec<WherePredicate>, | 62 | pub where_predicates: Vec<WherePredicate>, |
55 | } | 63 | } |
56 | 64 | ||
@@ -76,6 +84,7 @@ pub enum WherePredicateTypeTarget { | |||
76 | pub(crate) struct SourceMap { | 84 | pub(crate) struct SourceMap { |
77 | pub(crate) type_params: ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>, | 85 | pub(crate) type_params: ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>, |
78 | lifetime_params: ArenaMap<LocalLifetimeParamId, ast::LifetimeParam>, | 86 | lifetime_params: ArenaMap<LocalLifetimeParamId, ast::LifetimeParam>, |
87 | const_params: ArenaMap<LocalConstParamId, ast::ConstParam>, | ||
79 | } | 88 | } |
80 | 89 | ||
81 | impl GenericParams { | 90 | impl GenericParams { |
@@ -268,6 +277,13 @@ impl GenericParams { | |||
268 | let lifetime_ref = LifetimeRef::new_name(name); | 277 | let lifetime_ref = LifetimeRef::new_name(name); |
269 | self.fill_bounds(&lower_ctx, &lifetime_param, Either::Right(lifetime_ref)); | 278 | self.fill_bounds(&lower_ctx, &lifetime_param, Either::Right(lifetime_ref)); |
270 | } | 279 | } |
280 | for const_param in params.const_params() { | ||
281 | let name = const_param.name().map_or_else(Name::missing, |it| it.as_name()); | ||
282 | let ty = const_param.ty().map_or(TypeRef::Error, |it| TypeRef::from_ast(lower_ctx, it)); | ||
283 | let param = ConstParamData { name, ty }; | ||
284 | let param_id = self.consts.alloc(param); | ||
285 | sm.const_params.insert(param_id, const_param.clone()); | ||
286 | } | ||
271 | } | 287 | } |
272 | 288 | ||
273 | fn fill_where_predicates(&mut self, lower_ctx: &LowerCtx, where_clause: ast::WhereClause) { | 289 | fn fill_where_predicates(&mut self, lower_ctx: &LowerCtx, where_clause: ast::WhereClause) { |
@@ -353,12 +369,16 @@ impl GenericParams { | |||
353 | }); | 369 | }); |
354 | } | 370 | } |
355 | 371 | ||
356 | pub fn find_by_name(&self, name: &Name) -> Option<LocalTypeParamId> { | 372 | pub fn find_type_by_name(&self, name: &Name) -> Option<LocalTypeParamId> { |
357 | self.types | 373 | self.types |
358 | .iter() | 374 | .iter() |
359 | .find_map(|(id, p)| if p.name.as_ref() == Some(name) { Some(id) } else { None }) | 375 | .find_map(|(id, p)| if p.name.as_ref() == Some(name) { Some(id) } else { None }) |
360 | } | 376 | } |
361 | 377 | ||
378 | pub fn find_const_by_name(&self, name: &Name) -> Option<LocalConstParamId> { | ||
379 | self.consts.iter().find_map(|(id, p)| if p.name == *name { Some(id) } else { None }) | ||
380 | } | ||
381 | |||
362 | pub fn find_trait_self_param(&self) -> Option<LocalTypeParamId> { | 382 | pub fn find_trait_self_param(&self) -> Option<LocalTypeParamId> { |
363 | self.types.iter().find_map(|(id, p)| { | 383 | self.types.iter().find_map(|(id, p)| { |
364 | if p.provenance == TypeParamProvenance::TraitSelf { | 384 | if p.provenance == TypeParamProvenance::TraitSelf { |
@@ -390,6 +410,16 @@ impl HasChildSource<LocalLifetimeParamId> for GenericDefId { | |||
390 | } | 410 | } |
391 | } | 411 | } |
392 | 412 | ||
413 | impl HasChildSource<LocalConstParamId> for GenericDefId { | ||
414 | type Value = ast::ConstParam; | ||
415 | fn child_source( | ||
416 | &self, | ||
417 | db: &dyn DefDatabase, | ||
418 | ) -> InFile<ArenaMap<LocalConstParamId, Self::Value>> { | ||
419 | GenericParams::new(db, *self).1.map(|source_maps| source_maps.const_params) | ||
420 | } | ||
421 | } | ||
422 | |||
393 | impl ChildBySource for GenericDefId { | 423 | impl ChildBySource for GenericDefId { |
394 | fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { | 424 | fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { |
395 | let mut res = DynMap::default(); | 425 | let mut res = DynMap::default(); |
@@ -406,6 +436,10 @@ impl ChildBySource for GenericDefId { | |||
406 | let id = LifetimeParamId { parent: *self, local_id }; | 436 | let id = LifetimeParamId { parent: *self, local_id }; |
407 | res[keys::LIFETIME_PARAM].insert(sm.with_value(src.clone()), id); | 437 | res[keys::LIFETIME_PARAM].insert(sm.with_value(src.clone()), id); |
408 | } | 438 | } |
439 | for (local_id, src) in sm.value.const_params.iter() { | ||
440 | let id = ConstParamId { parent: *self, local_id }; | ||
441 | res[keys::CONST_PARAM].insert(sm.with_value(src.clone()), id); | ||
442 | } | ||
409 | res | 443 | res |
410 | } | 444 | } |
411 | } | 445 | } |
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 100dbf5d6..b6f510731 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -260,6 +260,7 @@ impl GenericParamsStorage { | |||
260 | fn alloc(&mut self, params: GenericParams) -> GenericParamsId { | 260 | fn alloc(&mut self, params: GenericParams) -> GenericParamsId { |
261 | if params.types.is_empty() | 261 | if params.types.is_empty() |
262 | && params.lifetimes.is_empty() | 262 | && params.lifetimes.is_empty() |
263 | && params.consts.is_empty() | ||
263 | && params.where_predicates.is_empty() | 264 | && params.where_predicates.is_empty() |
264 | { | 265 | { |
265 | return GenericParamsId::EMPTY; | 266 | return GenericParamsId::EMPTY; |
@@ -269,8 +270,12 @@ impl GenericParamsStorage { | |||
269 | } | 270 | } |
270 | } | 271 | } |
271 | 272 | ||
272 | static EMPTY_GENERICS: GenericParams = | 273 | static EMPTY_GENERICS: GenericParams = GenericParams { |
273 | GenericParams { types: Arena::new(), lifetimes: Arena::new(), where_predicates: Vec::new() }; | 274 | types: Arena::new(), |
275 | lifetimes: Arena::new(), | ||
276 | consts: Arena::new(), | ||
277 | where_predicates: Vec::new(), | ||
278 | }; | ||
274 | 279 | ||
275 | #[derive(Default, Debug, Eq, PartialEq)] | 280 | #[derive(Default, Debug, Eq, PartialEq)] |
276 | struct ItemTreeData { | 281 | struct ItemTreeData { |
diff --git a/crates/hir_def/src/keys.rs b/crates/hir_def/src/keys.rs index 9c585de2c..89b3ed868 100644 --- a/crates/hir_def/src/keys.rs +++ b/crates/hir_def/src/keys.rs | |||
@@ -8,8 +8,8 @@ use syntax::{ast, AstNode, AstPtr}; | |||
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | dyn_map::{DynMap, Policy}, | 10 | dyn_map::{DynMap, Policy}, |
11 | ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, StaticId, | 11 | ConstId, ConstParamId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, |
12 | StructId, TraitId, TypeAliasId, TypeParamId, UnionId, | 12 | StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | pub type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>; | 15 | pub type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>; |
@@ -29,6 +29,7 @@ pub const TUPLE_FIELD: Key<ast::TupleField, FieldId> = Key::new(); | |||
29 | pub const RECORD_FIELD: Key<ast::RecordField, FieldId> = Key::new(); | 29 | pub const RECORD_FIELD: Key<ast::RecordField, FieldId> = Key::new(); |
30 | pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new(); | 30 | pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new(); |
31 | pub const LIFETIME_PARAM: Key<ast::LifetimeParam, LifetimeParamId> = Key::new(); | 31 | pub const LIFETIME_PARAM: Key<ast::LifetimeParam, LifetimeParamId> = Key::new(); |
32 | pub const CONST_PARAM: Key<ast::ConstParam, ConstParamId> = Key::new(); | ||
32 | 33 | ||
33 | pub const MACRO: Key<ast::MacroCall, MacroDefId> = Key::new(); | 34 | pub const MACRO: Key<ast::MacroCall, MacroDefId> = Key::new(); |
34 | 35 | ||
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index ba09a9126..25f460504 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -232,6 +232,13 @@ pub struct LifetimeParamId { | |||
232 | pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>; | 232 | pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>; |
233 | 233 | ||
234 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 234 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
235 | pub struct ConstParamId { | ||
236 | pub parent: GenericDefId, | ||
237 | pub local_id: LocalConstParamId, | ||
238 | } | ||
239 | pub type LocalConstParamId = Idx<generics::ConstParamData>; | ||
240 | |||
241 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
235 | pub enum ContainerId { | 242 | pub enum ContainerId { |
236 | ModuleId(ModuleId), | 243 | ModuleId(ModuleId), |
237 | DefWithBodyId(DefWithBodyId), | 244 | DefWithBodyId(DefWithBodyId), |
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs index f8cc5e075..129f1dbac 100644 --- a/crates/hir_def/src/resolver.rs +++ b/crates/hir_def/src/resolver.rs | |||
@@ -20,9 +20,9 @@ use crate::{ | |||
20 | path::{ModPath, PathKind}, | 20 | path::{ModPath, PathKind}, |
21 | per_ns::PerNs, | 21 | per_ns::PerNs, |
22 | visibility::{RawVisibility, Visibility}, | 22 | visibility::{RawVisibility, Visibility}, |
23 | AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, | 23 | AdtId, AssocContainerId, ConstId, ConstParamId, ContainerId, DefWithBodyId, EnumId, |
24 | FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, | 24 | EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, |
25 | StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId, | 25 | ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId, |
26 | }; | 26 | }; |
27 | 27 | ||
28 | #[derive(Debug, Clone, Default)] | 28 | #[derive(Debug, Clone, Default)] |
@@ -93,6 +93,7 @@ pub enum ValueNs { | |||
93 | StaticId(StaticId), | 93 | StaticId(StaticId), |
94 | StructId(StructId), | 94 | StructId(StructId), |
95 | EnumVariantId(EnumVariantId), | 95 | EnumVariantId(EnumVariantId), |
96 | GenericParam(ConstParamId), | ||
96 | } | 97 | } |
97 | 98 | ||
98 | impl Resolver { | 99 | impl Resolver { |
@@ -163,7 +164,7 @@ impl Resolver { | |||
163 | } | 164 | } |
164 | 165 | ||
165 | Scope::GenericParams { params, def } => { | 166 | Scope::GenericParams { params, def } => { |
166 | if let Some(local_id) = params.find_by_name(first_name) { | 167 | if let Some(local_id) = params.find_type_by_name(first_name) { |
167 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | 168 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; |
168 | return Some(( | 169 | return Some(( |
169 | TypeNs::GenericParam(TypeParamId { local_id, parent: *def }), | 170 | TypeNs::GenericParam(TypeParamId { local_id, parent: *def }), |
@@ -285,11 +286,17 @@ impl Resolver { | |||
285 | Scope::ExprScope(_) => continue, | 286 | Scope::ExprScope(_) => continue, |
286 | 287 | ||
287 | Scope::GenericParams { params, def } if n_segments > 1 => { | 288 | Scope::GenericParams { params, def } if n_segments > 1 => { |
288 | if let Some(local_id) = params.find_by_name(first_name) { | 289 | if let Some(local_id) = params.find_type_by_name(first_name) { |
289 | let ty = TypeNs::GenericParam(TypeParamId { local_id, parent: *def }); | 290 | let ty = TypeNs::GenericParam(TypeParamId { local_id, parent: *def }); |
290 | return Some(ResolveValueResult::Partial(ty, 1)); | 291 | return Some(ResolveValueResult::Partial(ty, 1)); |
291 | } | 292 | } |
292 | } | 293 | } |
294 | Scope::GenericParams { params, def } if n_segments == 1 => { | ||
295 | if let Some(local_id) = params.find_const_by_name(first_name) { | ||
296 | let val = ValueNs::GenericParam(ConstParamId { local_id, parent: *def }); | ||
297 | return Some(ResolveValueResult::ValueNs(val)); | ||
298 | } | ||
299 | } | ||
293 | Scope::GenericParams { .. } => continue, | 300 | Scope::GenericParams { .. } => continue, |
294 | 301 | ||
295 | Scope::ImplDefScope(impl_) => { | 302 | Scope::ImplDefScope(impl_) => { |
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs index 66bdb8e88..f3567c49e 100644 --- a/crates/hir_ty/src/db.rs +++ b/crates/hir_ty/src/db.rs | |||
@@ -5,8 +5,8 @@ use std::sync::Arc; | |||
5 | use arena::map::ArenaMap; | 5 | use arena::map::ArenaMap; |
6 | use base_db::{impl_intern_key, salsa, CrateId, Upcast}; | 6 | use base_db::{impl_intern_key, salsa, CrateId, Upcast}; |
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | db::DefDatabase, expr::ExprId, DefWithBodyId, FunctionId, GenericDefId, ImplId, LocalFieldId, | 8 | db::DefDatabase, expr::ExprId, ConstParamId, DefWithBodyId, FunctionId, GenericDefId, ImplId, |
9 | TypeParamId, VariantId, | 9 | LocalFieldId, TypeParamId, VariantId, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
@@ -37,6 +37,9 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
37 | #[salsa::cycle(crate::lower::impl_self_ty_recover)] | 37 | #[salsa::cycle(crate::lower::impl_self_ty_recover)] |
38 | fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>; | 38 | fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>; |
39 | 39 | ||
40 | #[salsa::invoke(crate::lower::const_param_ty_query)] | ||
41 | fn const_param_ty(&self, def: ConstParamId) -> Ty; | ||
42 | |||
40 | #[salsa::invoke(crate::lower::impl_trait_query)] | 43 | #[salsa::invoke(crate::lower::impl_trait_query)] |
41 | fn impl_trait(&self, def: ImplId) -> Option<Binders<TraitRef>>; | 44 | fn impl_trait(&self, def: ImplId) -> Option<Binders<TraitRef>>; |
42 | 45 | ||
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index 80d7ed10e..5d541104e 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs | |||
@@ -89,6 +89,7 @@ impl<'a> InferenceContext<'a> { | |||
89 | return None; | 89 | return None; |
90 | } | 90 | } |
91 | } | 91 | } |
92 | ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)), | ||
92 | }; | 93 | }; |
93 | 94 | ||
94 | let ty = self.db.value_ty(typable); | 95 | let ty = self.db.value_ty(typable); |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 8da56cd11..222f61a11 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -16,9 +16,9 @@ use hir_def::{ | |||
16 | path::{GenericArg, Path, PathSegment, PathSegments}, | 16 | path::{GenericArg, Path, PathSegment, PathSegments}, |
17 | resolver::{HasResolver, Resolver, TypeNs}, | 17 | resolver::{HasResolver, Resolver, TypeNs}, |
18 | type_ref::{TypeBound, TypeRef}, | 18 | type_ref::{TypeBound, TypeRef}, |
19 | AdtId, AssocContainerId, AssocItemId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, | 19 | AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, |
20 | HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, | 20 | GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, |
21 | UnionId, VariantId, | 21 | TypeAliasId, TypeParamId, UnionId, VariantId, |
22 | }; | 22 | }; |
23 | use hir_expand::name::Name; | 23 | use hir_expand::name::Name; |
24 | use smallvec::SmallVec; | 24 | use smallvec::SmallVec; |
@@ -1221,6 +1221,15 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde | |||
1221 | Binders::new(generics.len(), Ty::from_hir(&ctx, &impl_data.target_type)) | 1221 | Binders::new(generics.len(), Ty::from_hir(&ctx, &impl_data.target_type)) |
1222 | } | 1222 | } |
1223 | 1223 | ||
1224 | pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { | ||
1225 | let parent_data = db.generic_params(def.parent); | ||
1226 | let data = &parent_data.consts[def.local_id]; | ||
1227 | let resolver = def.parent.resolver(db.upcast()); | ||
1228 | let ctx = TyLoweringContext::new(db, &resolver); | ||
1229 | |||
1230 | Ty::from_hir(&ctx, &data.ty) | ||
1231 | } | ||
1232 | |||
1224 | pub(crate) fn impl_self_ty_recover( | 1233 | pub(crate) fn impl_self_ty_recover( |
1225 | db: &dyn HirDatabase, | 1234 | db: &dyn HirDatabase, |
1226 | _cycle: &[String], | 1235 | _cycle: &[String], |
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index a61282d5a..8d431b920 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs | |||
@@ -2375,3 +2375,19 @@ fn infer_operator_overload() { | |||
2375 | "#]], | 2375 | "#]], |
2376 | ); | 2376 | ); |
2377 | } | 2377 | } |
2378 | |||
2379 | #[test] | ||
2380 | fn infer_const_params() { | ||
2381 | check_infer( | ||
2382 | r#" | ||
2383 | fn foo<const FOO: usize>() { | ||
2384 | let bar = FOO; | ||
2385 | } | ||
2386 | "#, | ||
2387 | expect![[r#" | ||
2388 | 27..49 '{ ...FOO; }': () | ||
2389 | 37..40 'bar': usize | ||
2390 | 43..46 'FOO': usize | ||
2391 | "#]], | ||
2392 | ); | ||
2393 | } | ||
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index 6431e7d6d..bcde2b6f1 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs | |||
@@ -24,6 +24,7 @@ pub enum SymbolKind { | |||
24 | Impl, | 24 | Impl, |
25 | Field, | 25 | Field, |
26 | TypeParam, | 26 | TypeParam, |
27 | ConstParam, | ||
27 | LifetimeParam, | 28 | LifetimeParam, |
28 | ValueParam, | 29 | ValueParam, |
29 | SelfParam, | 30 | SelfParam, |
@@ -225,6 +226,7 @@ impl TryToNav for Definition { | |||
225 | Definition::TypeParam(it) => Some(it.to_nav(db)), | 226 | Definition::TypeParam(it) => Some(it.to_nav(db)), |
226 | Definition::LifetimeParam(it) => Some(it.to_nav(db)), | 227 | Definition::LifetimeParam(it) => Some(it.to_nav(db)), |
227 | Definition::Label(it) => Some(it.to_nav(db)), | 228 | Definition::Label(it) => Some(it.to_nav(db)), |
229 | Definition::ConstParam(it) => Some(it.to_nav(db)), | ||
228 | } | 230 | } |
229 | } | 231 | } |
230 | } | 232 | } |
@@ -485,6 +487,23 @@ impl ToNav for hir::LifetimeParam { | |||
485 | } | 487 | } |
486 | } | 488 | } |
487 | 489 | ||
490 | impl ToNav for hir::ConstParam { | ||
491 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | ||
492 | let src = self.source(db); | ||
493 | let full_range = src.value.syntax().text_range(); | ||
494 | NavigationTarget { | ||
495 | file_id: src.file_id.original_file(db), | ||
496 | name: self.name(db).to_string().into(), | ||
497 | kind: Some(SymbolKind::ConstParam), | ||
498 | full_range, | ||
499 | focus_range: src.value.name().map(|n| n.syntax().text_range()), | ||
500 | container_name: None, | ||
501 | description: None, | ||
502 | docs: None, | ||
503 | } | ||
504 | } | ||
505 | } | ||
506 | |||
488 | /// Get a description of a symbol. | 507 | /// Get a description of a symbol. |
489 | /// | 508 | /// |
490 | /// e.g. `struct Name`, `enum Name`, `fn Name` | 509 | /// e.g. `struct Name`, `enum Name`, `fn Name` |
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index e10516f43..367fac05e 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs | |||
@@ -193,6 +193,7 @@ fn rewrite_intra_doc_link( | |||
193 | Definition::SelfType(_) | 193 | Definition::SelfType(_) |
194 | | Definition::Local(_) | 194 | | Definition::Local(_) |
195 | | Definition::TypeParam(_) | 195 | | Definition::TypeParam(_) |
196 | | Definition::ConstParam(_) | ||
196 | | Definition::LifetimeParam(_) | 197 | | Definition::LifetimeParam(_) |
197 | | Definition::Label(_) => return None, | 198 | | Definition::Label(_) => return None, |
198 | }?; | 199 | }?; |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 73245fbe7..49eb8caae 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -370,7 +370,10 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
370 | Adt::Enum(it) => from_def_source(db, it, mod_path), | 370 | Adt::Enum(it) => from_def_source(db, it, mod_path), |
371 | }) | 371 | }) |
372 | } | 372 | } |
373 | Definition::TypeParam(_) | Definition::LifetimeParam(_) | Definition::Label(_) => { | 373 | Definition::TypeParam(_) |
374 | | Definition::LifetimeParam(_) | ||
375 | | Definition::ConstParam(_) | ||
376 | | Definition::Label(_) => { | ||
374 | // FIXME: Hover for generic param | 377 | // FIXME: Hover for generic param |
375 | None | 378 | None |
376 | } | 379 | } |
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 21b2d7ca1..fa58fc319 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -1144,4 +1144,20 @@ fn foo<'a>() -> &'a () { | |||
1144 | "#]], | 1144 | "#]], |
1145 | ); | 1145 | ); |
1146 | } | 1146 | } |
1147 | |||
1148 | #[test] | ||
1149 | fn test_find_const_param() { | ||
1150 | check( | ||
1151 | r#" | ||
1152 | fn foo<const FOO<|>: usize>() -> usize { | ||
1153 | FOO | ||
1154 | } | ||
1155 | "#, | ||
1156 | expect![[r#" | ||
1157 | FOO ConstParam FileId(0) 7..23 13..16 Other | ||
1158 | |||
1159 | FileId(0) 42..45 Other | ||
1160 | "#]], | ||
1161 | ); | ||
1162 | } | ||
1147 | } | 1163 | } |
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 5ad96581b..ba0085244 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -819,6 +819,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
819 | }, | 819 | }, |
820 | Definition::SelfType(_) => HighlightTag::Symbol(SymbolKind::Impl), | 820 | Definition::SelfType(_) => HighlightTag::Symbol(SymbolKind::Impl), |
821 | Definition::TypeParam(_) => HighlightTag::Symbol(SymbolKind::TypeParam), | 821 | Definition::TypeParam(_) => HighlightTag::Symbol(SymbolKind::TypeParam), |
822 | Definition::ConstParam(_) => HighlightTag::Symbol(SymbolKind::ConstParam), | ||
822 | Definition::Local(local) => { | 823 | Definition::Local(local) => { |
823 | let tag = if local.is_param(db) { | 824 | let tag = if local.is_param(db) { |
824 | HighlightTag::Symbol(SymbolKind::ValueParam) | 825 | HighlightTag::Symbol(SymbolKind::ValueParam) |
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs index 2a6cc0cab..8b8867079 100644 --- a/crates/ide/src/syntax_highlighting/tags.rs +++ b/crates/ide/src/syntax_highlighting/tags.rs | |||
@@ -77,6 +77,7 @@ impl HighlightTag { | |||
77 | SymbolKind::Function => "function", | 77 | SymbolKind::Function => "function", |
78 | SymbolKind::TypeAlias => "type_alias", | 78 | SymbolKind::TypeAlias => "type_alias", |
79 | SymbolKind::TypeParam => "type_param", | 79 | SymbolKind::TypeParam => "type_param", |
80 | SymbolKind::ConstParam => "const_param", | ||
80 | SymbolKind::LifetimeParam => "lifetime", | 81 | SymbolKind::LifetimeParam => "lifetime", |
81 | SymbolKind::Macro => "macro", | 82 | SymbolKind::Macro => "macro", |
82 | SymbolKind::Local => "variable", | 83 | SymbolKind::Local => "variable", |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index 72ff9dd40..02270b077 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html | |||
@@ -118,6 +118,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
118 | <span class="keyword control">loop</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 118 | <span class="keyword control">loop</span> <span class="punctuation">{</span><span class="punctuation">}</span> |
119 | <span class="punctuation">}</span> | 119 | <span class="punctuation">}</span> |
120 | 120 | ||
121 | <span class="keyword">fn</span> <span class="function declaration">const_param</span><span class="punctuation"><</span><span class="keyword">const</span> <span class="const_param declaration">FOO</span><span class="punctuation">:</span> <span class="builtin_type">usize</span><span class="punctuation">></span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">usize</span> <span class="punctuation">{</span> | ||
122 | <span class="const_param">FOO</span> | ||
123 | <span class="punctuation">}</span> | ||
124 | |||
121 | <span class="keyword">use</span> <span class="module">ops</span><span class="operator">::</span><span class="trait">Fn</span><span class="punctuation">;</span> | 125 | <span class="keyword">use</span> <span class="module">ops</span><span class="operator">::</span><span class="trait">Fn</span><span class="punctuation">;</span> |
122 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation"><</span><span class="type_param declaration">F</span><span class="punctuation">:</span> <span class="trait">Fn</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">></span><span class="punctuation">(</span><span class="value_param declaration callable">f</span><span class="punctuation">:</span> <span class="type_param">F</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 126 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation"><</span><span class="type_param declaration">F</span><span class="punctuation">:</span> <span class="trait">Fn</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">></span><span class="punctuation">(</span><span class="value_param declaration callable">f</span><span class="punctuation">:</span> <span class="type_param">F</span><span class="punctuation">)</span> <span class="punctuation">{</span> |
123 | <span class="value_param callable">f</span><span class="punctuation">(</span><span class="punctuation">)</span> | 127 | <span class="value_param callable">f</span><span class="punctuation">(</span><span class="punctuation">)</span> |
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index e0df0d2b5..30b5b648e 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs | |||
@@ -91,6 +91,10 @@ fn never() -> ! { | |||
91 | loop {} | 91 | loop {} |
92 | } | 92 | } |
93 | 93 | ||
94 | fn const_param<const FOO: usize>() -> usize { | ||
95 | FOO | ||
96 | } | ||
97 | |||
94 | use ops::Fn; | 98 | use ops::Fn; |
95 | fn baz<F: Fn() -> ()>(f: F) { | 99 | fn baz<F: Fn() -> ()>(f: F) { |
96 | f() | 100 | f() |
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index d33a6cb86..cc5078bf0 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs | |||
@@ -6,8 +6,8 @@ | |||
6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). | 6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). |
7 | 7 | ||
8 | use hir::{ | 8 | use hir::{ |
9 | db::HirDatabase, Crate, Field, HasVisibility, Impl, Label, LifetimeParam, Local, MacroDef, | 9 | db::HirDatabase, ConstParam, Crate, Field, HasVisibility, Impl, Label, LifetimeParam, Local, |
10 | Module, ModuleDef, Name, PathResolution, Semantics, TypeParam, Visibility, | 10 | MacroDef, Module, ModuleDef, Name, PathResolution, Semantics, TypeParam, Visibility, |
11 | }; | 11 | }; |
12 | use syntax::{ | 12 | use syntax::{ |
13 | ast::{self, AstNode}, | 13 | ast::{self, AstNode}, |
@@ -26,6 +26,7 @@ pub enum Definition { | |||
26 | Local(Local), | 26 | Local(Local), |
27 | TypeParam(TypeParam), | 27 | TypeParam(TypeParam), |
28 | LifetimeParam(LifetimeParam), | 28 | LifetimeParam(LifetimeParam), |
29 | ConstParam(ConstParam), | ||
29 | Label(Label), | 30 | Label(Label), |
30 | } | 31 | } |
31 | 32 | ||
@@ -39,6 +40,7 @@ impl Definition { | |||
39 | Definition::Local(it) => Some(it.module(db)), | 40 | Definition::Local(it) => Some(it.module(db)), |
40 | Definition::TypeParam(it) => Some(it.module(db)), | 41 | Definition::TypeParam(it) => Some(it.module(db)), |
41 | Definition::LifetimeParam(it) => Some(it.module(db)), | 42 | Definition::LifetimeParam(it) => Some(it.module(db)), |
43 | Definition::ConstParam(it) => Some(it.module(db)), | ||
42 | Definition::Label(it) => Some(it.module(db)), | 44 | Definition::Label(it) => Some(it.module(db)), |
43 | } | 45 | } |
44 | } | 46 | } |
@@ -52,6 +54,7 @@ impl Definition { | |||
52 | Definition::Local(_) => None, | 54 | Definition::Local(_) => None, |
53 | Definition::TypeParam(_) => None, | 55 | Definition::TypeParam(_) => None, |
54 | Definition::LifetimeParam(_) => None, | 56 | Definition::LifetimeParam(_) => None, |
57 | Definition::ConstParam(_) => None, | ||
55 | Definition::Label(_) => None, | 58 | Definition::Label(_) => None, |
56 | } | 59 | } |
57 | } | 60 | } |
@@ -79,6 +82,7 @@ impl Definition { | |||
79 | Definition::Local(it) => it.name(db)?, | 82 | Definition::Local(it) => it.name(db)?, |
80 | Definition::TypeParam(it) => it.name(db), | 83 | Definition::TypeParam(it) => it.name(db), |
81 | Definition::LifetimeParam(it) => it.name(db), | 84 | Definition::LifetimeParam(it) => it.name(db), |
85 | Definition::ConstParam(it) => it.name(db), | ||
82 | Definition::Label(it) => it.name(db), | 86 | Definition::Label(it) => it.name(db), |
83 | }; | 87 | }; |
84 | Some(name) | 88 | Some(name) |
@@ -233,6 +237,10 @@ impl NameClass { | |||
233 | let def = sema.to_def(&it)?; | 237 | let def = sema.to_def(&it)?; |
234 | Some(NameClass::Definition(Definition::TypeParam(def))) | 238 | Some(NameClass::Definition(Definition::TypeParam(def))) |
235 | }, | 239 | }, |
240 | ast::ConstParam(it) => { | ||
241 | let def = sema.to_def(&it)?; | ||
242 | Some(NameClass::Definition(Definition::ConstParam(def))) | ||
243 | }, | ||
236 | _ => None, | 244 | _ => None, |
237 | } | 245 | } |
238 | } | 246 | } |
@@ -417,6 +425,7 @@ impl From<PathResolution> for Definition { | |||
417 | PathResolution::TypeParam(par) => Definition::TypeParam(par), | 425 | PathResolution::TypeParam(par) => Definition::TypeParam(par), |
418 | PathResolution::Macro(def) => Definition::Macro(def), | 426 | PathResolution::Macro(def) => Definition::Macro(def), |
419 | PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def), | 427 | PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def), |
428 | PathResolution::ConstParam(par) => Definition::ConstParam(par), | ||
420 | } | 429 | } |
421 | } | 430 | } |
422 | } | 431 | } |
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs index c2f6a655d..5c4366f16 100644 --- a/crates/rust-analyzer/src/semantic_tokens.rs +++ b/crates/rust-analyzer/src/semantic_tokens.rs | |||
@@ -44,6 +44,7 @@ define_semantic_token_types![ | |||
44 | (ESCAPE_SEQUENCE, "escapeSequence"), | 44 | (ESCAPE_SEQUENCE, "escapeSequence"), |
45 | (FORMAT_SPECIFIER, "formatSpecifier"), | 45 | (FORMAT_SPECIFIER, "formatSpecifier"), |
46 | (GENERIC, "generic"), | 46 | (GENERIC, "generic"), |
47 | (CONST_PARAMETER, "constParameter"), | ||
47 | (LIFETIME, "lifetime"), | 48 | (LIFETIME, "lifetime"), |
48 | (LABEL, "label"), | 49 | (LABEL, "label"), |
49 | (PUNCTUATION, "punctuation"), | 50 | (PUNCTUATION, "punctuation"), |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 1a38e79f0..999b18351 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -42,6 +42,7 @@ pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind { | |||
42 | SymbolKind::Field => lsp_types::SymbolKind::Field, | 42 | SymbolKind::Field => lsp_types::SymbolKind::Field, |
43 | SymbolKind::Static => lsp_types::SymbolKind::Constant, | 43 | SymbolKind::Static => lsp_types::SymbolKind::Constant, |
44 | SymbolKind::Const => lsp_types::SymbolKind::Constant, | 44 | SymbolKind::Const => lsp_types::SymbolKind::Constant, |
45 | SymbolKind::ConstParam => lsp_types::SymbolKind::Constant, | ||
45 | SymbolKind::Impl => lsp_types::SymbolKind::Object, | 46 | SymbolKind::Impl => lsp_types::SymbolKind::Object, |
46 | SymbolKind::Local | 47 | SymbolKind::Local |
47 | | SymbolKind::SelfParam | 48 | | SymbolKind::SelfParam |
@@ -378,6 +379,7 @@ fn semantic_token_type_and_modifiers( | |||
378 | SymbolKind::Impl => lsp_types::SemanticTokenType::TYPE, | 379 | SymbolKind::Impl => lsp_types::SemanticTokenType::TYPE, |
379 | SymbolKind::Field => lsp_types::SemanticTokenType::PROPERTY, | 380 | SymbolKind::Field => lsp_types::SemanticTokenType::PROPERTY, |
380 | SymbolKind::TypeParam => lsp_types::SemanticTokenType::TYPE_PARAMETER, | 381 | SymbolKind::TypeParam => lsp_types::SemanticTokenType::TYPE_PARAMETER, |
382 | SymbolKind::ConstParam => semantic_tokens::CONST_PARAMETER, | ||
381 | SymbolKind::LifetimeParam => semantic_tokens::LIFETIME, | 383 | SymbolKind::LifetimeParam => semantic_tokens::LIFETIME, |
382 | SymbolKind::Label => semantic_tokens::LABEL, | 384 | SymbolKind::Label => semantic_tokens::LABEL, |
383 | SymbolKind::ValueParam => lsp_types::SemanticTokenType::PARAMETER, | 385 | SymbolKind::ValueParam => lsp_types::SemanticTokenType::PARAMETER, |