@@ -23,19 +23,24 @@ pub use self::freshen::TypeFreshener;
23
23
pub use self :: region_inference:: GenericKind ;
24
24
25
25
use middle:: free_region:: FreeRegionMap ;
26
+ use middle:: mem_categorization as mc;
27
+ use middle:: mem_categorization:: McResult ;
28
+ use middle:: region:: { self , CodeExtent } ;
26
29
use middle:: subst;
27
30
use middle:: subst:: Substs ;
31
+ use middle:: subst:: Subst ;
32
+ use middle:: traits;
28
33
use middle:: ty:: { TyVid , IntVid , FloatVid , RegionVid , UnconstrainedNumeric } ;
29
34
use middle:: ty:: { self , Ty , HasTypeFlags } ;
30
35
use middle:: ty_fold:: { self , TypeFolder , TypeFoldable } ;
31
36
use middle:: ty_relate:: { Relate , RelateResult , TypeRelation } ;
32
37
use rustc_data_structures:: unify:: { self , UnificationTable } ;
33
- use std:: cell:: { RefCell } ;
38
+ use std:: cell:: { RefCell , Ref } ;
34
39
use std:: fmt;
35
40
use syntax:: ast;
36
41
use syntax:: codemap;
37
42
use syntax:: codemap:: Span ;
38
- use util:: nodemap:: FnvHashMap ;
43
+ use util:: nodemap:: { DefIdMap , FnvHashMap , NodeMap } ;
39
44
40
45
use self :: combine:: CombineFields ;
41
46
use self :: region_inference:: { RegionVarBindings , RegionSnapshot } ;
@@ -64,6 +69,8 @@ pub type fres<T> = Result<T, fixup_err>; // "fixup result"
64
69
pub struct InferCtxt < ' a , ' tcx : ' a > {
65
70
pub tcx : & ' a ty:: ctxt < ' tcx > ,
66
71
72
+ pub tables : & ' a RefCell < ty:: Tables < ' tcx > > ,
73
+
67
74
// We instantiate UnificationTable with bounds<Ty> because the
68
75
// types that might instantiate a general type variable have an
69
76
// order, represented by its upper and lower bounds.
@@ -80,7 +87,9 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
80
87
81
88
pub parameter_environment : ty:: ParameterEnvironment < ' a , ' tcx > ,
82
89
83
- // pub tables: &'a RefCell<ty::Tables<'tcx>>
90
+ normalize : bool ,
91
+
92
+ err_count_on_creation : usize ,
84
93
}
85
94
86
95
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
@@ -314,15 +323,19 @@ pub fn fixup_err_to_string(f: fixup_err) -> String {
314
323
}
315
324
316
325
pub fn new_infer_ctxt < ' a , ' tcx > ( tcx : & ' a ty:: ctxt < ' tcx > ,
326
+ tables : & ' a RefCell < ty:: Tables < ' tcx > > ,
317
327
param_env : Option < ty:: ParameterEnvironment < ' a , ' tcx > > )
318
328
-> InferCtxt < ' a , ' tcx > {
319
329
InferCtxt {
320
330
tcx : tcx,
331
+ tables : tables,
321
332
type_variables : RefCell :: new ( type_variable:: TypeVariableTable :: new ( ) ) ,
322
333
int_unification_table : RefCell :: new ( UnificationTable :: new ( ) ) ,
323
334
float_unification_table : RefCell :: new ( UnificationTable :: new ( ) ) ,
324
335
region_vars : RegionVarBindings :: new ( tcx) ,
325
- parameter_environment : param_env. unwrap_or ( tcx. empty_parameter_environment ( ) )
336
+ parameter_environment : param_env. unwrap_or ( tcx. empty_parameter_environment ( ) ) ,
337
+ normalize : true ,
338
+ err_count_on_creation : tcx. sess . err_count ( )
326
339
}
327
340
}
328
341
@@ -437,6 +450,92 @@ pub struct CombinedSnapshot {
437
450
region_vars_snapshot : RegionSnapshot ,
438
451
}
439
452
453
+ impl < ' a , ' tcx > mc:: Typer < ' tcx > for InferCtxt < ' a , ' tcx > {
454
+ fn node_ty ( & self , id : ast:: NodeId ) -> McResult < Ty < ' tcx > > {
455
+ let ty = self . node_ty ( id) ;
456
+ self . resolve_type_vars_or_error ( & ty)
457
+ }
458
+
459
+ fn expr_ty_adjusted ( & self , expr : & ast:: Expr ) -> McResult < Ty < ' tcx > > {
460
+ let ty = self . adjust_expr_ty ( expr, self . tables . borrow ( ) . adjustments . get ( & expr. id ) ) ;
461
+ self . resolve_type_vars_or_error ( & ty)
462
+ }
463
+
464
+ fn type_moves_by_default ( & self , ty : Ty < ' tcx > , span : Span ) -> bool {
465
+ let ty = self . resolve_type_vars_if_possible ( & ty) ;
466
+ !traits:: type_known_to_meet_builtin_bound ( self , self , ty, ty:: BoundCopy , span)
467
+ }
468
+
469
+ fn node_method_ty ( & self , method_call : ty:: MethodCall )
470
+ -> Option < Ty < ' tcx > > {
471
+ self . tables
472
+ . borrow ( )
473
+ . method_map
474
+ . get ( & method_call)
475
+ . map ( |method| method. ty )
476
+ . map ( |ty| self . resolve_type_vars_if_possible ( & ty) )
477
+ }
478
+
479
+ fn node_method_origin ( & self , method_call : ty:: MethodCall )
480
+ -> Option < ty:: MethodOrigin < ' tcx > >
481
+ {
482
+ self . tables
483
+ . borrow ( )
484
+ . method_map
485
+ . get ( & method_call)
486
+ . map ( |method| method. origin . clone ( ) )
487
+ }
488
+
489
+ fn adjustments ( & self ) -> Ref < NodeMap < ty:: AutoAdjustment < ' tcx > > > {
490
+ fn project_adjustments < ' a , ' tcx > ( tables : & ' a ty:: Tables < ' tcx > ) -> & ' a NodeMap < ty:: AutoAdjustment < ' tcx > > {
491
+ & tables. adjustments
492
+ }
493
+
494
+ Ref :: map ( self . tables . borrow ( ) , project_adjustments)
495
+ }
496
+
497
+ fn is_method_call ( & self , id : ast:: NodeId ) -> bool {
498
+ self . tables . borrow ( ) . method_map . contains_key ( & ty:: MethodCall :: expr ( id) )
499
+ }
500
+
501
+ fn temporary_scope ( & self , rvalue_id : ast:: NodeId ) -> Option < CodeExtent > {
502
+ self . parameter_environment . temporary_scope ( rvalue_id)
503
+ }
504
+
505
+ fn upvar_capture ( & self , upvar_id : ty:: UpvarId ) -> Option < ty:: UpvarCapture > {
506
+ self . tables . borrow ( ) . upvar_capture_map . get ( & upvar_id) . cloned ( )
507
+ }
508
+ }
509
+
510
+ impl < ' a , ' tcx > ty:: ClosureTyper < ' tcx > for InferCtxt < ' a , ' tcx > {
511
+ fn param_env < ' b > ( & ' b self ) -> & ' b ty:: ParameterEnvironment < ' b , ' tcx > {
512
+ & self . parameter_environment
513
+ }
514
+
515
+ fn closure_kind ( & self ,
516
+ def_id : ast:: DefId )
517
+ -> Option < ty:: ClosureKind >
518
+ {
519
+ self . tables . borrow ( ) . closure_kinds . get ( & def_id) . cloned ( )
520
+ }
521
+
522
+ fn closure_type ( & self ,
523
+ def_id : ast:: DefId ,
524
+ substs : & subst:: Substs < ' tcx > )
525
+ -> ty:: ClosureTy < ' tcx >
526
+ {
527
+ self . tables . borrow ( ) . closure_tys . get ( & def_id) . unwrap ( ) . subst ( self . tcx , substs)
528
+ }
529
+
530
+ fn closure_upvars ( & self ,
531
+ def_id : ast:: DefId ,
532
+ substs : & Substs < ' tcx > )
533
+ -> Option < Vec < ty:: ClosureUpvar < ' tcx > > >
534
+ {
535
+ ty:: ctxt:: closure_upvars ( self , def_id, substs)
536
+ }
537
+ }
538
+
440
539
impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
441
540
pub fn freshen < T : TypeFoldable < ' tcx > > ( & self , t : T ) -> T {
442
541
t. fold_with ( & mut self . freshener ( ) )
@@ -858,6 +957,48 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
858
957
self . region_vars . new_bound ( debruijn)
859
958
}
860
959
960
+ /// Apply `adjustment` to the type of `expr`
961
+ pub fn adjust_expr_ty ( & self ,
962
+ expr : & ast:: Expr ,
963
+ adjustment : Option < & ty:: AutoAdjustment < ' tcx > > )
964
+ -> Ty < ' tcx >
965
+ {
966
+ let raw_ty = self . expr_ty ( expr) ;
967
+ let raw_ty = self . shallow_resolve ( raw_ty) ;
968
+ let resolve_ty = |ty : Ty < ' tcx > | self . resolve_type_vars_if_possible ( & ty) ;
969
+ raw_ty. adjust ( self . tcx ,
970
+ expr. span ,
971
+ expr. id ,
972
+ adjustment,
973
+ |method_call| self . tables
974
+ . borrow ( )
975
+ . method_map
976
+ . get ( & method_call)
977
+ . map ( |method| resolve_ty ( method. ty ) ) )
978
+ }
979
+
980
+ pub fn node_ty ( & self , id : ast:: NodeId ) -> Ty < ' tcx > {
981
+ match self . tables . borrow ( ) . node_types . get ( & id) {
982
+ Some ( & t) => t,
983
+ // FIXME
984
+ None if self . tcx . sess . err_count ( ) - self . err_count_on_creation != 0 => self . tcx . types . err ,
985
+ None => {
986
+ self . tcx . sess . bug (
987
+ & format ! ( "no type for node {}: {} in fcx" ,
988
+ id, self . tcx. map. node_to_string( id) ) ) ;
989
+ }
990
+ }
991
+ }
992
+
993
+ pub fn expr_ty ( & self , ex : & ast:: Expr ) -> Ty < ' tcx > {
994
+ match self . tables . borrow ( ) . node_types . get ( & ex. id ) {
995
+ Some ( & t) => t,
996
+ None => {
997
+ self . tcx . sess . bug ( & format ! ( "no type for expr in fcx" ) ) ;
998
+ }
999
+ }
1000
+ }
1001
+
861
1002
pub fn resolve_regions_and_report_errors ( & self ,
862
1003
free_regions : & FreeRegionMap ,
863
1004
subject_node_id : ast:: NodeId ) {
@@ -932,6 +1073,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
932
1073
value. fold_with ( & mut r)
933
1074
}
934
1075
1076
+ fn resolve_type_vars_or_error ( & self , t : & Ty < ' tcx > ) -> mc:: McResult < Ty < ' tcx > > {
1077
+ let ty = self . resolve_type_vars_if_possible ( t) ;
1078
+ if ty. has_infer_types ( ) || ty. references_error ( ) { Err ( ( ) ) } else { Ok ( ty) }
1079
+ }
1080
+
935
1081
pub fn fully_resolve < T : TypeFoldable < ' tcx > > ( & self , value : & T ) -> fres < T > {
936
1082
/*!
937
1083
* Attempts to resolve all type/region variables in
0 commit comments