use base_db::CrateId;
use chalk_ir::{cast::Cast, fold::Shift, interner::HasInterner, Mutability, Safety};
+use hir_def::generics::TypeOrConstParamData;
use hir_def::intern::Interned;
use hir_def::{
adt::StructKind,
path::{GenericArg, Path, PathSegment, PathSegments},
resolver::{HasResolver, Resolver, TypeNs},
type_ref::{TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef},
- AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId,
- HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
- TypeAliasId, TypeParamId, UnionId, VariantId,
+ AdtId, AssocItemId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule,
+ ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId,
+ UnionId, VariantId,
};
+use hir_def::{ConstParamId, TypeOrConstParamId};
use hir_expand::{name::Name, ExpandResult};
use la_arena::ArenaMap;
use rustc_hash::FxHashSet;
use smallvec::SmallVec;
-use stdx::impl_from;
+use stdx::{impl_from, never};
use syntax::{ast, SmolStr};
use crate::all_super_traits;
TypeRef::Placeholder => TyKind::Error.intern(Interner),
TypeRef::Fn(params, is_varargs) => {
let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
- Substitution::from_iter(Interner, params.iter().map(|tr| ctx.lower_ty(&tr.1)))
+ Substitution::from_iter(Interner, params.iter().map(|(_, tr)| ctx.lower_ty(tr)))
});
TyKind::Function(FnPointer {
num_binders: 0, // FIXME lower `for<'a> fn()` correctly
if let Some(def) = self.resolver.generic_def() {
let generics = generics(self.db.upcast(), def);
let param = generics
- .iter()
+ .type_iter()
.filter(|(_, data)| {
data.provenance == TypeParamProvenance::ArgumentImplTrait
})
let idx = self.impl_trait_counter.get();
// FIXME we're probably doing something wrong here
self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
- let (parent_params, self_params, list_params, _impl_trait_params) =
- if let Some(def) = self.resolver.generic_def() {
- let generics = generics(self.db.upcast(), def);
- generics.provenance_split()
- } else {
- (0, 0, 0, 0)
- };
+ let (
+ parent_params,
+ self_params,
+ list_params,
+ const_params,
+ _impl_trait_params,
+ ) = if let Some(def) = self.resolver.generic_def() {
+ let generics = generics(self.db.upcast(), def);
+ generics.provenance_split()
+ } else {
+ (0, 0, 0, 0, 0)
+ };
TyKind::BoundVar(BoundVar::new(
self.in_binders,
- idx as usize + parent_params + self_params + list_params,
+ idx as usize + parent_params + self_params + list_params + const_params,
))
.intern(Interner)
}
/// This is only for `generic_predicates_for_param`, where we can't just
/// lower the self types of the predicates since that could lead to cycles.
/// So we just check here if the `type_ref` resolves to a generic param, and which.
- fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeParamId> {
+ fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeOrConstParamId> {
let path = match type_ref {
TypeRef::Path(path) => path,
_ => return None,
_ => return None,
};
match resolution {
- TypeNs::GenericParam(param_id) => Some(param_id),
+ TypeNs::GenericParam(param_id) => Some(param_id.into()),
_ => None,
}
}
);
match self.type_param_mode {
TypeParamLoweringMode::Placeholder => {
- TyKind::Placeholder(to_placeholder_idx(self.db, param_id))
+ TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
}
TypeParamLoweringMode::Variable => {
- let idx = generics.param_idx(param_id).expect("matching generics");
+ let idx = generics.param_idx(param_id.into()).expect("matching generics");
TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
}
}
let mut substs = Vec::new();
let def_generics = def_generic.map(|def| generics(self.db.upcast(), def));
- let (parent_params, self_params, type_params, impl_trait_params) =
- def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split());
- let total_len = parent_params + self_params + type_params + impl_trait_params;
+ let (parent_params, self_params, type_params, const_params, impl_trait_params) =
+ def_generics.map_or((0, 0, 0, 0, 0), |g| g.provenance_split());
+ let total_len =
+ parent_params + self_params + type_params + const_params + impl_trait_params;
substs.extend(iter::repeat(TyKind::Error.intern(Interner)).take(parent_params));
| WherePredicate::TypeBound { target, bound } => {
let self_ty = match target {
WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
- WherePredicateTypeTarget::TypeParam(param_id) => {
+ WherePredicateTypeTarget::TypeOrConstParam(param_id) => {
let generic_def = self.resolver.generic_def().expect("generics in scope");
let generics = generics(self.db.upcast(), generic_def);
- let param_id =
- hir_def::TypeParamId { parent: generic_def, local_id: *param_id };
+ let param_id = hir_def::TypeOrConstParamId {
+ parent: generic_def,
+ local_id: *param_id,
+ };
let placeholder = to_placeholder_idx(self.db, param_id);
match self.type_param_mode {
TypeParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
),
TypeNs::GenericParam(param_id) => {
- let predicates = db.generic_predicates_for_param(def, param_id, assoc_name);
+ let predicates = db.generic_predicates_for_param(def, param_id.into(), assoc_name);
let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
// FIXME: how to correctly handle higher-ranked bounds here?
WhereClause::Implemented(tr) => search(
return res;
}
// Handle `Self::Type` referring to own associated type in trait definitions
- if let GenericDefId::TraitId(trait_id) = param_id.parent {
+ if let GenericDefId::TraitId(trait_id) = param_id.parent() {
let generics = generics(db.upcast(), trait_id.into());
- if generics.params.types[param_id.local_id].provenance
- == TypeParamProvenance::TraitSelf
- {
+ if generics.params.tocs[param_id.local_id()].is_trait_self() {
let trait_ref = TyBuilder::trait_ref(db, trait_id)
.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
.build();
pub(crate) fn generic_predicates_for_param_query(
db: &dyn HirDatabase,
def: GenericDefId,
- param_id: TypeParamId,
+ param_id: TypeOrConstParamId,
assoc_name: Option<Name>,
) -> Arc<[Binders<QuantifiedWhereClause>]> {
let resolver = def.resolver(db.upcast());
| WherePredicate::TypeBound { target, bound, .. } => {
match target {
WherePredicateTypeTarget::TypeRef(type_ref) => {
- if ctx.lower_ty_only_param(type_ref) != Some(param_id) {
+ if ctx.lower_ty_only_param(type_ref) != Some(param_id.into()) {
return false;
}
}
- WherePredicateTypeTarget::TypeParam(local_id) => {
+ WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
if *local_id != param_id.local_id {
return false;
}
_db: &dyn HirDatabase,
_cycle: &[String],
_def: &GenericDefId,
- _param_id: &TypeParamId,
+ _param_id: &TypeOrConstParamId,
_assoc_name: &Option<Name>,
) -> Arc<[Binders<QuantifiedWhereClause>]> {
Arc::new([])
let generic_params = generics(db.upcast(), def);
let defaults = generic_params
- .iter()
+ .toc_iter()
.enumerate()
.map(|(idx, (_, p))| {
+ let p = match p {
+ TypeOrConstParamData::TypeParamData(p) => p,
+ TypeOrConstParamData::ConstParamData(_) => {
+ // FIXME: here we should add const generic parameters
+ let ty = TyKind::Error.intern(Interner);
+ return crate::make_only_type_binders(idx, ty);
+ }
+ };
let mut ty =
p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
// we still need one default per parameter
let defaults = generic_params
- .iter()
+ .toc_iter()
.enumerate()
.map(|(idx, _)| {
let ty = TyKind::Error.intern(Interner);
make_binders(&generics, ctx.lower_ty(&impl_data.self_ty))
}
+// returns None if def is a type arg
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 parent_data = db.generic_params(def.parent());
+ let data = &parent_data.tocs[def.local_id()];
+ let resolver = def.parent().resolver(db.upcast());
let ctx = TyLoweringContext::new(db, &resolver);
-
- ctx.lower_ty(&data.ty)
+ match data {
+ TypeOrConstParamData::TypeParamData(_) => {
+ never!();
+ Ty::new(Interner, TyKind::Error)
+ }
+ TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(&d.ty),
+ }
}
pub(crate) fn impl_self_ty_recover(