@@ -5,7 +5,7 @@ use std::rc::Rc;
55use pretty:: { termcolor, Pretty } ;
66use rustc_hir:: { def_id:: LocalDefId , HirId } ;
77use rustc_index:: IndexVec ;
8- use rustc_middle:: ty:: { self as mir_ty, TyCtxt } ;
8+ use rustc_middle:: ty:: { self as mir_ty, TyCtxt , TypeFoldable } ;
99
1010use crate :: analyze:: { self , did_cache:: DefIdCache , TypeParamMap } ;
1111use crate :: annot:: AnnotFormula ;
@@ -224,26 +224,44 @@ impl<'tcx> AnnotFnTranslator<'tcx> {
224224 }
225225 }
226226
227+ fn instantiate_generics < T > (
228+ & self ,
229+ ty : T ,
230+ generic_args : mir_ty:: GenericArgsRef < ' tcx > ,
231+ ) -> Option < T >
232+ where
233+ T : TypeFoldable < TyCtxt < ' tcx > > ,
234+ {
235+ if !self . generic_args . is_empty ( ) {
236+ Some ( mir_ty:: EarlyBinder :: bind ( ty) . instantiate ( self . tcx , generic_args) )
237+ } else {
238+ None
239+ }
240+ }
241+
227242 fn expr_ty ( & self , expr : & ' tcx rustc_hir:: Expr < ' tcx > ) -> mir_ty:: Ty < ' tcx > {
228243 let ty = self . typeck . expr_ty ( expr) ;
229- let instantiated = mir_ty :: EarlyBinder :: bind ( ty ) . instantiate ( self . tcx , self . generic_args ) ;
244+ let instantiated = self . instantiate_generics ( ty , self . generic_args ) . unwrap_or ( ty ) ;
230245 let typing_env = mir_ty:: TypingEnv :: fully_monomorphized ( ) ;
231246 self . tcx . normalize_erasing_regions ( typing_env, instantiated)
232247 }
233248
234249 fn pat_ty ( & self , pat : & ' tcx rustc_hir:: Pat < ' tcx > ) -> mir_ty:: Ty < ' tcx > {
235250 let ty = self . typeck . pat_ty ( pat) ;
236- let instantiated = mir_ty :: EarlyBinder :: bind ( ty ) . instantiate ( self . tcx , self . generic_args ) ;
251+ let instantiated = self . instantiate_generics ( ty , self . generic_args ) . unwrap_or ( ty ) ;
237252 let typing_env = mir_ty:: TypingEnv :: fully_monomorphized ( ) ;
238253 self . tcx . normalize_erasing_regions ( typing_env, instantiated)
239254 }
240255
241256 pub fn to_formula_fn ( & self ) -> FormulaFn < ' tcx > {
242257 let formula = self . to_formula ( self . body . value ) ;
243- let params = self
244- . tcx
245- . fn_sig ( self . local_def_id . to_def_id ( ) )
246- . instantiate ( self . tcx , self . generic_args )
258+ let fn_sig = self . tcx . fn_sig ( self . local_def_id . to_def_id ( ) ) ;
259+ let binder = if self . generic_args . is_empty ( ) {
260+ fn_sig. skip_binder ( )
261+ } else {
262+ fn_sig. instantiate ( self . tcx , self . generic_args )
263+ } ;
264+ let params = binder
247265 . skip_binder ( )
248266 . inputs ( )
249267 . to_vec ( ) ;
@@ -515,23 +533,27 @@ impl<'tcx> AnnotFnTranslator<'tcx> {
515533 outer_generic_args = ?self . generic_args,
516534 "resolving predicate call in formula"
517535 ) ;
518- let generic_args = mir_ty:: EarlyBinder :: bind ( generic_args)
519- . instantiate ( self . tcx , self . generic_args ) ;
536+ let ( is_unresolved_args, generic_args) = match self . instantiate_generics ( generic_args, self . generic_args ) {
537+ Some ( args) => ( false , args) ,
538+ None => ( true , generic_args)
539+ } ;
540+
520541 let instance = mir_ty:: Instance :: try_resolve (
521542 self . tcx ,
522543 typing_env,
523544 def_id,
524545 generic_args,
525546 )
526547 . unwrap ( ) ;
527- let pred_def_id = if let Some ( instance) = instance {
528- instance. def_id ( )
548+ let pred_def_id = instance. map_or ( def_id, |instance| instance. def_id ( ) ) ;
549+
550+ let pred = if is_unresolved_args {
551+ refine:: user_defined_pred ( self . tcx , pred_def_id) . into ( )
529552 } else {
530- def_id
553+ refine :: forall_pred ( self . tcx , pred_def_id ) . into ( )
531554 } ;
532- let pred = refine:: user_defined_pred ( self . tcx , pred_def_id) ;
533555 let arg_terms = args. iter ( ) . map ( |e| self . to_term ( e) ) . collect ( ) ;
534- let atom = chc:: Atom :: new ( pred. into ( ) , arg_terms) ;
556+ let atom = chc:: Atom :: new ( pred, arg_terms) ;
535557 return FormulaOrTerm :: Formula ( chc:: Formula :: Atom ( atom) ) ;
536558 }
537559 }
0 commit comments