@@ -13,14 +13,15 @@ use crate::infer::canonical::{Canonical, CanonicalVarValues};
13
13
use crate :: middle:: free_region:: RegionRelations ;
14
14
use crate :: middle:: lang_items;
15
15
use crate :: middle:: region;
16
+ use crate :: mir:: interpret:: ConstValue ;
16
17
use crate :: session:: config:: BorrowckMode ;
17
18
use crate :: traits:: { self , ObligationCause , PredicateObligations , TraitEngine } ;
18
19
use crate :: ty:: error:: { ExpectedFound , TypeError , UnconstrainedNumeric } ;
19
20
use crate :: ty:: fold:: TypeFoldable ;
20
21
use crate :: ty:: relate:: RelateResult ;
21
22
use crate :: ty:: subst:: { Kind , InternalSubsts , SubstsRef } ;
22
- use crate :: ty:: { self , GenericParamDefKind , Ty , TyCtxt , CtxtInterners } ;
23
- use crate :: ty:: { FloatVid , IntVid , TyVid } ;
23
+ use crate :: ty:: { self , GenericParamDefKind , Ty , TyCtxt , CtxtInterners , InferConst } ;
24
+ use crate :: ty:: { FloatVid , IntVid , TyVid , ConstVid } ;
24
25
use crate :: util:: nodemap:: FxHashMap ;
25
26
26
27
use arena:: SyncDroplessArena ;
@@ -34,6 +35,7 @@ use syntax_pos::symbol::InternedString;
34
35
use syntax_pos:: Span ;
35
36
36
37
use self :: combine:: CombineFields ;
38
+ use self :: const_variable:: ConstVariableOrigin ;
37
39
use self :: lexical_region_resolve:: LexicalRegionResolutions ;
38
40
use self :: outlives:: env:: OutlivesEnvironment ;
39
41
use self :: region_constraints:: { GenericKind , RegionConstraintData , VarInfos , VerifyBound } ;
@@ -60,6 +62,7 @@ pub mod region_constraints;
60
62
pub mod resolve;
61
63
mod sub;
62
64
pub mod type_variable;
65
+ pub mod const_variable;
63
66
pub mod unify_key;
64
67
65
68
#[ must_use]
@@ -72,7 +75,7 @@ pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
72
75
73
76
pub type Bound < T > = Option < T > ;
74
77
pub type UnitResult < ' tcx > = RelateResult < ' tcx , ( ) > ; // "unify result"
75
- pub type FixupResult < T > = Result < T , FixupError > ; // "fixup result"
78
+ pub type FixupResult < ' tcx , T > = Result < T , FixupError < ' tcx > > ; // "fixup result"
76
79
77
80
/// A flag that is used to suppress region errors. This is normally
78
81
/// false, but sometimes -- when we are doing region checks that the
@@ -122,7 +125,10 @@ pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
122
125
/// order, represented by its upper and lower bounds.
123
126
pub type_variables : RefCell < type_variable:: TypeVariableTable < ' tcx > > ,
124
127
125
- /// Map from integral variable to the kind of integer it represents
128
+ /// Map from const parameter variable to the kind of const it represents.
129
+ const_unification_table : RefCell < const_variable:: ConstVariableTable < ' tcx > > ,
130
+
131
+ /// Map from integral variable to the kind of integer it represents.
126
132
int_unification_table : RefCell < ut:: UnificationTable < ut:: InPlace < ty:: IntVid > > > ,
127
133
128
134
/// Map from floating variable to the kind of float it represents
@@ -422,10 +428,11 @@ impl NLLRegionVariableOrigin {
422
428
}
423
429
424
430
#[ derive( Copy , Clone , Debug ) ]
425
- pub enum FixupError {
431
+ pub enum FixupError < ' tcx > {
426
432
UnresolvedIntTy ( IntVid ) ,
427
433
UnresolvedFloatTy ( FloatVid ) ,
428
434
UnresolvedTy ( TyVid ) ,
435
+ UnresolvedConst ( ConstVid < ' tcx > ) ,
429
436
}
430
437
431
438
/// See the `region_obligations` field for more information.
@@ -436,7 +443,7 @@ pub struct RegionObligation<'tcx> {
436
443
pub origin : SubregionOrigin < ' tcx > ,
437
444
}
438
445
439
- impl fmt:: Display for FixupError {
446
+ impl < ' tcx > fmt:: Display for FixupError < ' tcx > {
440
447
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
441
448
use self :: FixupError :: * ;
442
449
@@ -452,6 +459,7 @@ impl fmt::Display for FixupError {
452
459
add a suffix to specify the type explicitly"
453
460
) ,
454
461
UnresolvedTy ( _) => write ! ( f, "unconstrained type" ) ,
462
+ UnresolvedConst ( _) => write ! ( f, "unconstrained const value" ) ,
455
463
}
456
464
}
457
465
}
@@ -524,6 +532,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
524
532
in_progress_tables,
525
533
projection_cache : Default :: default ( ) ,
526
534
type_variables : RefCell :: new ( type_variable:: TypeVariableTable :: new ( ) ) ,
535
+ const_unification_table : RefCell :: new ( const_variable:: ConstVariableTable :: new ( ) ) ,
527
536
int_unification_table : RefCell :: new ( ut:: UnificationTable :: new ( ) ) ,
528
537
float_unification_table : RefCell :: new ( ut:: UnificationTable :: new ( ) ) ,
529
538
region_constraints : RefCell :: new ( Some ( RegionConstraintCollector :: new ( ) ) ) ,
@@ -589,6 +598,7 @@ impl<'tcx> InferOk<'tcx, ()> {
589
598
pub struct CombinedSnapshot < ' a , ' tcx : ' a > {
590
599
projection_cache_snapshot : traits:: ProjectionCacheSnapshot ,
591
600
type_snapshot : type_variable:: Snapshot < ' tcx > ,
601
+ const_snapshot : const_variable:: Snapshot < ' tcx > ,
592
602
int_snapshot : ut:: Snapshot < ut:: InPlace < ty:: IntVid > > ,
593
603
float_snapshot : ut:: Snapshot < ut:: InPlace < ty:: FloatVid > > ,
594
604
region_constraints_snapshot : RegionSnapshot ,
@@ -652,6 +662,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
652
662
let mut type_variables = self . type_variables . borrow_mut ( ) ;
653
663
let mut int_unification_table = self . int_unification_table . borrow_mut ( ) ;
654
664
let mut float_unification_table = self . float_unification_table . borrow_mut ( ) ;
665
+ // FIXME(const_generics): should there be an equivalent function for const variables?
655
666
656
667
type_variables
657
668
. unsolved_variables ( )
@@ -722,6 +733,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
722
733
CombinedSnapshot {
723
734
projection_cache_snapshot : self . projection_cache . borrow_mut ( ) . snapshot ( ) ,
724
735
type_snapshot : self . type_variables . borrow_mut ( ) . snapshot ( ) ,
736
+ const_snapshot : self . const_unification_table . borrow_mut ( ) . snapshot ( ) ,
725
737
int_snapshot : self . int_unification_table . borrow_mut ( ) . snapshot ( ) ,
726
738
float_snapshot : self . float_unification_table . borrow_mut ( ) . snapshot ( ) ,
727
739
region_constraints_snapshot : self . borrow_region_constraints ( ) . start_snapshot ( ) ,
@@ -739,6 +751,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
739
751
let CombinedSnapshot {
740
752
projection_cache_snapshot,
741
753
type_snapshot,
754
+ const_snapshot,
742
755
int_snapshot,
743
756
float_snapshot,
744
757
region_constraints_snapshot,
@@ -751,28 +764,21 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
751
764
self . in_snapshot . set ( was_in_snapshot) ;
752
765
self . universe . set ( universe) ;
753
766
754
- self . projection_cache
755
- . borrow_mut ( )
756
- . rollback_to ( projection_cache_snapshot) ;
767
+ self . projection_cache . borrow_mut ( ) . rollback_to ( projection_cache_snapshot) ;
757
768
self . type_variables . borrow_mut ( ) . rollback_to ( type_snapshot) ;
758
- self . int_unification_table
759
- . borrow_mut ( )
760
- . rollback_to ( int_snapshot) ;
761
- self . float_unification_table
762
- . borrow_mut ( )
763
- . rollback_to ( float_snapshot) ;
764
- self . region_obligations
765
- . borrow_mut ( )
766
- . truncate ( region_obligations_snapshot) ;
767
- self . borrow_region_constraints ( )
768
- . rollback_to ( region_constraints_snapshot) ;
769
+ self . const_unification_table . borrow_mut ( ) . rollback_to ( const_snapshot) ;
770
+ self . int_unification_table . borrow_mut ( ) . rollback_to ( int_snapshot) ;
771
+ self . float_unification_table . borrow_mut ( ) . rollback_to ( float_snapshot) ;
772
+ self . region_obligations . borrow_mut ( ) . truncate ( region_obligations_snapshot) ;
773
+ self . borrow_region_constraints ( ) . rollback_to ( region_constraints_snapshot) ;
769
774
}
770
775
771
776
fn commit_from ( & self , snapshot : CombinedSnapshot < ' a , ' tcx > ) {
772
777
debug ! ( "commit_from()" ) ;
773
778
let CombinedSnapshot {
774
779
projection_cache_snapshot,
775
780
type_snapshot,
781
+ const_snapshot,
776
782
int_snapshot,
777
783
float_snapshot,
778
784
region_constraints_snapshot,
@@ -784,16 +790,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
784
790
785
791
self . in_snapshot . set ( was_in_snapshot) ;
786
792
787
- self . projection_cache
788
- . borrow_mut ( )
789
- . commit ( projection_cache_snapshot) ;
793
+ self . projection_cache . borrow_mut ( ) . commit ( projection_cache_snapshot) ;
790
794
self . type_variables . borrow_mut ( ) . commit ( type_snapshot) ;
795
+ self . const_unification_table . borrow_mut ( ) . commit ( const_snapshot) ;
791
796
self . int_unification_table . borrow_mut ( ) . commit ( int_snapshot) ;
792
- self . float_unification_table
793
- . borrow_mut ( )
794
- . commit ( float_snapshot) ;
795
- self . borrow_region_constraints ( )
796
- . commit ( region_constraints_snapshot) ;
797
+ self . float_unification_table . borrow_mut ( ) . commit ( float_snapshot) ;
798
+ self . borrow_region_constraints ( ) . commit ( region_constraints_snapshot) ;
797
799
}
798
800
799
801
/// Executes `f` and commit the bindings.
@@ -918,17 +920,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
918
920
predicate : & ty:: PolySubtypePredicate < ' tcx > ,
919
921
) -> Option < InferResult < ' tcx , ( ) > > {
920
922
// Subtle: it's ok to skip the binder here and resolve because
921
- // `shallow_resolve ` just ignores anything that is not a type
923
+ // `shallow_resolve_type ` just ignores anything that is not a type
922
924
// variable, and because type variable's can't (at present, at
923
925
// least) capture any of the things bound by this binder.
924
926
//
925
927
// Really, there is no *particular* reason to do this
926
- // `shallow_resolve ` here except as a
928
+ // `shallow_resolve_type ` here except as a
927
929
// micro-optimization. Naturally I could not
928
930
// resist. -nmatsakis
929
931
let two_unbound_type_vars = {
930
- let a = self . shallow_resolve ( predicate. skip_binder ( ) . a ) ;
931
- let b = self . shallow_resolve ( predicate. skip_binder ( ) . b ) ;
932
+ let a = self . shallow_resolve_type ( predicate. skip_binder ( ) . a ) ;
933
+ let b = self . shallow_resolve_type ( predicate. skip_binder ( ) . b ) ;
932
934
a. is_ty_var ( ) && b. is_ty_var ( )
933
935
} ;
934
936
@@ -999,6 +1001,32 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
999
1001
self . tcx . mk_ty_var ( self . next_ty_var_id ( true , origin) )
1000
1002
}
1001
1003
1004
+ pub fn next_const_var (
1005
+ & self ,
1006
+ ty : Ty < ' tcx > ,
1007
+ origin : ConstVariableOrigin
1008
+ ) -> & ' tcx ty:: LazyConst < ' tcx > {
1009
+ self . tcx . mk_const_var ( self . next_const_var_id ( origin) , ty)
1010
+ }
1011
+
1012
+ pub fn next_const_var_in_universe (
1013
+ & self ,
1014
+ ty : Ty < ' tcx > ,
1015
+ origin : ConstVariableOrigin ,
1016
+ universe : ty:: UniverseIndex ,
1017
+ ) -> & ' tcx ty:: LazyConst < ' tcx > {
1018
+ let vid = self . const_unification_table
1019
+ . borrow_mut ( )
1020
+ . new_var ( universe, origin) ;
1021
+ self . tcx . mk_const_var ( vid, ty)
1022
+ }
1023
+
1024
+ pub fn next_const_var_id ( & self , origin : ConstVariableOrigin ) -> ConstVid < ' tcx > {
1025
+ self . const_unification_table
1026
+ . borrow_mut ( )
1027
+ . new_var ( self . universe ( ) , origin)
1028
+ }
1029
+
1002
1030
fn next_int_var_id ( & self ) -> IntVid {
1003
1031
self . int_unification_table . borrow_mut ( ) . new_key ( None )
1004
1032
}
@@ -1092,7 +1120,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1092
1120
self . tcx . mk_ty_var ( ty_var_id) . into ( )
1093
1121
}
1094
1122
GenericParamDefKind :: Const { .. } => {
1095
- unimplemented ! ( ) // FIXME(const_generics)
1123
+ let const_var_id =
1124
+ self . const_unification_table
1125
+ . borrow_mut ( )
1126
+ . new_var (
1127
+ self . universe ( ) ,
1128
+ ConstVariableOrigin :: ConstParameterDefinition ( span, param. name ) ,
1129
+ ) ;
1130
+ self . tcx . mk_const_var ( const_var_id, self . tcx . type_of ( param. def_id ) ) . into ( )
1096
1131
}
1097
1132
}
1098
1133
}
@@ -1233,11 +1268,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1233
1268
self . resolve_type_vars_if_possible ( t) . to_string ( )
1234
1269
}
1235
1270
1236
- // We have this force-inlined variant of shallow_resolve() for the one
1271
+ // We have this force-inlined variant of `shallow_resolve_type` for the one
1237
1272
// callsite that is extremely hot. All other callsites use the normal
1238
1273
// variant.
1239
1274
#[ inline( always) ]
1240
- pub fn inlined_shallow_resolve ( & self , typ : Ty < ' tcx > ) -> Ty < ' tcx > {
1275
+ pub fn inlined_shallow_resolve_type ( & self , typ : Ty < ' tcx > ) -> Ty < ' tcx > {
1241
1276
match typ. sty {
1242
1277
ty:: Infer ( ty:: TyVar ( v) ) => {
1243
1278
// Not entirely obvious: if `typ` is a type variable,
@@ -1253,7 +1288,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1253
1288
. borrow_mut ( )
1254
1289
. probe ( v)
1255
1290
. known ( )
1256
- . map ( |t| self . shallow_resolve ( t) )
1291
+ . map ( |t| self . shallow_resolve_type ( t) )
1257
1292
. unwrap_or ( typ)
1258
1293
}
1259
1294
@@ -1284,8 +1319,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1284
1319
}
1285
1320
}
1286
1321
1287
- pub fn shallow_resolve ( & self , typ : Ty < ' tcx > ) -> Ty < ' tcx > {
1288
- self . inlined_shallow_resolve ( typ)
1322
+ pub fn shallow_resolve_type ( & self , typ : Ty < ' tcx > ) -> Ty < ' tcx > {
1323
+ self . inlined_shallow_resolve_type ( typ)
1289
1324
}
1290
1325
1291
1326
pub fn root_var ( & self , var : ty:: TyVid ) -> ty:: TyVid {
@@ -1323,9 +1358,60 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1323
1358
r. first_unresolved
1324
1359
}
1325
1360
1326
- pub fn fully_resolve < T : TypeFoldable < ' tcx > > ( & self , value : & T ) -> FixupResult < T > {
1361
+ pub fn probe_const_var (
1362
+ & self ,
1363
+ vid : ty:: ConstVid < ' tcx >
1364
+ ) -> Result < & ' tcx ty:: LazyConst < ' tcx > , ty:: UniverseIndex > {
1365
+ use self :: const_variable:: ConstVariableValue ;
1366
+
1367
+ match self . const_unification_table . borrow_mut ( ) . probe ( vid) {
1368
+ ConstVariableValue :: Known { value } => Ok ( value) ,
1369
+ ConstVariableValue :: Unknown { universe } => Err ( universe) ,
1370
+ }
1371
+ }
1372
+
1373
+ pub fn resolve_const_var (
1374
+ & self ,
1375
+ ct : & ' tcx ty:: LazyConst < ' tcx >
1376
+ ) -> & ' tcx ty:: LazyConst < ' tcx > {
1377
+ if let ty:: LazyConst :: Evaluated ( ty:: Const {
1378
+ val : ConstValue :: Infer ( InferConst :: Var ( v) ) ,
1379
+ ..
1380
+ } ) = ct {
1381
+ self . const_unification_table
1382
+ . borrow_mut ( )
1383
+ . probe ( * v)
1384
+ . known ( )
1385
+ . map ( |c| self . resolve_const_var ( c) )
1386
+ . unwrap_or ( ct)
1387
+ } else {
1388
+ ct
1389
+ }
1390
+ }
1391
+
1392
+ pub fn shallow_resolve_const (
1393
+ & self ,
1394
+ ct : & ' tcx ty:: LazyConst < ' tcx >
1395
+ ) -> & ' tcx ty:: LazyConst < ' tcx > {
1396
+ match ct {
1397
+ ty:: LazyConst :: Evaluated ( ty:: Const {
1398
+ val : ConstValue :: Infer ( InferConst :: Var ( vid) ) ,
1399
+ ..
1400
+ } ) => {
1401
+ self . const_unification_table
1402
+ . borrow_mut ( )
1403
+ . probe ( * vid)
1404
+ . known ( )
1405
+ . map ( |c| self . shallow_resolve_const ( c) )
1406
+ . unwrap_or ( ct)
1407
+ }
1408
+ _ => ct,
1409
+ }
1410
+ }
1411
+
1412
+ pub fn fully_resolve < T : TypeFoldable < ' tcx > > ( & self , value : & T ) -> FixupResult < ' tcx , T > {
1327
1413
/*!
1328
- * Attempts to resolve all type/region variables in
1414
+ * Attempts to resolve all type/region/const variables in
1329
1415
* `value`. Region inference must have been run already (e.g.,
1330
1416
* by calling `resolve_regions_and_report_errors`). If some
1331
1417
* variable was never unified, an `Err` results.
@@ -1441,7 +1527,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1441
1527
closure_substs : ty:: ClosureSubsts < ' tcx > ,
1442
1528
) -> Option < ty:: ClosureKind > {
1443
1529
let closure_kind_ty = closure_substs. closure_kind_ty ( closure_def_id, self . tcx ) ;
1444
- let closure_kind_ty = self . shallow_resolve ( & closure_kind_ty) ;
1530
+ let closure_kind_ty = self . shallow_resolve_type ( & closure_kind_ty) ;
1445
1531
closure_kind_ty. to_opt_closure_kind ( )
1446
1532
}
1447
1533
@@ -1455,7 +1541,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1455
1541
substs : ty:: ClosureSubsts < ' tcx > ,
1456
1542
) -> ty:: PolyFnSig < ' tcx > {
1457
1543
let closure_sig_ty = substs. closure_sig_ty ( def_id, self . tcx ) ;
1458
- let closure_sig_ty = self . shallow_resolve ( & closure_sig_ty) ;
1544
+ let closure_sig_ty = self . shallow_resolve_type ( & closure_sig_ty) ;
1459
1545
closure_sig_ty. fn_sig ( self . tcx )
1460
1546
}
1461
1547
0 commit comments