2019-05-01 15:06:11 +00:00
//! Conversion code from/to Chalk.
2019-12-21 14:00:44 +00:00
use std ::{ fmt , sync ::Arc } ;
2019-05-01 15:06:11 +00:00
2019-05-01 18:50:49 +00:00
use log ::debug ;
2020-04-05 16:24:18 +00:00
use chalk_ir ::{
2020-05-22 14:40:42 +00:00
cast ::Cast , fold ::shift ::Shift , interner ::HasInterner , GenericArg , Goal , GoalData ,
2020-05-18 19:25:23 +00:00
PlaceholderIndex , Scalar , TypeName , UniverseIndex ,
2020-04-05 16:24:18 +00:00
} ;
2019-05-01 15:06:11 +00:00
2020-05-18 19:25:23 +00:00
use hir_def ::{
type_ref ::Mutability , AssocContainerId , AssocItemId , GenericDefId , HasModule , Lookup ,
TypeAliasId ,
} ;
2019-12-03 11:16:39 +00:00
use ra_db ::{
salsa ::{ InternId , InternKey } ,
CrateId ,
2019-11-26 15:00:36 +00:00
} ;
2019-05-01 15:06:11 +00:00
2019-12-03 11:16:39 +00:00
use super ::{ builtin , AssocTyValue , Canonical , ChalkContext , Impl , Obligation } ;
2019-05-01 15:06:11 +00:00
use crate ::{
2020-05-18 19:25:23 +00:00
db ::HirDatabase ,
display ::HirDisplay ,
method_resolution ::TyFingerprint ,
primitive ::{ FloatBitness , FloatTy , IntBitness , IntTy , Signedness , Uncertain } ,
utils ::generics ,
2020-04-17 20:48:29 +00:00
ApplicationTy , DebruijnIndex , GenericPredicate , ProjectionTy , Substs , TraitRef , Ty , TypeCtor ,
2019-05-01 15:06:11 +00:00
} ;
2020-03-27 17:56:18 +00:00
pub ( super ) mod tls ;
2019-12-21 14:00:44 +00:00
#[ derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq) ]
2020-03-02 22:01:16 +00:00
pub struct Interner ;
2019-12-21 14:00:44 +00:00
2020-02-24 20:36:57 +00:00
impl chalk_ir ::interner ::Interner for Interner {
2020-05-22 14:40:42 +00:00
type InternedType = Box < chalk_ir ::TyData < Self > > ; // FIXME use Arc?
2019-12-21 14:00:44 +00:00
type InternedLifetime = chalk_ir ::LifetimeData < Self > ;
2020-05-22 14:40:42 +00:00
type InternedConst = Arc < chalk_ir ::ConstData < Self > > ;
type InternedConcreteConst = ( ) ;
type InternedGenericArg = chalk_ir ::GenericArgData < Self > ;
2020-01-17 21:12:15 +00:00
type InternedGoal = Arc < GoalData < Self > > ;
2020-02-24 20:36:57 +00:00
type InternedGoals = Vec < Goal < Self > > ;
2020-05-22 14:40:42 +00:00
type InternedSubstitution = Vec < GenericArg < Self > > ;
2020-04-10 15:44:29 +00:00
type InternedProgramClause = chalk_ir ::ProgramClauseData < Self > ;
2020-04-18 11:36:35 +00:00
type InternedProgramClauses = Arc < [ chalk_ir ::ProgramClause < Self > ] > ;
2020-04-10 15:44:29 +00:00
type InternedQuantifiedWhereClauses = Vec < chalk_ir ::QuantifiedWhereClause < Self > > ;
2020-05-22 14:40:42 +00:00
type InternedVariableKinds = Vec < chalk_ir ::VariableKind < Self > > ;
type InternedCanonicalVarKinds = Vec < chalk_ir ::CanonicalVarKind < Self > > ;
2019-12-21 14:00:44 +00:00
type DefId = InternId ;
2020-05-22 14:40:42 +00:00
type InternedAdtId = InternId ;
type Identifier = TypeAliasId ;
2019-12-21 14:00:44 +00:00
2020-05-22 14:40:42 +00:00
fn debug_adt_id ( type_kind_id : StructId , fmt : & mut fmt ::Formatter < '_ > ) -> Option < fmt ::Result > {
2020-03-27 17:56:18 +00:00
tls ::with_current_program ( | prog | Some ( prog ? . debug_struct_id ( type_kind_id , fmt ) ) )
2019-12-21 14:00:44 +00:00
}
2020-03-27 17:56:18 +00:00
fn debug_trait_id ( type_kind_id : TraitId , fmt : & mut fmt ::Formatter < '_ > ) -> Option < fmt ::Result > {
tls ::with_current_program ( | prog | Some ( prog ? . debug_trait_id ( type_kind_id , fmt ) ) )
2019-12-21 14:00:44 +00:00
}
2020-03-27 17:56:18 +00:00
fn debug_assoc_type_id ( id : AssocTypeId , fmt : & mut fmt ::Formatter < '_ > ) -> Option < fmt ::Result > {
tls ::with_current_program ( | prog | Some ( prog ? . debug_assoc_type_id ( id , fmt ) ) )
2019-12-21 14:00:44 +00:00
}
2020-01-17 21:12:15 +00:00
fn debug_alias (
2020-03-27 17:56:18 +00:00
alias : & chalk_ir ::AliasTy < Interner > ,
fmt : & mut fmt ::Formatter < '_ > ,
2019-12-21 14:00:44 +00:00
) -> Option < fmt ::Result > {
2020-03-27 17:56:18 +00:00
tls ::with_current_program ( | prog | Some ( prog ? . debug_alias ( alias , fmt ) ) )
2019-12-21 14:00:44 +00:00
}
2020-04-18 11:36:35 +00:00
fn debug_projection_ty (
proj : & chalk_ir ::ProjectionTy < Interner > ,
fmt : & mut fmt ::Formatter < '_ > ,
) -> Option < fmt ::Result > {
tls ::with_current_program ( | prog | Some ( prog ? . debug_projection_ty ( proj , fmt ) ) )
}
fn debug_opaque_ty (
opaque_ty : & chalk_ir ::OpaqueTy < Interner > ,
fmt : & mut fmt ::Formatter < '_ > ,
) -> Option < fmt ::Result > {
tls ::with_current_program ( | prog | Some ( prog ? . debug_opaque_ty ( opaque_ty , fmt ) ) )
}
fn debug_opaque_ty_id (
opaque_ty_id : chalk_ir ::OpaqueTyId < Self > ,
fmt : & mut fmt ::Formatter < '_ > ,
) -> Option < fmt ::Result > {
tls ::with_current_program ( | prog | Some ( prog ? . debug_opaque_ty_id ( opaque_ty_id , fmt ) ) )
}
2020-03-27 17:56:18 +00:00
fn debug_ty ( ty : & chalk_ir ::Ty < Interner > , fmt : & mut fmt ::Formatter < '_ > ) -> Option < fmt ::Result > {
tls ::with_current_program ( | prog | Some ( prog ? . debug_ty ( ty , fmt ) ) )
2020-03-27 13:50:08 +00:00
}
fn debug_lifetime (
2020-03-27 17:56:18 +00:00
lifetime : & chalk_ir ::Lifetime < Interner > ,
fmt : & mut fmt ::Formatter < '_ > ,
2020-03-27 13:50:08 +00:00
) -> Option < fmt ::Result > {
2020-03-27 17:56:18 +00:00
tls ::with_current_program ( | prog | Some ( prog ? . debug_lifetime ( lifetime , fmt ) ) )
2020-03-27 13:50:08 +00:00
}
2020-05-22 14:40:42 +00:00
fn debug_generic_arg (
parameter : & GenericArg < Interner > ,
2020-03-27 17:56:18 +00:00
fmt : & mut fmt ::Formatter < '_ > ,
2020-03-27 13:50:08 +00:00
) -> Option < fmt ::Result > {
2020-05-22 14:40:42 +00:00
tls ::with_current_program ( | prog | Some ( prog ? . debug_generic_arg ( parameter , fmt ) ) )
2020-03-27 13:50:08 +00:00
}
2020-03-27 17:56:18 +00:00
fn debug_goal ( goal : & Goal < Interner > , fmt : & mut fmt ::Formatter < '_ > ) -> Option < fmt ::Result > {
tls ::with_current_program ( | prog | Some ( prog ? . debug_goal ( goal , fmt ) ) )
2020-03-27 13:50:08 +00:00
}
fn debug_goals (
2020-03-27 17:56:18 +00:00
goals : & chalk_ir ::Goals < Interner > ,
fmt : & mut fmt ::Formatter < '_ > ,
2020-03-27 13:50:08 +00:00
) -> Option < fmt ::Result > {
2020-03-27 17:56:18 +00:00
tls ::with_current_program ( | prog | Some ( prog ? . debug_goals ( goals , fmt ) ) )
2020-03-27 13:50:08 +00:00
}
fn debug_program_clause_implication (
2020-03-27 17:56:18 +00:00
pci : & chalk_ir ::ProgramClauseImplication < Interner > ,
fmt : & mut fmt ::Formatter < '_ > ,
2020-03-27 13:50:08 +00:00
) -> Option < fmt ::Result > {
2020-03-27 17:56:18 +00:00
tls ::with_current_program ( | prog | Some ( prog ? . debug_program_clause_implication ( pci , fmt ) ) )
2020-03-27 13:50:08 +00:00
}
fn debug_application_ty (
2020-03-27 17:56:18 +00:00
application_ty : & chalk_ir ::ApplicationTy < Interner > ,
fmt : & mut fmt ::Formatter < '_ > ,
2020-03-27 13:50:08 +00:00
) -> Option < fmt ::Result > {
2020-03-27 17:56:18 +00:00
tls ::with_current_program ( | prog | Some ( prog ? . debug_application_ty ( application_ty , fmt ) ) )
2020-03-27 13:50:08 +00:00
}
fn debug_substitution (
2020-03-27 17:56:18 +00:00
substitution : & chalk_ir ::Substitution < Interner > ,
fmt : & mut fmt ::Formatter < '_ > ,
2020-03-27 13:50:08 +00:00
) -> Option < fmt ::Result > {
2020-03-27 17:56:18 +00:00
tls ::with_current_program ( | prog | Some ( prog ? . debug_substitution ( substitution , fmt ) ) )
2020-03-27 13:50:08 +00:00
}
fn debug_separator_trait_ref (
2020-03-27 17:56:18 +00:00
separator_trait_ref : & chalk_ir ::SeparatorTraitRef < Interner > ,
fmt : & mut fmt ::Formatter < '_ > ,
2020-03-27 13:50:08 +00:00
) -> Option < fmt ::Result > {
2020-03-27 17:56:18 +00:00
tls ::with_current_program ( | prog | {
Some ( prog ? . debug_separator_trait_ref ( separator_trait_ref , fmt ) )
} )
2020-03-27 13:50:08 +00:00
}
2020-03-02 22:01:16 +00:00
fn intern_ty ( & self , ty : chalk_ir ::TyData < Self > ) -> Box < chalk_ir ::TyData < Self > > {
2019-12-21 14:00:44 +00:00
Box ::new ( ty )
}
2020-03-27 13:50:08 +00:00
fn ty_data < ' a > ( & self , ty : & ' a Box < chalk_ir ::TyData < Self > > ) -> & ' a chalk_ir ::TyData < Self > {
2019-12-21 14:00:44 +00:00
ty
}
2020-03-27 13:50:08 +00:00
fn intern_lifetime (
& self ,
lifetime : chalk_ir ::LifetimeData < Self > ,
) -> chalk_ir ::LifetimeData < Self > {
2019-12-21 14:00:44 +00:00
lifetime
}
2020-03-27 13:50:08 +00:00
fn lifetime_data < ' a > (
& self ,
lifetime : & ' a chalk_ir ::LifetimeData < Self > ,
) -> & ' a chalk_ir ::LifetimeData < Self > {
2019-12-21 14:00:44 +00:00
lifetime
}
2020-05-22 14:40:42 +00:00
fn intern_const ( & self , constant : chalk_ir ::ConstData < Self > ) -> Arc < chalk_ir ::ConstData < Self > > {
Arc ::new ( constant )
}
fn const_data < ' a > (
& self ,
constant : & ' a Arc < chalk_ir ::ConstData < Self > > ,
) -> & ' a chalk_ir ::ConstData < Self > {
constant
}
fn const_eq ( & self , _ty : & Box < chalk_ir ::TyData < Self > > , _c1 : & ( ) , _c2 : & ( ) ) -> bool {
true
}
fn intern_generic_arg (
2020-03-27 13:50:08 +00:00
& self ,
2020-05-22 14:40:42 +00:00
parameter : chalk_ir ::GenericArgData < Self > ,
) -> chalk_ir ::GenericArgData < Self > {
2019-12-21 14:00:44 +00:00
parameter
}
2020-05-22 14:40:42 +00:00
fn generic_arg_data < ' a > (
2020-03-27 13:50:08 +00:00
& self ,
2020-05-22 14:40:42 +00:00
parameter : & ' a chalk_ir ::GenericArgData < Self > ,
) -> & ' a chalk_ir ::GenericArgData < Self > {
2019-12-21 14:00:44 +00:00
parameter
}
2020-01-17 21:12:15 +00:00
2020-03-27 13:50:08 +00:00
fn intern_goal ( & self , goal : GoalData < Self > ) -> Arc < GoalData < Self > > {
2020-01-17 21:12:15 +00:00
Arc ::new ( goal )
}
2020-05-16 08:49:43 +00:00
fn intern_goals < E > (
& self ,
data : impl IntoIterator < Item = Result < Goal < Self > , E > > ,
) -> Result < Self ::InternedGoals , E > {
2020-02-24 20:36:57 +00:00
data . into_iter ( ) . collect ( )
}
2020-03-27 13:50:08 +00:00
fn goal_data < ' a > ( & self , goal : & ' a Arc < GoalData < Self > > ) -> & ' a GoalData < Self > {
2020-01-17 21:12:15 +00:00
goal
}
2020-03-27 13:50:08 +00:00
fn goals_data < ' a > ( & self , goals : & ' a Vec < Goal < Interner > > ) -> & ' a [ Goal < Interner > ] {
2020-02-24 20:36:57 +00:00
goals
}
2020-01-17 21:12:15 +00:00
fn intern_substitution < E > (
2020-03-27 13:50:08 +00:00
& self ,
2020-05-22 14:40:42 +00:00
data : impl IntoIterator < Item = Result < GenericArg < Self > , E > > ,
) -> Result < Vec < GenericArg < Self > > , E > {
2020-01-17 21:12:15 +00:00
data . into_iter ( ) . collect ( )
}
2020-03-27 13:50:08 +00:00
fn substitution_data < ' a > (
& self ,
2020-05-22 14:40:42 +00:00
substitution : & ' a Vec < GenericArg < Self > > ,
) -> & ' a [ GenericArg < Self > ] {
2020-01-17 21:12:15 +00:00
substitution
}
2020-04-10 15:44:29 +00:00
fn intern_program_clause (
& self ,
data : chalk_ir ::ProgramClauseData < Self > ,
) -> chalk_ir ::ProgramClauseData < Self > {
data
}
fn program_clause_data < ' a > (
& self ,
clause : & ' a chalk_ir ::ProgramClauseData < Self > ,
) -> & ' a chalk_ir ::ProgramClauseData < Self > {
clause
}
2020-05-16 08:49:43 +00:00
fn intern_program_clauses < E > (
2020-04-10 15:44:29 +00:00
& self ,
2020-05-16 08:49:43 +00:00
data : impl IntoIterator < Item = Result < chalk_ir ::ProgramClause < Self > , E > > ,
) -> Result < Arc < [ chalk_ir ::ProgramClause < Self > ] > , E > {
2020-04-10 15:44:29 +00:00
data . into_iter ( ) . collect ( )
}
fn program_clauses_data < ' a > (
& self ,
2020-04-18 11:36:35 +00:00
clauses : & ' a Arc < [ chalk_ir ::ProgramClause < Self > ] > ,
2020-04-10 15:44:29 +00:00
) -> & ' a [ chalk_ir ::ProgramClause < Self > ] {
2020-04-18 11:36:35 +00:00
& clauses
2020-04-10 15:44:29 +00:00
}
2020-05-16 08:49:43 +00:00
fn intern_quantified_where_clauses < E > (
2020-04-10 15:44:29 +00:00
& self ,
2020-05-16 08:49:43 +00:00
data : impl IntoIterator < Item = Result < chalk_ir ::QuantifiedWhereClause < Self > , E > > ,
) -> Result < Self ::InternedQuantifiedWhereClauses , E > {
2020-04-10 15:44:29 +00:00
data . into_iter ( ) . collect ( )
}
fn quantified_where_clauses_data < ' a > (
& self ,
clauses : & ' a Self ::InternedQuantifiedWhereClauses ,
) -> & ' a [ chalk_ir ::QuantifiedWhereClause < Self > ] {
clauses
}
2020-04-18 11:36:35 +00:00
2020-05-22 14:40:42 +00:00
fn intern_generic_arg_kinds < E > (
2020-04-18 11:36:35 +00:00
& self ,
2020-05-22 14:40:42 +00:00
data : impl IntoIterator < Item = Result < chalk_ir ::VariableKind < Self > , E > > ,
) -> Result < Self ::InternedVariableKinds , E > {
2020-04-18 11:36:35 +00:00
data . into_iter ( ) . collect ( )
}
2020-05-22 14:40:42 +00:00
fn variable_kinds_data < ' a > (
2020-04-18 11:36:35 +00:00
& self ,
2020-05-22 14:40:42 +00:00
parameter_kinds : & ' a Self ::InternedVariableKinds ,
) -> & ' a [ chalk_ir ::VariableKind < Self > ] {
2020-04-18 11:36:35 +00:00
& parameter_kinds
}
2020-05-16 08:49:43 +00:00
fn intern_canonical_var_kinds < E > (
2020-04-18 11:36:35 +00:00
& self ,
2020-05-22 14:40:42 +00:00
data : impl IntoIterator < Item = Result < chalk_ir ::CanonicalVarKind < Self > , E > > ,
2020-05-16 08:49:43 +00:00
) -> Result < Self ::InternedCanonicalVarKinds , E > {
2020-04-18 11:36:35 +00:00
data . into_iter ( ) . collect ( )
}
fn canonical_var_kinds_data < ' a > (
& self ,
canonical_var_kinds : & ' a Self ::InternedCanonicalVarKinds ,
2020-05-22 14:40:42 +00:00
) -> & ' a [ chalk_ir ::CanonicalVarKind < Self > ] {
2020-04-18 11:36:35 +00:00
& canonical_var_kinds
}
2019-12-21 14:00:44 +00:00
}
2020-02-24 20:36:57 +00:00
impl chalk_ir ::interner ::HasInterner for Interner {
type Interner = Self ;
2019-12-21 14:00:44 +00:00
}
2020-02-24 20:36:57 +00:00
pub type AssocTypeId = chalk_ir ::AssocTypeId < Interner > ;
pub type AssociatedTyDatum = chalk_rust_ir ::AssociatedTyDatum < Interner > ;
pub type TraitId = chalk_ir ::TraitId < Interner > ;
pub type TraitDatum = chalk_rust_ir ::TraitDatum < Interner > ;
2020-05-22 14:40:42 +00:00
pub type StructId = chalk_ir ::AdtId < Interner > ;
pub type StructDatum = chalk_rust_ir ::AdtDatum < Interner > ;
2020-02-24 20:36:57 +00:00
pub type ImplId = chalk_ir ::ImplId < Interner > ;
pub type ImplDatum = chalk_rust_ir ::ImplDatum < Interner > ;
2020-03-02 21:30:38 +00:00
pub type AssociatedTyValueId = chalk_rust_ir ::AssociatedTyValueId < Interner > ;
2020-02-24 20:36:57 +00:00
pub type AssociatedTyValue = chalk_rust_ir ::AssociatedTyValue < Interner > ;
2019-12-21 13:29:33 +00:00
2019-05-01 15:06:11 +00:00
pub ( super ) trait ToChalk {
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
}
2020-03-13 15:05:46 +00:00
pub ( super ) 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 )
}
impl ToChalk for Ty {
2020-02-24 20:36:57 +00:00
type Chalk = chalk_ir ::Ty < Interner > ;
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> chalk_ir ::Ty < Interner > {
2019-05-01 15:06:11 +00:00
match self {
2019-05-04 13:53:23 +00:00
Ty ::Apply ( apply_ty ) = > {
2020-05-18 19:25:23 +00:00
if let TypeCtor ::Ref ( m ) = apply_ty . ctor {
return ref_to_chalk ( db , m , apply_ty . parameters ) ;
}
2019-12-21 13:46:15 +00:00
let name = apply_ty . ctor . to_chalk ( db ) ;
2020-01-17 21:12:15 +00:00
let substitution = apply_ty . parameters . to_chalk ( db ) ;
2020-03-27 13:50:08 +00:00
chalk_ir ::ApplicationTy { name , substitution } . cast ( & Interner ) . intern ( & Interner )
2019-05-04 13:53:23 +00:00
}
2019-08-05 19:13:34 +00:00
Ty ::Projection ( proj_ty ) = > {
let associated_ty_id = proj_ty . associated_ty . to_chalk ( db ) ;
2020-01-17 21:12:15 +00:00
let substitution = proj_ty . parameters . to_chalk ( db ) ;
2020-04-18 11:36:35 +00:00
chalk_ir ::AliasTy ::Projection ( chalk_ir ::ProjectionTy {
associated_ty_id ,
substitution ,
} )
. cast ( & Interner )
. intern ( & Interner )
2019-08-05 19:13:34 +00:00
}
2020-02-14 13:44:00 +00:00
Ty ::Placeholder ( id ) = > {
2020-01-31 15:52:43 +00:00
let interned_id = db . intern_type_param_id ( id ) ;
2020-02-07 14:13:15 +00:00
PlaceholderIndex {
ui : UniverseIndex ::ROOT ,
idx : interned_id . as_intern_id ( ) . as_usize ( ) ,
}
2020-03-02 22:01:16 +00:00
. to_ty ::< Interner > ( & Interner )
2019-05-01 15:06:11 +00:00
}
2020-04-05 16:24:18 +00:00
Ty ::Bound ( idx ) = > chalk_ir ::TyData ::BoundVar ( idx ) . intern ( & Interner ) ,
2019-05-01 15:06:11 +00:00
Ty ::Infer ( _infer_ty ) = > panic! ( " uncanonicalized infer ty " ) ,
2019-11-15 20:00:27 +00:00
Ty ::Dyn ( predicates ) = > {
2020-04-10 15:44:29 +00:00
let where_clauses = chalk_ir ::QuantifiedWhereClauses ::from (
& Interner ,
predicates . iter ( ) . filter ( | p | ! p . is_error ( ) ) . cloned ( ) . map ( | p | p . to_chalk ( db ) ) ,
) ;
2020-01-17 21:12:15 +00:00
let bounded_ty = chalk_ir ::DynTy { bounds : make_binders ( where_clauses , 1 ) } ;
2020-03-02 22:01:16 +00:00
chalk_ir ::TyData ::Dyn ( bounded_ty ) . intern ( & Interner )
2019-11-15 20:00:27 +00:00
}
2020-01-17 21:12:15 +00:00
Ty ::Opaque ( _ ) | Ty ::Unknown = > {
2020-03-27 13:50:08 +00:00
let substitution = chalk_ir ::Substitution ::empty ( & Interner ) ;
2019-10-29 12:01:33 +00:00
let name = TypeName ::Error ;
2020-03-27 13:50:08 +00:00
chalk_ir ::ApplicationTy { name , substitution } . cast ( & Interner ) . intern ( & Interner )
2019-05-05 12:42:12 +00:00
}
2019-05-01 15:06:11 +00:00
}
}
2020-03-13 15:05:46 +00:00
fn from_chalk ( db : & dyn HirDatabase , chalk : chalk_ir ::Ty < Interner > ) -> Self {
2020-03-27 13:50:08 +00:00
match chalk . data ( & Interner ) . clone ( ) {
2019-12-21 13:46:15 +00:00
chalk_ir ::TyData ::Apply ( apply_ty ) = > match apply_ty . name {
TypeName ::Error = > Ty ::Unknown ,
2020-05-18 19:25:23 +00:00
TypeName ::Ref ( m ) = > ref_from_chalk ( db , m , apply_ty . substitution ) ,
2019-12-21 13:46:15 +00:00
_ = > {
let ctor = from_chalk ( db , apply_ty . name ) ;
2020-01-17 21:12:15 +00:00
let parameters = from_chalk ( db , apply_ty . substitution ) ;
2019-12-21 13:46:15 +00:00
Ty ::Apply ( ApplicationTy { ctor , parameters } )
2019-05-01 15:06:11 +00:00
}
2019-12-21 13:46:15 +00:00
} ,
2019-12-21 13:29:33 +00:00
chalk_ir ::TyData ::Placeholder ( idx ) = > {
assert_eq! ( idx . ui , UniverseIndex ::ROOT ) ;
2020-02-07 14:13:15 +00:00
let interned_id = crate ::db ::GlobalTypeParamId ::from_intern_id (
crate ::salsa ::InternId ::from ( idx . idx ) ,
) ;
2020-02-14 13:44:00 +00:00
Ty ::Placeholder ( db . lookup_intern_type_param_id ( interned_id ) )
2019-12-21 13:29:33 +00:00
}
2020-04-18 11:36:35 +00:00
chalk_ir ::TyData ::Alias ( chalk_ir ::AliasTy ::Projection ( proj ) ) = > {
2019-09-22 18:08:46 +00:00
let associated_ty = from_chalk ( db , proj . associated_ty_id ) ;
2020-01-17 21:12:15 +00:00
let parameters = from_chalk ( db , proj . substitution ) ;
2019-09-22 18:08:46 +00:00
Ty ::Projection ( ProjectionTy { associated_ty , parameters } )
}
2020-04-18 11:36:35 +00:00
chalk_ir ::TyData ::Alias ( chalk_ir ::AliasTy ::Opaque ( _ ) ) = > unimplemented! ( ) ,
2020-01-17 21:12:15 +00:00
chalk_ir ::TyData ::Function ( _ ) = > unimplemented! ( ) ,
2020-04-05 16:24:18 +00:00
chalk_ir ::TyData ::BoundVar ( idx ) = > Ty ::Bound ( idx ) ,
2019-11-15 19:32:58 +00:00
chalk_ir ::TyData ::InferenceVar ( _iv ) = > Ty ::Unknown ,
chalk_ir ::TyData ::Dyn ( where_clauses ) = > {
2020-04-18 11:36:35 +00:00
assert_eq! ( where_clauses . bounds . binders . len ( & Interner ) , 1 ) ;
2020-04-10 15:44:29 +00:00
let predicates = where_clauses
. bounds
. skip_binders ( )
. iter ( & Interner )
. map ( | c | from_chalk ( db , c . clone ( ) ) )
. collect ( ) ;
2019-10-15 19:03:34 +00:00
Ty ::Dyn ( predicates )
}
2019-05-01 15:06:11 +00:00
}
}
}
2020-05-18 19:25:23 +00:00
const LIFETIME_PLACEHOLDER : PlaceholderIndex =
PlaceholderIndex { ui : UniverseIndex ::ROOT , idx : usize ::MAX } ;
/// We currently don't model lifetimes, but Chalk does. So, we have to insert a
/// fake lifetime here, because Chalks built-in logic may expect it to be there.
fn ref_to_chalk (
db : & dyn HirDatabase ,
mutability : Mutability ,
subst : Substs ,
) -> chalk_ir ::Ty < Interner > {
let arg = subst [ 0 ] . clone ( ) . to_chalk ( db ) ;
let lifetime = LIFETIME_PLACEHOLDER . to_lifetime ( & Interner ) ;
chalk_ir ::ApplicationTy {
name : TypeName ::Ref ( mutability . to_chalk ( db ) ) ,
substitution : chalk_ir ::Substitution ::from (
& Interner ,
vec! [ lifetime . cast ( & Interner ) , arg . cast ( & Interner ) ] ,
) ,
}
. intern ( & Interner )
}
/// Here we remove the lifetime from the type we got from Chalk.
fn ref_from_chalk (
db : & dyn HirDatabase ,
mutability : chalk_ir ::Mutability ,
subst : chalk_ir ::Substitution < Interner > ,
) -> Ty {
let tys = subst
. iter ( & Interner )
. filter_map ( | p | Some ( from_chalk ( db , p . ty ( & Interner ) ? . clone ( ) ) ) )
. collect ( ) ;
Ty ::apply ( TypeCtor ::Ref ( from_chalk ( db , mutability ) ) , Substs ( tys ) )
}
2019-05-01 15:06:11 +00:00
impl ToChalk for Substs {
2020-02-24 20:36:57 +00:00
type Chalk = chalk_ir ::Substitution < Interner > ;
2019-05-01 15:06:11 +00:00
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> chalk_ir ::Substitution < Interner > {
2020-03-27 13:50:08 +00:00
chalk_ir ::Substitution ::from ( & Interner , self . iter ( ) . map ( | ty | ty . clone ( ) . to_chalk ( db ) ) )
2019-05-01 15:06:11 +00:00
}
2020-03-13 15:05:46 +00:00
fn from_chalk ( db : & dyn HirDatabase , parameters : chalk_ir ::Substitution < Interner > ) -> Substs {
2019-09-26 19:37:03 +00:00
let tys = parameters
2020-03-27 13:50:08 +00:00
. iter ( & Interner )
. map ( | p | match p . ty ( & Interner ) {
2019-12-21 13:29:33 +00:00
Some ( ty ) = > from_chalk ( db , ty . clone ( ) ) ,
None = > unimplemented! ( ) ,
2019-05-01 15:06:11 +00:00
} )
2019-10-14 04:06:05 +00:00
. collect ( ) ;
2019-09-26 19:37:03 +00:00
Substs ( tys )
2019-05-01 15:06:11 +00:00
}
}
impl ToChalk for TraitRef {
2020-02-24 20:36:57 +00:00
type Chalk = chalk_ir ::TraitRef < Interner > ;
2019-05-01 15:06:11 +00:00
2020-03-13 15:05:46 +00:00
fn to_chalk ( self : TraitRef , db : & dyn HirDatabase ) -> chalk_ir ::TraitRef < Interner > {
2019-05-01 15:06:11 +00:00
let trait_id = self . trait_ . to_chalk ( db ) ;
2020-01-17 21:12:15 +00:00
let substitution = self . substs . to_chalk ( db ) ;
chalk_ir ::TraitRef { trait_id , substitution }
2019-05-01 15:06:11 +00:00
}
2020-03-13 15:05:46 +00:00
fn from_chalk ( db : & dyn HirDatabase , trait_ref : chalk_ir ::TraitRef < Interner > ) -> Self {
2019-05-01 15:06:11 +00:00
let trait_ = from_chalk ( db , trait_ref . trait_id ) ;
2020-01-17 21:12:15 +00:00
let substs = from_chalk ( db , trait_ref . substitution ) ;
2019-05-01 15:06:11 +00:00
TraitRef { trait_ , substs }
}
}
2019-12-21 13:29:33 +00:00
impl ToChalk for hir_def ::TraitId {
type Chalk = TraitId ;
2019-05-01 15:06:11 +00:00
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , _db : & dyn HirDatabase ) -> TraitId {
2019-12-21 14:00:44 +00:00
chalk_ir ::TraitId ( self . as_intern_id ( ) )
2019-05-01 15:06:11 +00:00
}
2020-03-13 15:05:46 +00:00
fn from_chalk ( _db : & dyn HirDatabase , trait_id : TraitId ) -> hir_def ::TraitId {
2019-12-21 14:00:44 +00:00
InternKey ::from_intern_id ( trait_id . 0 )
2019-05-01 15:06:11 +00:00
}
}
impl ToChalk for TypeCtor {
2020-02-24 20:36:57 +00:00
type Chalk = TypeName < Interner > ;
2019-05-01 15:06:11 +00:00
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> TypeName < Interner > {
2019-12-21 13:46:15 +00:00
match self {
TypeCtor ::AssociatedType ( type_alias ) = > {
let type_id = type_alias . to_chalk ( db ) ;
TypeName ::AssociatedType ( type_id )
}
2020-05-18 19:25:23 +00:00
TypeCtor ::Bool = > TypeName ::Scalar ( Scalar ::Bool ) ,
TypeCtor ::Char = > TypeName ::Scalar ( Scalar ::Char ) ,
TypeCtor ::Int ( Uncertain ::Known ( int_ty ) ) = > TypeName ::Scalar ( int_ty_to_chalk ( int_ty ) ) ,
TypeCtor ::Float ( Uncertain ::Known ( FloatTy { bitness : FloatBitness ::X32 } ) ) = > {
TypeName ::Scalar ( Scalar ::Float ( chalk_ir ::FloatTy ::F32 ) )
}
TypeCtor ::Float ( Uncertain ::Known ( FloatTy { bitness : FloatBitness ::X64 } ) ) = > {
TypeName ::Scalar ( Scalar ::Float ( chalk_ir ::FloatTy ::F64 ) )
}
TypeCtor ::Tuple { cardinality } = > TypeName ::Tuple ( cardinality . into ( ) ) ,
TypeCtor ::RawPtr ( mutability ) = > TypeName ::Raw ( mutability . to_chalk ( db ) ) ,
TypeCtor ::Slice = > TypeName ::Slice ,
TypeCtor ::Ref ( mutability ) = > TypeName ::Ref ( mutability . to_chalk ( db ) ) ,
TypeCtor ::Str = > TypeName ::Str ,
TypeCtor ::Int ( Uncertain ::Unknown )
| TypeCtor ::Float ( Uncertain ::Unknown )
| TypeCtor ::Adt ( _ )
| TypeCtor ::Array
| TypeCtor ::FnDef ( _ )
| TypeCtor ::FnPtr { .. }
| TypeCtor ::Never
| TypeCtor ::Closure { .. } = > {
2019-12-21 13:46:15 +00:00
// other TypeCtors get interned and turned into a chalk StructId
let struct_id = db . intern_type_ctor ( self ) . into ( ) ;
2020-05-22 14:40:42 +00:00
TypeName ::Adt ( struct_id )
2019-12-21 13:46:15 +00:00
}
}
2019-05-01 15:06:11 +00:00
}
2020-03-13 15:05:46 +00:00
fn from_chalk ( db : & dyn HirDatabase , type_name : TypeName < Interner > ) -> TypeCtor {
2019-12-21 13:46:15 +00:00
match type_name {
2020-05-22 14:40:42 +00:00
TypeName ::Adt ( struct_id ) = > db . lookup_intern_type_ctor ( struct_id . into ( ) ) ,
2019-12-21 13:46:15 +00:00
TypeName ::AssociatedType ( type_id ) = > TypeCtor ::AssociatedType ( from_chalk ( db , type_id ) ) ,
2020-04-18 11:36:35 +00:00
TypeName ::OpaqueType ( _ ) = > unreachable! ( ) ,
2020-05-16 08:49:43 +00:00
2020-05-18 19:25:23 +00:00
TypeName ::Scalar ( Scalar ::Bool ) = > TypeCtor ::Bool ,
TypeName ::Scalar ( Scalar ::Char ) = > TypeCtor ::Char ,
TypeName ::Scalar ( Scalar ::Int ( int_ty ) ) = > TypeCtor ::Int ( Uncertain ::Known ( IntTy {
signedness : Signedness ::Signed ,
bitness : bitness_from_chalk_int ( int_ty ) ,
} ) ) ,
TypeName ::Scalar ( Scalar ::Uint ( uint_ty ) ) = > TypeCtor ::Int ( Uncertain ::Known ( IntTy {
signedness : Signedness ::Unsigned ,
bitness : bitness_from_chalk_uint ( uint_ty ) ,
} ) ) ,
TypeName ::Scalar ( Scalar ::Float ( chalk_ir ::FloatTy ::F32 ) ) = > {
TypeCtor ::Float ( Uncertain ::Known ( FloatTy { bitness : FloatBitness ::X32 } ) )
}
TypeName ::Scalar ( Scalar ::Float ( chalk_ir ::FloatTy ::F64 ) ) = > {
TypeCtor ::Float ( Uncertain ::Known ( FloatTy { bitness : FloatBitness ::X64 } ) )
}
TypeName ::Tuple ( cardinality ) = > TypeCtor ::Tuple { cardinality : cardinality as u16 } ,
TypeName ::Raw ( mutability ) = > TypeCtor ::RawPtr ( from_chalk ( db , mutability ) ) ,
TypeName ::Slice = > TypeCtor ::Slice ,
TypeName ::Ref ( mutability ) = > TypeCtor ::Ref ( from_chalk ( db , mutability ) ) ,
TypeName ::Str = > TypeCtor ::Str ,
2020-05-16 08:49:43 +00:00
2020-05-22 14:40:42 +00:00
TypeName ::FnDef ( _ ) = > unreachable! ( ) ,
2019-12-21 13:46:15 +00:00
TypeName ::Error = > {
// this should not be reached, since we don't represent TypeName::Error with TypeCtor
unreachable! ( )
}
}
2019-05-01 15:06:11 +00:00
}
}
2020-05-18 19:25:23 +00:00
fn bitness_from_chalk_uint ( uint_ty : chalk_ir ::UintTy ) -> IntBitness {
use chalk_ir ::UintTy ;
match uint_ty {
UintTy ::Usize = > IntBitness ::Xsize ,
UintTy ::U8 = > IntBitness ::X8 ,
UintTy ::U16 = > IntBitness ::X16 ,
UintTy ::U32 = > IntBitness ::X32 ,
UintTy ::U64 = > IntBitness ::X64 ,
UintTy ::U128 = > IntBitness ::X128 ,
}
}
fn bitness_from_chalk_int ( int_ty : chalk_ir ::IntTy ) -> IntBitness {
use chalk_ir ::IntTy ;
match int_ty {
IntTy ::Isize = > IntBitness ::Xsize ,
IntTy ::I8 = > IntBitness ::X8 ,
IntTy ::I16 = > IntBitness ::X16 ,
IntTy ::I32 = > IntBitness ::X32 ,
IntTy ::I64 = > IntBitness ::X64 ,
IntTy ::I128 = > IntBitness ::X128 ,
}
}
fn int_ty_to_chalk ( int_ty : IntTy ) -> Scalar {
use chalk_ir ::{ IntTy , UintTy } ;
match int_ty . signedness {
Signedness ::Signed = > Scalar ::Int ( match int_ty . bitness {
IntBitness ::Xsize = > IntTy ::Isize ,
IntBitness ::X8 = > IntTy ::I8 ,
IntBitness ::X16 = > IntTy ::I16 ,
IntBitness ::X32 = > IntTy ::I32 ,
IntBitness ::X64 = > IntTy ::I64 ,
IntBitness ::X128 = > IntTy ::I128 ,
} ) ,
Signedness ::Unsigned = > Scalar ::Uint ( match int_ty . bitness {
IntBitness ::Xsize = > UintTy ::Usize ,
IntBitness ::X8 = > UintTy ::U8 ,
IntBitness ::X16 = > UintTy ::U16 ,
IntBitness ::X32 = > UintTy ::U32 ,
IntBitness ::X64 = > UintTy ::U64 ,
IntBitness ::X128 = > UintTy ::U128 ,
} ) ,
}
}
impl ToChalk for Mutability {
type Chalk = chalk_ir ::Mutability ;
fn to_chalk ( self , _db : & dyn HirDatabase ) -> Self ::Chalk {
match self {
Mutability ::Shared = > chalk_ir ::Mutability ::Not ,
Mutability ::Mut = > chalk_ir ::Mutability ::Mut ,
}
}
fn from_chalk ( _db : & dyn HirDatabase , chalk : Self ::Chalk ) -> Self {
match chalk {
chalk_ir ::Mutability ::Mut = > Mutability ::Mut ,
chalk_ir ::Mutability ::Not = > Mutability ::Shared ,
}
}
}
2019-09-09 20:10:58 +00:00
impl ToChalk for Impl {
2019-12-21 13:29:33 +00:00
type Chalk = ImplId ;
2019-05-01 15:06:11 +00:00
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> ImplId {
2019-11-15 18:28:00 +00:00
db . intern_chalk_impl ( self ) . into ( )
2019-05-01 15:06:11 +00:00
}
2020-03-13 15:05:46 +00:00
fn from_chalk ( db : & dyn HirDatabase , impl_id : ImplId ) -> Impl {
2019-11-15 18:28:00 +00:00
db . lookup_intern_chalk_impl ( impl_id . into ( ) )
2019-05-01 15:06:11 +00:00
}
}
2019-11-25 15:44:36 +00:00
impl ToChalk for TypeAliasId {
2019-12-21 13:29:33 +00:00
type Chalk = AssocTypeId ;
2019-11-25 15:44:36 +00:00
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , _db : & dyn HirDatabase ) -> AssocTypeId {
2019-12-21 14:00:44 +00:00
chalk_ir ::AssocTypeId ( self . as_intern_id ( ) )
2019-11-25 15:44:36 +00:00
}
2020-03-13 15:05:46 +00:00
fn from_chalk ( _db : & dyn HirDatabase , type_alias_id : AssocTypeId ) -> TypeAliasId {
2019-12-21 14:00:44 +00:00
InternKey ::from_intern_id ( type_alias_id . 0 )
2019-11-25 15:44:36 +00:00
}
}
2019-11-15 19:32:58 +00:00
impl ToChalk for AssocTyValue {
2019-12-21 13:29:33 +00:00
type Chalk = AssociatedTyValueId ;
2019-11-15 19:32:58 +00:00
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> AssociatedTyValueId {
2019-11-15 19:32:58 +00:00
db . intern_assoc_ty_value ( self ) . into ( )
}
2020-03-13 15:05:46 +00:00
fn from_chalk ( db : & dyn HirDatabase , assoc_ty_value_id : AssociatedTyValueId ) -> AssocTyValue {
2019-11-15 19:32:58 +00:00
db . lookup_intern_assoc_ty_value ( assoc_ty_value_id . into ( ) )
}
}
2019-05-05 12:21:00 +00:00
impl ToChalk for GenericPredicate {
2020-02-24 20:36:57 +00:00
type Chalk = chalk_ir ::QuantifiedWhereClause < Interner > ;
2019-05-05 12:21:00 +00:00
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> chalk_ir ::QuantifiedWhereClause < Interner > {
2019-05-05 12:21:00 +00:00
match self {
GenericPredicate ::Implemented ( trait_ref ) = > {
2020-04-05 16:24:18 +00:00
let chalk_trait_ref = trait_ref . to_chalk ( db ) ;
let chalk_trait_ref = chalk_trait_ref . shifted_in ( & Interner ) ;
make_binders ( chalk_ir ::WhereClause ::Implemented ( chalk_trait_ref ) , 0 )
}
GenericPredicate ::Projection ( projection_pred ) = > {
let ty = projection_pred . ty . to_chalk ( db ) . shifted_in ( & Interner ) ;
2020-04-18 11:36:35 +00:00
let projection = projection_pred . projection_ty . to_chalk ( db ) . shifted_in ( & Interner ) ;
let alias = chalk_ir ::AliasTy ::Projection ( projection ) ;
2020-04-05 16:24:18 +00:00
make_binders ( chalk_ir ::WhereClause ::AliasEq ( chalk_ir ::AliasEq { alias , ty } ) , 0 )
2019-05-05 12:21:00 +00:00
}
2019-12-21 14:00:44 +00:00
GenericPredicate ::Error = > panic! ( " tried passing GenericPredicate::Error to Chalk " ) ,
2019-05-05 12:21:00 +00:00
}
}
fn from_chalk (
2020-03-13 15:05:46 +00:00
db : & dyn HirDatabase ,
2020-02-24 20:36:57 +00:00
where_clause : chalk_ir ::QuantifiedWhereClause < Interner > ,
2019-05-05 12:21:00 +00:00
) -> GenericPredicate {
2020-04-06 15:24:08 +00:00
// we don't produce any where clauses with binders and can't currently deal with them
match where_clause
2020-04-10 15:44:29 +00:00
. skip_binders ( )
2020-04-06 15:24:08 +00:00
. shifted_out ( & Interner )
. expect ( " unexpected bound vars in where clause " )
{
2019-10-15 19:03:34 +00:00
chalk_ir ::WhereClause ::Implemented ( tr ) = > {
GenericPredicate ::Implemented ( from_chalk ( db , tr ) )
}
2020-01-17 21:12:15 +00:00
chalk_ir ::WhereClause ::AliasEq ( projection_eq ) = > {
2020-04-18 11:36:35 +00:00
let projection_ty = from_chalk (
db ,
match projection_eq . alias {
chalk_ir ::AliasTy ::Projection ( p ) = > p ,
_ = > unimplemented! ( ) ,
} ,
) ;
2019-10-15 19:03:34 +00:00
let ty = from_chalk ( db , projection_eq . ty ) ;
GenericPredicate ::Projection ( super ::ProjectionPredicate { projection_ty , ty } )
}
}
2019-05-05 12:21:00 +00:00
}
}
2019-05-12 15:53:44 +00:00
impl ToChalk for ProjectionTy {
2020-04-18 11:36:35 +00:00
type Chalk = chalk_ir ::ProjectionTy < Interner > ;
2019-05-12 15:53:44 +00:00
2020-04-18 11:36:35 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> chalk_ir ::ProjectionTy < Interner > {
chalk_ir ::ProjectionTy {
2019-05-12 15:53:44 +00:00
associated_ty_id : self . associated_ty . to_chalk ( db ) ,
2020-01-17 21:12:15 +00:00
substitution : self . parameters . to_chalk ( db ) ,
2019-05-12 15:53:44 +00:00
}
}
2019-10-15 19:03:34 +00:00
fn from_chalk (
2020-03-13 15:05:46 +00:00
db : & dyn HirDatabase ,
2020-04-18 11:36:35 +00:00
projection_ty : chalk_ir ::ProjectionTy < Interner > ,
2019-10-15 19:03:34 +00:00
) -> ProjectionTy {
2019-05-12 15:53:44 +00:00
ProjectionTy {
associated_ty : from_chalk ( db , projection_ty . associated_ty_id ) ,
2020-01-17 21:12:15 +00:00
parameters : from_chalk ( db , projection_ty . substitution ) ,
2019-05-12 15:53:44 +00:00
}
}
}
2019-07-07 16:14:56 +00:00
impl ToChalk for super ::ProjectionPredicate {
2020-04-10 15:44:43 +00:00
type Chalk = chalk_ir ::AliasEq < Interner > ;
2019-07-07 16:14:56 +00:00
2020-04-10 15:44:43 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> chalk_ir ::AliasEq < Interner > {
2020-04-18 11:36:35 +00:00
chalk_ir ::AliasEq {
alias : chalk_ir ::AliasTy ::Projection ( self . projection_ty . to_chalk ( db ) ) ,
ty : self . ty . to_chalk ( db ) ,
}
2019-07-07 16:14:56 +00:00
}
2020-04-10 15:44:43 +00:00
fn from_chalk ( _db : & dyn HirDatabase , _normalize : chalk_ir ::AliasEq < Interner > ) -> Self {
2019-07-07 16:14:56 +00:00
unimplemented! ( )
}
}
2019-07-08 19:43:52 +00:00
impl ToChalk for Obligation {
2020-02-24 20:36:57 +00:00
type Chalk = chalk_ir ::DomainGoal < Interner > ;
2019-07-08 19:43:52 +00:00
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> chalk_ir ::DomainGoal < Interner > {
2019-07-08 19:43:52 +00:00
match self {
2020-03-27 13:50:08 +00:00
Obligation ::Trait ( tr ) = > tr . to_chalk ( db ) . cast ( & Interner ) ,
Obligation ::Projection ( pr ) = > pr . to_chalk ( db ) . cast ( & Interner ) ,
2019-07-08 19:43:52 +00:00
}
}
2020-03-13 15:05:46 +00:00
fn from_chalk ( _db : & dyn HirDatabase , _goal : chalk_ir ::DomainGoal < Interner > ) -> Self {
2019-07-08 19:43:52 +00:00
unimplemented! ( )
}
}
2019-06-29 15:40:00 +00:00
impl < T > ToChalk for Canonical < T >
where
T : ToChalk ,
2020-04-18 11:36:35 +00:00
T ::Chalk : HasInterner < Interner = Interner > ,
2019-06-29 15:40:00 +00:00
{
type Chalk = chalk_ir ::Canonical < T ::Chalk > ;
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> chalk_ir ::Canonical < T ::Chalk > {
2020-05-22 14:40:42 +00:00
let parameter = chalk_ir ::CanonicalVarKind ::new (
chalk_ir ::VariableKind ::Ty ,
chalk_ir ::UniverseIndex ::ROOT ,
) ;
2019-06-29 15:40:00 +00:00
let value = self . value . to_chalk ( db ) ;
2020-04-18 11:36:35 +00:00
chalk_ir ::Canonical {
value ,
binders : chalk_ir ::CanonicalVarKinds ::from ( & Interner , vec! [ parameter ; self . num_vars ] ) ,
}
2019-06-29 15:40:00 +00:00
}
2020-03-13 15:05:46 +00:00
fn from_chalk ( db : & dyn HirDatabase , canonical : chalk_ir ::Canonical < T ::Chalk > ) -> Canonical < T > {
2020-04-18 11:36:35 +00:00
Canonical {
num_vars : canonical . binders . len ( & Interner ) ,
value : from_chalk ( db , canonical . value ) ,
}
2019-06-29 15:40:00 +00:00
}
}
2019-07-09 19:34:23 +00:00
impl ToChalk for Arc < super ::TraitEnvironment > {
2020-02-24 20:36:57 +00:00
type Chalk = chalk_ir ::Environment < Interner > ;
2019-06-29 15:40:00 +00:00
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> chalk_ir ::Environment < Interner > {
2019-06-29 17:14:52 +00:00
let mut clauses = Vec ::new ( ) ;
for pred in & self . predicates {
if pred . is_error ( ) {
// for env, we just ignore errors
continue ;
}
2020-02-24 20:36:57 +00:00
let program_clause : chalk_ir ::ProgramClause < Interner > =
2020-03-27 13:50:08 +00:00
pred . clone ( ) . to_chalk ( db ) . cast ( & Interner ) ;
clauses . push ( program_clause . into_from_env_clause ( & Interner ) ) ;
2019-06-29 17:14:52 +00:00
}
2020-04-10 15:44:29 +00:00
chalk_ir ::Environment ::new ( & Interner ) . add_clauses ( & Interner , clauses )
2019-06-29 15:40:00 +00:00
}
fn from_chalk (
2020-03-13 15:05:46 +00:00
_db : & dyn HirDatabase ,
2020-02-24 20:36:57 +00:00
_env : chalk_ir ::Environment < Interner > ,
2019-07-09 19:34:23 +00:00
) -> Arc < super ::TraitEnvironment > {
2019-06-29 17:14:52 +00:00
unimplemented! ( )
2019-06-29 15:40:00 +00:00
}
}
2019-10-15 19:03:34 +00:00
impl < T : ToChalk > ToChalk for super ::InEnvironment < T >
where
2020-02-24 20:36:57 +00:00
T ::Chalk : chalk_ir ::interner ::HasInterner < Interner = Interner > ,
2019-10-15 19:03:34 +00:00
{
2019-06-29 15:40:00 +00:00
type Chalk = chalk_ir ::InEnvironment < T ::Chalk > ;
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> chalk_ir ::InEnvironment < T ::Chalk > {
2019-06-29 15:40:00 +00:00
chalk_ir ::InEnvironment {
environment : self . environment . to_chalk ( db ) ,
goal : self . value . to_chalk ( db ) ,
}
}
fn from_chalk (
2020-03-13 15:05:46 +00:00
db : & dyn HirDatabase ,
2019-06-29 15:40:00 +00:00
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-12-03 11:16:39 +00:00
impl ToChalk for builtin ::BuiltinImplData {
2019-12-21 13:46:15 +00:00
type Chalk = ImplDatum ;
2019-12-03 11:16:39 +00:00
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> ImplDatum {
2019-12-03 11:16:39 +00:00
let impl_type = chalk_rust_ir ::ImplType ::External ;
let where_clauses = self . where_clauses . into_iter ( ) . map ( | w | w . to_chalk ( db ) ) . collect ( ) ;
let impl_datum_bound =
chalk_rust_ir ::ImplDatumBound { trait_ref : self . trait_ref . to_chalk ( db ) , where_clauses } ;
let associated_ty_value_ids =
self . assoc_ty_values . into_iter ( ) . map ( | v | v . to_chalk ( db ) ) . collect ( ) ;
chalk_rust_ir ::ImplDatum {
binders : make_binders ( impl_datum_bound , self . num_vars ) ,
impl_type ,
polarity : chalk_rust_ir ::Polarity ::Positive ,
associated_ty_value_ids ,
}
}
2020-03-13 15:05:46 +00:00
fn from_chalk ( _db : & dyn HirDatabase , _data : ImplDatum ) -> Self {
2019-12-03 11:16:39 +00:00
unimplemented! ( )
}
}
impl ToChalk for builtin ::BuiltinImplAssocTyValueData {
2019-12-21 13:46:15 +00:00
type Chalk = AssociatedTyValue ;
2019-12-03 11:16:39 +00:00
2020-03-13 15:05:46 +00:00
fn to_chalk ( self , db : & dyn HirDatabase ) -> AssociatedTyValue {
2020-04-05 16:24:18 +00:00
let ty = self . value . to_chalk ( db ) ;
let value_bound = chalk_rust_ir ::AssociatedTyValueBound { ty } ;
2019-12-03 11:16:39 +00:00
chalk_rust_ir ::AssociatedTyValue {
associated_ty_id : self . assoc_ty_id . to_chalk ( db ) ,
impl_id : self . impl_ . to_chalk ( db ) ,
value : make_binders ( value_bound , self . num_vars ) ,
}
}
fn from_chalk (
2020-03-13 15:05:46 +00:00
_db : & dyn HirDatabase ,
2019-12-21 13:46:15 +00:00
_data : AssociatedTyValue ,
2019-12-03 11:16:39 +00:00
) -> builtin ::BuiltinImplAssocTyValueData {
unimplemented! ( )
}
}
2020-04-18 11:36:35 +00:00
fn make_binders < T > ( value : T , num_vars : usize ) -> chalk_ir ::Binders < T >
where
T : HasInterner < Interner = Interner > ,
{
2020-04-10 15:44:29 +00:00
chalk_ir ::Binders ::new (
2020-05-22 14:40:42 +00:00
chalk_ir ::VariableKinds ::from (
2020-04-18 11:36:35 +00:00
& Interner ,
2020-05-22 14:40:42 +00:00
std ::iter ::repeat ( chalk_ir ::VariableKind ::Ty ) . take ( num_vars ) ,
2020-04-18 11:36:35 +00:00
) ,
2019-05-01 15:06:11 +00:00
value ,
2020-04-10 15:44:29 +00:00
)
2019-05-01 15:06:11 +00:00
}
2019-05-05 12:21:00 +00:00
fn convert_where_clauses (
2020-03-13 15:05:46 +00:00
db : & dyn HirDatabase ,
2019-11-25 12:39:12 +00:00
def : GenericDefId ,
2019-05-05 12:21:00 +00:00
substs : & Substs ,
2020-02-24 20:36:57 +00:00
) -> Vec < chalk_ir ::QuantifiedWhereClause < Interner > > {
2019-05-05 12:21:00 +00:00
let generic_predicates = db . generic_predicates ( def ) ;
let mut result = Vec ::with_capacity ( generic_predicates . len ( ) ) ;
for pred in generic_predicates . iter ( ) {
2020-02-02 16:11:54 +00:00
if pred . value . is_error ( ) {
2019-12-21 14:00:44 +00:00
// skip errored predicates completely
continue ;
2019-05-11 18:31:41 +00:00
}
2020-02-02 16:11:54 +00:00
result . push ( pred . clone ( ) . subst ( substs ) . to_chalk ( db ) ) ;
2019-05-05 12:21:00 +00:00
}
2019-05-05 12:42:12 +00:00
result
2019-05-05 12:21:00 +00:00
}
2020-04-12 10:28:24 +00:00
fn generic_predicate_to_inline_bound (
db : & dyn HirDatabase ,
pred : & GenericPredicate ,
self_ty : & Ty ,
) -> Option < chalk_rust_ir ::InlineBound < Interner > > {
// An InlineBound is like a GenericPredicate, except the self type is left out.
// We don't have a special type for this, but Chalk does.
match pred {
GenericPredicate ::Implemented ( trait_ref ) = > {
if & trait_ref . substs [ 0 ] ! = self_ty {
// we can only convert predicates back to type bounds if they
// have the expected self type
return None ;
}
let args_no_self = trait_ref . substs [ 1 .. ]
. iter ( )
. map ( | ty | ty . clone ( ) . to_chalk ( db ) . cast ( & Interner ) )
. collect ( ) ;
let trait_bound =
chalk_rust_ir ::TraitBound { trait_id : trait_ref . trait_ . to_chalk ( db ) , args_no_self } ;
Some ( chalk_rust_ir ::InlineBound ::TraitBound ( trait_bound ) )
}
GenericPredicate ::Projection ( proj ) = > {
if & proj . projection_ty . parameters [ 0 ] ! = self_ty {
return None ;
}
let trait_ = match proj . projection_ty . associated_ty . lookup ( db . upcast ( ) ) . container {
AssocContainerId ::TraitId ( t ) = > t ,
_ = > panic! ( " associated type not in trait " ) ,
} ;
let args_no_self = proj . projection_ty . parameters [ 1 .. ]
. iter ( )
. map ( | ty | ty . clone ( ) . to_chalk ( db ) . cast ( & Interner ) )
. collect ( ) ;
let alias_eq_bound = chalk_rust_ir ::AliasEqBound {
value : proj . ty . clone ( ) . to_chalk ( db ) ,
trait_bound : chalk_rust_ir ::TraitBound {
trait_id : trait_ . to_chalk ( db ) ,
args_no_self ,
} ,
associated_ty_id : proj . projection_ty . associated_ty . to_chalk ( db ) ,
parameters : Vec ::new ( ) , // FIXME we don't support generic associated types yet
} ;
Some ( chalk_rust_ir ::InlineBound ::AliasEqBound ( alias_eq_bound ) )
}
GenericPredicate ::Error = > None ,
}
}
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 14:40:42 +00:00
fn adt_datum ( & self , struct_id : StructId ) -> 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
}
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 ,
_fn_def_id : chalk_ir ::FnDefId < Interner > ,
) -> Arc < chalk_rust_ir ::FnDefDatum < Interner > > {
// We don't yet provide any FnDefs to Chalk
unimplemented! ( )
}
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 > ] ,
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 ( ) ) ;
let self_ty_fp = TyFingerprint ::for_impl ( & ty ) ;
2019-12-21 14:00:44 +00:00
// Note: Since we're using impls_for_trait, only impls where the trait
// can be resolved should ever reach Chalk. `impl_datum` relies on that
// and will panic if the trait can't be resolved.
2019-09-09 20:10:58 +00:00
let mut result : Vec < _ > = self
2019-05-07 15:35:45 +00:00
. db
2020-04-11 11:11:33 +00:00
. impls_for_trait ( self . krate , trait_ , self_ty_fp )
2019-05-01 15:06:11 +00:00
. iter ( )
2019-09-09 20:10:58 +00:00
. copied ( )
2020-02-29 20:24:40 +00:00
. map ( Impl ::ImplDef )
2019-09-09 20:10:58 +00:00
. map ( | impl_ | impl_ . to_chalk ( self . db ) )
2019-05-07 15:35:45 +00:00
. collect ( ) ;
2019-09-09 20:10:58 +00:00
2020-02-21 18:05:27 +00:00
let arg : Option < Ty > =
2020-03-27 13:50:08 +00:00
parameters . get ( 1 ) . map ( | p | from_chalk ( self . db , p . assert_ty_ref ( & Interner ) . clone ( ) ) ) ;
2019-12-03 11:16:39 +00:00
2020-02-21 18:05:27 +00:00
builtin ::get_builtin_impls ( self . db , self . krate , & ty , & arg , trait_ , | i | {
2019-12-03 11:16:39 +00:00
result . push ( i . to_chalk ( self . db ) )
} ) ;
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
}
2019-12-21 13:29:33 +00:00
fn impl_provided_for ( & self , auto_trait_id : TraitId , struct_id : StructId ) -> bool {
2019-05-01 18:50:49 +00:00
debug! ( " impl_provided_for {:?}, {:?} " , auto_trait_id , struct_id ) ;
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-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 ,
_well_known_trait : chalk_rust_ir ::WellKnownTrait ,
2020-04-16 10:39:00 +00:00
) -> Option < chalk_ir ::TraitId < Interner > > {
// FIXME tell Chalk about well-known traits (here and in trait_datum)
None
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 ( ) )
}
fn opaque_ty_data (
& self ,
_id : chalk_ir ::OpaqueTyId < Interner > ,
) -> Arc < chalk_rust_ir ::OpaqueTyDatum < Interner > > {
unimplemented! ( )
}
2020-05-16 08:49:43 +00:00
fn force_impl_for (
& self ,
_well_known : chalk_rust_ir ::WellKnownTrait ,
_ty : & chalk_ir ::TyData < Interner > ,
) -> Option < bool > {
// this method is mostly for rustc
None
}
fn is_object_safe ( & self , _trait_id : chalk_ir ::TraitId < Interner > ) -> bool {
// FIXME: implement actual object safety
true
}
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 ) ;
2019-11-25 15:58:17 +00:00
let type_alias : TypeAliasId = from_chalk ( db , 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 ) ;
let self_ty = Ty ::Bound ( crate ::BoundVar ::new ( crate ::DebruijnIndex ::INNERMOST , 0 ) ) ;
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 ) ;
let bound_data = chalk_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 ) ;
2019-06-26 09:54:13 +00:00
let flags = chalk_rust_ir ::TraitFlags {
2019-11-26 15:00:36 +00:00
auto : trait_data . auto ,
2020-03-13 15:05:46 +00:00
upstream : trait_ . lookup ( db . upcast ( ) ) . container . module ( db . upcast ( ) ) . 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
2019-06-26 09:54:13 +00:00
// FIXME set these flags correctly
marker : false ,
fundamental : false ,
} ;
2019-11-26 15:00:36 +00: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 19:32:58 +00:00
let trait_datum_bound = chalk_rust_ir ::TraitDatumBound { where_clauses } ;
2020-04-05 16:24:18 +00:00
let well_known = None ; // FIXME set this (depending on lang items)
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 )
}
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 ,
2019-12-21 13:29:33 +00:00
struct_id : StructId ,
) -> Arc < StructDatum > {
2019-06-26 09:54:13 +00:00
debug! ( " struct_datum {:?} " , struct_id ) ;
2020-05-22 14:40:42 +00:00
let type_ctor : TypeCtor = from_chalk ( db , TypeName ::Adt ( struct_id ) ) ;
2019-06-26 09:54:13 +00:00
debug! ( " struct {:?} = {:?} " , struct_id , type_ctor ) ;
2019-09-26 19:37:03 +00: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 | {
2020-03-13 15:05:46 +00:00
let generic_params = generics ( db . upcast ( ) , generic_def ) ;
2020-04-17 20:48:29 +00:00
let bound_vars = Substs ::bound_vars ( & generic_params , DebruijnIndex ::INNERMOST ) ;
2019-09-26 19:37:03 +00:00
convert_where_clauses ( db , generic_def , & bound_vars )
} )
. unwrap_or_else ( Vec ::new ) ;
2020-05-22 14:40:42 +00:00
let flags = chalk_rust_ir ::AdtFlags {
2019-06-26 09:54:13 +00:00
upstream ,
// FIXME set fundamental flag correctly
fundamental : false ,
} ;
2020-05-22 14:40:42 +00:00
let struct_datum_bound = chalk_rust_ir ::AdtDatumBound {
2019-06-26 09:54:13 +00:00
fields : Vec ::new ( ) , // FIXME add fields (only relevant for auto traits)
where_clauses ,
} ;
2019-11-15 19:32:58 +00:00
let struct_datum =
StructDatum { id : struct_id , binders : make_binders ( struct_datum_bound , num_params ) , flags } ;
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 > {
2019-06-26 09:54:13 +00:00
let _p = ra_prof ::profile ( " impl_datum " ) ;
debug! ( " impl_datum {:?} " , impl_id ) ;
2019-09-09 20:10:58 +00:00
let impl_ : Impl = from_chalk ( db , impl_id ) ;
match impl_ {
2020-02-29 20:24:40 +00:00
Impl ::ImplDef ( impl_def ) = > impl_def_datum ( db , krate , impl_id , impl_def ) ,
2019-12-21 14:00:44 +00:00
_ = > Arc ::new ( builtin ::impl_datum ( db , krate , impl_ ) . to_chalk ( db ) ) ,
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_ ;
2020-03-13 15:05:46 +00:00
let impl_type = if impl_id . lookup ( db . upcast ( ) ) . container . module ( db . upcast ( ) ) . krate = = krate {
2019-06-26 09:54:13 +00:00
chalk_rust_ir ::ImplType ::Local
} else {
chalk_rust_ir ::ImplType ::External
} ;
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 ) ;
2019-10-10 18:51:50 +00:00
let polarity = if negative {
chalk_rust_ir ::Polarity ::Negative
} else {
chalk_rust_ir ::Polarity ::Positive
2019-06-26 09:54:13 +00:00
} ;
2019-10-10 18:51:50 +00:00
2019-11-15 19:32:58 +00:00
let impl_datum_bound = chalk_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
} )
2019-11-27 09:47:18 +00:00
. map ( | type_alias | AssocTyValue ::TypeAlias ( 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 > {
2019-11-15 19:32:58 +00:00
let data : AssocTyValue = from_chalk ( db , id ) ;
match data {
AssocTyValue ::TypeAlias ( type_alias ) = > {
type_alias_associated_ty_value ( db , krate , type_alias )
}
2019-12-03 11:16:39 +00:00
_ = > Arc ::new ( builtin ::associated_ty_value ( db , krate , data ) . to_chalk ( db ) ) ,
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 ( ) ) ;
let value_bound = chalk_rust_ir ::AssociatedTyValueBound { ty : ty . value . to_chalk ( db ) } ;
2019-11-15 19:32:58 +00:00
let value = chalk_rust_ir ::AssociatedTyValue {
2020-02-29 20:24:40 +00:00
impl_id : Impl ::ImplDef ( impl_id ) . to_chalk ( db ) ,
2019-11-15 19:32:58 +00:00
associated_ty_id : assoc_ty . to_chalk ( db ) ,
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 )
}
2019-12-21 13:29:33 +00:00
impl From < StructId > for crate ::TypeCtorId {
fn from ( struct_id : StructId ) -> Self {
2019-12-21 14:00:44 +00:00
InternKey ::from_intern_id ( struct_id . 0 )
2019-05-01 15:06:11 +00:00
}
}
2019-12-21 13:29:33 +00:00
impl From < crate ::TypeCtorId > for StructId {
2019-11-27 14:46:02 +00:00
fn from ( type_ctor_id : crate ::TypeCtorId ) -> Self {
2020-05-22 14:40:42 +00:00
chalk_ir ::AdtId ( type_ctor_id . as_intern_id ( ) )
2019-05-01 15:06:11 +00:00
}
}
2019-12-21 13:29:33 +00:00
impl From < ImplId > for crate ::traits ::GlobalImplId {
fn from ( impl_id : ImplId ) -> Self {
2019-12-21 14:00:44 +00:00
InternKey ::from_intern_id ( impl_id . 0 )
2019-05-01 15:06:11 +00:00
}
}
2019-12-21 13:29:33 +00:00
impl From < crate ::traits ::GlobalImplId > for ImplId {
2019-11-27 14:46:02 +00:00
fn from ( impl_id : crate ::traits ::GlobalImplId ) -> Self {
2019-12-21 14:00:44 +00:00
chalk_ir ::ImplId ( impl_id . as_intern_id ( ) )
2019-05-01 15:06:11 +00:00
}
}
2019-11-15 19:32:58 +00:00
2020-03-02 21:30:38 +00:00
impl From < chalk_rust_ir ::AssociatedTyValueId < Interner > > for crate ::traits ::AssocTyValueId {
fn from ( id : chalk_rust_ir ::AssociatedTyValueId < Interner > ) -> Self {
Self ::from_intern_id ( id . 0 )
2019-11-15 19:32:58 +00:00
}
}
2020-03-02 21:30:38 +00:00
impl From < crate ::traits ::AssocTyValueId > for chalk_rust_ir ::AssociatedTyValueId < Interner > {
2019-11-27 14:46:02 +00:00
fn from ( assoc_ty_value_id : crate ::traits ::AssocTyValueId ) -> Self {
2020-03-02 21:30:38 +00:00
chalk_rust_ir ::AssociatedTyValueId ( assoc_ty_value_id . as_intern_id ( ) )
2019-11-15 19:32:58 +00:00
}
}