2019-05-01 10:06:11 -05:00
//! Conversion code from/to Chalk.
use std ::sync ::Arc ;
2019-05-01 13:50:49 -05:00
use log ::debug ;
2019-07-04 15:05:17 -05:00
use chalk_ir ::{
2019-11-27 03:47:18 -06:00
cast ::Cast , family ::ChalkIr , Identifier , Parameter , PlaceholderIndex , TypeId , TypeKindId ,
TypeName , UniverseIndex ,
2019-07-04 15:05:17 -05:00
} ;
2019-11-15 13:32:58 -06:00
use chalk_rust_ir ::{ AssociatedTyDatum , AssociatedTyValue , ImplDatum , StructDatum , TraitDatum } ;
2019-11-27 00:42:55 -06:00
use ra_db ::CrateId ;
2019-05-01 10:06:11 -05:00
2019-11-26 09:00:36 -06:00
use hir_def ::{
2019-11-27 13:12:09 -06:00
expr ::Expr , lang_item ::LangItemTarget , AssocItemId , AstItemDef , ContainerId , GenericDefId ,
ImplId , Lookup , TraitId , TypeAliasId ,
2019-11-26 09:00:36 -06:00
} ;
2019-10-30 10:56:20 -05:00
use hir_expand ::name ;
2019-05-01 10:06:11 -05:00
use ra_db ::salsa ::{ InternId , InternKey } ;
2019-11-15 13:32:58 -06:00
use super ::{ AssocTyValue , Canonical , ChalkContext , Impl , Obligation } ;
2019-05-01 10:06:11 -05:00
use crate ::{
2019-11-30 05:35:37 -06:00
db ::HirDatabase , display ::HirDisplay , ApplicationTy , GenericPredicate , ProjectionTy , Substs ,
TraitRef , Ty , TypeCtor , TypeWalk ,
2019-05-01 10:06:11 -05:00
} ;
2019-05-05 07:42:12 -05:00
/// This represents a trait whose name we could not resolve.
const UNKNOWN_TRAIT : chalk_ir ::TraitId =
chalk_ir ::TraitId ( chalk_ir ::RawId { index : u32 ::max_value ( ) } ) ;
2019-05-01 10:06:11 -05:00
pub ( super ) trait ToChalk {
type Chalk ;
fn to_chalk ( self , db : & impl HirDatabase ) -> Self ::Chalk ;
fn from_chalk ( db : & impl HirDatabase , chalk : Self ::Chalk ) -> Self ;
}
pub ( super ) fn from_chalk < T , ChalkT > ( db : & impl HirDatabase , chalk : ChalkT ) -> T
where
T : ToChalk < Chalk = ChalkT > ,
{
T ::from_chalk ( db , chalk )
}
impl ToChalk for Ty {
2019-10-15 14:03:34 -05:00
type Chalk = chalk_ir ::Ty < ChalkIr > ;
fn to_chalk ( self , db : & impl HirDatabase ) -> chalk_ir ::Ty < ChalkIr > {
2019-05-01 10:06:11 -05:00
match self {
2019-05-04 08:53:23 -05:00
Ty ::Apply ( apply_ty ) = > {
2019-08-11 08:54:31 -05:00
let name = match apply_ty . ctor {
TypeCtor ::AssociatedType ( type_alias ) = > {
let type_id = type_alias . to_chalk ( db ) ;
TypeName ::AssociatedType ( type_id )
}
_ = > {
// other TypeCtors get interned and turned into a chalk StructId
let struct_id = apply_ty . ctor . to_chalk ( db ) ;
TypeName ::TypeKindId ( struct_id . into ( ) )
}
} ;
2019-05-04 08:53:23 -05:00
let parameters = apply_ty . parameters . to_chalk ( db ) ;
2019-11-15 13:32:58 -06:00
chalk_ir ::ApplicationTy { name , parameters } . cast ( ) . intern ( )
2019-05-04 08:53:23 -05:00
}
2019-08-05 14:13:34 -05:00
Ty ::Projection ( proj_ty ) = > {
let associated_ty_id = proj_ty . associated_ty . to_chalk ( db ) ;
let parameters = proj_ty . parameters . to_chalk ( db ) ;
2019-11-15 13:32:58 -06:00
chalk_ir ::ProjectionTy { associated_ty_id , parameters } . cast ( ) . intern ( )
2019-08-05 14:13:34 -05:00
}
2019-05-01 10:06:11 -05:00
Ty ::Param { idx , .. } = > {
2019-10-15 14:03:34 -05:00
PlaceholderIndex { ui : UniverseIndex ::ROOT , idx : idx as usize } . to_ty ::< ChalkIr > ( )
2019-05-01 10:06:11 -05:00
}
2019-11-15 13:32:58 -06:00
Ty ::Bound ( idx ) = > chalk_ir ::TyData ::BoundVar ( idx as usize ) . intern ( ) ,
2019-05-01 10:06:11 -05:00
Ty ::Infer ( _infer_ty ) = > panic! ( " uncanonicalized infer ty " ) ,
2019-11-15 14:00:27 -06:00
Ty ::Dyn ( predicates ) = > {
let where_clauses = predicates . iter ( ) . cloned ( ) . map ( | p | p . to_chalk ( db ) ) . collect ( ) ;
chalk_ir ::TyData ::Dyn ( make_binders ( where_clauses , 1 ) ) . intern ( )
}
Ty ::Opaque ( predicates ) = > {
let where_clauses = predicates . iter ( ) . cloned ( ) . map ( | p | p . to_chalk ( db ) ) . collect ( ) ;
chalk_ir ::TyData ::Opaque ( make_binders ( where_clauses , 1 ) ) . intern ( )
}
Ty ::Unknown = > {
2019-10-29 07:01:33 -05:00
let parameters = Vec ::new ( ) ;
let name = TypeName ::Error ;
2019-11-15 13:32:58 -06:00
chalk_ir ::ApplicationTy { name , parameters } . cast ( ) . intern ( )
2019-05-05 07:42:12 -05:00
}
2019-05-01 10:06:11 -05:00
}
}
2019-10-15 14:03:34 -05:00
fn from_chalk ( db : & impl HirDatabase , chalk : chalk_ir ::Ty < ChalkIr > ) -> Self {
2019-11-15 13:32:58 -06:00
match chalk . data ( ) . clone ( ) {
chalk_ir ::TyData ::Apply ( apply_ty ) = > {
2019-08-11 08:54:31 -05:00
// FIXME this is kind of hacky due to the fact that
// TypeName::Placeholder is a Ty::Param on our side
2019-05-01 10:06:11 -05:00
match apply_ty . name {
2019-05-04 08:53:23 -05:00
TypeName ::TypeKindId ( TypeKindId ::StructId ( struct_id ) ) = > {
let ctor = from_chalk ( db , struct_id ) ;
let parameters = from_chalk ( db , apply_ty . parameters ) ;
Ty ::Apply ( ApplicationTy { ctor , parameters } )
}
2019-08-11 08:54:31 -05:00
TypeName ::AssociatedType ( type_id ) = > {
let ctor = TypeCtor ::AssociatedType ( from_chalk ( db , type_id ) ) ;
let parameters = from_chalk ( db , apply_ty . parameters ) ;
Ty ::Apply ( ApplicationTy { ctor , parameters } )
}
2019-10-29 07:01:33 -05:00
TypeName ::Error = > Ty ::Unknown ,
2019-05-01 10:06:11 -05:00
// FIXME handle TypeKindId::Trait/Type here
2019-05-04 08:53:23 -05:00
TypeName ::TypeKindId ( _ ) = > unimplemented! ( ) ,
2019-05-01 10:06:11 -05:00
TypeName ::Placeholder ( idx ) = > {
assert_eq! ( idx . ui , UniverseIndex ::ROOT ) ;
Ty ::Param { idx : idx . idx as u32 , name : crate ::Name ::missing ( ) }
}
}
}
2019-11-15 13:32:58 -06:00
chalk_ir ::TyData ::Projection ( proj ) = > {
2019-09-22 13:08:46 -05:00
let associated_ty = from_chalk ( db , proj . associated_ty_id ) ;
let parameters = from_chalk ( db , proj . parameters ) ;
Ty ::Projection ( ProjectionTy { associated_ty , parameters } )
}
2019-11-15 13:32:58 -06:00
chalk_ir ::TyData ::ForAll ( _ ) = > unimplemented! ( ) ,
chalk_ir ::TyData ::BoundVar ( idx ) = > Ty ::Bound ( idx as u32 ) ,
chalk_ir ::TyData ::InferenceVar ( _iv ) = > Ty ::Unknown ,
chalk_ir ::TyData ::Dyn ( where_clauses ) = > {
2019-10-15 14:03:34 -05:00
assert_eq! ( where_clauses . binders . len ( ) , 1 ) ;
let predicates =
where_clauses . value . into_iter ( ) . map ( | c | from_chalk ( db , c ) ) . collect ( ) ;
Ty ::Dyn ( predicates )
}
2019-11-15 13:32:58 -06:00
chalk_ir ::TyData ::Opaque ( where_clauses ) = > {
2019-10-15 14:03:34 -05:00
assert_eq! ( where_clauses . binders . len ( ) , 1 ) ;
let predicates =
where_clauses . value . into_iter ( ) . map ( | c | from_chalk ( db , c ) ) . collect ( ) ;
Ty ::Opaque ( predicates )
}
2019-05-01 10:06:11 -05:00
}
}
}
impl ToChalk for Substs {
2019-10-15 14:03:34 -05:00
type Chalk = Vec < chalk_ir ::Parameter < ChalkIr > > ;
2019-05-01 10:06:11 -05:00
2019-10-15 14:03:34 -05:00
fn to_chalk ( self , db : & impl HirDatabase ) -> Vec < Parameter < ChalkIr > > {
2019-05-01 10:06:11 -05:00
self . iter ( ) . map ( | ty | ty . clone ( ) . to_chalk ( db ) . cast ( ) ) . collect ( )
}
2019-10-15 14:03:34 -05:00
fn from_chalk ( db : & impl HirDatabase , parameters : Vec < chalk_ir ::Parameter < ChalkIr > > ) -> Substs {
2019-09-26 14:37:03 -05:00
let tys = parameters
2019-05-01 10:06:11 -05:00
. into_iter ( )
. map ( | p | match p {
chalk_ir ::Parameter ( chalk_ir ::ParameterKind ::Ty ( ty ) ) = > from_chalk ( db , ty ) ,
chalk_ir ::Parameter ( chalk_ir ::ParameterKind ::Lifetime ( _ ) ) = > unimplemented! ( ) ,
} )
2019-10-13 23:06:05 -05:00
. collect ( ) ;
2019-09-26 14:37:03 -05:00
Substs ( tys )
2019-05-01 10:06:11 -05:00
}
}
impl ToChalk for TraitRef {
2019-10-15 14:03:34 -05:00
type Chalk = chalk_ir ::TraitRef < ChalkIr > ;
2019-05-01 10:06:11 -05:00
2019-10-15 14:03:34 -05:00
fn to_chalk ( self : TraitRef , db : & impl HirDatabase ) -> chalk_ir ::TraitRef < ChalkIr > {
2019-05-01 10:06:11 -05:00
let trait_id = self . trait_ . to_chalk ( db ) ;
let parameters = self . substs . to_chalk ( db ) ;
chalk_ir ::TraitRef { trait_id , parameters }
}
2019-10-15 14:03:34 -05:00
fn from_chalk ( db : & impl HirDatabase , trait_ref : chalk_ir ::TraitRef < ChalkIr > ) -> Self {
2019-05-01 10:06:11 -05:00
let trait_ = from_chalk ( db , trait_ref . trait_id ) ;
let substs = from_chalk ( db , trait_ref . parameters ) ;
TraitRef { trait_ , substs }
}
}
2019-11-26 09:00:36 -06:00
impl ToChalk for TraitId {
2019-05-01 10:06:11 -05:00
type Chalk = chalk_ir ::TraitId ;
fn to_chalk ( self , _db : & impl HirDatabase ) -> chalk_ir ::TraitId {
2019-11-26 09:00:36 -06:00
chalk_ir ::TraitId ( id_to_chalk ( self ) )
2019-05-01 10:06:11 -05:00
}
2019-11-26 09:00:36 -06:00
fn from_chalk ( _db : & impl HirDatabase , trait_id : chalk_ir ::TraitId ) -> TraitId {
id_from_chalk ( trait_id . 0 )
2019-05-01 10:06:11 -05:00
}
}
impl ToChalk for TypeCtor {
type Chalk = chalk_ir ::StructId ;
fn to_chalk ( self , db : & impl HirDatabase ) -> chalk_ir ::StructId {
db . intern_type_ctor ( self ) . into ( )
}
fn from_chalk ( db : & impl HirDatabase , struct_id : chalk_ir ::StructId ) -> TypeCtor {
db . lookup_intern_type_ctor ( struct_id . into ( ) )
}
}
2019-09-09 15:10:58 -05:00
impl ToChalk for Impl {
2019-05-01 10:06:11 -05:00
type Chalk = chalk_ir ::ImplId ;
fn to_chalk ( self , db : & impl HirDatabase ) -> chalk_ir ::ImplId {
2019-11-15 12:28:00 -06:00
db . intern_chalk_impl ( self ) . into ( )
2019-05-01 10:06:11 -05:00
}
2019-09-09 15:10:58 -05:00
fn from_chalk ( db : & impl HirDatabase , impl_id : chalk_ir ::ImplId ) -> Impl {
2019-11-15 12:28:00 -06:00
db . lookup_intern_chalk_impl ( impl_id . into ( ) )
2019-05-01 10:06:11 -05:00
}
}
2019-11-25 09:44:36 -06:00
impl ToChalk for TypeAliasId {
type Chalk = chalk_ir ::TypeId ;
fn to_chalk ( self , _db : & impl HirDatabase ) -> chalk_ir ::TypeId {
chalk_ir ::TypeId ( id_to_chalk ( self ) )
}
fn from_chalk ( _db : & impl HirDatabase , type_alias_id : chalk_ir ::TypeId ) -> TypeAliasId {
id_from_chalk ( type_alias_id . 0 )
}
}
2019-11-15 13:32:58 -06:00
impl ToChalk for AssocTyValue {
type Chalk = chalk_rust_ir ::AssociatedTyValueId ;
fn to_chalk ( self , db : & impl HirDatabase ) -> chalk_rust_ir ::AssociatedTyValueId {
db . intern_assoc_ty_value ( self ) . into ( )
}
fn from_chalk (
db : & impl HirDatabase ,
assoc_ty_value_id : chalk_rust_ir ::AssociatedTyValueId ,
) -> AssocTyValue {
db . lookup_intern_assoc_ty_value ( assoc_ty_value_id . into ( ) )
}
}
2019-05-05 07:21:00 -05:00
impl ToChalk for GenericPredicate {
2019-10-15 14:03:34 -05:00
type Chalk = chalk_ir ::QuantifiedWhereClause < ChalkIr > ;
2019-05-05 07:21:00 -05:00
2019-10-15 14:03:34 -05:00
fn to_chalk ( self , db : & impl HirDatabase ) -> chalk_ir ::QuantifiedWhereClause < ChalkIr > {
2019-05-05 07:21:00 -05:00
match self {
GenericPredicate ::Implemented ( trait_ref ) = > {
make_binders ( chalk_ir ::WhereClause ::Implemented ( trait_ref . to_chalk ( db ) ) , 0 )
}
2019-08-23 10:19:37 -05:00
GenericPredicate ::Projection ( projection_pred ) = > make_binders (
chalk_ir ::WhereClause ::ProjectionEq ( chalk_ir ::ProjectionEq {
projection : projection_pred . projection_ty . to_chalk ( db ) ,
ty : projection_pred . ty . to_chalk ( db ) ,
} ) ,
0 ,
) ,
2019-05-05 07:42:12 -05:00
GenericPredicate ::Error = > {
let impossible_trait_ref = chalk_ir ::TraitRef {
trait_id : UNKNOWN_TRAIT ,
parameters : vec ! [ Ty ::Unknown . to_chalk ( db ) . cast ( ) ] ,
} ;
make_binders ( chalk_ir ::WhereClause ::Implemented ( impossible_trait_ref ) , 0 )
}
2019-05-05 07:21:00 -05:00
}
}
fn from_chalk (
2019-10-15 14:03:34 -05:00
db : & impl HirDatabase ,
where_clause : chalk_ir ::QuantifiedWhereClause < ChalkIr > ,
2019-05-05 07:21:00 -05:00
) -> GenericPredicate {
2019-10-15 14:03:34 -05:00
match where_clause . value {
chalk_ir ::WhereClause ::Implemented ( tr ) = > {
if tr . trait_id = = UNKNOWN_TRAIT {
// FIXME we need an Error enum on the Chalk side to avoid this
return GenericPredicate ::Error ;
}
GenericPredicate ::Implemented ( from_chalk ( db , tr ) )
}
chalk_ir ::WhereClause ::ProjectionEq ( projection_eq ) = > {
let projection_ty = from_chalk ( db , projection_eq . projection ) ;
let ty = from_chalk ( db , projection_eq . ty ) ;
GenericPredicate ::Projection ( super ::ProjectionPredicate { projection_ty , ty } )
}
}
2019-05-05 07:21:00 -05:00
}
}
2019-05-12 10:53:44 -05:00
impl ToChalk for ProjectionTy {
2019-10-15 14:03:34 -05:00
type Chalk = chalk_ir ::ProjectionTy < ChalkIr > ;
2019-05-12 10:53:44 -05:00
2019-10-15 14:03:34 -05:00
fn to_chalk ( self , db : & impl HirDatabase ) -> chalk_ir ::ProjectionTy < ChalkIr > {
2019-05-12 10:53:44 -05:00
chalk_ir ::ProjectionTy {
associated_ty_id : self . associated_ty . to_chalk ( db ) ,
parameters : self . parameters . to_chalk ( db ) ,
}
}
2019-10-15 14:03:34 -05:00
fn from_chalk (
db : & impl HirDatabase ,
projection_ty : chalk_ir ::ProjectionTy < ChalkIr > ,
) -> ProjectionTy {
2019-05-12 10:53:44 -05:00
ProjectionTy {
associated_ty : from_chalk ( db , projection_ty . associated_ty_id ) ,
parameters : from_chalk ( db , projection_ty . parameters ) ,
}
}
}
2019-07-07 11:14:56 -05:00
impl ToChalk for super ::ProjectionPredicate {
2019-10-15 14:03:34 -05:00
type Chalk = chalk_ir ::Normalize < ChalkIr > ;
2019-07-07 11:14:56 -05:00
2019-10-15 14:03:34 -05:00
fn to_chalk ( self , db : & impl HirDatabase ) -> chalk_ir ::Normalize < ChalkIr > {
2019-07-07 11:14:56 -05:00
chalk_ir ::Normalize {
projection : self . projection_ty . to_chalk ( db ) ,
ty : self . ty . to_chalk ( db ) ,
}
}
2019-10-15 14:03:34 -05:00
fn from_chalk ( _db : & impl HirDatabase , _normalize : chalk_ir ::Normalize < ChalkIr > ) -> Self {
2019-07-07 11:14:56 -05:00
unimplemented! ( )
}
}
2019-07-08 14:43:52 -05:00
impl ToChalk for Obligation {
2019-10-15 14:03:34 -05:00
type Chalk = chalk_ir ::DomainGoal < ChalkIr > ;
2019-07-08 14:43:52 -05:00
2019-10-15 14:03:34 -05:00
fn to_chalk ( self , db : & impl HirDatabase ) -> chalk_ir ::DomainGoal < ChalkIr > {
2019-07-08 14:43:52 -05:00
match self {
Obligation ::Trait ( tr ) = > tr . to_chalk ( db ) . cast ( ) ,
Obligation ::Projection ( pr ) = > pr . to_chalk ( db ) . cast ( ) ,
}
}
2019-10-15 14:03:34 -05:00
fn from_chalk ( _db : & impl HirDatabase , _goal : chalk_ir ::DomainGoal < ChalkIr > ) -> Self {
2019-07-08 14:43:52 -05:00
unimplemented! ( )
}
}
2019-06-29 10:40:00 -05:00
impl < T > ToChalk for Canonical < T >
where
T : ToChalk ,
{
type Chalk = chalk_ir ::Canonical < T ::Chalk > ;
fn to_chalk ( self , db : & impl HirDatabase ) -> chalk_ir ::Canonical < T ::Chalk > {
let parameter = chalk_ir ::ParameterKind ::Ty ( chalk_ir ::UniverseIndex ::ROOT ) ;
let value = self . value . to_chalk ( db ) ;
let canonical = chalk_ir ::Canonical { value , binders : vec ! [ parameter ; self . num_vars ] } ;
canonical
}
fn from_chalk ( db : & impl HirDatabase , canonical : chalk_ir ::Canonical < T ::Chalk > ) -> Canonical < T > {
Canonical { num_vars : canonical . binders . len ( ) , value : from_chalk ( db , canonical . value ) }
}
}
2019-07-09 14:34:23 -05:00
impl ToChalk for Arc < super ::TraitEnvironment > {
2019-10-29 07:01:33 -05:00
type Chalk = chalk_ir ::Environment < ChalkIr > ;
2019-06-29 10:40:00 -05:00
2019-10-29 07:01:33 -05:00
fn to_chalk ( self , db : & impl HirDatabase ) -> chalk_ir ::Environment < ChalkIr > {
2019-06-29 12:14:52 -05:00
let mut clauses = Vec ::new ( ) ;
for pred in & self . predicates {
if pred . is_error ( ) {
// for env, we just ignore errors
continue ;
}
2019-10-15 14:03:34 -05:00
let program_clause : chalk_ir ::ProgramClause < ChalkIr > = pred . clone ( ) . to_chalk ( db ) . cast ( ) ;
2019-09-07 09:30:37 -05:00
clauses . push ( program_clause . into_from_env_clause ( ) ) ;
2019-06-29 12:14:52 -05:00
}
chalk_ir ::Environment ::new ( ) . add_clauses ( clauses )
2019-06-29 10:40:00 -05:00
}
fn from_chalk (
_db : & impl HirDatabase ,
2019-10-29 07:01:33 -05:00
_env : chalk_ir ::Environment < ChalkIr > ,
2019-07-09 14:34:23 -05:00
) -> Arc < super ::TraitEnvironment > {
2019-06-29 12:14:52 -05:00
unimplemented! ( )
2019-06-29 10:40:00 -05:00
}
}
2019-10-15 14:03:34 -05:00
impl < T : ToChalk > ToChalk for super ::InEnvironment < T >
where
T ::Chalk : chalk_ir ::family ::HasTypeFamily < TypeFamily = ChalkIr > ,
{
2019-06-29 10:40:00 -05:00
type Chalk = chalk_ir ::InEnvironment < T ::Chalk > ;
fn to_chalk ( self , db : & impl HirDatabase ) -> chalk_ir ::InEnvironment < T ::Chalk > {
chalk_ir ::InEnvironment {
environment : self . environment . to_chalk ( db ) ,
goal : self . value . to_chalk ( db ) ,
}
}
fn from_chalk (
db : & impl HirDatabase ,
in_env : chalk_ir ::InEnvironment < T ::Chalk > ,
) -> super ::InEnvironment < T > {
super ::InEnvironment {
environment : from_chalk ( db , in_env . environment ) ,
value : from_chalk ( db , in_env . goal ) ,
}
}
}
2019-05-01 10:06:11 -05:00
fn make_binders < T > ( value : T , num_vars : usize ) -> chalk_ir ::Binders < T > {
chalk_ir ::Binders {
value ,
binders : std ::iter ::repeat ( chalk_ir ::ParameterKind ::Ty ( ( ) ) ) . take ( num_vars ) . collect ( ) ,
}
}
2019-05-05 07:21:00 -05:00
fn convert_where_clauses (
db : & impl HirDatabase ,
2019-11-25 06:39:12 -06:00
def : GenericDefId ,
2019-05-05 07:21:00 -05:00
substs : & Substs ,
2019-10-15 14:03:34 -05:00
) -> Vec < chalk_ir ::QuantifiedWhereClause < ChalkIr > > {
2019-05-05 07:21:00 -05:00
let generic_predicates = db . generic_predicates ( def ) ;
let mut result = Vec ::with_capacity ( generic_predicates . len ( ) ) ;
for pred in generic_predicates . iter ( ) {
2019-05-11 13:31:41 -05:00
if pred . is_error ( ) {
// HACK: Return just the single predicate (which is always false
// anyway), otherwise Chalk can easily get into slow situations
return vec! [ pred . clone ( ) . subst ( substs ) . to_chalk ( db ) ] ;
}
2019-05-05 07:42:12 -05:00
result . push ( pred . clone ( ) . subst ( substs ) . to_chalk ( db ) ) ;
2019-05-05 07:21:00 -05:00
}
2019-05-05 07:42:12 -05:00
result
2019-05-05 07:21:00 -05:00
}
2019-11-16 06:21:51 -06:00
impl < ' a , DB > chalk_solve ::RustIrDatabase < ChalkIr > for ChalkContext < ' a , DB >
2019-05-01 10:06:11 -05:00
where
DB : HirDatabase ,
{
2019-11-16 06:21:51 -06:00
fn associated_ty_data ( & self , id : TypeId ) -> Arc < AssociatedTyDatum < ChalkIr > > {
2019-06-26 04:54:13 -05:00
self . db . associated_ty_data ( id )
2019-05-01 10:06:11 -05:00
}
2019-11-16 06:21:51 -06:00
fn trait_datum ( & self , trait_id : chalk_ir ::TraitId ) -> Arc < TraitDatum < ChalkIr > > {
2019-06-26 04:54:13 -05:00
self . db . trait_datum ( self . krate , trait_id )
2019-05-01 10:06:11 -05:00
}
2019-11-16 06:21:51 -06:00
fn struct_datum ( & self , struct_id : chalk_ir ::StructId ) -> Arc < StructDatum < ChalkIr > > {
2019-06-26 04:54:13 -05:00
self . db . struct_datum ( self . krate , struct_id )
2019-05-01 10:06:11 -05:00
}
2019-11-27 03:47:18 -06:00
fn impl_datum ( & self , impl_id : chalk_ir ::ImplId ) -> Arc < ImplDatum < ChalkIr > > {
2019-06-26 04:54:13 -05:00
self . db . impl_datum ( self . krate , impl_id )
2019-05-01 10:06:11 -05:00
}
2019-09-24 11:27:31 -05:00
fn impls_for_trait (
& self ,
trait_id : chalk_ir ::TraitId ,
2019-10-15 14:03:34 -05:00
parameters : & [ Parameter < ChalkIr > ] ,
2019-11-27 03:47:18 -06:00
) -> Vec < chalk_ir ::ImplId > {
2019-05-01 13:50:49 -05:00
debug! ( " impls_for_trait {:?} " , trait_id ) ;
2019-05-05 07:42:12 -05:00
if trait_id = = UNKNOWN_TRAIT {
return Vec ::new ( ) ;
}
2019-11-26 09:00:36 -06:00
let trait_ : TraitId = from_chalk ( self . db , trait_id ) ;
2019-09-09 15:10:58 -05:00
let mut result : Vec < _ > = self
2019-05-07 10:35:45 -05:00
. db
2019-11-27 00:42:55 -06:00
. impls_for_trait ( self . krate , trait_ . into ( ) )
2019-05-01 10:06:11 -05:00
. iter ( )
2019-09-09 15:10:58 -05:00
. copied ( )
2019-11-27 03:02:54 -06:00
. map ( | it | Impl ::ImplBlock ( it . into ( ) ) )
2019-09-09 15:10:58 -05:00
. map ( | impl_ | impl_ . to_chalk ( self . db ) )
2019-05-07 10:35:45 -05:00
. collect ( ) ;
2019-09-09 15:10:58 -05:00
let ty : Ty = from_chalk ( self . db , parameters [ 0 ] . assert_ty_ref ( ) . clone ( ) ) ;
if let Ty ::Apply ( ApplicationTy { ctor : TypeCtor ::Closure { def , expr } , .. } ) = ty {
2019-09-24 16:04:33 -05:00
for & fn_trait in
[ super ::FnTrait ::FnOnce , super ::FnTrait ::FnMut , super ::FnTrait ::Fn ] . iter ( )
2019-09-09 15:10:58 -05:00
{
if let Some ( actual_trait ) = get_fn_trait ( self . db , self . krate , fn_trait ) {
2019-11-26 09:00:36 -06:00
if trait_ = = actual_trait {
2019-09-09 15:10:58 -05:00
let impl_ = super ::ClosureFnTraitImplData { def , expr , fn_trait } ;
result . push ( Impl ::ClosureFnTraitImpl ( impl_ ) . to_chalk ( self . db ) ) ;
}
}
}
}
2019-05-07 10:35:45 -05:00
debug! ( " impls_for_trait returned {} impls " , result . len ( ) ) ;
result
2019-05-01 10:06:11 -05:00
}
2019-05-01 10:57:56 -05:00
fn impl_provided_for (
& self ,
auto_trait_id : chalk_ir ::TraitId ,
struct_id : chalk_ir ::StructId ,
) -> bool {
2019-05-01 13:50:49 -05:00
debug! ( " impl_provided_for {:?}, {:?} " , auto_trait_id , struct_id ) ;
2019-05-01 10:06:11 -05:00
false // FIXME
}
fn type_name ( & self , _id : TypeKindId ) -> Identifier {
unimplemented! ( )
}
2019-11-15 13:32:58 -06:00
fn associated_ty_value (
2019-05-01 10:06:11 -05:00
& self ,
2019-11-15 13:32:58 -06:00
id : chalk_rust_ir ::AssociatedTyValueId ,
2019-11-16 06:21:51 -06:00
) -> Arc < AssociatedTyValue < ChalkIr > > {
2019-11-27 00:42:55 -06:00
self . db . associated_ty_value ( self . krate . into ( ) , id )
2019-05-01 10:06:11 -05:00
}
2019-10-15 14:03:34 -05:00
fn custom_clauses ( & self ) -> Vec < chalk_ir ::ProgramClause < ChalkIr > > {
2019-05-01 16:26:42 -05:00
vec! [ ]
}
2019-09-23 13:33:47 -05:00
fn local_impls_to_coherence_check (
& self ,
_trait_id : chalk_ir ::TraitId ,
) -> Vec < chalk_ir ::ImplId > {
// We don't do coherence checking (yet)
unimplemented! ( )
2019-05-01 16:26:42 -05:00
}
2019-05-01 10:06:11 -05:00
}
2019-06-26 04:54:13 -05:00
pub ( crate ) fn associated_ty_data_query (
db : & impl HirDatabase ,
id : TypeId ,
2019-11-16 06:21:51 -06:00
) -> Arc < AssociatedTyDatum < ChalkIr > > {
2019-06-26 04:54:13 -05:00
debug! ( " associated_ty_data {:?} " , id ) ;
2019-11-25 09:58:17 -06:00
let type_alias : TypeAliasId = from_chalk ( db , id ) ;
let trait_ = match type_alias . lookup ( db ) . container {
ContainerId ::TraitId ( t ) = > t ,
2019-06-26 04:54:13 -05:00
_ = > panic! ( " associated type not in trait " ) ,
} ;
2019-11-25 09:58:17 -06:00
let generic_params = db . generic_params ( type_alias . into ( ) ) ;
2019-11-15 13:32:58 -06:00
let bound_data = chalk_rust_ir ::AssociatedTyDatumBound {
// FIXME add bounds and where clauses
bounds : vec ! [ ] ,
where_clauses : vec ! [ ] ,
} ;
2019-06-26 04:54:13 -05:00
let datum = AssociatedTyDatum {
2019-11-26 09:00:36 -06:00
trait_id : trait_ . to_chalk ( db ) ,
2019-06-26 04:54:13 -05:00
id ,
2019-11-25 09:58:17 -06:00
name : lalrpop_intern ::intern ( & db . type_alias_data ( type_alias ) . name . to_string ( ) ) ,
2019-11-15 13:32:58 -06:00
binders : make_binders ( bound_data , generic_params . count_params_including_parent ( ) ) ,
2019-06-26 04:54:13 -05:00
} ;
Arc ::new ( datum )
}
pub ( crate ) fn trait_datum_query (
db : & impl HirDatabase ,
2019-11-27 00:42:55 -06:00
krate : CrateId ,
2019-06-26 04:54:13 -05:00
trait_id : chalk_ir ::TraitId ,
2019-11-16 06:21:51 -06:00
) -> Arc < TraitDatum < ChalkIr > > {
2019-06-26 04:54:13 -05:00
debug! ( " trait_datum {:?} " , trait_id ) ;
if trait_id = = UNKNOWN_TRAIT {
2019-11-15 13:32:58 -06:00
let trait_datum_bound = chalk_rust_ir ::TraitDatumBound { where_clauses : Vec ::new ( ) } ;
2019-10-10 13:51:50 -05:00
let flags = chalk_rust_ir ::TraitFlags {
auto : false ,
marker : false ,
upstream : true ,
fundamental : false ,
non_enumerable : true ,
2019-11-15 13:32:58 -06:00
coinductive : false ,
2019-10-10 13:51:50 -05:00
} ;
2019-11-15 13:32:58 -06:00
return Arc ::new ( TraitDatum {
id : trait_id ,
binders : make_binders ( trait_datum_bound , 1 ) ,
flags ,
associated_ty_ids : vec ! [ ] ,
} ) ;
2019-06-26 04:54:13 -05:00
}
2019-11-26 09:00:36 -06:00
let trait_ : TraitId = from_chalk ( db , trait_id ) ;
let trait_data = db . trait_data ( trait_ ) ;
debug! ( " trait {:?} = {:?} " , trait_id , trait_data . name ) ;
let generic_params = db . generic_params ( trait_ . into ( ) ) ;
2019-06-26 04:54:13 -05:00
let bound_vars = Substs ::bound_vars ( & generic_params ) ;
let flags = chalk_rust_ir ::TraitFlags {
2019-11-26 09:00:36 -06:00
auto : trait_data . auto ,
2019-11-27 00:42:55 -06:00
upstream : trait_ . module ( db ) . krate ! = krate ,
2019-09-09 14:24:24 -05:00
non_enumerable : true ,
2019-11-15 13:32:58 -06:00
coinductive : false , // only relevant for Chalk testing
2019-06-26 04:54:13 -05:00
// FIXME set these flags correctly
marker : false ,
fundamental : false ,
} ;
2019-11-26 09:00:36 -06:00
let where_clauses = convert_where_clauses ( db , trait_ . into ( ) , & bound_vars ) ;
let associated_ty_ids =
trait_data . associated_types ( ) . map ( | type_alias | type_alias . to_chalk ( db ) ) . collect ( ) ;
2019-11-15 13:32:58 -06:00
let trait_datum_bound = chalk_rust_ir ::TraitDatumBound { where_clauses } ;
let trait_datum = TraitDatum {
id : trait_id ,
binders : make_binders ( trait_datum_bound , bound_vars . len ( ) ) ,
flags ,
associated_ty_ids ,
} ;
2019-06-26 04:54:13 -05:00
Arc ::new ( trait_datum )
}
pub ( crate ) fn struct_datum_query (
db : & impl HirDatabase ,
2019-11-27 00:42:55 -06:00
krate : CrateId ,
2019-06-26 04:54:13 -05:00
struct_id : chalk_ir ::StructId ,
2019-11-16 06:21:51 -06:00
) -> Arc < StructDatum < ChalkIr > > {
2019-06-26 04:54:13 -05:00
debug! ( " struct_datum {:?} " , struct_id ) ;
2019-09-26 14:37:03 -05:00
let type_ctor : TypeCtor = from_chalk ( db , struct_id ) ;
2019-06-26 04:54:13 -05:00
debug! ( " struct {:?} = {:?} " , struct_id , type_ctor ) ;
2019-09-26 14:37:03 -05:00
let num_params = type_ctor . num_ty_params ( db ) ;
let upstream = type_ctor . krate ( db ) ! = Some ( krate ) ;
let where_clauses = type_ctor
. as_generic_def ( )
. map ( | generic_def | {
2019-11-21 07:23:02 -06:00
let generic_params = db . generic_params ( generic_def . into ( ) ) ;
2019-06-26 04:54:13 -05:00
let bound_vars = Substs ::bound_vars ( & generic_params ) ;
2019-09-26 14:37:03 -05:00
convert_where_clauses ( db , generic_def , & bound_vars )
} )
. unwrap_or_else ( Vec ::new ) ;
2019-06-26 04:54:13 -05:00
let flags = chalk_rust_ir ::StructFlags {
upstream ,
// FIXME set fundamental flag correctly
fundamental : false ,
} ;
let struct_datum_bound = chalk_rust_ir ::StructDatumBound {
fields : Vec ::new ( ) , // FIXME add fields (only relevant for auto traits)
where_clauses ,
} ;
2019-11-15 13:32:58 -06:00
let struct_datum =
StructDatum { id : struct_id , binders : make_binders ( struct_datum_bound , num_params ) , flags } ;
2019-06-26 04:54:13 -05:00
Arc ::new ( struct_datum )
}
pub ( crate ) fn impl_datum_query (
db : & impl HirDatabase ,
2019-11-27 00:42:55 -06:00
krate : CrateId ,
2019-11-27 03:47:18 -06:00
impl_id : chalk_ir ::ImplId ,
2019-11-16 06:21:51 -06:00
) -> Arc < ImplDatum < ChalkIr > > {
2019-06-26 04:54:13 -05:00
let _p = ra_prof ::profile ( " impl_datum " ) ;
debug! ( " impl_datum {:?} " , impl_id ) ;
2019-09-09 15:10:58 -05:00
let impl_ : Impl = from_chalk ( db , impl_id ) ;
match impl_ {
Impl ::ImplBlock ( impl_block ) = > impl_block_datum ( db , krate , impl_id , impl_block ) ,
2019-11-15 13:32:58 -06:00
Impl ::ClosureFnTraitImpl ( data ) = > closure_fn_trait_impl_datum ( db , krate , data ) ,
2019-09-09 15:10:58 -05:00
}
2019-11-15 13:32:58 -06:00
. unwrap_or_else ( invalid_impl_datum )
2019-09-09 15:10:58 -05:00
}
fn impl_block_datum (
db : & impl HirDatabase ,
2019-11-27 00:42:55 -06:00
krate : CrateId ,
2019-11-27 03:47:18 -06:00
chalk_id : chalk_ir ::ImplId ,
2019-09-09 15:10:58 -05:00
impl_id : ImplId ,
2019-11-16 06:21:51 -06:00
) -> Option < Arc < ImplDatum < ChalkIr > > > {
2019-11-30 05:35:37 -06:00
let trait_ref = db . impl_trait ( impl_id ) ? ;
2019-11-27 03:47:18 -06:00
let impl_data = db . impl_data ( impl_id ) ;
let generic_params = db . generic_params ( impl_id . into ( ) ) ;
2019-06-26 04:54:13 -05:00
let bound_vars = Substs ::bound_vars ( & generic_params ) ;
2019-11-27 03:47:18 -06:00
let trait_ref = trait_ref . subst ( & bound_vars ) ;
2019-11-15 13:32:58 -06:00
let trait_ = trait_ref . trait_ ;
2019-11-27 03:47:18 -06:00
let impl_type = if impl_id . module ( db ) . krate = = krate {
2019-06-26 04:54:13 -05:00
chalk_rust_ir ::ImplType ::Local
} else {
chalk_rust_ir ::ImplType ::External
} ;
2019-11-27 03:47:18 -06:00
let where_clauses = convert_where_clauses ( db , impl_id . into ( ) , & bound_vars ) ;
let negative = impl_data . is_negative ;
2019-06-26 04:54:13 -05:00
debug! (
" impl {:?}: {}{} where {:?} " ,
2019-11-27 03:47:18 -06:00
chalk_id ,
2019-06-26 04:54:13 -05:00
if negative { " ! " } else { " " } ,
trait_ref . display ( db ) ,
where_clauses
) ;
let trait_ref = trait_ref . to_chalk ( db ) ;
2019-10-10 13:51:50 -05:00
let polarity = if negative {
chalk_rust_ir ::Polarity ::Negative
} else {
chalk_rust_ir ::Polarity ::Positive
2019-06-26 04:54:13 -05:00
} ;
2019-10-10 13:51:50 -05:00
2019-11-15 13:32:58 -06:00
let impl_datum_bound = chalk_rust_ir ::ImplDatumBound { trait_ref , where_clauses } ;
2019-11-26 09:00:36 -06:00
let trait_data = db . trait_data ( trait_ ) ;
2019-11-27 03:47:18 -06:00
let associated_ty_value_ids = impl_data
. items
. iter ( )
2019-11-15 13:32:58 -06:00
. filter_map ( | item | match item {
2019-11-27 03:47:18 -06:00
AssocItemId ::TypeAliasId ( type_alias ) = > Some ( * type_alias ) ,
2019-11-15 13:32:58 -06:00
_ = > None ,
} )
2019-11-27 03:47:18 -06:00
. filter ( | & type_alias | {
2019-11-15 13:32:58 -06:00
// don't include associated types that don't exist in the trait
2019-11-27 03:47:18 -06:00
let name = & db . type_alias_data ( type_alias ) . name ;
trait_data . associated_type_by_name ( name ) . is_some ( )
2019-11-15 13:32:58 -06:00
} )
2019-11-27 03:47:18 -06:00
. map ( | type_alias | AssocTyValue ::TypeAlias ( type_alias ) . to_chalk ( db ) )
2019-11-15 13:32:58 -06:00
. collect ( ) ;
2019-06-26 04:54:13 -05:00
debug! ( " impl_datum: {:?} " , impl_datum_bound ) ;
2019-10-10 13:51:50 -05:00
let impl_datum = ImplDatum {
binders : make_binders ( impl_datum_bound , bound_vars . len ( ) ) ,
impl_type ,
polarity ,
2019-11-15 13:32:58 -06:00
associated_ty_value_ids ,
2019-10-10 13:51:50 -05:00
} ;
2019-11-15 13:32:58 -06:00
Some ( Arc ::new ( impl_datum ) )
2019-06-26 04:54:13 -05:00
}
2019-11-16 06:21:51 -06:00
fn invalid_impl_datum ( ) -> Arc < ImplDatum < ChalkIr > > {
2019-09-09 15:10:58 -05:00
let trait_ref = chalk_ir ::TraitRef {
trait_id : UNKNOWN_TRAIT ,
2019-11-15 13:32:58 -06:00
parameters : vec ! [ chalk_ir ::TyData ::BoundVar ( 0 ) . cast ( ) . intern ( ) . cast ( ) ] ,
2019-10-10 13:51:50 -05:00
} ;
2019-11-15 13:32:58 -06:00
let impl_datum_bound = chalk_rust_ir ::ImplDatumBound { trait_ref , where_clauses : Vec ::new ( ) } ;
2019-10-10 13:51:50 -05:00
let impl_datum = ImplDatum {
binders : make_binders ( impl_datum_bound , 1 ) ,
2019-09-09 15:10:58 -05:00
impl_type : chalk_rust_ir ::ImplType ::External ,
2019-10-10 13:51:50 -05:00
polarity : chalk_rust_ir ::Polarity ::Positive ,
2019-11-15 13:32:58 -06:00
associated_ty_value_ids : Vec ::new ( ) ,
2019-09-09 15:10:58 -05:00
} ;
Arc ::new ( impl_datum )
}
fn closure_fn_trait_impl_datum (
db : & impl HirDatabase ,
2019-11-27 00:42:55 -06:00
krate : CrateId ,
2019-09-09 15:10:58 -05:00
data : super ::ClosureFnTraitImplData ,
2019-11-16 06:21:51 -06:00
) -> Option < Arc < ImplDatum < ChalkIr > > > {
2019-09-09 15:10:58 -05:00
// for some closure |X, Y| -> Z:
// impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V }
let trait_ = get_fn_trait ( db , krate , data . fn_trait ) ? ; // get corresponding fn trait
2019-11-15 13:32:58 -06:00
// validate FnOnce trait, since we need it in the assoc ty value definition
// and don't want to return a valid value only to find out later that FnOnce
// is broken
let fn_once_trait = get_fn_trait ( db , krate , super ::FnTrait ::FnOnce ) ? ;
2019-11-26 08:21:29 -06:00
let _output = db . trait_data ( fn_once_trait ) . associated_type_by_name ( & name ::OUTPUT_TYPE ) ? ;
2019-11-15 13:32:58 -06:00
2019-11-24 11:53:42 -06:00
let num_args : u16 = match & db . body ( data . def . into ( ) ) [ data . expr ] {
2019-11-27 08:46:02 -06:00
Expr ::Lambda { args , .. } = > args . len ( ) as u16 ,
2019-09-09 15:10:58 -05:00
_ = > {
log ::warn! ( " closure for closure type {:?} not found " , data ) ;
0
}
} ;
let arg_ty = Ty ::apply (
TypeCtor ::Tuple { cardinality : num_args } ,
2019-09-26 14:37:03 -05:00
Substs ::builder ( num_args as usize ) . fill_with_bound_vars ( 0 ) . build ( ) ,
2019-09-09 15:10:58 -05:00
) ;
let sig_ty = Ty ::apply (
TypeCtor ::FnPtr { num_args } ,
2019-09-26 14:37:03 -05:00
Substs ::builder ( num_args as usize + 1 ) . fill_with_bound_vars ( 0 ) . build ( ) ,
2019-09-09 15:10:58 -05:00
) ;
let self_ty = Ty ::apply_one ( TypeCtor ::Closure { def : data . def , expr : data . expr } , sig_ty ) ;
2019-09-26 14:37:03 -05:00
let trait_ref = TraitRef {
2019-11-26 08:21:29 -06:00
trait_ : trait_ . into ( ) ,
substs : Substs ::build_for_def ( db , trait_ ) . push ( self_ty ) . push ( arg_ty ) . build ( ) ,
2019-09-26 14:37:03 -05:00
} ;
2019-09-09 15:10:58 -05:00
2019-11-15 13:32:58 -06:00
let output_ty_id = AssocTyValue ::ClosureFnTraitImplOutput ( data . clone ( ) ) . to_chalk ( db ) ;
2019-09-09 15:10:58 -05:00
let impl_type = chalk_rust_ir ::ImplType ::External ;
let impl_datum_bound = chalk_rust_ir ::ImplDatumBound {
2019-10-10 13:51:50 -05:00
trait_ref : trait_ref . to_chalk ( db ) ,
2019-09-09 15:10:58 -05:00
where_clauses : Vec ::new ( ) ,
2019-10-10 13:51:50 -05:00
} ;
let impl_datum = ImplDatum {
binders : make_binders ( impl_datum_bound , num_args as usize + 1 ) ,
2019-09-09 15:10:58 -05:00
impl_type ,
2019-10-10 13:51:50 -05:00
polarity : chalk_rust_ir ::Polarity ::Positive ,
2019-11-15 13:32:58 -06:00
associated_ty_value_ids : vec ! [ output_ty_id ] ,
2019-09-09 15:10:58 -05:00
} ;
Some ( Arc ::new ( impl_datum ) )
}
2019-11-15 13:32:58 -06:00
pub ( crate ) fn associated_ty_value_query (
db : & impl HirDatabase ,
2019-11-27 00:42:55 -06:00
krate : CrateId ,
2019-11-15 13:32:58 -06:00
id : chalk_rust_ir ::AssociatedTyValueId ,
2019-11-16 06:21:51 -06:00
) -> Arc < chalk_rust_ir ::AssociatedTyValue < ChalkIr > > {
2019-11-15 13:32:58 -06:00
let data : AssocTyValue = from_chalk ( db , id ) ;
match data {
AssocTyValue ::TypeAlias ( type_alias ) = > {
type_alias_associated_ty_value ( db , krate , type_alias )
}
AssocTyValue ::ClosureFnTraitImplOutput ( data ) = > {
closure_fn_trait_output_assoc_ty_value ( db , krate , data )
}
}
}
fn type_alias_associated_ty_value (
db : & impl HirDatabase ,
2019-11-27 00:42:55 -06:00
_krate : CrateId ,
2019-11-27 02:40:10 -06:00
type_alias : TypeAliasId ,
2019-11-16 06:21:51 -06:00
) -> Arc < AssociatedTyValue < ChalkIr > > {
2019-11-27 02:40:10 -06:00
let type_alias_data = db . type_alias_data ( type_alias ) ;
let impl_id = match type_alias . lookup ( db ) . container {
ContainerId ::ImplId ( it ) = > it ,
_ = > panic! ( " assoc ty value should be in impl " ) ,
} ;
2019-11-30 05:35:37 -06:00
let trait_ref = db . impl_trait ( impl_id ) . expect ( " assoc ty value should not exist " ) ; // we don't return any assoc ty values if the impl'd trait can't be resolved
2019-11-27 02:40:10 -06:00
2019-11-26 08:21:29 -06:00
let assoc_ty = db
2019-11-27 13:12:09 -06:00
. trait_data ( trait_ref . trait_ )
2019-11-27 02:40:10 -06:00
. associated_type_by_name ( & type_alias_data . name )
2019-11-26 08:21:29 -06:00
. expect ( " assoc ty value should not exist " ) ; // validated when building the impl data as well
2019-11-27 02:40:10 -06:00
let generic_params = db . generic_params ( impl_id . into ( ) ) ;
2019-11-15 13:32:58 -06:00
let bound_vars = Substs ::bound_vars ( & generic_params ) ;
2019-11-27 02:40:10 -06:00
let ty = db . ty ( type_alias . into ( ) ) . subst ( & bound_vars ) ;
2019-11-15 13:32:58 -06:00
let value_bound = chalk_rust_ir ::AssociatedTyValueBound { ty : ty . to_chalk ( db ) } ;
let value = chalk_rust_ir ::AssociatedTyValue {
2019-11-27 02:40:10 -06:00
impl_id : Impl ::ImplBlock ( impl_id . into ( ) ) . to_chalk ( db ) ,
2019-11-15 13:32:58 -06:00
associated_ty_id : assoc_ty . to_chalk ( db ) ,
value : make_binders ( value_bound , bound_vars . len ( ) ) ,
} ;
Arc ::new ( value )
}
fn closure_fn_trait_output_assoc_ty_value (
db : & impl HirDatabase ,
2019-11-27 00:42:55 -06:00
krate : CrateId ,
2019-11-15 13:32:58 -06:00
data : super ::ClosureFnTraitImplData ,
2019-11-16 06:21:51 -06:00
) -> Arc < AssociatedTyValue < ChalkIr > > {
2019-11-15 13:32:58 -06:00
let impl_id = Impl ::ClosureFnTraitImpl ( data . clone ( ) ) . to_chalk ( db ) ;
2019-11-24 11:53:42 -06:00
let num_args : u16 = match & db . body ( data . def . into ( ) ) [ data . expr ] {
2019-11-27 08:46:02 -06:00
Expr ::Lambda { args , .. } = > args . len ( ) as u16 ,
2019-11-15 13:32:58 -06:00
_ = > {
log ::warn! ( " closure for closure type {:?} not found " , data ) ;
0
}
} ;
let output_ty = Ty ::Bound ( num_args . into ( ) ) ;
let fn_once_trait =
get_fn_trait ( db , krate , super ::FnTrait ::FnOnce ) . expect ( " assoc ty value should not exist " ) ;
2019-11-26 08:21:29 -06:00
let output_ty_id = db
. trait_data ( fn_once_trait )
. associated_type_by_name ( & name ::OUTPUT_TYPE )
. expect ( " assoc ty value should not exist " ) ;
2019-11-15 13:32:58 -06:00
let value_bound = chalk_rust_ir ::AssociatedTyValueBound { ty : output_ty . to_chalk ( db ) } ;
let value = chalk_rust_ir ::AssociatedTyValue {
associated_ty_id : output_ty_id . to_chalk ( db ) ,
impl_id ,
value : make_binders ( value_bound , num_args as usize + 1 ) ,
} ;
Arc ::new ( value )
}
2019-11-27 00:42:55 -06:00
fn get_fn_trait (
db : & impl HirDatabase ,
krate : CrateId ,
fn_trait : super ::FnTrait ,
) -> Option < TraitId > {
let target = db . lang_item ( krate , fn_trait . lang_item_name ( ) . into ( ) ) ? ;
2019-09-09 15:10:58 -05:00
match target {
2019-11-26 08:21:29 -06:00
LangItemTarget ::TraitId ( t ) = > Some ( t ) ,
2019-09-09 15:10:58 -05:00
_ = > None ,
}
}
2019-05-01 10:06:11 -05:00
fn id_from_chalk < T : InternKey > ( chalk_id : chalk_ir ::RawId ) -> T {
T ::from_intern_id ( InternId ::from ( chalk_id . index ) )
}
fn id_to_chalk < T : InternKey > ( salsa_id : T ) -> chalk_ir ::RawId {
chalk_ir ::RawId { index : salsa_id . as_intern_id ( ) . as_u32 ( ) }
}
2019-11-27 08:46:02 -06:00
impl From < chalk_ir ::StructId > for crate ::TypeCtorId {
2019-05-01 10:06:11 -05:00
fn from ( struct_id : chalk_ir ::StructId ) -> Self {
id_from_chalk ( struct_id . 0 )
}
}
2019-11-27 08:46:02 -06:00
impl From < crate ::TypeCtorId > for chalk_ir ::StructId {
fn from ( type_ctor_id : crate ::TypeCtorId ) -> Self {
2019-05-01 10:06:11 -05:00
chalk_ir ::StructId ( id_to_chalk ( type_ctor_id ) )
}
}
2019-11-27 08:46:02 -06:00
impl From < chalk_ir ::ImplId > for crate ::traits ::GlobalImplId {
2019-05-01 10:06:11 -05:00
fn from ( impl_id : chalk_ir ::ImplId ) -> Self {
id_from_chalk ( impl_id . 0 )
}
}
2019-11-27 08:46:02 -06:00
impl From < crate ::traits ::GlobalImplId > for chalk_ir ::ImplId {
fn from ( impl_id : crate ::traits ::GlobalImplId ) -> Self {
2019-05-01 10:06:11 -05:00
chalk_ir ::ImplId ( id_to_chalk ( impl_id ) )
}
}
2019-11-15 13:32:58 -06:00
2019-11-27 08:46:02 -06:00
impl From < chalk_rust_ir ::AssociatedTyValueId > for crate ::traits ::AssocTyValueId {
2019-11-15 13:32:58 -06:00
fn from ( id : chalk_rust_ir ::AssociatedTyValueId ) -> Self {
id_from_chalk ( id . 0 )
}
}
2019-11-27 08:46:02 -06:00
impl From < crate ::traits ::AssocTyValueId > for chalk_rust_ir ::AssociatedTyValueId {
fn from ( assoc_ty_value_id : crate ::traits ::AssocTyValueId ) -> Self {
2019-11-15 13:32:58 -06:00
chalk_rust_ir ::AssociatedTyValueId ( id_to_chalk ( assoc_ty_value_id ) )
}
}