aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs170
1 files changed, 160 insertions, 10 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index c2d7abd17..b80b67a7a 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -5,10 +5,13 @@ use log::debug;
5 5
6use chalk_ir::{ 6use chalk_ir::{
7 cast::Cast, fold::shift::Shift, interner::HasInterner, GenericArg, Goal, GoalData, 7 cast::Cast, fold::shift::Shift, interner::HasInterner, GenericArg, Goal, GoalData,
8 PlaceholderIndex, TypeName, UniverseIndex, 8 PlaceholderIndex, Scalar, TypeName, UniverseIndex,
9}; 9};
10 10
11use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId}; 11use hir_def::{
12 type_ref::Mutability, AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup,
13 TypeAliasId,
14};
12use ra_db::{ 15use ra_db::{
13 salsa::{InternId, InternKey}, 16 salsa::{InternId, InternKey},
14 CrateId, 17 CrateId,
@@ -16,7 +19,11 @@ use ra_db::{
16 19
17use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; 20use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
18use crate::{ 21use 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,
20 ApplicationTy, DebruijnIndex, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, 27 ApplicationTy, DebruijnIndex, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
21}; 28};
22 29
@@ -330,6 +337,9 @@ impl ToChalk for Ty {
330 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { 337 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
331 match self { 338 match self {
332 Ty::Apply(apply_ty) => { 339 Ty::Apply(apply_ty) => {
340 if let TypeCtor::Ref(m) = apply_ty.ctor {
341 return ref_to_chalk(db, m, apply_ty.parameters);
342 }
333 let name = apply_ty.ctor.to_chalk(db); 343 let name = apply_ty.ctor.to_chalk(db);
334 let substitution = apply_ty.parameters.to_chalk(db); 344 let substitution = apply_ty.parameters.to_chalk(db);
335 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) 345 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
@@ -373,6 +383,7 @@ impl ToChalk for Ty {
373 match chalk.data(&Interner).clone() { 383 match chalk.data(&Interner).clone() {
374 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { 384 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
375 TypeName::Error => Ty::Unknown, 385 TypeName::Error => Ty::Unknown,
386 TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution),
376 _ => { 387 _ => {
377 let ctor = from_chalk(db, apply_ty.name); 388 let ctor = from_chalk(db, apply_ty.name);
378 let parameters = from_chalk(db, apply_ty.substitution); 389 let parameters = from_chalk(db, apply_ty.substitution);
@@ -409,6 +420,41 @@ impl ToChalk for Ty {
409 } 420 }
410} 421}
411 422
423const 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.
428fn 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.
446fn 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
412impl ToChalk for Substs { 458impl ToChalk for Substs {
413 type Chalk = chalk_ir::Substitution<Interner>; 459 type Chalk = chalk_ir::Substitution<Interner>;
414 460
@@ -465,7 +511,31 @@ impl ToChalk for TypeCtor {
465 let type_id = type_alias.to_chalk(db); 511 let type_id = type_alias.to_chalk(db);
466 TypeName::AssociatedType(type_id) 512 TypeName::AssociatedType(type_id)
467 } 513 }
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 { .. } => {
469 // other TypeCtors get interned and turned into a chalk StructId 539 // other TypeCtors get interned and turned into a chalk StructId
470 let struct_id = db.intern_type_ctor(self).into(); 540 let struct_id = db.intern_type_ctor(self).into();
471 TypeName::Adt(struct_id) 541 TypeName::Adt(struct_id)
@@ -479,12 +549,27 @@ impl ToChalk for TypeCtor {
479 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), 549 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
480 TypeName::OpaqueType(_) => unreachable!(), 550 TypeName::OpaqueType(_) => unreachable!(),
481 551
482 TypeName::Scalar(_) => unreachable!(), 552 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool,
483 TypeName::Tuple(_) => unreachable!(), 553 TypeName::Scalar(Scalar::Char) => TypeCtor::Char,
484 TypeName::Raw(_) => unreachable!(), 554 TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(Uncertain::Known(IntTy {
485 TypeName::Slice => unreachable!(), 555 signedness: Signedness::Signed,
486 TypeName::Ref(_) => unreachable!(), 556 bitness: bitness_from_chalk_int(int_ty),
487 TypeName::Str => unreachable!(), 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,
488 573
489 TypeName::FnDef(_) => unreachable!(), 574 TypeName::FnDef(_) => unreachable!(),
490 575
@@ -496,6 +581,71 @@ impl ToChalk for TypeCtor {
496 } 581 }
497} 582}
498 583
584fn 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
597fn 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
610fn 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
633impl 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
499impl ToChalk for Impl { 649impl ToChalk for Impl {
500 type Chalk = ImplId; 650 type Chalk = ImplId;
501 651