@@ -18,7 +18,7 @@ pub use relate::combine::PredicateEmittingRelation;
1818use rustc_data_structures:: captures:: Captures ;
1919use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap } ;
2020use rustc_data_structures:: sync:: Lrc ;
21- use rustc_data_structures:: undo_log:: Rollback ;
21+ use rustc_data_structures:: undo_log:: { Rollback , UndoLogs } ;
2222use rustc_data_structures:: unify as ut;
2323use rustc_errors:: { DiagCtxtHandle , ErrorGuaranteed } ;
2424use rustc_hir as hir;
@@ -50,6 +50,7 @@ use snapshot::undo_log::InferCtxtUndoLogs;
5050use tracing:: { debug, instrument} ;
5151use type_variable:: TypeVariableOrigin ;
5252
53+ use crate :: infer:: region_constraints:: UndoLog ;
5354use crate :: traits:: { self , ObligationCause , ObligationInspector , PredicateObligation , TraitEngine } ;
5455
5556pub mod at;
@@ -67,6 +68,13 @@ pub mod resolve;
6768pub ( crate ) mod snapshot;
6869mod type_variable;
6970
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.
7078#[ must_use]
7179#[ derive( Debug ) ]
7280pub struct InferOk < ' tcx , T > {
@@ -163,12 +171,12 @@ impl<'tcx> InferCtxtInner<'tcx> {
163171 undo_log : InferCtxtUndoLogs :: default ( ) ,
164172
165173 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 ( ) ) ,
172180 region_obligations : vec ! [ ] ,
173181 opaque_type_storage : Default :: default ( ) ,
174182 }
@@ -1004,8 +1012,8 @@ impl<'tcx> InferCtxt<'tcx> {
10041012 ty:: Const :: new_infer ( self . tcx , ty:: InferConst :: EffectVar ( effect_vid) ) . into ( )
10051013 }
10061014
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.
10091017 pub fn fresh_args_for_item ( & self , span : Span , def_id : DefId ) -> GenericArgsRef < ' tcx > {
10101018 GenericArgs :: for_item ( self . tcx , def_id, |param, _| self . var_for_def ( span, param) )
10111019 }
@@ -1036,18 +1044,14 @@ impl<'tcx> InferCtxt<'tcx> {
10361044 /// Clone the list of variable regions. This is used only during NLL processing
10371045 /// to put the set of region variables into the NLL region context.
10381046 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 ( )
10511055 }
10521056
10531057 #[ instrument( level = "debug" , skip( self ) , ret) ]
@@ -1383,10 +1387,10 @@ impl<'tcx> InferCtxt<'tcx> {
13831387 ///
13841388 /// The constant can be located on a trait like `<A as B>::C`, in which case the given
13851389 /// 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
13901394 /// returned.
13911395 ///
13921396 /// This handles inferences variables within both `param_env` and `args` by
0 commit comments