@@ -19,11 +19,8 @@ pub use self::freshen::TypeFreshener;
19
19
pub use self :: region_inference:: { GenericKind , VerifyBound } ;
20
20
21
21
use hir:: def_id:: DefId ;
22
- use hir;
23
22
use middle:: free_region:: { FreeRegionMap , RegionRelations } ;
24
23
use middle:: region:: RegionMaps ;
25
- use middle:: mem_categorization as mc;
26
- use middle:: mem_categorization:: McResult ;
27
24
use middle:: lang_items;
28
25
use mir:: tcx:: LvalueTy ;
29
26
use ty:: subst:: { Kind , Subst , Substs } ;
@@ -34,9 +31,8 @@ use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
34
31
use ty:: relate:: RelateResult ;
35
32
use traits:: { self , ObligationCause , PredicateObligations , Reveal } ;
36
33
use rustc_data_structures:: unify:: { self , UnificationTable } ;
37
- use std:: cell:: { Cell , RefCell , Ref , RefMut } ;
34
+ use std:: cell:: { Cell , RefCell , Ref } ;
38
35
use std:: fmt;
39
- use std:: ops:: Deref ;
40
36
use syntax:: ast;
41
37
use errors:: DiagnosticBuilder ;
42
38
use syntax_pos:: { self , Span , DUMMY_SP } ;
@@ -76,71 +72,14 @@ pub type Bound<T> = Option<T>;
76
72
pub type UnitResult < ' tcx > = RelateResult < ' tcx , ( ) > ; // "unify result"
77
73
pub type FixupResult < T > = Result < T , FixupError > ; // "fixup result"
78
74
79
- /// A version of &ty::TypeckTables which can be `Missing` (not needed),
80
- /// `InProgress` (during typeck) or `Interned` (result of typeck).
81
- /// Only the `InProgress` version supports `borrow_mut`.
82
- #[ derive( Copy , Clone ) ]
83
- pub enum InferTables < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
84
- Interned ( & ' a ty:: TypeckTables < ' gcx > ) ,
85
- InProgress ( & ' a RefCell < ty:: TypeckTables < ' tcx > > ) ,
86
- Missing
87
- }
88
-
89
- pub enum InferTablesRef < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
90
- Interned ( & ' a ty:: TypeckTables < ' gcx > ) ,
91
- InProgress ( Ref < ' a , ty:: TypeckTables < ' tcx > > )
92
- }
93
-
94
- impl < ' a , ' gcx , ' tcx > Deref for InferTablesRef < ' a , ' gcx , ' tcx > {
95
- type Target = ty:: TypeckTables < ' tcx > ;
96
- fn deref ( & self ) -> & Self :: Target {
97
- match * self {
98
- InferTablesRef :: Interned ( tables) => tables,
99
- InferTablesRef :: InProgress ( ref tables) => tables
100
- }
101
- }
102
- }
103
-
104
- impl < ' a , ' gcx , ' tcx > InferTables < ' a , ' gcx , ' tcx > {
105
- pub fn borrow ( self ) -> InferTablesRef < ' a , ' gcx , ' tcx > {
106
- match self {
107
- InferTables :: Interned ( tables) => InferTablesRef :: Interned ( tables) ,
108
- InferTables :: InProgress ( tables) => InferTablesRef :: InProgress ( tables. borrow ( ) ) ,
109
- InferTables :: Missing => {
110
- bug ! ( "InferTables: infcx.tables.borrow() with no tables" )
111
- }
112
- }
113
- }
114
-
115
- pub fn expect_interned ( self ) -> & ' a ty:: TypeckTables < ' gcx > {
116
- match self {
117
- InferTables :: Interned ( tables) => tables,
118
- InferTables :: InProgress ( _) => {
119
- bug ! ( "InferTables: infcx.tables.expect_interned() during type-checking" ) ;
120
- }
121
- InferTables :: Missing => {
122
- bug ! ( "InferTables: infcx.tables.expect_interned() with no tables" )
123
- }
124
- }
125
- }
126
-
127
- pub fn borrow_mut ( self ) -> RefMut < ' a , ty:: TypeckTables < ' tcx > > {
128
- match self {
129
- InferTables :: Interned ( _) => {
130
- bug ! ( "InferTables: infcx.tables.borrow_mut() outside of type-checking" ) ;
131
- }
132
- InferTables :: InProgress ( tables) => tables. borrow_mut ( ) ,
133
- InferTables :: Missing => {
134
- bug ! ( "InferTables: infcx.tables.borrow_mut() with no tables" )
135
- }
136
- }
137
- }
138
- }
139
-
140
75
pub struct InferCtxt < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
141
76
pub tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
142
77
143
- pub tables : InferTables < ' a , ' gcx , ' tcx > ,
78
+ /// During type-checking/inference of a body, `in_progress_tables`
79
+ /// contains a reference to the tables being built up, which are
80
+ /// used for reading closure kinds/signatures as they are inferred,
81
+ /// and for error reporting logic to read arbitrary node types.
82
+ pub in_progress_tables : Option < & ' a RefCell < ty:: TypeckTables < ' tcx > > > ,
144
83
145
84
// Cache for projections. This cache is snapshotted along with the
146
85
// infcx.
@@ -396,106 +335,45 @@ impl fmt::Display for FixupError {
396
335
}
397
336
}
398
337
399
- pub trait InferEnv < ' a , ' tcx > {
400
- fn to_parts ( self , tcx : TyCtxt < ' a , ' tcx , ' tcx > )
401
- -> ( Option < & ' a ty:: TypeckTables < ' tcx > > ,
402
- Option < ty:: TypeckTables < ' tcx > > ) ;
403
- }
404
-
405
- impl < ' a , ' tcx > InferEnv < ' a , ' tcx > for ( ) {
406
- fn to_parts ( self , _: TyCtxt < ' a , ' tcx , ' tcx > )
407
- -> ( Option < & ' a ty:: TypeckTables < ' tcx > > ,
408
- Option < ty:: TypeckTables < ' tcx > > ) {
409
- ( None , None )
410
- }
411
- }
412
-
413
- impl < ' a , ' tcx > InferEnv < ' a , ' tcx > for & ' a ty:: TypeckTables < ' tcx > {
414
- fn to_parts ( self , _: TyCtxt < ' a , ' tcx , ' tcx > )
415
- -> ( Option < & ' a ty:: TypeckTables < ' tcx > > ,
416
- Option < ty:: TypeckTables < ' tcx > > ) {
417
- ( Some ( self ) , None )
418
- }
419
- }
420
-
421
- impl < ' a , ' tcx > InferEnv < ' a , ' tcx > for ty:: TypeckTables < ' tcx > {
422
- fn to_parts ( self , _: TyCtxt < ' a , ' tcx , ' tcx > )
423
- -> ( Option < & ' a ty:: TypeckTables < ' tcx > > ,
424
- Option < ty:: TypeckTables < ' tcx > > ) {
425
- ( None , Some ( self ) )
426
- }
427
- }
428
-
429
- impl < ' a , ' tcx > InferEnv < ' a , ' tcx > for hir:: BodyId {
430
- fn to_parts ( self , tcx : TyCtxt < ' a , ' tcx , ' tcx > )
431
- -> ( Option < & ' a ty:: TypeckTables < ' tcx > > ,
432
- Option < ty:: TypeckTables < ' tcx > > ) {
433
- let def_id = tcx. hir . body_owner_def_id ( self ) ;
434
- ( Some ( tcx. typeck_tables_of ( def_id) ) , None )
435
- }
436
- }
437
-
438
- /// Helper type of a temporary returned by tcx.infer_ctxt(...).
338
+ /// Helper type of a temporary returned by tcx.infer_ctxt().
439
339
/// Necessary because we can't write the following bound:
440
340
/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(InferCtxt<'b, 'gcx, 'tcx>).
441
341
pub struct InferCtxtBuilder < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
442
342
global_tcx : TyCtxt < ' a , ' gcx , ' gcx > ,
443
343
arena : DroplessArena ,
444
344
fresh_tables : Option < RefCell < ty:: TypeckTables < ' tcx > > > ,
445
- tables : Option < & ' a ty:: TypeckTables < ' gcx > > ,
446
345
}
447
346
448
347
impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' gcx > {
449
- pub fn infer_ctxt < E : InferEnv < ' a , ' gcx > > ( self , env : E ) -> InferCtxtBuilder < ' a , ' gcx , ' tcx > {
450
- let ( tables, fresh_tables) = env. to_parts ( self ) ;
348
+ pub fn infer_ctxt ( self ) -> InferCtxtBuilder < ' a , ' gcx , ' tcx > {
451
349
InferCtxtBuilder {
452
350
global_tcx : self ,
453
351
arena : DroplessArena :: new ( ) ,
454
- fresh_tables : fresh_tables. map ( RefCell :: new) ,
455
- tables : tables,
456
- }
457
- }
458
-
459
- /// Fake InferCtxt with the global tcx. Used by pre-MIR borrowck
460
- /// for MemCategorizationContext/ExprUseVisitor.
461
- /// If any inference functionality is used, ICEs will occur.
462
- pub fn borrowck_fake_infer_ctxt ( self , body : hir:: BodyId )
463
- -> InferCtxt < ' a , ' gcx , ' gcx > {
464
- let ( tables, _) = body. to_parts ( self ) ;
465
- InferCtxt {
466
- tcx : self ,
467
- tables : InferTables :: Interned ( tables. unwrap ( ) ) ,
468
- type_variables : RefCell :: new ( type_variable:: TypeVariableTable :: new ( ) ) ,
469
- int_unification_table : RefCell :: new ( UnificationTable :: new ( ) ) ,
470
- float_unification_table : RefCell :: new ( UnificationTable :: new ( ) ) ,
471
- region_vars : RegionVarBindings :: new ( self ) ,
472
- selection_cache : traits:: SelectionCache :: new ( ) ,
473
- evaluation_cache : traits:: EvaluationCache :: new ( ) ,
474
- projection_cache : RefCell :: new ( traits:: ProjectionCache :: new ( ) ) ,
475
- reported_trait_errors : RefCell :: new ( FxHashSet ( ) ) ,
476
- tainted_by_errors_flag : Cell :: new ( false ) ,
477
- err_count_on_creation : self . sess . err_count ( ) ,
478
- in_snapshot : Cell :: new ( false ) ,
352
+ fresh_tables : None ,
479
353
}
480
354
}
481
355
}
482
356
483
357
impl < ' a , ' gcx , ' tcx > InferCtxtBuilder < ' a , ' gcx , ' tcx > {
358
+ /// Used only by `rustc_typeck` during body type-checking/inference,
359
+ /// will initialize `in_progress_tables` with fresh `TypeckTables`.
360
+ pub fn with_fresh_in_progress_tables ( mut self ) -> Self {
361
+ self . fresh_tables = Some ( RefCell :: new ( ty:: TypeckTables :: empty ( ) ) ) ;
362
+ self
363
+ }
364
+
484
365
pub fn enter < F , R > ( & ' tcx mut self , f : F ) -> R
485
366
where F : for < ' b > FnOnce ( InferCtxt < ' b , ' gcx , ' tcx > ) -> R
486
367
{
487
368
let InferCtxtBuilder {
488
369
global_tcx,
489
370
ref arena,
490
371
ref fresh_tables,
491
- tables,
492
372
} = * self ;
493
- let tables = tables. map ( InferTables :: Interned ) . unwrap_or_else ( || {
494
- fresh_tables. as_ref ( ) . map_or ( InferTables :: Missing , InferTables :: InProgress )
495
- } ) ;
373
+ let in_progress_tables = fresh_tables. as_ref ( ) ;
496
374
global_tcx. enter_local ( arena, |tcx| f ( InferCtxt {
497
- tcx : tcx ,
498
- tables : tables ,
375
+ tcx,
376
+ in_progress_tables ,
499
377
projection_cache : RefCell :: new ( traits:: ProjectionCache :: new ( ) ) ,
500
378
type_variables : RefCell :: new ( type_variable:: TypeVariableTable :: new ( ) ) ,
501
379
int_unification_table : RefCell :: new ( UnificationTable :: new ( ) ) ,
@@ -618,7 +496,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
618
496
return value;
619
497
}
620
498
621
- self . infer_ctxt ( ( ) ) . enter ( |infcx| {
499
+ self . infer_ctxt ( ) . enter ( |infcx| {
622
500
value. trans_normalize ( & infcx, param_env)
623
501
} )
624
502
}
@@ -640,7 +518,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
640
518
return value;
641
519
}
642
520
643
- self . infer_ctxt ( ( ) ) . enter ( |infcx| {
521
+ self . infer_ctxt ( ) . enter ( |infcx| {
644
522
value. trans_normalize ( & infcx, env. reveal_all ( ) )
645
523
} )
646
524
}
@@ -844,10 +722,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
844
722
was_in_snapshot : in_snapshot,
845
723
// Borrow tables "in progress" (i.e. during typeck)
846
724
// to ban writes from within a snapshot to them.
847
- _in_progress_tables : match self . tables {
848
- InferTables :: InProgress ( ref tables) => tables. try_borrow ( ) . ok ( ) ,
849
- _ => None
850
- }
725
+ _in_progress_tables : self . in_progress_tables . map ( |tables| {
726
+ tables. borrow ( )
727
+ } )
851
728
}
852
729
}
853
730
@@ -1190,28 +1067,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1190
1067
self . tainted_by_errors_flag . set ( true )
1191
1068
}
1192
1069
1193
- pub fn node_type ( & self , id : ast:: NodeId ) -> Ty < ' tcx > {
1194
- match self . tables . borrow ( ) . node_types . get ( & id) {
1195
- Some ( & t) => t,
1196
- // FIXME
1197
- None if self . is_tainted_by_errors ( ) =>
1198
- self . tcx . types . err ,
1199
- None => {
1200
- bug ! ( "no type for node {}: {} in fcx" ,
1201
- id, self . tcx. hir. node_to_string( id) ) ;
1202
- }
1203
- }
1204
- }
1205
-
1206
- pub fn expr_ty ( & self , ex : & hir:: Expr ) -> Ty < ' tcx > {
1207
- match self . tables . borrow ( ) . node_types . get ( & ex. id ) {
1208
- Some ( & t) => t,
1209
- None => {
1210
- bug ! ( "no type for expr in fcx" ) ;
1211
- }
1212
- }
1213
- }
1214
-
1215
1070
pub fn resolve_regions_and_report_errors ( & self ,
1216
1071
region_context : DefId ,
1217
1072
region_map : & RegionMaps ,
@@ -1310,21 +1165,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1310
1165
value. fold_with ( & mut r)
1311
1166
}
1312
1167
1313
- /// Resolves all type variables in `t` and then, if any were left
1314
- /// unresolved, substitutes an error type. This is used after the
1315
- /// main checking when doing a second pass before writeback. The
1316
- /// justification is that writeback will produce an error for
1317
- /// these unconstrained type variables.
1318
- fn resolve_type_vars_or_error ( & self , t : & Ty < ' tcx > ) -> mc:: McResult < Ty < ' tcx > > {
1319
- let ty = self . resolve_type_vars_if_possible ( t) ;
1320
- if ty. references_error ( ) || ty. is_ty_var ( ) {
1321
- debug ! ( "resolve_type_vars_or_error: error from {:?}" , ty) ;
1322
- Err ( ( ) )
1323
- } else {
1324
- Ok ( ty)
1325
- }
1326
- }
1327
-
1328
1168
pub fn fully_resolve < T : TypeFoldable < ' tcx > > ( & self , value : & T ) -> FixupResult < T > {
1329
1169
/*!
1330
1170
* Attempts to resolve all type/region variables in
@@ -1484,30 +1324,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1484
1324
self . region_vars . verify_generic_bound ( origin, kind, a, bound) ;
1485
1325
}
1486
1326
1487
- pub fn node_ty ( & self , id : ast:: NodeId ) -> McResult < Ty < ' tcx > > {
1488
- let ty = self . node_type ( id) ;
1489
- self . resolve_type_vars_or_error ( & ty)
1490
- }
1491
-
1492
- pub fn expr_ty_adjusted ( & self , expr : & hir:: Expr ) -> McResult < Ty < ' tcx > > {
1493
- let ty = self . tables . borrow ( ) . expr_ty_adjusted ( expr) ;
1494
- self . resolve_type_vars_or_error ( & ty)
1495
- }
1496
-
1497
1327
pub fn type_moves_by_default ( & self ,
1498
1328
param_env : ty:: ParamEnv < ' tcx > ,
1499
1329
ty : Ty < ' tcx > ,
1500
1330
span : Span )
1501
1331
-> bool {
1502
1332
let ty = self . resolve_type_vars_if_possible ( & ty) ;
1503
- if let Some ( ( param_env, ty) ) = self . tcx . lift_to_global ( & ( param_env, ty) ) {
1504
- // Even if the type may have no inference variables, during
1505
- // type-checking closure types are in local tables only.
1506
- let local_closures = match self . tables {
1507
- InferTables :: InProgress ( _) => ty. has_closure_types ( ) ,
1508
- _ => false
1509
- } ;
1510
- if !local_closures {
1333
+ // Even if the type may have no inference variables, during
1334
+ // type-checking closure types are in local tables only.
1335
+ if !self . in_progress_tables . is_some ( ) || !ty. has_closure_types ( ) {
1336
+ if let Some ( ( param_env, ty) ) = self . tcx . lift_to_global ( & ( param_env, ty) ) {
1511
1337
return ty. moves_by_default ( self . tcx . global_tcx ( ) , param_env, span) ;
1512
1338
}
1513
1339
}
@@ -1521,15 +1347,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1521
1347
!traits:: type_known_to_meet_bound ( self , param_env, ty, copy_def_id, span)
1522
1348
}
1523
1349
1524
- pub fn upvar_capture ( & self , upvar_id : ty:: UpvarId ) -> Option < ty:: UpvarCapture < ' tcx > > {
1525
- self . tables . borrow ( ) . upvar_capture_map . get ( & upvar_id) . cloned ( )
1526
- }
1527
-
1528
1350
pub fn closure_kind ( & self ,
1529
1351
def_id : DefId )
1530
1352
-> Option < ty:: ClosureKind >
1531
1353
{
1532
- if let InferTables :: InProgress ( tables) = self . tables {
1354
+ if let Some ( tables) = self . in_progress_tables {
1533
1355
if let Some ( id) = self . tcx . hir . as_local_node_id ( def_id) {
1534
1356
return tables. borrow ( )
1535
1357
. closure_kinds
@@ -1547,7 +1369,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1547
1369
}
1548
1370
1549
1371
pub fn closure_type ( & self , def_id : DefId ) -> ty:: PolyFnSig < ' tcx > {
1550
- if let InferTables :: InProgress ( tables) = self . tables {
1372
+ if let Some ( tables) = self . in_progress_tables {
1551
1373
if let Some ( id) = self . tcx . hir . as_local_node_id ( def_id) {
1552
1374
if let Some ( & ty) = tables. borrow ( ) . closure_tys . get ( & id) {
1553
1375
return ty;
0 commit comments