@@ -104,14 +104,14 @@ impl<'tcx> ReplacePlacesVisitor<'tcx> {
104104}
105105
106106#[ derive( Debug , Clone ) ]
107- struct DeferredDefTy {
108- cache : Rc < RefCell < HashMap < rty :: TypeArgs , rty:: RefinedType > > > ,
107+ struct DeferredDefTy < ' tcx > {
108+ cache : Rc < RefCell < HashMap < mir_ty :: GenericArgsRef < ' tcx > , rty:: RefinedType > > > ,
109109}
110110
111111#[ derive( Debug , Clone ) ]
112- enum DefTy {
112+ enum DefTy < ' tcx > {
113113 Concrete ( rty:: RefinedType ) ,
114- Deferred ( DeferredDefTy ) ,
114+ Deferred ( DeferredDefTy < ' tcx > ) ,
115115}
116116
117117#[ derive( Clone ) ]
@@ -123,7 +123,7 @@ pub struct Analyzer<'tcx> {
123123 /// currently contains only local-def templates,
124124 /// but will be extended to contain externally known def's refinement types
125125 /// (at least for every defs referenced by local def bodies)
126- defs : HashMap < DefId , DefTy > ,
126+ defs : HashMap < DefId , DefTy < ' tcx > > ,
127127
128128 /// Resulting CHC system.
129129 system : Rc < RefCell < chc:: System > > ,
@@ -241,15 +241,17 @@ impl<'tcx> Analyzer<'tcx> {
241241 pub fn def_ty_with_args (
242242 & mut self ,
243243 def_id : DefId ,
244- rty_args : rty :: TypeArgs ,
244+ generic_args : mir_ty :: GenericArgsRef < ' tcx > ,
245245 ) -> Option < rty:: RefinedType > {
246246 let deferred_ty = match self . defs . get ( & def_id) ? {
247247 DefTy :: Concrete ( rty) => {
248+ let type_builder = TypeBuilder :: new ( self . tcx , def_id) ;
249+
248250 let mut def_ty = rty. clone ( ) ;
249251 def_ty. instantiate_ty_params (
250- rty_args
251- . clone ( )
252- . into_iter ( )
252+ generic_args
253+ . types ( )
254+ . map ( |ty| type_builder . build ( ty ) )
253255 . map ( rty:: RefinedType :: unrefined)
254256 . collect ( ) ,
255257 ) ;
@@ -259,21 +261,17 @@ impl<'tcx> Analyzer<'tcx> {
259261 } ;
260262
261263 let deferred_ty_cache = Rc :: clone ( & deferred_ty. cache ) ; // to cut reference to allow &mut self
262- if let Some ( rty) = deferred_ty_cache. borrow ( ) . get ( & rty_args ) {
264+ if let Some ( rty) = deferred_ty_cache. borrow ( ) . get ( & generic_args ) {
263265 return Some ( rty. clone ( ) ) ;
264266 }
265267
266- let type_builder = TypeBuilder :: new ( self . tcx , def_id) . with_param_mapper ( {
267- let rty_args = rty_args. clone ( ) ;
268- move |ty : rty:: ParamType | rty_args[ ty. idx ] . clone ( )
269- } ) ;
270268 let mut analyzer = self . local_def_analyzer ( def_id. as_local ( ) ?) ;
271- analyzer. type_builder ( type_builder ) ;
269+ analyzer. generic_args ( generic_args ) ;
272270
273271 let expected = analyzer. expected_ty ( ) ;
274272 deferred_ty_cache
275273 . borrow_mut ( )
276- . insert ( rty_args , expected. clone ( ) ) ;
274+ . insert ( generic_args , expected. clone ( ) ) ;
277275
278276 analyzer. run ( & expected) ;
279277 Some ( expected)
@@ -340,4 +338,30 @@ impl<'tcx> Analyzer<'tcx> {
340338 self . tcx . dcx ( ) . err ( format ! ( "verification error: {:?}" , err) ) ;
341339 }
342340 }
341+
342+ /// Computes the signature of the local function.
343+ ///
344+ /// This is a drop-in replacement of `self.tcx.fn_sig(local_def_id).instantiate_identity().skip_binder()`,
345+ /// but extracts parameter and return types directly from the given `body` to obtain a signature that
346+ /// reflects potential type instantiations happened after `optimized_mir`.
347+ pub fn local_fn_sig_with_body (
348+ & self ,
349+ local_def_id : LocalDefId ,
350+ body : & mir:: Body < ' tcx > ,
351+ ) -> mir_ty:: FnSig < ' tcx > {
352+ let ty = self . tcx . type_of ( local_def_id) . instantiate_identity ( ) ;
353+ let sig = if let mir_ty:: TyKind :: Closure ( _, substs) = ty. kind ( ) {
354+ substs. as_closure ( ) . sig ( ) . skip_binder ( )
355+ } else {
356+ ty. fn_sig ( self . tcx ) . skip_binder ( )
357+ } ;
358+
359+ self . tcx . mk_fn_sig (
360+ body. args_iter ( ) . map ( |arg| body. local_decls [ arg] . ty ) ,
361+ body. return_ty ( ) ,
362+ sig. c_variadic ,
363+ sig. unsafety ,
364+ sig. abi ,
365+ )
366+ }
343367}
0 commit comments