Skip to content

Commit e81c76a

Browse files
committed
Use Chalk's built-in representations of primitive types
For references, we make sure Chalk actually gets a lifetime here.
1 parent 0fb7134 commit e81c76a

File tree

1 file changed

+160
-10
lines changed

1 file changed

+160
-10
lines changed

crates/ra_hir_ty/src/traits/chalk.rs

Lines changed: 160 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,25 @@ use log::debug;
55

66
use chalk_ir::{
77
cast::Cast, fold::shift::Shift, interner::HasInterner, GenericArg, Goal, GoalData,
8-
PlaceholderIndex, TypeName, UniverseIndex,
8+
PlaceholderIndex, Scalar, TypeName, UniverseIndex,
99
};
1010

11-
use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId};
11+
use hir_def::{
12+
type_ref::Mutability, AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup,
13+
TypeAliasId,
14+
};
1215
use ra_db::{
1316
salsa::{InternId, InternKey},
1417
CrateId,
1518
};
1619

1720
use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
1821
use crate::{
19-
db::HirDatabase, display::HirDisplay, method_resolution::TyFingerprint, utils::generics,
22+
db::HirDatabase,
23+
display::HirDisplay,
24+
method_resolution::TyFingerprint,
25+
primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain},
26+
utils::generics,
2027
ApplicationTy, DebruijnIndex, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
2128
};
2229

@@ -330,6 +337,9 @@ impl ToChalk for Ty {
330337
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
331338
match self {
332339
Ty::Apply(apply_ty) => {
340+
if let TypeCtor::Ref(m) = apply_ty.ctor {
341+
return ref_to_chalk(db, m, apply_ty.parameters);
342+
}
333343
let name = apply_ty.ctor.to_chalk(db);
334344
let substitution = apply_ty.parameters.to_chalk(db);
335345
chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
@@ -373,6 +383,7 @@ impl ToChalk for Ty {
373383
match chalk.data(&Interner).clone() {
374384
chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
375385
TypeName::Error => Ty::Unknown,
386+
TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution),
376387
_ => {
377388
let ctor = from_chalk(db, apply_ty.name);
378389
let parameters = from_chalk(db, apply_ty.substitution);
@@ -409,6 +420,41 @@ impl ToChalk for Ty {
409420
}
410421
}
411422

423+
const LIFETIME_PLACEHOLDER: PlaceholderIndex =
424+
PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX };
425+
426+
/// We currently don't model lifetimes, but Chalk does. So, we have to insert a
427+
/// fake lifetime here, because Chalks built-in logic may expect it to be there.
428+
fn ref_to_chalk(
429+
db: &dyn HirDatabase,
430+
mutability: Mutability,
431+
subst: Substs,
432+
) -> chalk_ir::Ty<Interner> {
433+
let arg = subst[0].clone().to_chalk(db);
434+
let lifetime = LIFETIME_PLACEHOLDER.to_lifetime(&Interner);
435+
chalk_ir::ApplicationTy {
436+
name: TypeName::Ref(mutability.to_chalk(db)),
437+
substitution: chalk_ir::Substitution::from(
438+
&Interner,
439+
vec![lifetime.cast(&Interner), arg.cast(&Interner)],
440+
),
441+
}
442+
.intern(&Interner)
443+
}
444+
445+
/// Here we remove the lifetime from the type we got from Chalk.
446+
fn ref_from_chalk(
447+
db: &dyn HirDatabase,
448+
mutability: chalk_ir::Mutability,
449+
subst: chalk_ir::Substitution<Interner>,
450+
) -> Ty {
451+
let tys = subst
452+
.iter(&Interner)
453+
.filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
454+
.collect();
455+
Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
456+
}
457+
412458
impl ToChalk for Substs {
413459
type Chalk = chalk_ir::Substitution<Interner>;
414460

@@ -465,7 +511,31 @@ impl ToChalk for TypeCtor {
465511
let type_id = type_alias.to_chalk(db);
466512
TypeName::AssociatedType(type_id)
467513
}
468-
_ => {
514+
515+
TypeCtor::Bool => TypeName::Scalar(Scalar::Bool),
516+
TypeCtor::Char => TypeName::Scalar(Scalar::Char),
517+
TypeCtor::Int(Uncertain::Known(int_ty)) => TypeName::Scalar(int_ty_to_chalk(int_ty)),
518+
TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X32 })) => {
519+
TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
520+
}
521+
TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X64 })) => {
522+
TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
523+
}
524+
525+
TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
526+
TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
527+
TypeCtor::Slice => TypeName::Slice,
528+
TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
529+
TypeCtor::Str => TypeName::Str,
530+
531+
TypeCtor::Int(Uncertain::Unknown)
532+
| TypeCtor::Float(Uncertain::Unknown)
533+
| TypeCtor::Adt(_)
534+
| TypeCtor::Array
535+
| TypeCtor::FnDef(_)
536+
| TypeCtor::FnPtr { .. }
537+
| TypeCtor::Never
538+
| TypeCtor::Closure { .. } => {
469539
// other TypeCtors get interned and turned into a chalk StructId
470540
let struct_id = db.intern_type_ctor(self).into();
471541
TypeName::Adt(struct_id)
@@ -479,12 +549,27 @@ impl ToChalk for TypeCtor {
479549
TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
480550
TypeName::OpaqueType(_) => unreachable!(),
481551

482-
TypeName::Scalar(_) => unreachable!(),
483-
TypeName::Tuple(_) => unreachable!(),
484-
TypeName::Raw(_) => unreachable!(),
485-
TypeName::Slice => unreachable!(),
486-
TypeName::Ref(_) => unreachable!(),
487-
TypeName::Str => unreachable!(),
552+
TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool,
553+
TypeName::Scalar(Scalar::Char) => TypeCtor::Char,
554+
TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(Uncertain::Known(IntTy {
555+
signedness: Signedness::Signed,
556+
bitness: bitness_from_chalk_int(int_ty),
557+
})),
558+
TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(Uncertain::Known(IntTy {
559+
signedness: Signedness::Unsigned,
560+
bitness: bitness_from_chalk_uint(uint_ty),
561+
})),
562+
TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
563+
TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X32 }))
564+
}
565+
TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
566+
TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X64 }))
567+
}
568+
TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 },
569+
TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)),
570+
TypeName::Slice => TypeCtor::Slice,
571+
TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)),
572+
TypeName::Str => TypeCtor::Str,
488573

489574
TypeName::FnDef(_) => unreachable!(),
490575

@@ -496,6 +581,71 @@ impl ToChalk for TypeCtor {
496581
}
497582
}
498583

584+
fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness {
585+
use chalk_ir::UintTy;
586+
587+
match uint_ty {
588+
UintTy::Usize => IntBitness::Xsize,
589+
UintTy::U8 => IntBitness::X8,
590+
UintTy::U16 => IntBitness::X16,
591+
UintTy::U32 => IntBitness::X32,
592+
UintTy::U64 => IntBitness::X64,
593+
UintTy::U128 => IntBitness::X128,
594+
}
595+
}
596+
597+
fn bitness_from_chalk_int(int_ty: chalk_ir::IntTy) -> IntBitness {
598+
use chalk_ir::IntTy;
599+
600+
match int_ty {
601+
IntTy::Isize => IntBitness::Xsize,
602+
IntTy::I8 => IntBitness::X8,
603+
IntTy::I16 => IntBitness::X16,
604+
IntTy::I32 => IntBitness::X32,
605+
IntTy::I64 => IntBitness::X64,
606+
IntTy::I128 => IntBitness::X128,
607+
}
608+
}
609+
610+
fn int_ty_to_chalk(int_ty: IntTy) -> Scalar {
611+
use chalk_ir::{IntTy, UintTy};
612+
613+
match int_ty.signedness {
614+
Signedness::Signed => Scalar::Int(match int_ty.bitness {
615+
IntBitness::Xsize => IntTy::Isize,
616+
IntBitness::X8 => IntTy::I8,
617+
IntBitness::X16 => IntTy::I16,
618+
IntBitness::X32 => IntTy::I32,
619+
IntBitness::X64 => IntTy::I64,
620+
IntBitness::X128 => IntTy::I128,
621+
}),
622+
Signedness::Unsigned => Scalar::Uint(match int_ty.bitness {
623+
IntBitness::Xsize => UintTy::Usize,
624+
IntBitness::X8 => UintTy::U8,
625+
IntBitness::X16 => UintTy::U16,
626+
IntBitness::X32 => UintTy::U32,
627+
IntBitness::X64 => UintTy::U64,
628+
IntBitness::X128 => UintTy::U128,
629+
}),
630+
}
631+
}
632+
633+
impl ToChalk for Mutability {
634+
type Chalk = chalk_ir::Mutability;
635+
fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk {
636+
match self {
637+
Mutability::Shared => chalk_ir::Mutability::Not,
638+
Mutability::Mut => chalk_ir::Mutability::Mut,
639+
}
640+
}
641+
fn from_chalk(_db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
642+
match chalk {
643+
chalk_ir::Mutability::Mut => Mutability::Mut,
644+
chalk_ir::Mutability::Not => Mutability::Shared,
645+
}
646+
}
647+
}
648+
499649
impl ToChalk for Impl {
500650
type Chalk = ImplId;
501651

0 commit comments

Comments
 (0)