@@ -5,18 +5,25 @@ use log::debug;
5
5
6
6
use chalk_ir:: {
7
7
cast:: Cast , fold:: shift:: Shift , interner:: HasInterner , GenericArg , Goal , GoalData ,
8
- PlaceholderIndex , TypeName , UniverseIndex ,
8
+ PlaceholderIndex , Scalar , TypeName , UniverseIndex ,
9
9
} ;
10
10
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
+ } ;
12
15
use ra_db:: {
13
16
salsa:: { InternId , InternKey } ,
14
17
CrateId ,
15
18
} ;
16
19
17
20
use super :: { builtin, AssocTyValue , Canonical , ChalkContext , Impl , Obligation } ;
18
21
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,
20
27
ApplicationTy , DebruijnIndex , GenericPredicate , ProjectionTy , Substs , TraitRef , Ty , TypeCtor ,
21
28
} ;
22
29
@@ -330,6 +337,9 @@ impl ToChalk for Ty {
330
337
fn to_chalk ( self , db : & dyn HirDatabase ) -> chalk_ir:: Ty < Interner > {
331
338
match self {
332
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
343
let name = apply_ty. ctor . to_chalk ( db) ;
334
344
let substitution = apply_ty. parameters . to_chalk ( db) ;
335
345
chalk_ir:: ApplicationTy { name, substitution } . cast ( & Interner ) . intern ( & Interner )
@@ -373,6 +383,7 @@ impl ToChalk for Ty {
373
383
match chalk. data ( & Interner ) . clone ( ) {
374
384
chalk_ir:: TyData :: Apply ( apply_ty) => match apply_ty. name {
375
385
TypeName :: Error => Ty :: Unknown ,
386
+ TypeName :: Ref ( m) => ref_from_chalk ( db, m, apply_ty. substitution ) ,
376
387
_ => {
377
388
let ctor = from_chalk ( db, apply_ty. name ) ;
378
389
let parameters = from_chalk ( db, apply_ty. substitution ) ;
@@ -409,6 +420,41 @@ impl ToChalk for Ty {
409
420
}
410
421
}
411
422
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
+
412
458
impl ToChalk for Substs {
413
459
type Chalk = chalk_ir:: Substitution < Interner > ;
414
460
@@ -465,7 +511,31 @@ impl ToChalk for TypeCtor {
465
511
let type_id = type_alias. to_chalk ( db) ;
466
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
539
// other TypeCtors get interned and turned into a chalk StructId
470
540
let struct_id = db. intern_type_ctor ( self ) . into ( ) ;
471
541
TypeName :: Adt ( struct_id)
@@ -479,12 +549,27 @@ impl ToChalk for TypeCtor {
479
549
TypeName :: AssociatedType ( type_id) => TypeCtor :: AssociatedType ( from_chalk ( db, type_id) ) ,
480
550
TypeName :: OpaqueType ( _) => unreachable ! ( ) ,
481
551
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 ,
488
573
489
574
TypeName :: FnDef ( _) => unreachable ! ( ) ,
490
575
@@ -496,6 +581,71 @@ impl ToChalk for TypeCtor {
496
581
}
497
582
}
498
583
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
+
499
649
impl ToChalk for Impl {
500
650
type Chalk = ImplId ;
501
651
0 commit comments