@@ -18,7 +18,7 @@ pub use relate::combine::PredicateEmittingRelation;
18
18
use rustc_data_structures:: captures:: Captures ;
19
19
use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap } ;
20
20
use rustc_data_structures:: sync:: Lrc ;
21
- use rustc_data_structures:: undo_log:: Rollback ;
21
+ use rustc_data_structures:: undo_log:: { Rollback , UndoLogs } ;
22
22
use rustc_data_structures:: unify as ut;
23
23
use rustc_errors:: { DiagCtxtHandle , ErrorGuaranteed } ;
24
24
use rustc_hir as hir;
@@ -50,6 +50,7 @@ use snapshot::undo_log::InferCtxtUndoLogs;
50
50
use tracing:: { debug, instrument} ;
51
51
use type_variable:: TypeVariableOrigin ;
52
52
53
+ use crate :: infer:: region_constraints:: UndoLog ;
53
54
use crate :: traits:: { self , ObligationCause , ObligationInspector , PredicateObligation , TraitEngine } ;
54
55
55
56
pub mod at;
@@ -67,6 +68,13 @@ pub mod resolve;
67
68
pub ( crate ) mod snapshot;
68
69
mod type_variable;
69
70
71
+ /// `InferOk<'tcx, ()>` is used a lot. It may seem like a useless wrapper
72
+ /// around `Vec<PredicateObligation<'tcx>>`, but it has one important property:
73
+ /// because `InferOk` is marked with `#[must_use]`, if you have a method
74
+ /// `InferCtxt::f` that returns `InferResult<'tcx, ()>` and you call it with
75
+ /// `infcx.f()?;` you'll get a warning about the obligations being discarded
76
+ /// without use, which is probably unintentional and has been a source of bugs
77
+ /// in the past.
70
78
#[ must_use]
71
79
#[ derive( Debug ) ]
72
80
pub struct InferOk < ' tcx , T > {
@@ -163,12 +171,12 @@ impl<'tcx> InferCtxtInner<'tcx> {
163
171
undo_log : InferCtxtUndoLogs :: default ( ) ,
164
172
165
173
projection_cache : Default :: default ( ) ,
166
- type_variable_storage : type_variable :: TypeVariableStorage :: new ( ) ,
167
- const_unification_storage : ut :: UnificationTableStorage :: new ( ) ,
168
- int_unification_storage : ut :: UnificationTableStorage :: new ( ) ,
169
- float_unification_storage : ut :: UnificationTableStorage :: new ( ) ,
170
- effect_unification_storage : ut :: UnificationTableStorage :: new ( ) ,
171
- region_constraint_storage : Some ( RegionConstraintStorage :: new ( ) ) ,
174
+ type_variable_storage : Default :: default ( ) ,
175
+ const_unification_storage : Default :: default ( ) ,
176
+ int_unification_storage : Default :: default ( ) ,
177
+ float_unification_storage : Default :: default ( ) ,
178
+ effect_unification_storage : Default :: default ( ) ,
179
+ region_constraint_storage : Some ( Default :: default ( ) ) ,
172
180
region_obligations : vec ! [ ] ,
173
181
opaque_type_storage : Default :: default ( ) ,
174
182
}
@@ -1004,8 +1012,8 @@ impl<'tcx> InferCtxt<'tcx> {
1004
1012
ty:: Const :: new_infer ( self . tcx , ty:: InferConst :: EffectVar ( effect_vid) ) . into ( )
1005
1013
}
1006
1014
1007
- /// Given a set of generics defined on a type or impl, returns the generic parameters mapping each
1008
- /// type/region parameter to a fresh inference variable.
1015
+ /// Given a set of generics defined on a type or impl, returns the generic parameters mapping
1016
+ /// each type/region parameter to a fresh inference variable.
1009
1017
pub fn fresh_args_for_item ( & self , span : Span , def_id : DefId ) -> GenericArgsRef < ' tcx > {
1010
1018
GenericArgs :: for_item ( self . tcx , def_id, |param, _| self . var_for_def ( span, param) )
1011
1019
}
@@ -1036,18 +1044,14 @@ impl<'tcx> InferCtxt<'tcx> {
1036
1044
/// Clone the list of variable regions. This is used only during NLL processing
1037
1045
/// to put the set of region variables into the NLL region context.
1038
1046
pub fn get_region_var_origins ( & self ) -> VarInfos {
1039
- let mut inner = self . inner . borrow_mut ( ) ;
1040
- let ( var_infos, data) = inner
1041
- . region_constraint_storage
1042
- // We clone instead of taking because borrowck still wants to use
1043
- // the inference context after calling this for diagnostics
1044
- // and the new trait solver.
1045
- . clone ( )
1046
- . expect ( "regions already resolved" )
1047
- . with_log ( & mut inner. undo_log )
1048
- . into_infos_and_data ( ) ;
1049
- assert ! ( data. is_empty( ) ) ;
1050
- var_infos
1047
+ let inner = self . inner . borrow ( ) ;
1048
+ assert ! ( !UndoLogs :: <UndoLog <' _>>:: in_snapshot( & inner. undo_log) ) ;
1049
+ let storage = inner. region_constraint_storage . as_ref ( ) . expect ( "regions already resolved" ) ;
1050
+ assert ! ( storage. data. is_empty( ) ) ;
1051
+ // We clone instead of taking because borrowck still wants to use the
1052
+ // inference context after calling this for diagnostics and the new
1053
+ // trait solver.
1054
+ storage. var_infos . clone ( )
1051
1055
}
1052
1056
1053
1057
#[ instrument( level = "debug" , skip( self ) , ret) ]
@@ -1383,10 +1387,10 @@ impl<'tcx> InferCtxt<'tcx> {
1383
1387
///
1384
1388
/// The constant can be located on a trait like `<A as B>::C`, in which case the given
1385
1389
/// generic parameters and environment are used to resolve the constant. Alternatively if the
1386
- /// constant has generic parameters in scope the instantiations are used to evaluate the value of
1387
- /// the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count
1388
- /// constant `bar::<T>()` requires a instantiation for `T`, if the instantiation for `T` is still
1389
- /// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is
1390
+ /// constant has generic parameters in scope the instantiations are used to evaluate the value
1391
+ /// of the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count
1392
+ /// constant `bar::<T>()` requires a instantiation for `T`, if the instantiation for `T` is
1393
+ /// still too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is
1390
1394
/// returned.
1391
1395
///
1392
1396
/// This handles inferences variables within both `param_env` and `args` by
0 commit comments