@@ -98,6 +98,12 @@ impl<'tcx> InferCtxt<'tcx> {
9898 }
9999}
100100
101+ /// To avoid leaking inference variables from snapshots, fudge inference
102+ /// by replacing inference variables from the snapshot with fresh ones
103+ /// created outside of it.
104+ ///
105+ /// To see how this works, check out the documentation of the [`FudgeInference`]
106+ /// wrapper used by [`fn InferCtxt::fudge_inference_if_ok`].
101107#[ macro_export]
102108macro_rules! fudge_vars_no_snapshot_leaks {
103109 ( $tcx: lifetime, $t: ty) => {
@@ -136,13 +142,22 @@ macro_rules! fudge_vars_no_snapshot_leaks {
136142 } ;
137143}
138144
145+ /// When rolling back a snapshot, replaces inference variables in `T` created
146+ /// during the snapshot with new inference variables created afterwards.
139147struct FudgeInference < T > ( T ) ;
140148impl < ' tcx , T : TypeFoldable < TyCtxt < ' tcx > > > NoSnapshotLeaks < ' tcx > for FudgeInference < T > {
141149 type StartData = VariableLengths ;
142150 type EndData = ( T , Option < InferenceFudgeData > ) ;
151+
152+ /// Store which inference variables already exist at the start
153+ /// of the snapshot.
143154 fn snapshot_start_data ( infcx : & InferCtxt < ' tcx > ) -> Self :: StartData {
144155 infcx. variable_lengths ( )
145156 }
157+ /// At the end of the snapshot, fetch the metadata for all variables
158+ /// created during the snapshot. As these variables get discarded during
159+ /// rollback, we have to get this information before rollback and use it
160+ /// to create new inference variables after.
146161 fn end_of_snapshot (
147162 infcx : & InferCtxt < ' tcx > ,
148163 FudgeInference ( value) : FudgeInference < T > ,
@@ -154,6 +169,9 @@ impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> NoSnapshotLeaks<'tcx> for FudgeInferen
154169 ( value, None )
155170 }
156171 }
172+ /// Using the metadata fetched in `fn end_of_snapshot`, replace all leaking
173+ /// inference variables with new ones, reusing the metadata of the leaked
174+ /// variables.
157175 fn avoid_leaks ( infcx : & InferCtxt < ' tcx > , ( value, fudge_data) : Self :: EndData ) -> Self {
158176 if let Some ( fudge_data) = fudge_data {
159177 FudgeInference ( fudge_data. fudge_inference ( infcx, value) )
@@ -163,6 +181,8 @@ impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> NoSnapshotLeaks<'tcx> for FudgeInferen
163181 }
164182}
165183
184+ /// At the end of a snpashot, right before rollback, remember all newly created
185+ /// inference variables and their metadata.
166186pub struct InferenceFudgeData {
167187 type_vars : ( Range < TyVid > , Vec < TypeVariableOrigin > ) ,
168188 int_vars : Range < IntVid > ,
@@ -210,6 +230,10 @@ impl InferenceFudgeData {
210230 }
211231}
212232
233+ /// Using the `InferenceFudgeData` created right before rollback, replace
234+ /// all leaked inference variables of the snapshot with newly created ones.
235+ ///
236+ /// This is used after the snapshot has already been rolled back.
213237struct InferenceFudger < ' a , ' tcx > {
214238 infcx : & ' a InferCtxt < ' tcx > ,
215239 data : InferenceFudgeData ,
0 commit comments