match self {
Ty::Apply(apply_ty) => match apply_ty.ctor {
TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters),
+ TypeCtor::Array => array_to_chalk(db, apply_ty.parameters),
TypeCtor::FnPtr { num_args: _ } => {
let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner);
chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution })
Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner),
Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
Ty::Dyn(predicates) => {
- let where_clauses = chalk_ir::QuantifiedWhereClauses::from(
+ let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
&Interner,
predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)),
);
let bounded_ty = chalk_ir::DynTy {
bounds: make_binders(where_clauses, 1),
- lifetime: LIFETIME_PLACEHOLDER.to_lifetime(&Interner),
+ lifetime: FAKE_PLACEHOLDER.to_lifetime(&Interner),
};
chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
}
chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
TypeName::Error => Ty::Unknown,
TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution),
+ TypeName::Array => array_from_chalk(db, apply_ty.substitution),
_ => {
let ctor = from_chalk(db, apply_ty.name);
let parameters = from_chalk(db, apply_ty.substitution);
let parameters = from_chalk(db, opaque_ty.substitution);
Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })
}
- chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => {
- let parameters: Substs = from_chalk(db, substitution);
+ chalk_ir::TyData::Function(chalk_ir::Fn { num_binders, substitution }) => {
+ assert_eq!(num_binders, 0);
+ let parameters: Substs = from_chalk(
+ db,
+ substitution.shifted_out(&Interner).expect("fn ptr should have no binders"),
+ );
Ty::Apply(ApplicationTy {
ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16 },
parameters,
}
}
-const LIFETIME_PLACEHOLDER: PlaceholderIndex =
+const FAKE_PLACEHOLDER: PlaceholderIndex =
PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX };
/// We currently don't model lifetimes, but Chalk does. So, we have to insert a
subst: Substs,
) -> chalk_ir::Ty<Interner> {
let arg = subst[0].clone().to_chalk(db);
- let lifetime = LIFETIME_PLACEHOLDER.to_lifetime(&Interner);
+ let lifetime = FAKE_PLACEHOLDER.to_lifetime(&Interner);
chalk_ir::ApplicationTy {
name: TypeName::Ref(mutability.to_chalk(db)),
- substitution: chalk_ir::Substitution::from(
+ substitution: chalk_ir::Substitution::from_iter(
&Interner,
vec![lifetime.cast(&Interner), arg.cast(&Interner)],
),
Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
}
+/// We currently don't model constants, but Chalk does. So, we have to insert a
+/// fake constant here, because Chalks built-in logic may expect it to be there.
+fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> {
+ let arg = subst[0].clone().to_chalk(db);
+ let usize_ty = chalk_ir::ApplicationTy {
+ name: TypeName::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)),
+ substitution: chalk_ir::Substitution::empty(&Interner),
+ }
+ .intern(&Interner);
+ let const_ = FAKE_PLACEHOLDER.to_const(&Interner, usize_ty);
+ chalk_ir::ApplicationTy {
+ name: TypeName::Array,
+ substitution: chalk_ir::Substitution::from_iter(
+ &Interner,
+ vec![arg.cast(&Interner), const_.cast(&Interner)],
+ ),
+ }
+ .intern(&Interner)
+}
+
+/// Here we remove the const from the type we got from Chalk.
+fn array_from_chalk(db: &dyn HirDatabase, subst: chalk_ir::Substitution<Interner>) -> Ty {
+ let tys = subst
+ .iter(&Interner)
+ .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
+ .collect();
+ Ty::apply(TypeCtor::Array, Substs(tys))
+}
+
impl ToChalk for Substs {
type Chalk = chalk_ir::Substitution<Interner>;
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
- chalk_ir::Substitution::from(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
+ chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
}
fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs {
TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
TypeCtor::Slice => TypeName::Slice,
+ TypeCtor::Array => TypeName::Array,
TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
TypeCtor::Str => TypeName::Str,
TypeCtor::FnDef(callable_def) => {
}
TypeCtor::Never => TypeName::Never,
- TypeCtor::Adt(_)
- | TypeCtor::Array
- | TypeCtor::FnPtr { .. }
- | TypeCtor::Closure { .. } => {
+ // FIXME convert these
+ TypeCtor::Adt(_) | TypeCtor::FnPtr { .. } | TypeCtor::Closure { .. } => {
// other TypeCtors get interned and turned into a chalk StructId
let struct_id = db.intern_type_ctor(self).into();
TypeName::Adt(struct_id)
// we shouldn't get these from Chalk
panic!("encountered LifetimeOutlives from Chalk")
}
+
+ chalk_ir::WhereClause::TypeOutlives(_) => {
+ // we shouldn't get these from Chalk
+ panic!("encountered TypeOutlives from Chalk")
+ }
}
}
}
)
});
let value = self.value.to_chalk(db);
- chalk_ir::Canonical { value, binders: chalk_ir::CanonicalVarKinds::from(&Interner, kinds) }
+ chalk_ir::Canonical {
+ value,
+ binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds),
+ }
}
fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
T: HasInterner<Interner = Interner>,
{
chalk_ir::Binders::new(
- chalk_ir::VariableKinds::from(
+ chalk_ir::VariableKinds::from_iter(
&Interner,
std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars),
),