@@ -5,18 +5,25 @@ use log::debug;
55
66use 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+ } ;
1215use ra_db:: {
1316 salsa:: { InternId , InternKey } ,
1417 CrateId ,
1518} ;
1619
1720use super :: { builtin, AssocTyValue , Canonical , ChalkContext , Impl , Obligation } ;
1821use 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+
412458impl 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+
499649impl ToChalk for Impl {
500650 type Chalk = ImplId ;
501651
0 commit comments