@@ -86,6 +86,7 @@ use syntax_pos::Span;
86
86
87
87
use std:: fmt;
88
88
use std:: rc:: Rc ;
89
+ use util:: nodemap:: ItemLocalMap ;
89
90
90
91
#[ derive( Clone , PartialEq ) ]
91
92
pub enum Categorization < ' tcx > {
@@ -285,6 +286,7 @@ pub struct MemCategorizationContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
285
286
pub tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
286
287
pub region_scope_tree : & ' a region:: ScopeTree ,
287
288
pub tables : & ' a ty:: TypeckTables < ' tcx > ,
289
+ rvalue_promotable_map : Option < Rc < ItemLocalMap < bool > > > ,
288
290
infcx : Option < & ' a InferCtxt < ' a , ' gcx , ' tcx > > ,
289
291
}
290
292
@@ -392,21 +394,46 @@ impl MutabilityCategory {
392
394
impl < ' a , ' tcx > MemCategorizationContext < ' a , ' tcx , ' tcx > {
393
395
pub fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
394
396
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 > > > )
396
399
-> 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
+ }
398
407
}
399
408
}
400
409
401
410
impl < ' 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.
402
420
pub fn with_infer ( infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > ,
403
421
region_scope_tree : & ' a region:: ScopeTree ,
404
422
tables : & ' a ty:: TypeckTables < ' tcx > )
405
423
-> 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
+
406
432
MemCategorizationContext {
407
- tcx : infcx . tcx ,
433
+ tcx,
408
434
region_scope_tree,
409
435
tables,
436
+ rvalue_promotable_map,
410
437
infcx : Some ( infcx) ,
411
438
}
412
439
}
@@ -869,8 +896,9 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
869
896
span : Span ,
870
897
expr_ty : Ty < ' tcx > )
871
898
-> 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 ) ;
874
902
875
903
// Always promote `[T; 0]` (even when e.g. borrowed mutably).
876
904
let promotable = match expr_ty. sty {
@@ -885,7 +913,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
885
913
let re = if promotable {
886
914
self . tcx . types . re_static
887
915
} else {
888
- self . temporary_scope ( self . tcx . hir . node_to_hir_id ( id ) . local_id )
916
+ self . temporary_scope ( hir_id . local_id )
889
917
} ;
890
918
let ret = self . cat_rvalue ( id, span, re, expr_ty) ;
891
919
debug ! ( "cat_rvalue_node ret {:?}" , ret) ;
0 commit comments