@@ -106,9 +106,24 @@ impl<'tcx> ReplacePlacesVisitor<'tcx> {
106106 }
107107}
108108
109+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
110+ enum DeferredDefMode {
111+ Analyze ,
112+ NoAnalyze ,
113+ }
114+
115+ impl DeferredDefMode {
116+ fn should_analyze ( & self ) -> bool {
117+ matches ! ( self , DeferredDefMode :: Analyze )
118+ }
119+ }
120+
109121#[ derive( Debug , Clone ) ]
110122struct DeferredDefTy < ' tcx > {
123+ // this is different from a key in defs when the def is extern_spec_fn
124+ local_def_id : LocalDefId ,
111125 cache : Rc < RefCell < HashMap < mir_ty:: GenericArgsRef < ' tcx > , rty:: RefinedType > > > ,
126+ mode : DeferredDefMode ,
112127}
113128
114129#[ derive( Debug , Clone ) ]
@@ -290,12 +305,40 @@ impl<'tcx> Analyzer<'tcx> {
290305 self . defs . insert ( def_id, DefTy :: Concrete ( rty) ) ;
291306 }
292307
293- pub fn register_deferred_def ( & mut self , def_id : DefId ) {
294- tracing:: info!( def_id = ?def_id, "register_deferred_def" ) ;
308+ pub fn register_deferred_def ( & mut self , local_def_id : LocalDefId ) {
309+ self . register_deferred_def_impl (
310+ local_def_id. to_def_id ( ) ,
311+ local_def_id,
312+ DeferredDefMode :: Analyze ,
313+ ) ;
314+ }
315+
316+ pub fn register_deferred_def_without_analysis (
317+ & mut self ,
318+ target_def_id : DefId ,
319+ local_def_id : LocalDefId ,
320+ ) {
321+ self . register_deferred_def_impl ( target_def_id, local_def_id, DeferredDefMode :: NoAnalyze ) ;
322+ }
323+
324+ fn register_deferred_def_impl (
325+ & mut self ,
326+ target_def_id : DefId ,
327+ local_def_id : LocalDefId ,
328+ mode : DeferredDefMode ,
329+ ) {
330+ tracing:: info!(
331+ ?target_def_id,
332+ ?local_def_id,
333+ ?mode,
334+ "register_deferred_def"
335+ ) ;
295336 self . defs . insert (
296- def_id ,
337+ target_def_id ,
297338 DefTy :: Deferred ( DeferredDefTy {
339+ local_def_id,
298340 cache : Rc :: new ( RefCell :: new ( HashMap :: new ( ) ) ) ,
341+ mode,
299342 } ) ,
300343 ) ;
301344 }
@@ -312,10 +355,10 @@ impl<'tcx> Analyzer<'tcx> {
312355 def_id : DefId ,
313356 generic_args : mir_ty:: GenericArgsRef < ' tcx > ,
314357 ) -> Option < rty:: RefinedType > {
358+ let type_builder = TypeBuilder :: new ( self . tcx , def_id) ;
359+
315360 let deferred_ty = match self . defs . get ( & def_id) ? {
316361 DefTy :: Concrete ( rty) => {
317- let type_builder = TypeBuilder :: new ( self . tcx , def_id) ;
318-
319362 let mut def_ty = rty. clone ( ) ;
320363 def_ty. instantiate_ty_params (
321364 generic_args
@@ -333,16 +376,29 @@ impl<'tcx> Analyzer<'tcx> {
333376 if let Some ( rty) = deferred_ty_cache. borrow ( ) . get ( & generic_args) {
334377 return Some ( rty. clone ( ) ) ;
335378 }
379+ let deferred_ty_mode = deferred_ty. mode ;
336380
337- let mut analyzer = self . local_def_analyzer ( def_id . as_local ( ) ? ) ;
381+ let mut analyzer = self . local_def_analyzer ( deferred_ty . local_def_id ) ;
338382 analyzer. generic_args ( generic_args) ;
339383
340- let expected = analyzer. expected_ty ( ) ;
384+ let mut expected = analyzer. expected_ty ( ) ;
385+ // parameters in annotations are left as params
386+ // TODO: remove this after annotation V2
387+ expected. instantiate_ty_params (
388+ generic_args
389+ . types ( )
390+ . map ( |ty| type_builder. build ( ty) )
391+ . map ( rty:: RefinedType :: unrefined)
392+ . collect ( ) ,
393+ ) ;
341394 deferred_ty_cache
342395 . borrow_mut ( )
343396 . insert ( generic_args, expected. clone ( ) ) ;
397+ tracing:: info!( ?def_id, rty = %expected. display( ) , ?generic_args, "deferred def" ) ;
344398
345- analyzer. run ( & expected) ;
399+ if deferred_ty_mode. should_analyze ( ) {
400+ analyzer. run ( & expected) ;
401+ }
346402 Some ( expected)
347403 }
348404
0 commit comments