@@ -31,7 +31,7 @@ use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
31
31
use ty:: relate:: RelateResult ;
32
32
use traits:: { self , ObligationCause , PredicateObligations , Reveal } ;
33
33
use rustc_data_structures:: unify:: { self , UnificationTable } ;
34
- use std:: cell:: { Cell , RefCell , Ref } ;
34
+ use std:: cell:: { Cell , RefCell , Ref , RefMut } ;
35
35
use std:: fmt;
36
36
use syntax:: ast;
37
37
use errors:: DiagnosticBuilder ;
@@ -103,8 +103,12 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
103
103
// Map from floating variable to the kind of float it represents
104
104
float_unification_table : RefCell < UnificationTable < ty:: FloatVid > > ,
105
105
106
- // For region variables.
107
- region_constraints : RefCell < RegionConstraintCollector < ' tcx > > ,
106
+ // Tracks the set of region variables and the constraints between
107
+ // them. This is initially `Some(_)` but when
108
+ // `resolve_regions_and_report_errors` is invoked, this gets set
109
+ // to `None` -- further attempts to perform unification etc may
110
+ // fail if new region constraints would've been added.
111
+ region_constraints : RefCell < Option < RegionConstraintCollector < ' tcx > > > ,
108
112
109
113
// Once region inference is done, the values for each variable.
110
114
lexical_region_resolutions : RefCell < Option < LexicalRegionResolutions < ' tcx > > > ,
@@ -424,7 +428,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
424
428
type_variables : RefCell :: new ( type_variable:: TypeVariableTable :: new ( ) ) ,
425
429
int_unification_table : RefCell :: new ( UnificationTable :: new ( ) ) ,
426
430
float_unification_table : RefCell :: new ( UnificationTable :: new ( ) ) ,
427
- region_constraints : RefCell :: new ( RegionConstraintCollector :: new ( ) ) ,
431
+ region_constraints : RefCell :: new ( Some ( RegionConstraintCollector :: new ( ) ) ) ,
428
432
lexical_region_resolutions : RefCell :: new ( None ) ,
429
433
selection_cache : traits:: SelectionCache :: new ( ) ,
430
434
evaluation_cache : traits:: EvaluationCache :: new ( ) ,
@@ -767,7 +771,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
767
771
type_snapshot : self . type_variables . borrow_mut ( ) . snapshot ( ) ,
768
772
int_snapshot : self . int_unification_table . borrow_mut ( ) . snapshot ( ) ,
769
773
float_snapshot : self . float_unification_table . borrow_mut ( ) . snapshot ( ) ,
770
- region_constraints_snapshot : self . region_constraints . borrow_mut ( ) . start_snapshot ( ) ,
774
+ region_constraints_snapshot : self . borrow_region_constraints ( ) . start_snapshot ( ) ,
771
775
was_in_snapshot : in_snapshot,
772
776
// Borrow tables "in progress" (i.e. during typeck)
773
777
// to ban writes from within a snapshot to them.
@@ -801,8 +805,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
801
805
self . float_unification_table
802
806
. borrow_mut ( )
803
807
. rollback_to ( float_snapshot) ;
804
- self . region_constraints
805
- . borrow_mut ( )
808
+ self . borrow_region_constraints ( )
806
809
. rollback_to ( region_constraints_snapshot) ;
807
810
}
808
811
@@ -830,8 +833,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
830
833
self . float_unification_table
831
834
. borrow_mut ( )
832
835
. commit ( float_snapshot) ;
833
- self . region_constraints
834
- . borrow_mut ( )
836
+ self . borrow_region_constraints ( )
835
837
. commit ( region_constraints_snapshot) ;
836
838
}
837
839
@@ -887,7 +889,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
887
889
sub : ty:: Region < ' tcx > ,
888
890
sup : ty:: RegionVid )
889
891
{
890
- self . region_constraints . borrow_mut ( ) . add_given ( sub, sup) ;
892
+ self . borrow_region_constraints ( ) . add_given ( sub, sup) ;
891
893
}
892
894
893
895
pub fn can_sub < T > ( & self ,
@@ -927,7 +929,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
927
929
a : ty:: Region < ' tcx > ,
928
930
b : ty:: Region < ' tcx > ) {
929
931
debug ! ( "sub_regions({:?} <: {:?})" , a, b) ;
930
- self . region_constraints . borrow_mut ( ) . make_subregion ( origin, a, b) ;
932
+ self . borrow_region_constraints ( ) . make_subregion ( origin, a, b) ;
931
933
}
932
934
933
935
pub fn equality_predicate ( & self ,
@@ -1030,7 +1032,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1030
1032
1031
1033
pub fn next_region_var ( & self , origin : RegionVariableOrigin )
1032
1034
-> ty:: Region < ' tcx > {
1033
- self . tcx . mk_region ( ty:: ReVar ( self . region_constraints . borrow_mut ( ) . new_region_var ( origin) ) )
1035
+ self . tcx . mk_region ( ty:: ReVar ( self . borrow_region_constraints ( ) . new_region_var ( origin) ) )
1034
1036
}
1035
1037
1036
1038
/// Create a region inference variable for the given
@@ -1114,6 +1116,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1114
1116
self . tainted_by_errors_flag . set ( true )
1115
1117
}
1116
1118
1119
+ /// Process the region constraints and report any errors that
1120
+ /// result. After this, no more unification operations should be
1121
+ /// done -- or the compiler will panic -- but it is legal to use
1122
+ /// `resolve_type_vars_if_possible` as well as `fully_resolve`.
1117
1123
pub fn resolve_regions_and_report_errors ( & self ,
1118
1124
region_context : DefId ,
1119
1125
region_map : & region:: ScopeTree ,
@@ -1126,8 +1132,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1126
1132
region_context,
1127
1133
region_map,
1128
1134
free_regions) ;
1129
- let ( lexical_region_resolutions, errors) =
1130
- self . region_constraints . borrow_mut ( ) . resolve_regions ( & region_rels) ;
1135
+ let mut region_constraints = self . region_constraints . borrow_mut ( )
1136
+ . take ( )
1137
+ . expect ( "regions already resolved" ) ;
1138
+ let ( lexical_region_resolutions, errors) = region_constraints. resolve_regions ( & region_rels) ;
1131
1139
1132
1140
let old_value = self . lexical_region_resolutions . replace ( Some ( lexical_region_resolutions) ) ;
1133
1141
assert ! ( old_value. is_none( ) ) ;
@@ -1365,7 +1373,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1365
1373
a,
1366
1374
bound) ;
1367
1375
1368
- self . region_constraints . borrow_mut ( ) . verify_generic_bound ( origin, kind, a, bound) ;
1376
+ self . borrow_region_constraints ( ) . verify_generic_bound ( origin, kind, a, bound) ;
1369
1377
}
1370
1378
1371
1379
pub fn type_moves_by_default ( & self ,
@@ -1446,11 +1454,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1446
1454
/// Normalizes associated types in `value`, potentially returning
1447
1455
/// new obligations that must further be processed.
1448
1456
pub fn partially_normalize_associated_types_in < T > ( & self ,
1449
- span : Span ,
1450
- body_id : ast:: NodeId ,
1451
- param_env : ty:: ParamEnv < ' tcx > ,
1452
- value : & T )
1453
- -> InferOk < ' tcx , T >
1457
+ span : Span ,
1458
+ body_id : ast:: NodeId ,
1459
+ param_env : ty:: ParamEnv < ' tcx > ,
1460
+ value : & T )
1461
+ -> InferOk < ' tcx , T >
1454
1462
where T : TypeFoldable < ' tcx >
1455
1463
{
1456
1464
debug ! ( "partially_normalize_associated_types_in(value={:?})" , value) ;
@@ -1463,6 +1471,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1463
1471
obligations) ;
1464
1472
InferOk { value, obligations }
1465
1473
}
1474
+
1475
+ fn borrow_region_constraints ( & self ) -> RefMut < ' _ , RegionConstraintCollector < ' tcx > > {
1476
+ RefMut :: map (
1477
+ self . region_constraints . borrow_mut ( ) ,
1478
+ |c| c. as_mut ( ) . expect ( "region constraints already solved" ) )
1479
+ }
1466
1480
}
1467
1481
1468
1482
impl < ' a , ' gcx , ' tcx > TypeTrace < ' tcx > {
0 commit comments