Skip to content

Commit 372c506

Browse files
committed
uwu
1 parent d37af33 commit 372c506

File tree

3 files changed

+137
-140
lines changed

3 files changed

+137
-140
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use rustc_hir_analysis::astconv::AstConv;
1313
use rustc_infer::infer;
1414
use rustc_infer::infer::error_reporting::sub_relations::SubRelations;
1515
use rustc_infer::infer::error_reporting::TypeErrCtxt;
16-
use rustc_infer::infer::snapshot::NoLeaksUnchecked;
1716
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1817
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
1918
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
@@ -171,21 +170,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
171170
if fn_sig.has_escaping_bound_vars() {
172171
return fn_sig;
173172
}
174-
// We explicitly assert that value does not contain inference variables,
175-
// so this definitely does not leak inference variables.
176173
self.probe(|_| {
177174
let ocx = ObligationCtxt::new(self);
178175
let normalized_fn_sig =
179176
ocx.normalize(&ObligationCause::dummy(), self.param_env, fn_sig);
180177
if ocx.select_all_or_error().is_empty() {
181178
let normalized_fn_sig = self.resolve_vars_if_possible(normalized_fn_sig);
182179
if !normalized_fn_sig.has_infer() {
183-
return NoLeaksUnchecked { value: normalized_fn_sig };
180+
return normalized_fn_sig;
184181
}
185182
}
186-
NoLeaksUnchecked { value: fn_sig }
183+
fn_sig
187184
})
188-
.value
189185
}),
190186
autoderef_steps: Box::new(|ty| {
191187
let mut autoderef = self.autoderef(DUMMY_SP, ty).silence_errors();
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
use super::VariableLengths;
2+
use rustc_middle::ty::{self, Ty, TyCtxt};
3+
use rustc_middle::ty::{TypeVisitor, TypeSuperVisitable};
4+
use std::ops::ControlFlow;
5+
use crate::infer::InferCtxt;
6+
7+
pub struct HasSnapshotLeaksVisitor {
8+
universe: ty::UniverseIndex,
9+
variable_lengths: VariableLengths,
10+
}
11+
impl HasSnapshotLeaksVisitor {
12+
pub fn new<'tcx>(infcx: &InferCtxt<'tcx>) -> Self {
13+
HasSnapshotLeaksVisitor {
14+
universe: infcx.universe(),
15+
variable_lengths: infcx.variable_lengths(),
16+
}
17+
}
18+
}
19+
20+
fn continue_if(b: bool) -> ControlFlow<()> {
21+
if b { ControlFlow::Continue(()) } else { ControlFlow::Break(()) }
22+
}
23+
24+
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasSnapshotLeaksVisitor {
25+
type Result = ControlFlow<()>;
26+
27+
fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result {
28+
match r.kind() {
29+
ty::ReVar(var) => continue_if(var.as_usize() < self.variable_lengths.region_vars),
30+
ty::RePlaceholder(p) => continue_if(self.universe.can_name(p.universe)),
31+
ty::ReEarlyParam(_)
32+
| ty::ReBound(_, _)
33+
| ty::ReLateParam(_)
34+
| ty::ReStatic
35+
| ty::ReErased
36+
| ty::ReError(_) => ControlFlow::Continue(()),
37+
}
38+
}
39+
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
40+
match t.kind() {
41+
ty::Infer(ty::TyVar(var)) => {
42+
continue_if(var.as_usize() < self.variable_lengths.type_vars)
43+
}
44+
ty::Infer(ty::IntVar(var)) => {
45+
continue_if(var.as_usize() < self.variable_lengths.int_vars)
46+
}
47+
ty::Infer(ty::FloatVar(var)) => {
48+
continue_if(var.as_usize() < self.variable_lengths.float_vars)
49+
}
50+
ty::Placeholder(p) => continue_if(self.universe.can_name(p.universe)),
51+
ty::Infer(ty::FreshTy(..) | ty::FreshIntTy(..) | ty::FreshFloatTy(..))
52+
| ty::Bool
53+
| ty::Char
54+
| ty::Int(_)
55+
| ty::Uint(_)
56+
| ty::Float(_)
57+
| ty::Adt(_, _)
58+
| ty::Foreign(_)
59+
| ty::Str
60+
| ty::Array(_, _)
61+
| ty::Slice(_)
62+
| ty::RawPtr(_)
63+
| ty::Ref(_, _, _)
64+
| ty::FnDef(_, _)
65+
| ty::FnPtr(_)
66+
| ty::Dynamic(_, _, _)
67+
| ty::Closure(_, _)
68+
| ty::CoroutineClosure(_, _)
69+
| ty::Coroutine(_, _)
70+
| ty::CoroutineWitness(_, _)
71+
| ty::Never
72+
| ty::Tuple(_)
73+
| ty::Alias(_, _)
74+
| ty::Param(_)
75+
| ty::Bound(_, _)
76+
| ty::Error(_) => t.super_visit_with(self),
77+
}
78+
}
79+
fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
80+
match c.kind() {
81+
ty::ConstKind::Infer(ty::InferConst::Var(var)) => {
82+
continue_if(var.as_usize() < self.variable_lengths.const_vars)
83+
}
84+
// FIXME(const_trait_impl): need to handle effect vars here and in `fudge_inference_if_ok`.
85+
ty::ConstKind::Infer(ty::InferConst::EffectVar(_)) => ControlFlow::Continue(()),
86+
ty::ConstKind::Placeholder(p) => continue_if(self.universe.can_name(p.universe)),
87+
ty::ConstKind::Infer(ty::InferConst::Fresh(_))
88+
| ty::ConstKind::Param(_)
89+
| ty::ConstKind::Bound(_, _)
90+
| ty::ConstKind::Unevaluated(_)
91+
| ty::ConstKind::Value(_)
92+
| ty::ConstKind::Expr(_)
93+
| ty::ConstKind::Error(_) => c.super_visit_with(self),
94+
}
95+
}
96+
}
97+
98+
#[macro_export]
99+
macro_rules! type_foldable_verify_no_snapshot_leaks {
100+
($tcx:lifetime, $t:ty) => {
101+
const _: () = {
102+
use rustc_middle::ty::TypeVisitable;
103+
use $crate::infer::snapshot::check_leaks::HasSnapshotLeaksVisitor;
104+
use $crate::infer::InferCtxt;
105+
impl<$tcx> $crate::infer::snapshot::NoSnapshotLeaks<$tcx> for $t {
106+
type DataStart = HasSnapshotLeaksVisitor;
107+
type DataEnd = HasSnapshotLeaksVisitor;
108+
fn mk_data_snapshot_start(infcx: &$crate::infer::InferCtxt<$tcx>) -> Self::DataStart {
109+
HasSnapshotLeaksVisitor::new(infcx)
110+
}
111+
fn mk_data_snapshot_end(
112+
_: &InferCtxt<'tcx>,
113+
visitor: Self::DataStart,
114+
) -> Self::DataEnd {
115+
visitor
116+
}
117+
fn avoid_leaks(
118+
self,
119+
_: &InferCtxt<$tcx>,
120+
mut visitor: HasSnapshotLeaksVisitor,
121+
) -> Self {
122+
if cfg!(debug_assertions) && self.visit_with(&mut visitor).is_break() {
123+
bug!("leaking vars from snapshot: {self:?}");
124+
}
125+
126+
self
127+
}
128+
}
129+
};
130+
};
131+
}

compiler/rustc_infer/src/infer/snapshot/mod.rs

Lines changed: 4 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
use std::ops::ControlFlow;
2-
31
use super::region_constraints::RegionSnapshot;
42
use super::InferCtxt;
53
use rustc_data_structures::undo_log::UndoLogs;
6-
use rustc_middle::ty::TypeSuperVisitable;
7-
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
4+
use rustc_middle::ty;
85

6+
pub mod check_leaks;
97
mod fudge;
108
pub(crate) mod undo_log;
119

@@ -149,10 +147,6 @@ pub trait NoSnapshotLeaks<'tcx> {
149147
}
150148

151149
pub trait TrivialNoSnapshotLeaks<'tcx> {}
152-
pub struct NoLeaksUnchecked<T> {
153-
pub value: T,
154-
}
155-
impl<'tcx, T> TrivialNoSnapshotLeaks<'tcx> for NoLeaksUnchecked<T> {}
156150
impl<'tcx, T: TrivialNoSnapshotLeaks<'tcx>> NoSnapshotLeaks<'tcx> for T {
157151
type DataStart = ();
158152
type DataEnd = ();
@@ -163,97 +157,6 @@ impl<'tcx, T: TrivialNoSnapshotLeaks<'tcx>> NoSnapshotLeaks<'tcx> for T {
163157
}
164158
}
165159

166-
pub struct HasSnapshotLeaksVisitor {
167-
universe: ty::UniverseIndex,
168-
variable_lengths: VariableLengths,
169-
}
170-
impl HasSnapshotLeaksVisitor {
171-
pub fn new<'tcx>(infcx: &InferCtxt<'tcx>) -> Self {
172-
HasSnapshotLeaksVisitor {
173-
universe: infcx.universe(),
174-
variable_lengths: infcx.variable_lengths(),
175-
}
176-
}
177-
}
178-
179-
fn continue_if(b: bool) -> ControlFlow<()> {
180-
if b { ControlFlow::Continue(()) } else { ControlFlow::Break(()) }
181-
}
182-
183-
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasSnapshotLeaksVisitor {
184-
type Result = ControlFlow<()>;
185-
186-
fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result {
187-
match r.kind() {
188-
ty::ReVar(var) => continue_if(var.as_usize() < self.variable_lengths.region_vars),
189-
ty::RePlaceholder(p) => continue_if(self.universe.can_name(p.universe)),
190-
ty::ReEarlyParam(_)
191-
| ty::ReBound(_, _)
192-
| ty::ReLateParam(_)
193-
| ty::ReStatic
194-
| ty::ReErased
195-
| ty::ReError(_) => ControlFlow::Continue(()),
196-
}
197-
}
198-
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
199-
match t.kind() {
200-
ty::Infer(ty::TyVar(var)) => {
201-
continue_if(var.as_usize() < self.variable_lengths.type_vars)
202-
}
203-
ty::Infer(ty::IntVar(var)) => {
204-
continue_if(var.as_usize() < self.variable_lengths.int_vars)
205-
}
206-
ty::Infer(ty::FloatVar(var)) => {
207-
continue_if(var.as_usize() < self.variable_lengths.float_vars)
208-
}
209-
ty::Placeholder(p) => continue_if(self.universe.can_name(p.universe)),
210-
ty::Infer(ty::FreshTy(..) | ty::FreshIntTy(..) | ty::FreshFloatTy(..))
211-
| ty::Bool
212-
| ty::Char
213-
| ty::Int(_)
214-
| ty::Uint(_)
215-
| ty::Float(_)
216-
| ty::Adt(_, _)
217-
| ty::Foreign(_)
218-
| ty::Str
219-
| ty::Array(_, _)
220-
| ty::Slice(_)
221-
| ty::RawPtr(_)
222-
| ty::Ref(_, _, _)
223-
| ty::FnDef(_, _)
224-
| ty::FnPtr(_)
225-
| ty::Dynamic(_, _, _)
226-
| ty::Closure(_, _)
227-
| ty::CoroutineClosure(_, _)
228-
| ty::Coroutine(_, _)
229-
| ty::CoroutineWitness(_, _)
230-
| ty::Never
231-
| ty::Tuple(_)
232-
| ty::Alias(_, _)
233-
| ty::Param(_)
234-
| ty::Bound(_, _)
235-
| ty::Error(_) => t.super_visit_with(self),
236-
}
237-
}
238-
fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
239-
match c.kind() {
240-
ty::ConstKind::Infer(ty::InferConst::Var(var)) => {
241-
continue_if(var.as_usize() < self.variable_lengths.const_vars)
242-
}
243-
// FIXME(const_trait_impl): need to handle effect vars here and in `fudge_inference_if_ok`.
244-
ty::ConstKind::Infer(ty::InferConst::EffectVar(_)) => ControlFlow::Continue(()),
245-
ty::ConstKind::Placeholder(p) => continue_if(self.universe.can_name(p.universe)),
246-
ty::ConstKind::Infer(ty::InferConst::Fresh(_))
247-
| ty::ConstKind::Param(_)
248-
| ty::ConstKind::Bound(_, _)
249-
| ty::ConstKind::Unevaluated(_)
250-
| ty::ConstKind::Value(_)
251-
| ty::ConstKind::Expr(_)
252-
| ty::ConstKind::Error(_) => c.super_visit_with(self),
253-
}
254-
}
255-
}
256-
257160
#[macro_export]
258161
macro_rules! trivial_no_snapshot_leaks {
259162
($tcx:lifetime, $t:ty) => {
@@ -274,47 +177,13 @@ macro_rules! trivial_no_snapshot_leaks {
274177
};
275178
}
276179

277-
#[macro_export]
278-
macro_rules! type_foldable_verify_no_snapshot_leaks {
279-
($tcx:lifetime, $t:ty) => {
280-
const _: () = {
281-
use rustc_middle::ty::TypeVisitable;
282-
use $crate::infer::snapshot::HasSnapshotLeaksVisitor;
283-
use $crate::infer::InferCtxt;
284-
impl<$tcx> $crate::infer::snapshot::NoSnapshotLeaks<$tcx> for $t {
285-
type DataStart = HasSnapshotLeaksVisitor;
286-
type DataEnd = HasSnapshotLeaksVisitor;
287-
fn mk_data_snapshot_start(infcx: &$crate::infer::InferCtxt<$tcx>) -> Self::Data {
288-
HasSnapshotLeaksVisitor::new(infcx)
289-
}
290-
fn mk_data_snapshot_end(
291-
_: &InferCtxt<'tcx>,
292-
visitor: Self::DataStart,
293-
) -> Self::DataEnd {
294-
visitor
295-
}
296-
fn avoid_leaks(
297-
self,
298-
_: InferCtxt<$tcx>,
299-
&visitor: HasSnapshotLeaksVisitor,
300-
) -> Self {
301-
if cfg!(debug_assertions) && self.visit_with(&mut visitor) {
302-
bug!("leaking vars from snapshot: {self:?}");
303-
}
304-
305-
self
306-
}
307-
}
308-
};
309-
};
310-
}
311-
312180
mod impls {
313181
use super::{NoSnapshotLeaks, TrivialNoSnapshotLeaks};
314182
use crate::fudge_vars_no_snapshot_leaks;
315183
use crate::infer::InferCtxt;
316184
use crate::traits::solve::{CanonicalResponse, Certainty};
317185
use crate::traits::MismatchedProjectionTypes;
186+
use crate::type_foldable_verify_no_snapshot_leaks;
318187
use rustc_hir::def_id::DefId;
319188
use rustc_middle::infer::canonical::Canonical;
320189
use rustc_middle::traits::query::{MethodAutoderefStepsResult, NoSolution};
@@ -339,6 +208,7 @@ mod impls {
339208
trivial_no_snapshot_leaks!('tcx, (bool, Certainty));
340209
// FIXME(#122188): This is wrong, this can leak inference vars in `opt_bad_ty` and `steps`.
341210
trivial_no_snapshot_leaks!('tcx, MethodAutoderefStepsResult<'tcx>);
211+
type_foldable_verify_no_snapshot_leaks!('tcx, ty::PolyFnSig<'tcx>);
342212
fudge_vars_no_snapshot_leaks!('tcx, TypeError<'tcx>);
343213
fudge_vars_no_snapshot_leaks!('tcx, MismatchedProjectionTypes<'tcx>);
344214

0 commit comments

Comments
 (0)