@@ -86,6 +86,7 @@ use syntax_pos::Span;
8686
8787use std:: fmt;
8888use std:: rc:: Rc ;
89+ use util:: nodemap:: ItemLocalMap ;
8990
9091#[ derive( Clone , PartialEq ) ]
9192pub enum Categorization < ' tcx > {
@@ -285,6 +286,7 @@ pub struct MemCategorizationContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
285286 pub tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
286287 pub region_scope_tree : & ' a region:: ScopeTree ,
287288 pub tables : & ' a ty:: TypeckTables < ' tcx > ,
289+ rvalue_promotable_map : Option < Rc < ItemLocalMap < bool > > > ,
288290 infcx : Option < & ' a InferCtxt < ' a , ' gcx , ' tcx > > ,
289291}
290292
@@ -392,21 +394,46 @@ impl MutabilityCategory {
392394impl < ' a , ' tcx > MemCategorizationContext < ' a , ' tcx , ' tcx > {
393395 pub fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
394396 region_scope_tree : & ' a region:: ScopeTree ,
395- tables : & ' a ty:: TypeckTables < ' tcx > )
397+ tables : & ' a ty:: TypeckTables < ' tcx > ,
398+ rvalue_promotable_map : Option < Rc < ItemLocalMap < bool > > > )
396399 -> MemCategorizationContext < ' a , ' tcx , ' tcx > {
397- MemCategorizationContext { tcx, region_scope_tree, tables, infcx : None }
400+ MemCategorizationContext {
401+ tcx,
402+ region_scope_tree,
403+ tables,
404+ rvalue_promotable_map,
405+ infcx : None
406+ }
398407 }
399408}
400409
401410impl < ' a , ' gcx , ' tcx > MemCategorizationContext < ' a , ' gcx , ' tcx > {
411+ /// Creates a `MemCategorizationContext` during type inference.
412+ /// This is used during upvar analysis and a few other places.
413+ /// Because the typeck tables are not yet complete, the results
414+ /// from the analysis must be used with caution:
415+ ///
416+ /// - rvalue promotions are not known, so the lifetimes of
417+ /// temporaries may be overly conservative;
418+ /// - similarly, as the results of upvar analysis are not yet
419+ /// known, the results around upvar accesses may be incorrect.
402420 pub fn with_infer ( infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > ,
403421 region_scope_tree : & ' a region:: ScopeTree ,
404422 tables : & ' a ty:: TypeckTables < ' tcx > )
405423 -> MemCategorizationContext < ' a , ' gcx , ' tcx > {
424+ let tcx = infcx. tcx ;
425+
426+ // Subtle: we can't do rvalue promotion analysis until the
427+ // typeck phase is complete, which means that you can't trust
428+ // the rvalue lifetimes that result, but that's ok, since we
429+ // don't need to know those during type inference.
430+ let rvalue_promotable_map = None ;
431+
406432 MemCategorizationContext {
407- tcx : infcx . tcx ,
433+ tcx,
408434 region_scope_tree,
409435 tables,
436+ rvalue_promotable_map,
410437 infcx : Some ( infcx) ,
411438 }
412439 }
@@ -869,8 +896,9 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
869896 span : Span ,
870897 expr_ty : Ty < ' tcx > )
871898 -> cmt < ' tcx > {
872- let promotable = self . tcx . rvalue_promotable_to_static . borrow ( ) . get ( & id) . cloned ( )
873- . unwrap_or ( false ) ;
899+ let hir_id = self . tcx . hir . node_to_hir_id ( id) ;
900+ let promotable = self . rvalue_promotable_map . as_ref ( ) . map ( |m| m[ & hir_id. local_id ] )
901+ . unwrap_or ( false ) ;
874902
875903 // Always promote `[T; 0]` (even when e.g. borrowed mutably).
876904 let promotable = match expr_ty. sty {
@@ -885,7 +913,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
885913 let re = if promotable {
886914 self . tcx . types . re_static
887915 } else {
888- self . temporary_scope ( self . tcx . hir . node_to_hir_id ( id ) . local_id )
916+ self . temporary_scope ( hir_id . local_id )
889917 } ;
890918 let ret = self . cat_rvalue ( id, span, re, expr_ty) ;
891919 debug ! ( "cat_rvalue_node ret {:?}" , ret) ;
0 commit comments