@@ -84,16 +84,55 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
8484 ) -> Vec < chc:: Clause > {
8585 let mut clauses = Vec :: new ( ) ;
8686
87- if expected_args. is_empty ( ) {
88- // elaboration: we need at least one predicate variable in parameter (see mir_function_ty_impl)
89- expected_args. push ( rty:: RefinedType :: unrefined ( rty:: Type :: unit ( ) ) . vacuous ( ) ) ;
90- }
9187 tracing:: debug!(
9288 got = %got. display( ) ,
9389 expected = %crate :: pretty:: FunctionType :: new( & expected_args, & expected_ret) . display( ) ,
9490 "fn_sub_type"
9591 ) ;
9692
93+ match got. abi {
94+ rty:: FunctionAbi :: Rust => {
95+ if expected_args. is_empty ( ) {
96+ // elaboration: we need at least one predicate variable in parameter (see mir_function_ty_impl)
97+ expected_args. push ( rty:: RefinedType :: unrefined ( rty:: Type :: unit ( ) ) . vacuous ( ) ) ;
98+ }
99+ }
100+ rty:: FunctionAbi :: RustCall => {
101+ // &Closure, { v: (own i32, own bool) | v = (<0>, <false>) }
102+ // =>
103+ // &Closure, { v: i32 | (<v>, _) = (<0>, <false>) }, { v: bool | (_, <v>) = (<0>, <false>) }
104+
105+ let rty:: RefinedType { ty, mut refinement } =
106+ expected_args. pop ( ) . expect ( "rust-call last arg" ) ;
107+ let ty = ty. into_tuple ( ) . expect ( "rust-call last arg is tuple" ) ;
108+ let mut replacement_tuple = Vec :: new ( ) ; // will be (<v>, _) or (_, <v>)
109+ for elem in & ty. elems {
110+ let existential = refinement. existentials . push ( elem. ty . to_sort ( ) ) ;
111+ replacement_tuple. push ( chc:: Term :: var ( rty:: RefinedTypeVar :: Existential (
112+ existential,
113+ ) ) ) ;
114+ }
115+
116+ for ( i, elem) in ty. elems . into_iter ( ) . enumerate ( ) {
117+ // all tuple elements are boxed during the translation to rty::Type
118+ let mut param_ty = elem. deref ( ) ;
119+ param_ty
120+ . refinement
121+ . push_conj ( refinement. clone ( ) . subst_value_var ( || {
122+ let mut value_elems = replacement_tuple. clone ( ) ;
123+ value_elems[ i] = chc:: Term :: var ( rty:: RefinedTypeVar :: Value ) . boxed ( ) ;
124+ chc:: Term :: tuple ( value_elems)
125+ } ) ) ;
126+ expected_args. push ( param_ty) ;
127+ }
128+
129+ tracing:: info!(
130+ expected = %crate :: pretty:: FunctionType :: new( & expected_args, & expected_ret) . display( ) ,
131+ "rust-call expanded" ,
132+ ) ;
133+ }
134+ }
135+
97136 // TODO: check sty and length is equal
98137 let mut builder = self . env . build_clause ( ) ;
99138 for ( param_idx, param_rty) in got. params . iter_enumerated ( ) {
@@ -175,6 +214,12 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
175214 chc:: Term :: bool ( val. try_to_bool ( ) . unwrap ( ) ) ,
176215 )
177216 }
217+ ( mir_ty:: TyKind :: Tuple ( tys) , _) if tys. is_empty ( ) => {
218+ PlaceType :: with_ty_and_term ( rty:: Type :: unit ( ) , chc:: Term :: tuple ( vec ! [ ] ) )
219+ }
220+ ( mir_ty:: TyKind :: Closure ( _, args) , _) if args. as_closure ( ) . upvar_tys ( ) . is_empty ( ) => {
221+ PlaceType :: with_ty_and_term ( rty:: Type :: unit ( ) , chc:: Term :: tuple ( vec ! [ ] ) )
222+ }
178223 (
179224 mir_ty:: TyKind :: Ref ( _, elem, Mutability :: Not ) ,
180225 ConstValue :: Scalar ( Scalar :: Ptr ( ptr, _) ) ,
@@ -568,12 +613,25 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
568613 let ret = rty:: RefinedType :: new ( rty:: Type :: unit ( ) , ret_formula. into ( ) ) ;
569614 rty:: FunctionType :: new ( [ param1, param2] . into_iter ( ) . collect ( ) , ret) . into ( )
570615 }
571- Some ( ( def_id, args) ) => self
572- . ctx
573- . def_ty_with_args ( def_id, args)
574- . expect ( "unknown def" )
575- . ty
576- . vacuous ( ) ,
616+ Some ( ( def_id, args) ) => {
617+ let param_env = self . tcx . param_env ( self . local_def_id ) ;
618+ let instance =
619+ mir_ty:: Instance :: resolve ( self . tcx , param_env, def_id, args) . unwrap ( ) ;
620+ let resolved_def_id = if let Some ( instance) = instance {
621+ instance. def_id ( )
622+ } else {
623+ def_id
624+ } ;
625+ if def_id != resolved_def_id {
626+ tracing:: info!( ?def_id, ?resolved_def_id, "resolve" , ) ;
627+ }
628+
629+ self . ctx
630+ . def_ty_with_args ( resolved_def_id, args)
631+ . expect ( "unknown def" )
632+ . ty
633+ . vacuous ( )
634+ }
577635 _ => self . operand_type ( func. clone ( ) ) . ty ,
578636 } ;
579637 let expected_args: IndexVec < _ , _ > = args
0 commit comments