Add ConstParams to the HIR
This commit is contained in:
parent
77ad203a71
commit
0acdb73076
@ -18,10 +18,10 @@ use hir_def::{
|
||||
resolver::{HasResolver, Resolver},
|
||||
src::HasSource as _,
|
||||
type_ref::{Mutability, TypeRef},
|
||||
AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, DefWithBodyId, EnumId,
|
||||
FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId,
|
||||
LocalModuleId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId,
|
||||
UnionId,
|
||||
AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId,
|
||||
DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId,
|
||||
LocalEnumVariantId, LocalFieldId, LocalModuleId, Lookup, ModuleId, StaticId, StructId, TraitId,
|
||||
TypeAliasId, TypeParamId, UnionId,
|
||||
};
|
||||
use hir_def::{find_path::PrefixKind, item_scope::ItemInNs, visibility::Visibility};
|
||||
use hir_expand::{
|
||||
@ -1125,7 +1125,12 @@ impl GenericDef {
|
||||
id: LifetimeParamId { parent: self.into(), local_id },
|
||||
})
|
||||
.map(GenericParam::LifetimeParam);
|
||||
ty_params.chain(lt_params).collect()
|
||||
let const_params = generics
|
||||
.consts
|
||||
.iter()
|
||||
.map(|(local_id, _)| ConstParam { id: ConstParamId { parent: self.into(), local_id } })
|
||||
.map(GenericParam::ConstParam);
|
||||
ty_params.chain(lt_params).chain(const_params).collect()
|
||||
}
|
||||
|
||||
pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeParam> {
|
||||
@ -1237,8 +1242,9 @@ impl Label {
|
||||
pub enum GenericParam {
|
||||
TypeParam(TypeParam),
|
||||
LifetimeParam(LifetimeParam),
|
||||
ConstParam(ConstParam),
|
||||
}
|
||||
impl_from!(TypeParam, LifetimeParam for GenericParam);
|
||||
impl_from!(TypeParam, LifetimeParam, ConstParam for GenericParam);
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct TypeParam {
|
||||
@ -1300,6 +1306,26 @@ impl LifetimeParam {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ConstParam {
|
||||
pub(crate) id: ConstParamId,
|
||||
}
|
||||
|
||||
impl ConstParam {
|
||||
pub fn name(self, db: &dyn HirDatabase) -> Name {
|
||||
let params = db.generic_params(self.id.parent);
|
||||
params.consts[self.id.local_id].name.clone()
|
||||
}
|
||||
|
||||
pub fn module(self, db: &dyn HirDatabase) -> Module {
|
||||
self.id.parent.module(db.upcast()).into()
|
||||
}
|
||||
|
||||
pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
|
||||
self.id.parent.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Impl {
|
||||
pub(crate) id: ImplId,
|
||||
|
@ -44,6 +44,7 @@ from_id![
|
||||
(hir_def::ImplId, crate::Impl),
|
||||
(hir_def::TypeParamId, crate::TypeParam),
|
||||
(hir_def::LifetimeParamId, crate::LifetimeParam),
|
||||
(hir_def::ConstParamId, crate::ConstParam),
|
||||
(hir_expand::MacroDefId, crate::MacroDef)
|
||||
];
|
||||
|
||||
|
@ -10,8 +10,8 @@ use hir_expand::InFile;
|
||||
use syntax::ast;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase, Const, Enum, Field, FieldSource, Function, Impl, LifetimeParam, MacroDef,
|
||||
Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant,
|
||||
db::HirDatabase, Const, ConstParam, Enum, Field, FieldSource, Function, Impl, LifetimeParam,
|
||||
MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant,
|
||||
};
|
||||
|
||||
pub trait HasSource {
|
||||
@ -140,3 +140,11 @@ impl HasSource for LifetimeParam {
|
||||
child_source.map(|it| it[self.id.local_id].clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl HasSource for ConstParam {
|
||||
type Ast = ast::ConstParam;
|
||||
fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> {
|
||||
let child_source = self.id.parent.child_source(db.upcast());
|
||||
child_source.map(|it| it[self.id.local_id].clone())
|
||||
}
|
||||
}
|
||||
|
@ -34,9 +34,9 @@ pub use crate::{
|
||||
attrs::{HasAttrs, Namespace},
|
||||
code_model::{
|
||||
Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const,
|
||||
Crate, CrateDependency, DefWithBody, Enum, Field, FieldSource, Function, GenericDef,
|
||||
HasVisibility, Impl, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, ScopeDef,
|
||||
Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef,
|
||||
ConstParam, Crate, CrateDependency, DefWithBody, Enum, Field, FieldSource, Function,
|
||||
GenericDef, HasVisibility, Impl, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef,
|
||||
ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef,
|
||||
},
|
||||
has_source::HasSource,
|
||||
semantics::{PathResolution, Semantics, SemanticsScope},
|
||||
|
@ -25,9 +25,9 @@ use crate::{
|
||||
diagnostics::Diagnostic,
|
||||
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
|
||||
source_analyzer::{resolve_hir_path, SourceAnalyzer},
|
||||
AssocItem, Callable, Crate, Field, Function, HirFileId, Impl, InFile, Label, LifetimeParam,
|
||||
Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam,
|
||||
VariantDef,
|
||||
AssocItem, Callable, ConstParam, Crate, Field, Function, HirFileId, Impl, InFile, Label,
|
||||
LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type,
|
||||
TypeAlias, TypeParam, VariantDef,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@ -38,6 +38,7 @@ pub enum PathResolution {
|
||||
Local(Local),
|
||||
/// A generic parameter
|
||||
TypeParam(TypeParam),
|
||||
ConstParam(ConstParam),
|
||||
SelfType(Impl),
|
||||
Macro(MacroDef),
|
||||
AssocItem(AssocItem),
|
||||
@ -59,7 +60,9 @@ impl PathResolution {
|
||||
PathResolution::Def(ModuleDef::TypeAlias(alias)) => {
|
||||
Some(TypeNs::TypeAliasId((*alias).into()))
|
||||
}
|
||||
PathResolution::Local(_) | PathResolution::Macro(_) => None,
|
||||
PathResolution::Local(_) | PathResolution::Macro(_) | PathResolution::ConstParam(_) => {
|
||||
None
|
||||
}
|
||||
PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
|
||||
PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
|
||||
PathResolution::AssocItem(AssocItem::Const(_))
|
||||
@ -744,6 +747,7 @@ to_def_impls![
|
||||
(crate::Variant, ast::Variant, enum_variant_to_def),
|
||||
(crate::TypeParam, ast::TypeParam, type_param_to_def),
|
||||
(crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def),
|
||||
(crate::ConstParam, ast::ConstParam, const_param_to_def),
|
||||
(crate::MacroDef, ast::MacroRules, macro_rules_to_def),
|
||||
(crate::Local, ast::IdentPat, bind_pat_to_def),
|
||||
(crate::Label, ast::Label, label_to_def),
|
||||
|
@ -6,9 +6,9 @@ use hir_def::{
|
||||
dyn_map::DynMap,
|
||||
expr::{LabelId, PatId},
|
||||
keys::{self, Key},
|
||||
ConstId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId, GenericDefId, ImplId,
|
||||
LifetimeParamId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
|
||||
VariantId,
|
||||
ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId, GenericDefId,
|
||||
ImplId, LifetimeParamId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId,
|
||||
UnionId, VariantId,
|
||||
};
|
||||
use hir_expand::{name::AsName, AstId, MacroDefKind};
|
||||
use rustc_hash::FxHashMap;
|
||||
@ -157,6 +157,18 @@ impl SourceToDefCtx<'_, '_> {
|
||||
dyn_map[keys::LIFETIME_PARAM].get(&src).copied()
|
||||
}
|
||||
|
||||
pub(super) fn const_param_to_def(
|
||||
&mut self,
|
||||
src: InFile<ast::ConstParam>,
|
||||
) -> Option<ConstParamId> {
|
||||
let container: ChildContainer =
|
||||
self.find_generic_param_container(src.as_ref().map(|it| it.syntax()))?.into();
|
||||
let db = self.db;
|
||||
let dyn_map =
|
||||
&*self.cache.entry(container).or_insert_with(|| container.child_by_source(db));
|
||||
dyn_map[keys::CONST_PARAM].get(&src).copied()
|
||||
}
|
||||
|
||||
// FIXME: use DynMap as well?
|
||||
pub(super) fn macro_rules_to_def(
|
||||
&mut self,
|
||||
|
@ -479,6 +479,7 @@ pub(crate) fn resolve_hir_path(
|
||||
ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()),
|
||||
ValueNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
|
||||
ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()),
|
||||
ValueNs::GenericParam(it) => PathResolution::ConstParam(it.into()),
|
||||
};
|
||||
Some(res)
|
||||
});
|
||||
|
@ -21,11 +21,11 @@ use crate::{
|
||||
keys,
|
||||
src::{HasChildSource, HasSource},
|
||||
type_ref::{LifetimeRef, TypeBound, TypeRef},
|
||||
AdtId, GenericDefId, LifetimeParamId, LocalLifetimeParamId, LocalTypeParamId, Lookup,
|
||||
TypeParamId,
|
||||
AdtId, ConstParamId, GenericDefId, LifetimeParamId, LocalConstParamId, LocalLifetimeParamId,
|
||||
LocalTypeParamId, Lookup, TypeParamId,
|
||||
};
|
||||
|
||||
/// Data about a generic parameter (to a function, struct, impl, ...).
|
||||
/// Data about a generic type parameter (to a function, struct, impl, ...).
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct TypeParamData {
|
||||
pub name: Option<Name>,
|
||||
@ -33,12 +33,19 @@ pub struct TypeParamData {
|
||||
pub provenance: TypeParamProvenance,
|
||||
}
|
||||
|
||||
/// Data about a generic parameter (to a function, struct, impl, ...).
|
||||
/// Data about a generic lifetime parameter (to a function, struct, impl, ...).
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct LifetimeParamData {
|
||||
pub name: Name,
|
||||
}
|
||||
|
||||
/// Data about a generic const parameter (to a function, struct, impl, ...).
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct ConstParamData {
|
||||
pub name: Name,
|
||||
pub ty: TypeRef,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum TypeParamProvenance {
|
||||
TypeParamList,
|
||||
@ -51,6 +58,7 @@ pub enum TypeParamProvenance {
|
||||
pub struct GenericParams {
|
||||
pub types: Arena<TypeParamData>,
|
||||
pub lifetimes: Arena<LifetimeParamData>,
|
||||
pub consts: Arena<ConstParamData>,
|
||||
pub where_predicates: Vec<WherePredicate>,
|
||||
}
|
||||
|
||||
@ -76,6 +84,7 @@ pub enum WherePredicateTypeTarget {
|
||||
pub(crate) struct SourceMap {
|
||||
pub(crate) type_params: ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>,
|
||||
lifetime_params: ArenaMap<LocalLifetimeParamId, ast::LifetimeParam>,
|
||||
const_params: ArenaMap<LocalConstParamId, ast::ConstParam>,
|
||||
}
|
||||
|
||||
impl GenericParams {
|
||||
@ -268,6 +277,13 @@ impl GenericParams {
|
||||
let lifetime_ref = LifetimeRef::new_name(name);
|
||||
self.fill_bounds(&lower_ctx, &lifetime_param, Either::Right(lifetime_ref));
|
||||
}
|
||||
for const_param in params.const_params() {
|
||||
let name = const_param.name().map_or_else(Name::missing, |it| it.as_name());
|
||||
let ty = const_param.ty().map_or(TypeRef::Error, |it| TypeRef::from_ast(lower_ctx, it));
|
||||
let param = ConstParamData { name, ty };
|
||||
let param_id = self.consts.alloc(param);
|
||||
sm.const_params.insert(param_id, const_param.clone());
|
||||
}
|
||||
}
|
||||
|
||||
fn fill_where_predicates(&mut self, lower_ctx: &LowerCtx, where_clause: ast::WhereClause) {
|
||||
@ -353,12 +369,16 @@ impl GenericParams {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn find_by_name(&self, name: &Name) -> Option<LocalTypeParamId> {
|
||||
pub fn find_type_by_name(&self, name: &Name) -> Option<LocalTypeParamId> {
|
||||
self.types
|
||||
.iter()
|
||||
.find_map(|(id, p)| if p.name.as_ref() == Some(name) { Some(id) } else { None })
|
||||
}
|
||||
|
||||
pub fn find_const_by_name(&self, name: &Name) -> Option<LocalConstParamId> {
|
||||
self.consts.iter().find_map(|(id, p)| if p.name == *name { Some(id) } else { None })
|
||||
}
|
||||
|
||||
pub fn find_trait_self_param(&self) -> Option<LocalTypeParamId> {
|
||||
self.types.iter().find_map(|(id, p)| {
|
||||
if p.provenance == TypeParamProvenance::TraitSelf {
|
||||
@ -390,6 +410,16 @@ impl HasChildSource<LocalLifetimeParamId> for GenericDefId {
|
||||
}
|
||||
}
|
||||
|
||||
impl HasChildSource<LocalConstParamId> for GenericDefId {
|
||||
type Value = ast::ConstParam;
|
||||
fn child_source(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
) -> InFile<ArenaMap<LocalConstParamId, Self::Value>> {
|
||||
GenericParams::new(db, *self).1.map(|source_maps| source_maps.const_params)
|
||||
}
|
||||
}
|
||||
|
||||
impl ChildBySource for GenericDefId {
|
||||
fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
|
||||
let mut res = DynMap::default();
|
||||
@ -406,6 +436,10 @@ impl ChildBySource for GenericDefId {
|
||||
let id = LifetimeParamId { parent: *self, local_id };
|
||||
res[keys::LIFETIME_PARAM].insert(sm.with_value(src.clone()), id);
|
||||
}
|
||||
for (local_id, src) in sm.value.const_params.iter() {
|
||||
let id = ConstParamId { parent: *self, local_id };
|
||||
res[keys::CONST_PARAM].insert(sm.with_value(src.clone()), id);
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
|
@ -260,6 +260,7 @@ impl GenericParamsStorage {
|
||||
fn alloc(&mut self, params: GenericParams) -> GenericParamsId {
|
||||
if params.types.is_empty()
|
||||
&& params.lifetimes.is_empty()
|
||||
&& params.consts.is_empty()
|
||||
&& params.where_predicates.is_empty()
|
||||
{
|
||||
return GenericParamsId::EMPTY;
|
||||
@ -269,8 +270,12 @@ impl GenericParamsStorage {
|
||||
}
|
||||
}
|
||||
|
||||
static EMPTY_GENERICS: GenericParams =
|
||||
GenericParams { types: Arena::new(), lifetimes: Arena::new(), where_predicates: Vec::new() };
|
||||
static EMPTY_GENERICS: GenericParams = GenericParams {
|
||||
types: Arena::new(),
|
||||
lifetimes: Arena::new(),
|
||||
consts: Arena::new(),
|
||||
where_predicates: Vec::new(),
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, Eq, PartialEq)]
|
||||
struct ItemTreeData {
|
||||
|
@ -8,8 +8,8 @@ use syntax::{ast, AstNode, AstPtr};
|
||||
|
||||
use crate::{
|
||||
dyn_map::{DynMap, Policy},
|
||||
ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, StaticId,
|
||||
StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
|
||||
ConstId, ConstParamId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId,
|
||||
StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
|
||||
};
|
||||
|
||||
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();
|
||||
pub const RECORD_FIELD: Key<ast::RecordField, FieldId> = Key::new();
|
||||
pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new();
|
||||
pub const LIFETIME_PARAM: Key<ast::LifetimeParam, LifetimeParamId> = Key::new();
|
||||
pub const CONST_PARAM: Key<ast::ConstParam, ConstParamId> = Key::new();
|
||||
|
||||
pub const MACRO: Key<ast::MacroCall, MacroDefId> = Key::new();
|
||||
|
||||
|
@ -231,6 +231,13 @@ pub struct LifetimeParamId {
|
||||
}
|
||||
pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct ConstParamId {
|
||||
pub parent: GenericDefId,
|
||||
pub local_id: LocalConstParamId,
|
||||
}
|
||||
pub type LocalConstParamId = Idx<generics::ConstParamData>;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum ContainerId {
|
||||
ModuleId(ModuleId),
|
||||
|
@ -20,9 +20,9 @@ use crate::{
|
||||
path::{ModPath, PathKind},
|
||||
per_ns::PerNs,
|
||||
visibility::{RawVisibility, Visibility},
|
||||
AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId,
|
||||
FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId,
|
||||
StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
|
||||
AdtId, AssocContainerId, ConstId, ConstParamId, ContainerId, DefWithBodyId, EnumId,
|
||||
EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId,
|
||||
ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
@ -93,6 +93,7 @@ pub enum ValueNs {
|
||||
StaticId(StaticId),
|
||||
StructId(StructId),
|
||||
EnumVariantId(EnumVariantId),
|
||||
GenericParam(ConstParamId),
|
||||
}
|
||||
|
||||
impl Resolver {
|
||||
@ -163,7 +164,7 @@ impl Resolver {
|
||||
}
|
||||
|
||||
Scope::GenericParams { params, def } => {
|
||||
if let Some(local_id) = params.find_by_name(first_name) {
|
||||
if let Some(local_id) = params.find_type_by_name(first_name) {
|
||||
let idx = if path.segments.len() == 1 { None } else { Some(1) };
|
||||
return Some((
|
||||
TypeNs::GenericParam(TypeParamId { local_id, parent: *def }),
|
||||
@ -285,11 +286,17 @@ impl Resolver {
|
||||
Scope::ExprScope(_) => continue,
|
||||
|
||||
Scope::GenericParams { params, def } if n_segments > 1 => {
|
||||
if let Some(local_id) = params.find_by_name(first_name) {
|
||||
if let Some(local_id) = params.find_type_by_name(first_name) {
|
||||
let ty = TypeNs::GenericParam(TypeParamId { local_id, parent: *def });
|
||||
return Some(ResolveValueResult::Partial(ty, 1));
|
||||
}
|
||||
}
|
||||
Scope::GenericParams { params, def } if n_segments == 1 => {
|
||||
if let Some(local_id) = params.find_const_by_name(first_name) {
|
||||
let val = ValueNs::GenericParam(ConstParamId { local_id, parent: *def });
|
||||
return Some(ResolveValueResult::ValueNs(val));
|
||||
}
|
||||
}
|
||||
Scope::GenericParams { .. } => continue,
|
||||
|
||||
Scope::ImplDefScope(impl_) => {
|
||||
|
@ -5,8 +5,8 @@ use std::sync::Arc;
|
||||
use arena::map::ArenaMap;
|
||||
use base_db::{impl_intern_key, salsa, CrateId, Upcast};
|
||||
use hir_def::{
|
||||
db::DefDatabase, expr::ExprId, DefWithBodyId, FunctionId, GenericDefId, ImplId, LocalFieldId,
|
||||
TypeParamId, VariantId,
|
||||
db::DefDatabase, expr::ExprId, ConstParamId, DefWithBodyId, FunctionId, GenericDefId, ImplId,
|
||||
LocalFieldId, TypeParamId, VariantId,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@ -37,6 +37,9 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
|
||||
#[salsa::cycle(crate::lower::impl_self_ty_recover)]
|
||||
fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>;
|
||||
|
||||
#[salsa::invoke(crate::lower::const_param_ty_query)]
|
||||
fn const_param_ty(&self, def: ConstParamId) -> Ty;
|
||||
|
||||
#[salsa::invoke(crate::lower::impl_trait_query)]
|
||||
fn impl_trait(&self, def: ImplId) -> Option<Binders<TraitRef>>;
|
||||
|
||||
|
@ -89,6 +89,7 @@ impl<'a> InferenceContext<'a> {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)),
|
||||
};
|
||||
|
||||
let ty = self.db.value_ty(typable);
|
||||
|
@ -16,9 +16,9 @@ use hir_def::{
|
||||
path::{GenericArg, Path, PathSegment, PathSegments},
|
||||
resolver::{HasResolver, Resolver, TypeNs},
|
||||
type_ref::{TypeBound, TypeRef},
|
||||
AdtId, AssocContainerId, AssocItemId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId,
|
||||
HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId,
|
||||
UnionId, VariantId,
|
||||
AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId,
|
||||
GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
|
||||
TypeAliasId, TypeParamId, UnionId, VariantId,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use smallvec::SmallVec;
|
||||
@ -1221,6 +1221,15 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde
|
||||
Binders::new(generics.len(), Ty::from_hir(&ctx, &impl_data.target_type))
|
||||
}
|
||||
|
||||
pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
|
||||
let parent_data = db.generic_params(def.parent);
|
||||
let data = &parent_data.consts[def.local_id];
|
||||
let resolver = def.parent.resolver(db.upcast());
|
||||
let ctx = TyLoweringContext::new(db, &resolver);
|
||||
|
||||
Ty::from_hir(&ctx, &data.ty)
|
||||
}
|
||||
|
||||
pub(crate) fn impl_self_ty_recover(
|
||||
db: &dyn HirDatabase,
|
||||
_cycle: &[String],
|
||||
|
@ -2375,3 +2375,20 @@ fn infer_operator_overload() {
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn infer_const_params() {
|
||||
check_infer(
|
||||
r#"
|
||||
fn foo<const FOO: usize>() {
|
||||
let bar = FOO;
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
27..49 '{ ...FOO; }': ()
|
||||
37..40 'bar': usize
|
||||
43..46 'FOO': usize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user