2019-05-01 15:06:11 +00:00
//! Conversion code from/to Chalk.
2020-05-22 15:14:53 +00:00
use std ::sync ::Arc ;
2019-05-01 15:06:11 +00:00
2019-05-01 18:50:49 +00:00
use log ::debug ;
2020-10-30 17:57:16 +00:00
use chalk_ir ::{ fold ::shift ::Shift , CanonicalVarKinds , GenericArg } ;
2020-03-04 22:00:44 +00:00
use chalk_solve ::rust_ir ::{ self , OpaqueTyDatumBound , WellKnownTrait } ;
2019-05-01 15:06:11 +00:00
2020-08-13 14:25:38 +00:00
use base_db ::{ salsa ::InternKey , CrateId } ;
2020-05-18 19:25:23 +00:00
use hir_def ::{
2020-05-22 13:55:15 +00:00
lang_item ::{ lang_attr , LangItemTarget } ,
2020-05-22 15:14:53 +00:00
AssocContainerId , AssocItemId , HasModule , Lookup , TypeAliasId ,
2019-11-26 15:00:36 +00:00
} ;
2020-09-10 12:01:23 +00:00
use hir_expand ::name ::name ;
2019-05-01 15:06:11 +00:00
2020-07-12 13:26:02 +00:00
use super ::ChalkContext ;
2019-05-01 15:06:11 +00:00
use crate ::{
2020-07-11 17:12:10 +00:00
db ::HirDatabase ,
display ::HirDisplay ,
2021-03-13 16:36:07 +00:00
from_assoc_type_id ,
2020-07-11 17:12:10 +00:00
method_resolution ::{ TyFingerprint , ALL_FLOAT_FPS , ALL_INT_FPS } ,
2021-03-13 16:36:07 +00:00
to_assoc_type_id ,
2020-07-11 17:12:10 +00:00
utils ::generics ,
2021-03-13 16:55:50 +00:00
BoundVar , CallableDefId , CallableSig , DebruijnIndex , FnDefId , GenericPredicate ,
ProjectionPredicate , ProjectionTy , Substs , TraitRef , Ty , TyKind ,
2020-07-12 13:26:02 +00:00
} ;
use mapping ::{
2021-03-13 16:36:07 +00:00
convert_where_clauses , generic_predicate_to_inline_bound , make_binders , TypeAliasAsValue ,
2019-05-01 15:06:11 +00:00
} ;
2021-03-13 13:44:51 +00:00
pub use self ::interner ::Interner ;
2020-11-02 15:31:38 +00:00
pub ( crate ) use self ::interner ::* ;
2020-04-10 15:44:29 +00:00
2020-05-22 15:14:53 +00:00
pub ( super ) mod tls ;
mod interner ;
mod mapping ;
2019-12-21 13:29:33 +00:00
2021-03-12 18:12:17 +00:00
pub ( crate ) trait ToChalk {
2019-05-01 15:06:11 +00:00
type Chalk ;
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> Self ::Chalk ;
fn from_chalk ( db : & dyn HirDatabase , chalk : Self ::Chalk ) -> Self ;
2019-05-01 15:06:11 +00:00
}
2021-03-12 18:12:17 +00:00
pub ( crate ) fn from_chalk < T , ChalkT > ( db : & dyn HirDatabase , chalk : ChalkT ) -> T
2019-05-01 15:06:11 +00:00
where
T : ToChalk < Chalk = ChalkT > ,
{
T ::from_chalk ( db , chalk )
}
2020-03-13 15:05:46 +00:00
impl < ' a > chalk_solve ::RustIrDatabase < Interner > for ChalkContext < ' a > {
2019-12-21 13:29:33 +00:00
fn associated_ty_data ( & self , id : AssocTypeId ) -> Arc < AssociatedTyDatum > {
2019-06-26 09:54:13 +00:00
self . db . associated_ty_data ( id )
2019-05-01 15:06:11 +00:00
}
2019-12-21 13:29:33 +00:00
fn trait_datum ( & self , trait_id : TraitId ) -> Arc < TraitDatum > {
2019-06-26 09:54:13 +00:00
self . db . trait_datum ( self . krate , trait_id )
2019-05-01 15:06:11 +00:00
}
2020-05-22 15:50:58 +00:00
fn adt_datum ( & self , struct_id : AdtId ) -> Arc < StructDatum > {
2019-06-26 09:54:13 +00:00
self . db . struct_datum ( self . krate , struct_id )
2019-05-01 15:06:11 +00:00
}
2020-12-23 09:41:03 +00:00
fn adt_repr ( & self , _struct_id : AdtId ) -> Arc < rust_ir ::AdtRepr < Interner > > {
// FIXME: keep track of these
Arc ::new ( rust_ir ::AdtRepr { c : false , packed : false , int : None } )
}
fn discriminant_type ( & self , _ty : chalk_ir ::Ty < Interner > ) -> chalk_ir ::Ty < Interner > {
// FIXME: keep track of this
chalk_ir ::TyKind ::Scalar ( chalk_ir ::Scalar ::Uint ( chalk_ir ::UintTy ::U32 ) ) . intern ( & Interner )
2020-06-22 11:18:10 +00:00
}
2019-12-21 13:29:33 +00:00
fn impl_datum ( & self , impl_id : ImplId ) -> Arc < ImplDatum > {
2019-06-26 09:54:13 +00:00
self . db . impl_datum ( self . krate , impl_id )
2019-05-01 15:06:11 +00:00
}
2020-05-22 14:40:42 +00:00
fn fn_def_datum (
& self ,
2020-05-22 16:15:53 +00:00
fn_def_id : chalk_ir ::FnDefId < Interner > ,
2020-05-27 19:05:21 +00:00
) -> Arc < rust_ir ::FnDefDatum < Interner > > {
2020-05-22 16:15:53 +00:00
self . db . fn_def_datum ( self . krate , fn_def_id )
2020-05-22 14:40:42 +00:00
}
2019-09-24 16:27:31 +00:00
fn impls_for_trait (
& self ,
2019-12-21 13:29:33 +00:00
trait_id : TraitId ,
2020-05-22 14:40:42 +00:00
parameters : & [ GenericArg < Interner > ] ,
2020-07-11 17:12:10 +00:00
binders : & CanonicalVarKinds < Interner > ,
2019-12-21 13:29:33 +00:00
) -> Vec < ImplId > {
2019-05-01 18:50:49 +00:00
debug! ( " impls_for_trait {:?} " , trait_id ) ;
2019-12-21 13:29:33 +00:00
let trait_ : hir_def ::TraitId = from_chalk ( self . db , trait_id ) ;
2019-12-21 14:00:44 +00:00
2020-04-11 11:11:33 +00:00
let ty : Ty = from_chalk ( self . db , parameters [ 0 ] . assert_ty_ref ( & Interner ) . clone ( ) ) ;
2020-10-30 17:57:16 +00:00
fn binder_kind (
ty : & Ty ,
binders : & CanonicalVarKinds < Interner > ,
) -> Option < chalk_ir ::TyVariableKind > {
2021-03-13 13:44:51 +00:00
if let TyKind ::BoundVar ( bv ) = ty . interned ( & Interner ) {
2020-07-11 17:12:10 +00:00
let binders = binders . as_slice ( & Interner ) ;
if bv . debruijn = = DebruijnIndex ::INNERMOST {
if let chalk_ir ::VariableKind ::Ty ( tk ) = binders [ bv . index ] . kind {
return Some ( tk ) ;
}
}
}
None
}
2020-04-11 11:11:33 +00:00
let self_ty_fp = TyFingerprint ::for_impl ( & ty ) ;
2020-07-11 17:12:10 +00:00
let fps : & [ TyFingerprint ] = match binder_kind ( & ty , binders ) {
2020-10-30 17:57:16 +00:00
Some ( chalk_ir ::TyVariableKind ::Integer ) = > & ALL_INT_FPS ,
Some ( chalk_ir ::TyVariableKind ::Float ) = > & ALL_FLOAT_FPS ,
2020-07-11 17:12:10 +00:00
_ = > self_ty_fp . as_ref ( ) . map ( std ::slice ::from_ref ) . unwrap_or ( & [ ] ) ,
} ;
2020-04-11 11:11:33 +00:00
2019-12-21 14:00:44 +00:00
// Note: Since we're using impls_for_trait, only impls where the trait
2020-11-20 17:00:34 +00:00
// can be resolved should ever reach Chalk. Symbol’ s value as variable is void: impl_datum relies on that
2019-12-21 14:00:44 +00:00
// and will panic if the trait can't be resolved.
2020-07-01 15:15:20 +00:00
let in_deps = self . db . trait_impls_in_deps ( self . krate ) ;
let in_self = self . db . trait_impls_in_crate ( self . krate ) ;
2020-06-18 23:29:34 +00:00
let impl_maps = [ in_deps , in_self ] ;
2020-07-12 13:26:02 +00:00
let id_to_chalk = | id : hir_def ::ImplId | id . to_chalk ( self . db ) ;
2020-06-18 23:29:34 +00:00
2020-07-12 13:26:02 +00:00
let result : Vec < _ > = if fps . is_empty ( ) {
2020-07-11 17:12:10 +00:00
debug! ( " Unrestricted search for {:?} impls... " , trait_ ) ;
impl_maps
. iter ( )
. flat_map ( | crate_impl_defs | crate_impl_defs . for_trait ( trait_ ) . map ( id_to_chalk ) )
. collect ( )
} else {
impl_maps
2020-06-18 23:29:34 +00:00
. iter ( )
. flat_map ( | crate_impl_defs | {
2020-07-11 17:12:10 +00:00
fps . iter ( ) . flat_map ( move | fp | {
crate_impl_defs . for_trait_and_self_ty ( trait_ , * fp ) . map ( id_to_chalk )
} )
2020-06-18 23:29:34 +00:00
} )
2020-07-11 17:12:10 +00:00
. collect ( )
2020-06-18 23:29:34 +00:00
} ;
2019-09-09 20:10:58 +00:00
2019-05-07 15:35:45 +00:00
debug! ( " impls_for_trait returned {} impls " , result . len ( ) ) ;
result
2019-05-01 15:06:11 +00:00
}
2020-10-30 17:57:16 +00:00
fn impl_provided_for ( & self , auto_trait_id : TraitId , kind : & chalk_ir ::TyKind < Interner > ) -> bool {
debug! ( " impl_provided_for {:?}, {:?} " , auto_trait_id , kind ) ;
2019-05-01 15:06:11 +00:00
false // FIXME
}
2019-12-21 13:29:33 +00:00
fn associated_ty_value ( & self , id : AssociatedTyValueId ) -> Arc < AssociatedTyValue > {
2020-02-18 12:53:02 +00:00
self . db . associated_ty_value ( self . krate , id )
2019-05-01 15:06:11 +00:00
}
2020-03-04 22:00:44 +00:00
2020-02-24 20:36:57 +00:00
fn custom_clauses ( & self ) -> Vec < chalk_ir ::ProgramClause < Interner > > {
2019-05-01 21:26:42 +00:00
vec! [ ]
}
2019-12-21 13:29:33 +00:00
fn local_impls_to_coherence_check ( & self , _trait_id : TraitId ) -> Vec < ImplId > {
2019-09-23 18:33:47 +00:00
// We don't do coherence checking (yet)
unimplemented! ( )
2019-05-01 21:26:42 +00:00
}
2020-03-02 22:01:16 +00:00
fn interner ( & self ) -> & Interner {
& Interner
}
2020-04-10 15:44:29 +00:00
fn well_known_trait_id (
& self ,
2020-05-27 19:05:21 +00:00
well_known_trait : rust_ir ::WellKnownTrait ,
2020-04-16 10:39:00 +00:00
) -> Option < chalk_ir ::TraitId < Interner > > {
2020-05-22 13:55:15 +00:00
let lang_attr = lang_attr_from_well_known_trait ( well_known_trait ) ;
2020-06-22 11:18:10 +00:00
let trait_ = match self . db . lang_item ( self . krate , lang_attr . into ( ) ) {
2020-05-22 13:55:15 +00:00
Some ( LangItemTarget ::TraitId ( trait_ ) ) = > trait_ ,
_ = > return None ,
} ;
Some ( trait_ . to_chalk ( self . db ) )
2020-04-10 15:44:29 +00:00
}
2020-04-18 11:36:35 +00:00
fn program_clauses_for_env (
& self ,
environment : & chalk_ir ::Environment < Interner > ,
) -> chalk_ir ::ProgramClauses < Interner > {
self . db . program_clauses_for_chalk_env ( self . krate , environment . clone ( ) )
}
2020-03-04 22:00:44 +00:00
fn opaque_ty_data ( & self , id : chalk_ir ::OpaqueTyId < Interner > ) -> Arc < OpaqueTyDatum > {
let interned_id = crate ::db ::InternedOpaqueTyId ::from ( id ) ;
let full_id = self . db . lookup_intern_impl_trait_id ( interned_id ) ;
2020-09-10 12:01:23 +00:00
let bound = match full_id {
crate ::OpaqueTyId ::ReturnTypeImplTrait ( func , idx ) = > {
let datas = self
. db
. return_type_impl_traits ( func )
. expect ( " impl trait id without impl traits " ) ;
let data = & datas . value . impl_traits [ idx as usize ] ;
let bound = OpaqueTyDatumBound {
bounds : make_binders (
data . bounds
. value
. iter ( )
. cloned ( )
. filter ( | b | ! b . is_error ( ) )
. map ( | b | b . to_chalk ( self . db ) )
. collect ( ) ,
1 ,
) ,
where_clauses : make_binders ( vec! [ ] , 0 ) ,
} ;
let num_vars = datas . num_binders ;
make_binders ( bound , num_vars )
}
crate ::OpaqueTyId ::AsyncBlockTypeImplTrait ( .. ) = > {
if let Some ( ( future_trait , future_output ) ) = self
. db
. lang_item ( self . krate , " future_trait " . into ( ) )
. and_then ( | item | item . as_trait ( ) )
. and_then ( | trait_ | {
let alias =
self . db . trait_data ( trait_ ) . associated_type_by_name ( & name! [ Output ] ) ? ;
Some ( ( trait_ , alias ) )
} )
{
2020-11-20 17:00:34 +00:00
// Making up Symbol’ s value as variable is void: AsyncBlock<T>:
2020-09-11 16:12:42 +00:00
//
// |--------------------OpaqueTyDatum-------------------|
// |-------------OpaqueTyDatumBound--------------|
// for<T> <Self> [Future<Self>, Future::Output<Self> = T]
// ^1 ^0 ^0 ^0 ^1
2020-09-10 12:01:23 +00:00
let impl_bound = GenericPredicate ::Implemented ( TraitRef {
trait_ : future_trait ,
// Self type as the first parameter.
2021-03-13 13:44:51 +00:00
substs : Substs ::single (
TyKind ::BoundVar ( BoundVar {
debruijn : DebruijnIndex ::INNERMOST ,
index : 0 ,
} )
. intern ( & Interner ) ,
) ,
2020-09-10 12:01:23 +00:00
} ) ;
let proj_bound = GenericPredicate ::Projection ( ProjectionPredicate {
// The parameter of the opaque type.
2021-03-13 13:44:51 +00:00
ty : TyKind ::BoundVar ( BoundVar { debruijn : DebruijnIndex ::ONE , index : 0 } )
. intern ( & Interner ) ,
2020-09-10 12:01:23 +00:00
projection_ty : ProjectionTy {
2021-03-13 16:36:07 +00:00
associated_ty : to_assoc_type_id ( future_output ) ,
2020-09-10 12:01:23 +00:00
// Self type as the first parameter.
2021-03-13 13:44:51 +00:00
parameters : Substs ::single (
TyKind ::BoundVar ( BoundVar ::new ( DebruijnIndex ::INNERMOST , 0 ) )
. intern ( & Interner ) ,
) ,
2020-09-10 12:01:23 +00:00
} ,
} ) ;
let bound = OpaqueTyDatumBound {
bounds : make_binders (
vec! [ impl_bound . to_chalk ( self . db ) , proj_bound . to_chalk ( self . db ) ] ,
1 ,
) ,
where_clauses : make_binders ( vec! [ ] , 0 ) ,
} ;
// The opaque type has 1 parameter.
make_binders ( bound , 1 )
} else {
2020-11-20 17:00:34 +00:00
// If failed to find Symbol’ s value as variable is void: Future::Output, return empty bounds as fallback.
2020-09-10 12:01:23 +00:00
let bound = OpaqueTyDatumBound {
bounds : make_binders ( vec! [ ] , 0 ) ,
where_clauses : make_binders ( vec! [ ] , 0 ) ,
} ;
// The opaque type has 1 parameter.
make_binders ( bound , 1 )
}
}
2020-03-04 22:00:44 +00:00
} ;
2020-09-10 12:01:23 +00:00
Arc ::new ( OpaqueTyDatum { opaque_ty_id : id , bound } )
2020-03-04 22:00:44 +00:00
}
fn hidden_opaque_type ( & self , _id : chalk_ir ::OpaqueTyId < Interner > ) -> chalk_ir ::Ty < Interner > {
// FIXME: actually provide the hidden type; it is relevant for auto traits
2021-03-13 13:44:51 +00:00
TyKind ::Unknown . intern ( & Interner ) . to_chalk ( self . db )
2020-04-18 11:36:35 +00:00
}
2020-05-16 08:49:43 +00:00
fn is_object_safe ( & self , _trait_id : chalk_ir ::TraitId < Interner > ) -> bool {
// FIXME: implement actual object safety
true
}
2020-06-22 11:18:10 +00:00
fn closure_kind (
& self ,
_closure_id : chalk_ir ::ClosureId < Interner > ,
_substs : & chalk_ir ::Substitution < Interner > ,
) -> rust_ir ::ClosureKind {
2020-07-12 13:26:02 +00:00
// Fn is the closure kind that implements all three traits
rust_ir ::ClosureKind ::Fn
2020-06-22 11:18:10 +00:00
}
fn closure_inputs_and_output (
& self ,
_closure_id : chalk_ir ::ClosureId < Interner > ,
2020-07-12 13:26:02 +00:00
substs : & chalk_ir ::Substitution < Interner > ,
2020-06-22 11:18:10 +00:00
) -> chalk_ir ::Binders < rust_ir ::FnDefInputsAndOutputDatum < Interner > > {
2020-07-12 13:26:02 +00:00
let sig_ty : Ty =
from_chalk ( self . db , substs . at ( & Interner , 0 ) . assert_ty_ref ( & Interner ) . clone ( ) ) ;
2021-02-28 21:12:07 +00:00
let sig = CallableSig ::from_substs (
2020-07-12 13:26:02 +00:00
& sig_ty . substs ( ) . expect ( " first closure param should be fn ptr " ) ,
) ;
let io = rust_ir ::FnDefInputsAndOutputDatum {
argument_types : sig . params ( ) . iter ( ) . map ( | ty | ty . clone ( ) . to_chalk ( self . db ) ) . collect ( ) ,
return_type : sig . ret ( ) . clone ( ) . to_chalk ( self . db ) ,
} ;
make_binders ( io . shifted_in ( & Interner ) , 0 )
2020-06-22 11:18:10 +00:00
}
fn closure_upvars (
& self ,
_closure_id : chalk_ir ::ClosureId < Interner > ,
_substs : & chalk_ir ::Substitution < Interner > ,
) -> chalk_ir ::Binders < chalk_ir ::Ty < Interner > > {
2020-07-12 13:26:02 +00:00
let ty = Ty ::unit ( ) . to_chalk ( self . db ) ;
make_binders ( ty , 0 )
2020-06-22 11:18:10 +00:00
}
fn closure_fn_substitution (
& self ,
_closure_id : chalk_ir ::ClosureId < Interner > ,
_substs : & chalk_ir ::Substitution < Interner > ,
) -> chalk_ir ::Substitution < Interner > {
2020-07-12 13:26:02 +00:00
Substs ::empty ( ) . to_chalk ( self . db )
2020-06-22 11:18:10 +00:00
}
2020-07-11 13:22:46 +00:00
2020-07-13 20:03:26 +00:00
fn trait_name ( & self , trait_id : chalk_ir ::TraitId < Interner > ) -> String {
let id = from_chalk ( self . db , trait_id ) ;
self . db . trait_data ( id ) . name . to_string ( )
2020-07-11 13:22:46 +00:00
}
2021-03-01 20:57:39 +00:00
fn adt_name ( & self , chalk_ir ::AdtId ( adt_id ) : AdtId ) -> String {
match adt_id {
2020-09-09 16:55:05 +00:00
hir_def ::AdtId ::StructId ( id ) = > self . db . struct_data ( id ) . name . to_string ( ) ,
hir_def ::AdtId ::EnumId ( id ) = > self . db . enum_data ( id ) . name . to_string ( ) ,
hir_def ::AdtId ::UnionId ( id ) = > self . db . union_data ( id ) . name . to_string ( ) ,
}
2020-07-11 13:22:46 +00:00
}
2020-07-13 20:03:26 +00:00
fn assoc_type_name ( & self , assoc_ty_id : chalk_ir ::AssocTypeId < Interner > ) -> String {
2020-09-09 16:55:05 +00:00
let id = self . db . associated_ty_data ( assoc_ty_id ) . name ;
self . db . type_alias_data ( id ) . name . to_string ( )
2020-07-11 13:22:46 +00:00
}
2020-07-13 20:03:26 +00:00
fn opaque_type_name ( & self , opaque_ty_id : chalk_ir ::OpaqueTyId < Interner > ) -> String {
format! ( " Opaque_ {} " , opaque_ty_id . 0 )
2020-07-11 13:22:46 +00:00
}
2020-07-13 20:03:26 +00:00
fn fn_def_name ( & self , fn_def_id : chalk_ir ::FnDefId < Interner > ) -> String {
format! ( " fn_ {} " , fn_def_id . 0 )
2020-07-11 13:22:46 +00:00
}
2020-10-06 22:05:20 +00:00
fn generator_datum (
& self ,
_ : chalk_ir ::GeneratorId < Interner > ,
) -> std ::sync ::Arc < chalk_solve ::rust_ir ::GeneratorDatum < Interner > > {
2020-10-06 22:19:34 +00:00
// FIXME
unimplemented! ( )
2020-10-06 22:05:20 +00:00
}
fn generator_witness_datum (
& self ,
_ : chalk_ir ::GeneratorId < Interner > ,
) -> std ::sync ::Arc < chalk_solve ::rust_ir ::GeneratorWitnessDatum < Interner > > {
2020-10-06 22:19:34 +00:00
// FIXME
unimplemented! ( )
2020-10-06 22:05:20 +00:00
}
2020-11-20 17:00:34 +00:00
fn unification_database ( & self ) -> & dyn chalk_ir ::UnificationDatabase < Interner > {
self
}
}
impl < ' a > chalk_ir ::UnificationDatabase < Interner > for ChalkContext < ' a > {
fn fn_def_variance (
& self ,
fn_def_id : chalk_ir ::FnDefId < Interner > ,
) -> chalk_ir ::Variances < Interner > {
self . db . fn_def_variance ( self . krate , fn_def_id )
}
fn adt_variance ( & self , adt_id : chalk_ir ::AdtId < Interner > ) -> chalk_ir ::Variances < Interner > {
self . db . adt_variance ( self . krate , adt_id )
}
2020-04-18 11:36:35 +00:00
}
pub ( crate ) fn program_clauses_for_chalk_env_query (
db : & dyn HirDatabase ,
krate : CrateId ,
environment : chalk_ir ::Environment < Interner > ,
) -> chalk_ir ::ProgramClauses < Interner > {
chalk_solve ::program_clauses_for_env ( & ChalkContext { db , krate } , & environment )
2019-05-01 15:06:11 +00:00
}
2019-06-26 09:54:13 +00:00
pub ( crate ) fn associated_ty_data_query (
2020-03-13 15:05:46 +00:00
db : & dyn HirDatabase ,
2019-12-21 13:29:33 +00:00
id : AssocTypeId ,
) -> Arc < AssociatedTyDatum > {
2019-06-26 09:54:13 +00:00
debug! ( " associated_ty_data {:?} " , id ) ;
2021-03-13 16:36:07 +00:00
let type_alias : TypeAliasId = from_assoc_type_id ( id ) ;
2020-03-13 15:05:46 +00:00
let trait_ = match type_alias . lookup ( db . upcast ( ) ) . container {
2019-12-20 10:59:50 +00:00
AssocContainerId ::TraitId ( t ) = > t ,
2019-06-26 09:54:13 +00:00
_ = > panic! ( " associated type not in trait " ) ,
} ;
2020-04-12 10:28:24 +00:00
// Lower bounds -- we could/should maybe move this to a separate query in `lower`
let type_alias_data = db . type_alias_data ( type_alias ) ;
2020-03-13 15:05:46 +00:00
let generic_params = generics ( db . upcast ( ) , type_alias . into ( ) ) ;
2020-04-17 20:48:29 +00:00
let bound_vars = Substs ::bound_vars ( & generic_params , DebruijnIndex ::INNERMOST ) ;
2020-04-12 10:28:24 +00:00
let resolver = hir_def ::resolver ::HasResolver ::resolver ( type_alias , db . upcast ( ) ) ;
let ctx = crate ::TyLoweringContext ::new ( db , & resolver )
. with_type_param_mode ( crate ::lower ::TypeParamLoweringMode ::Variable ) ;
2021-03-13 13:44:51 +00:00
let self_ty =
TyKind ::BoundVar ( BoundVar ::new ( crate ::DebruijnIndex ::INNERMOST , 0 ) ) . intern ( & Interner ) ;
2020-04-12 10:28:24 +00:00
let bounds = type_alias_data
. bounds
. iter ( )
. flat_map ( | bound | GenericPredicate ::from_type_bound ( & ctx , bound , self_ty . clone ( ) ) )
. filter_map ( | pred | generic_predicate_to_inline_bound ( db , & pred , & self_ty ) )
. map ( | bound | make_binders ( bound . shifted_in ( & Interner ) , 0 ) )
. collect ( ) ;
let where_clauses = convert_where_clauses ( db , type_alias . into ( ) , & bound_vars ) ;
2020-05-27 19:05:21 +00:00
let bound_data = rust_ir ::AssociatedTyDatumBound { bounds , where_clauses } ;
2019-06-26 09:54:13 +00:00
let datum = AssociatedTyDatum {
2019-11-26 15:00:36 +00:00
trait_id : trait_ . to_chalk ( db ) ,
2019-06-26 09:54:13 +00:00
id ,
2020-03-03 05:57:16 +00:00
name : type_alias ,
2019-12-07 12:05:05 +00:00
binders : make_binders ( bound_data , generic_params . len ( ) ) ,
2019-06-26 09:54:13 +00:00
} ;
Arc ::new ( datum )
}
pub ( crate ) fn trait_datum_query (
2020-03-13 15:05:46 +00:00
db : & dyn HirDatabase ,
2019-11-27 06:42:55 +00:00
krate : CrateId ,
2019-12-21 13:29:33 +00:00
trait_id : TraitId ,
) -> Arc < TraitDatum > {
2019-06-26 09:54:13 +00:00
debug! ( " trait_datum {:?} " , trait_id ) ;
2019-12-21 13:29:33 +00:00
let trait_ : hir_def ::TraitId = from_chalk ( db , trait_id ) ;
2019-11-26 15:00:36 +00:00
let trait_data = db . trait_data ( trait_ ) ;
debug! ( " trait {:?} = {:?} " , trait_id , trait_data . name ) ;
2020-03-13 15:05:46 +00:00
let generic_params = generics ( db . upcast ( ) , trait_ . into ( ) ) ;
2020-04-17 20:48:29 +00:00
let bound_vars = Substs ::bound_vars ( & generic_params , DebruijnIndex ::INNERMOST ) ;
2020-05-27 19:05:21 +00:00
let flags = rust_ir ::TraitFlags {
2019-11-26 15:00:36 +00:00
auto : trait_data . auto ,
2021-03-09 18:09:02 +00:00
upstream : trait_ . lookup ( db . upcast ( ) ) . container . krate ( ) ! = krate ,
2019-09-09 19:24:24 +00:00
non_enumerable : true ,
2019-11-15 19:32:58 +00:00
coinductive : false , // only relevant for Chalk testing
2020-06-22 11:18:10 +00:00
// FIXME: set these flags correctly
2019-06-26 09:54:13 +00:00
marker : false ,
fundamental : false ,
} ;
2019-11-26 15:00:36 +00:00
let where_clauses = convert_where_clauses ( db , trait_ . into ( ) , & bound_vars ) ;
2021-03-13 16:36:07 +00:00
let associated_ty_ids =
trait_data . associated_types ( ) . map ( | type_alias | to_assoc_type_id ( type_alias ) ) . collect ( ) ;
2020-05-27 19:05:21 +00:00
let trait_datum_bound = rust_ir ::TraitDatumBound { where_clauses } ;
2020-05-22 13:55:15 +00:00
let well_known =
lang_attr ( db . upcast ( ) , trait_ ) . and_then ( | name | well_known_trait_from_lang_attr ( & name ) ) ;
2019-11-15 19:32:58 +00:00
let trait_datum = TraitDatum {
id : trait_id ,
binders : make_binders ( trait_datum_bound , bound_vars . len ( ) ) ,
flags ,
associated_ty_ids ,
2020-04-05 16:24:18 +00:00
well_known ,
2019-11-15 19:32:58 +00:00
} ;
2019-06-26 09:54:13 +00:00
Arc ::new ( trait_datum )
}
2020-05-22 13:55:15 +00:00
fn well_known_trait_from_lang_attr ( name : & str ) -> Option < WellKnownTrait > {
Some ( match name {
2020-06-22 11:18:10 +00:00
" sized " = > WellKnownTrait ::Sized ,
" copy " = > WellKnownTrait ::Copy ,
" clone " = > WellKnownTrait ::Clone ,
" drop " = > WellKnownTrait ::Drop ,
" fn_once " = > WellKnownTrait ::FnOnce ,
" fn_mut " = > WellKnownTrait ::FnMut ,
" fn " = > WellKnownTrait ::Fn ,
" unsize " = > WellKnownTrait ::Unsize ,
2020-09-25 11:59:18 +00:00
" coerce_unsized " = > WellKnownTrait ::CoerceUnsized ,
2020-12-23 09:41:03 +00:00
" discriminant_kind " = > WellKnownTrait ::DiscriminantKind ,
2020-05-22 13:55:15 +00:00
_ = > return None ,
} )
}
fn lang_attr_from_well_known_trait ( attr : WellKnownTrait ) -> & 'static str {
match attr {
2020-06-22 11:18:10 +00:00
WellKnownTrait ::Sized = > " sized " ,
WellKnownTrait ::Copy = > " copy " ,
WellKnownTrait ::Clone = > " clone " ,
WellKnownTrait ::Drop = > " drop " ,
WellKnownTrait ::FnOnce = > " fn_once " ,
WellKnownTrait ::FnMut = > " fn_mut " ,
WellKnownTrait ::Fn = > " fn " ,
WellKnownTrait ::Unsize = > " unsize " ,
2020-09-13 02:24:19 +00:00
WellKnownTrait ::Unpin = > " unpin " ,
2020-09-25 11:59:18 +00:00
WellKnownTrait ::CoerceUnsized = > " coerce_unsized " ,
2020-12-23 09:41:03 +00:00
WellKnownTrait ::DiscriminantKind = > " discriminant_kind " ,
2020-05-22 13:55:15 +00:00
}
}
2019-06-26 09:54:13 +00:00
pub ( crate ) fn struct_datum_query (
2020-03-13 15:05:46 +00:00
db : & dyn HirDatabase ,
2019-11-27 06:42:55 +00:00
krate : CrateId ,
2020-05-22 15:50:58 +00:00
struct_id : AdtId ,
2019-12-21 13:29:33 +00:00
) -> Arc < StructDatum > {
2019-06-26 09:54:13 +00:00
debug! ( " struct_datum {:?} " , struct_id ) ;
2021-03-01 20:57:39 +00:00
let chalk_ir ::AdtId ( adt_id ) = struct_id ;
2021-02-28 18:13:37 +00:00
let num_params = generics ( db . upcast ( ) , adt_id . into ( ) ) . len ( ) ;
let upstream = adt_id . module ( db . upcast ( ) ) . krate ( ) ! = krate ;
2021-03-12 19:51:08 +00:00
let where_clauses = {
let generic_params = generics ( db . upcast ( ) , adt_id . into ( ) ) ;
let bound_vars = Substs ::bound_vars ( & generic_params , DebruijnIndex ::INNERMOST ) ;
convert_where_clauses ( db , adt_id . into ( ) , & bound_vars )
} ;
2020-05-27 19:05:21 +00:00
let flags = rust_ir ::AdtFlags {
2019-06-26 09:54:13 +00:00
upstream ,
2020-06-22 11:18:10 +00:00
// FIXME set fundamental and phantom_data flags correctly
2019-06-26 09:54:13 +00:00
fundamental : false ,
2020-06-22 11:18:10 +00:00
phantom_data : false ,
2019-06-26 09:54:13 +00:00
} ;
2020-07-11 13:22:46 +00:00
// FIXME provide enum variants properly (for auto traits)
let variant = rust_ir ::AdtVariantDatum {
fields : Vec ::new ( ) , // FIXME add fields (only relevant for auto traits),
} ;
2020-07-10 16:30:32 +00:00
let struct_datum_bound = rust_ir ::AdtDatumBound { variants : vec ! [ variant ] , where_clauses } ;
2020-07-11 13:22:46 +00:00
let struct_datum = StructDatum {
// FIXME set ADT kind
kind : rust_ir ::AdtKind ::Struct ,
id : struct_id ,
binders : make_binders ( struct_datum_bound , num_params ) ,
2020-07-10 16:30:32 +00:00
flags ,
2020-07-11 13:22:46 +00:00
} ;
2019-06-26 09:54:13 +00:00
Arc ::new ( struct_datum )
}
pub ( crate ) fn impl_datum_query (
2020-03-13 15:05:46 +00:00
db : & dyn HirDatabase ,
2019-11-27 06:42:55 +00:00
krate : CrateId ,
2019-12-21 13:29:33 +00:00
impl_id : ImplId ,
) -> Arc < ImplDatum > {
2020-08-12 14:32:36 +00:00
let _p = profile ::span ( " impl_datum " ) ;
2019-06-26 09:54:13 +00:00
debug! ( " impl_datum {:?} " , impl_id ) ;
2020-07-12 13:26:02 +00:00
let impl_ : hir_def ::ImplId = from_chalk ( db , impl_id ) ;
impl_def_datum ( db , krate , impl_id , impl_ )
2019-09-09 20:10:58 +00:00
}
2020-02-29 20:24:40 +00:00
fn impl_def_datum (
2020-03-13 15:05:46 +00:00
db : & dyn HirDatabase ,
2019-11-27 06:42:55 +00:00
krate : CrateId ,
2019-12-21 13:29:33 +00:00
chalk_id : ImplId ,
impl_id : hir_def ::ImplId ,
2019-12-21 14:00:44 +00:00
) -> Arc < ImplDatum > {
let trait_ref = db
. impl_trait ( impl_id )
// ImplIds for impls where the trait ref can't be resolved should never reach Chalk
2020-01-31 15:52:43 +00:00
. expect ( " invalid impl passed to Chalk " )
. value ;
2019-11-27 09:47:18 +00:00
let impl_data = db . impl_data ( impl_id ) ;
2020-03-13 15:05:46 +00:00
let generic_params = generics ( db . upcast ( ) , impl_id . into ( ) ) ;
2020-04-17 20:48:29 +00:00
let bound_vars = Substs ::bound_vars ( & generic_params , DebruijnIndex ::INNERMOST ) ;
2019-11-15 19:32:58 +00:00
let trait_ = trait_ref . trait_ ;
2021-03-09 18:09:02 +00:00
let impl_type = if impl_id . lookup ( db . upcast ( ) ) . container . krate ( ) = = krate {
2020-05-27 19:05:21 +00:00
rust_ir ::ImplType ::Local
2019-06-26 09:54:13 +00:00
} else {
2020-05-27 19:05:21 +00:00
rust_ir ::ImplType ::External
2019-06-26 09:54:13 +00:00
} ;
2019-11-27 09:47:18 +00:00
let where_clauses = convert_where_clauses ( db , impl_id . into ( ) , & bound_vars ) ;
let negative = impl_data . is_negative ;
2019-06-26 09:54:13 +00:00
debug! (
" impl {:?}: {}{} where {:?} " ,
2019-11-27 09:47:18 +00:00
chalk_id ,
2019-06-26 09:54:13 +00:00
if negative { " ! " } else { " " } ,
trait_ref . display ( db ) ,
where_clauses
) ;
let trait_ref = trait_ref . to_chalk ( db ) ;
2020-05-27 19:05:21 +00:00
let polarity = if negative { rust_ir ::Polarity ::Negative } else { rust_ir ::Polarity ::Positive } ;
2019-10-10 18:51:50 +00:00
2020-05-27 19:05:21 +00:00
let impl_datum_bound = rust_ir ::ImplDatumBound { trait_ref , where_clauses } ;
2019-11-26 15:00:36 +00:00
let trait_data = db . trait_data ( trait_ ) ;
2019-11-27 09:47:18 +00:00
let associated_ty_value_ids = impl_data
. items
. iter ( )
2019-11-15 19:32:58 +00:00
. filter_map ( | item | match item {
2019-11-27 09:47:18 +00:00
AssocItemId ::TypeAliasId ( type_alias ) = > Some ( * type_alias ) ,
2019-11-15 19:32:58 +00:00
_ = > None ,
} )
2019-11-27 09:47:18 +00:00
. filter ( | & type_alias | {
2019-11-15 19:32:58 +00:00
// don't include associated types that don't exist in the trait
2019-11-27 09:47:18 +00:00
let name = & db . type_alias_data ( type_alias ) . name ;
trait_data . associated_type_by_name ( name ) . is_some ( )
2019-11-15 19:32:58 +00:00
} )
2020-07-12 13:26:02 +00:00
. map ( | type_alias | TypeAliasAsValue ( type_alias ) . to_chalk ( db ) )
2019-11-15 19:32:58 +00:00
. collect ( ) ;
2019-06-26 09:54:13 +00:00
debug! ( " impl_datum: {:?} " , impl_datum_bound ) ;
2019-10-10 18:51:50 +00:00
let impl_datum = ImplDatum {
binders : make_binders ( impl_datum_bound , bound_vars . len ( ) ) ,
impl_type ,
polarity ,
2019-11-15 19:32:58 +00:00
associated_ty_value_ids ,
2019-10-10 18:51:50 +00:00
} ;
2019-09-09 20:10:58 +00:00
Arc ::new ( impl_datum )
}
2019-11-15 19:32:58 +00:00
pub ( crate ) fn associated_ty_value_query (
2020-03-13 15:05:46 +00:00
db : & dyn HirDatabase ,
2019-11-27 06:42:55 +00:00
krate : CrateId ,
2019-12-21 13:46:15 +00:00
id : AssociatedTyValueId ,
) -> Arc < AssociatedTyValue > {
2020-07-12 13:26:02 +00:00
let type_alias : TypeAliasAsValue = from_chalk ( db , id ) ;
type_alias_associated_ty_value ( db , krate , type_alias . 0 )
2019-11-15 19:32:58 +00:00
}
fn type_alias_associated_ty_value (
2020-03-13 15:05:46 +00:00
db : & dyn HirDatabase ,
2019-11-27 06:42:55 +00:00
_krate : CrateId ,
2019-11-27 08:40:10 +00:00
type_alias : TypeAliasId ,
2019-12-21 13:29:33 +00:00
) -> Arc < AssociatedTyValue > {
2019-11-27 08:40:10 +00:00
let type_alias_data = db . type_alias_data ( type_alias ) ;
2020-03-13 15:05:46 +00:00
let impl_id = match type_alias . lookup ( db . upcast ( ) ) . container {
2019-12-20 10:59:50 +00:00
AssocContainerId ::ImplId ( it ) = > it ,
2019-11-27 08:40:10 +00:00
_ = > panic! ( " assoc ty value should be in impl " ) ,
} ;
2020-01-31 15:52:43 +00:00
let trait_ref = db . impl_trait ( impl_id ) . expect ( " assoc ty value should not exist " ) . value ; // we don't return any assoc ty values if the impl'd trait can't be resolved
2019-11-27 08:40:10 +00:00
2019-11-26 14:21:29 +00:00
let assoc_ty = db
2019-11-27 19:12:09 +00:00
. trait_data ( trait_ref . trait_ )
2019-11-27 08:40:10 +00:00
. associated_type_by_name ( & type_alias_data . name )
2019-11-26 14:21:29 +00:00
. expect ( " assoc ty value should not exist " ) ; // validated when building the impl data as well
2020-01-31 15:52:43 +00:00
let ty = db . ty ( type_alias . into ( ) ) ;
2020-05-27 19:05:21 +00:00
let value_bound = rust_ir ::AssociatedTyValueBound { ty : ty . value . to_chalk ( db ) } ;
let value = rust_ir ::AssociatedTyValue {
2020-07-12 13:26:02 +00:00
impl_id : impl_id . to_chalk ( db ) ,
2021-03-13 16:36:07 +00:00
associated_ty_id : to_assoc_type_id ( assoc_ty ) ,
2020-01-31 15:52:43 +00:00
value : make_binders ( value_bound , ty . num_binders ) ,
2019-11-15 19:32:58 +00:00
} ;
Arc ::new ( value )
}
2020-05-22 16:15:53 +00:00
pub ( crate ) fn fn_def_datum_query (
db : & dyn HirDatabase ,
_krate : CrateId ,
fn_def_id : FnDefId ,
) -> Arc < FnDefDatum > {
2020-07-16 11:15:00 +00:00
let callable_def : CallableDefId = from_chalk ( db , fn_def_id ) ;
2020-05-22 16:15:53 +00:00
let generic_params = generics ( db . upcast ( ) , callable_def . into ( ) ) ;
let sig = db . callable_item_signature ( callable_def ) ;
let bound_vars = Substs ::bound_vars ( & generic_params , DebruijnIndex ::INNERMOST ) ;
let where_clauses = convert_where_clauses ( db , callable_def . into ( ) , & bound_vars ) ;
2020-05-27 19:05:21 +00:00
let bound = rust_ir ::FnDefDatumBound {
2020-05-22 16:15:53 +00:00
// Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
2020-06-22 11:18:10 +00:00
inputs_and_output : make_binders (
rust_ir ::FnDefInputsAndOutputDatum {
argument_types : sig
. value
. params ( )
. iter ( )
. map ( | ty | ty . clone ( ) . to_chalk ( db ) )
. collect ( ) ,
return_type : sig . value . ret ( ) . clone ( ) . to_chalk ( db ) ,
}
. shifted_in ( & Interner ) ,
0 ,
) ,
2020-05-22 16:15:53 +00:00
where_clauses ,
} ;
2020-07-30 17:37:28 +00:00
let datum = FnDefDatum {
id : fn_def_id ,
2020-09-13 02:24:19 +00:00
sig : chalk_ir ::FnSig {
abi : ( ) ,
safety : chalk_ir ::Safety ::Safe ,
variadic : sig . value . is_varargs ,
} ,
2020-07-30 17:37:28 +00:00
binders : make_binders ( bound , sig . num_binders ) ,
} ;
2020-05-22 16:15:53 +00:00
Arc ::new ( datum )
}
2020-11-20 17:00:34 +00:00
pub ( crate ) fn fn_def_variance_query (
db : & dyn HirDatabase ,
_krate : CrateId ,
fn_def_id : FnDefId ,
) -> Variances {
let callable_def : CallableDefId = from_chalk ( db , fn_def_id ) ;
let generic_params = generics ( db . upcast ( ) , callable_def . into ( ) ) ;
2021-02-02 15:07:10 +00:00
Variances ::from_iter (
2020-11-20 17:00:34 +00:00
& Interner ,
std ::iter ::repeat ( chalk_ir ::Variance ::Invariant ) . take ( generic_params . len ( ) ) ,
)
}
pub ( crate ) fn adt_variance_query (
db : & dyn HirDatabase ,
_krate : CrateId ,
2021-03-01 20:57:39 +00:00
chalk_ir ::AdtId ( adt_id ) : AdtId ,
2020-11-20 17:00:34 +00:00
) -> Variances {
2021-03-01 20:57:39 +00:00
let generic_params = generics ( db . upcast ( ) , adt_id . into ( ) ) ;
2021-02-02 15:07:10 +00:00
Variances ::from_iter (
2020-11-20 17:00:34 +00:00
& Interner ,
std ::iter ::repeat ( chalk_ir ::Variance ::Invariant ) . take ( generic_params . len ( ) ) ,
)
}
2020-07-16 11:13:17 +00:00
impl From < FnDefId > for crate ::db ::InternedCallableDefId {
2020-05-22 16:15:53 +00:00
fn from ( fn_def_id : FnDefId ) -> Self {
InternKey ::from_intern_id ( fn_def_id . 0 )
}
}
2020-07-16 11:13:17 +00:00
impl From < crate ::db ::InternedCallableDefId > for FnDefId {
fn from ( callable_def_id : crate ::db ::InternedCallableDefId ) -> Self {
2020-05-22 16:15:53 +00:00
chalk_ir ::FnDefId ( callable_def_id . as_intern_id ( ) )
}
}
2020-03-04 22:00:44 +00:00
impl From < OpaqueTyId > for crate ::db ::InternedOpaqueTyId {
fn from ( id : OpaqueTyId ) -> Self {
InternKey ::from_intern_id ( id . 0 )
}
}
impl From < crate ::db ::InternedOpaqueTyId > for OpaqueTyId {
fn from ( id : crate ::db ::InternedOpaqueTyId ) -> Self {
chalk_ir ::OpaqueTyId ( id . as_intern_id ( ) )
}
}
2021-03-13 18:27:09 +00:00
impl From < chalk_ir ::ClosureId < Interner > > for crate ::db ::InternedClosureId {
2020-07-12 13:26:02 +00:00
fn from ( id : chalk_ir ::ClosureId < Interner > ) -> Self {
2020-03-02 21:30:38 +00:00
Self ::from_intern_id ( id . 0 )
2019-11-15 19:32:58 +00:00
}
}
2021-03-13 18:27:09 +00:00
impl From < crate ::db ::InternedClosureId > for chalk_ir ::ClosureId < Interner > {
fn from ( id : crate ::db ::InternedClosureId ) -> Self {
2020-07-12 13:26:02 +00:00
chalk_ir ::ClosureId ( id . as_intern_id ( ) )
2019-11-15 19:32:58 +00:00
}
}