1use std::convert::Infallible;
49use std::mem;
50use std::sync::Arc;
51
52use rustc_index::{Idx, IndexVec};
53use thin_vec::ThinVec;
54use tracing::{debug, instrument};
55
56use crate::inherent::*;
57use crate::visit::{TypeVisitable, TypeVisitableExt as _};
58use crate::{self as ty, BoundVarIndexKind, Interner, Region};
59
60pub trait TypeFoldable<I: Interner>: TypeVisitable<I> + Clone {
72 fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error>;
83
84 fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self;
98}
99
100pub trait TypeSuperFoldable<I: Interner>: TypeFoldable<I> {
102 fn try_super_fold_with<F: FallibleTypeFolder<I>>(
109 self,
110 folder: &mut F,
111 ) -> Result<Self, F::Error>;
112
113 fn super_fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self;
117}
118
119pub trait TypeFolder<I: Interner>: Sized {
125 fn cx(&self) -> I;
126
127 fn fold_binder<T>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T>
128 where
129 T: TypeFoldable<I>,
130 {
131 t.super_fold_with(self)
132 }
133
134 fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
135 t.super_fold_with(self)
136 }
137
138 fn fold_region(&mut self, r: Region<I>) -> Region<I> {
141 r
142 }
143
144 fn fold_const(&mut self, c: I::Const) -> I::Const {
145 c.super_fold_with(self)
146 }
147
148 fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
149 p.super_fold_with(self)
150 }
151
152 fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses {
153 c.super_fold_with(self)
154 }
155}
156
157pub trait FallibleTypeFolder<I: Interner>: Sized {
165 type Error;
166
167 fn cx(&self) -> I;
168
169 fn try_fold_binder<T>(&mut self, t: ty::Binder<I, T>) -> Result<ty::Binder<I, T>, Self::Error>
170 where
171 T: TypeFoldable<I>,
172 {
173 t.try_super_fold_with(self)
174 }
175
176 fn try_fold_ty(&mut self, t: I::Ty) -> Result<I::Ty, Self::Error> {
177 t.try_super_fold_with(self)
178 }
179
180 fn try_fold_region(&mut self, r: Region<I>) -> Result<Region<I>, Self::Error> {
183 Ok(r)
184 }
185
186 fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, Self::Error> {
187 c.try_super_fold_with(self)
188 }
189
190 fn try_fold_predicate(&mut self, p: I::Predicate) -> Result<I::Predicate, Self::Error> {
191 p.try_super_fold_with(self)
192 }
193
194 fn try_fold_clauses(&mut self, c: I::Clauses) -> Result<I::Clauses, Self::Error> {
195 c.try_super_fold_with(self)
196 }
197}
198
199impl<I: Interner, T: TypeFoldable<I>, U: TypeFoldable<I>> TypeFoldable<I> for (T, U) {
203 fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<(T, U), F::Error> {
204 Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?))
205 }
206
207 fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
208 (self.0.fold_with(folder), self.1.fold_with(folder))
209 }
210}
211
212impl<I: Interner, A: TypeFoldable<I>, B: TypeFoldable<I>, C: TypeFoldable<I>> TypeFoldable<I>
213 for (A, B, C)
214{
215 fn try_fold_with<F: FallibleTypeFolder<I>>(
216 self,
217 folder: &mut F,
218 ) -> Result<(A, B, C), F::Error> {
219 Ok((
220 self.0.try_fold_with(folder)?,
221 self.1.try_fold_with(folder)?,
222 self.2.try_fold_with(folder)?,
223 ))
224 }
225
226 fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
227 (self.0.fold_with(folder), self.1.fold_with(folder), self.2.fold_with(folder))
228 }
229}
230
231impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Option<T> {
232 fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
233 Ok(match self {
234 Some(v) => Some(v.try_fold_with(folder)?),
235 None => None,
236 })
237 }
238
239 fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
240 Some(self?.fold_with(folder))
241 }
242}
243
244impl<I: Interner, T: TypeFoldable<I>, E: TypeFoldable<I>> TypeFoldable<I> for Result<T, E> {
245 fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
246 Ok(match self {
247 Ok(v) => Ok(v.try_fold_with(folder)?),
248 Err(e) => Err(e.try_fold_with(folder)?),
249 })
250 }
251
252 fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
253 match self {
254 Ok(v) => Ok(v.fold_with(folder)),
255 Err(e) => Err(e.fold_with(folder)),
256 }
257 }
258}
259
260fn fold_arc<T: Clone, E>(
261 mut arc: Arc<T>,
262 fold: impl FnOnce(T) -> Result<T, E>,
263) -> Result<Arc<T>, E> {
264 unsafe {
268 Arc::make_mut(&mut arc);
274
275 let ptr = Arc::into_raw(arc).cast::<mem::ManuallyDrop<T>>();
278 let mut unique = Arc::from_raw(ptr);
279
280 let slot = Arc::get_mut(&mut unique).unwrap_unchecked();
284
285 let owned = mem::ManuallyDrop::take(slot);
290 let folded = fold(owned)?;
291 *slot = mem::ManuallyDrop::new(folded);
292
293 Ok(Arc::from_raw(Arc::into_raw(unique).cast()))
295 }
296}
297
298impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Arc<T> {
299 fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
300 fold_arc(self, |t| t.try_fold_with(folder))
301 }
302
303 fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
304 match fold_arc::<T, Infallible>(self, |t| Ok(t.fold_with(folder))) {
305 Ok(t) => t,
306 }
307 }
308}
309
310impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Box<T> {
311 fn try_fold_with<F: FallibleTypeFolder<I>>(mut self, folder: &mut F) -> Result<Self, F::Error> {
312 *self = (*self).try_fold_with(folder)?;
313 Ok(self)
314 }
315
316 fn fold_with<F: TypeFolder<I>>(mut self, folder: &mut F) -> Self {
317 *self = (*self).fold_with(folder);
318 self
319 }
320}
321
322impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Vec<T> {
323 fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
324 self.into_iter().map(|t| t.try_fold_with(folder)).collect()
325 }
326
327 fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
328 self.into_iter().map(|t| t.fold_with(folder)).collect()
329 }
330}
331
332impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for ThinVec<T> {
333 fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
334 self.into_iter().map(|t| t.try_fold_with(folder)).collect()
335 }
336
337 fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
338 self.into_iter().map(|t| t.fold_with(folder)).collect()
339 }
340}
341
342impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Box<[T]> {
343 fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
344 Vec::from(self).try_fold_with(folder).map(Vec::into_boxed_slice)
345 }
346
347 fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
348 Vec::into_boxed_slice(Vec::from(self).fold_with(folder))
349 }
350}
351
352impl<I: Interner, T: TypeFoldable<I>, Ix: Idx> TypeFoldable<I> for IndexVec<Ix, T> {
353 fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
354 self.raw.try_fold_with(folder).map(IndexVec::from_raw)
355 }
356
357 fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
358 IndexVec::from_raw(self.raw.fold_with(folder))
359 }
360}
361
362struct Shifter<I: Interner> {
372 cx: I,
373 current_index: ty::DebruijnIndex,
374 amount: u32,
375}
376
377impl<I: Interner> Shifter<I> {
378 fn new(cx: I, amount: u32) -> Self {
379 Shifter { cx, current_index: ty::INNERMOST, amount }
380 }
381}
382
383impl<I: Interner> TypeFolder<I> for Shifter<I> {
384 fn cx(&self) -> I {
385 self.cx
386 }
387
388 fn fold_binder<T: TypeFoldable<I>>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T> {
389 self.current_index.shift_in(1);
390 let t = t.super_fold_with(self);
391 self.current_index.shift_out(1);
392 t
393 }
394
395 fn fold_region(&mut self, r: Region<I>) -> Region<I> {
396 match r.kind() {
397 ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br)
398 if debruijn >= self.current_index =>
399 {
400 let debruijn = debruijn.shifted_in(self.amount);
401 Region::new_bound(self.cx, debruijn, br)
402 }
403 _ => r,
404 }
405 }
406
407 fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
408 match ty.kind() {
409 ty::Bound(BoundVarIndexKind::Bound(debruijn), bound_ty)
410 if debruijn >= self.current_index =>
411 {
412 let debruijn = debruijn.shifted_in(self.amount);
413 Ty::new_bound(self.cx, debruijn, bound_ty)
414 }
415
416 _ if ty.has_vars_bound_at_or_above(self.current_index) => ty.super_fold_with(self),
417 _ => ty,
418 }
419 }
420
421 fn fold_const(&mut self, ct: I::Const) -> I::Const {
422 match ct.kind() {
423 ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_ct)
424 if debruijn >= self.current_index =>
425 {
426 let debruijn = debruijn.shifted_in(self.amount);
427 Const::new_bound(self.cx, debruijn, bound_ct)
428 }
429 _ => ct.super_fold_with(self),
430 }
431 }
432
433 fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
434 if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p }
435 }
436
437 fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses {
438 if c.has_vars_bound_at_or_above(self.current_index) { c.super_fold_with(self) } else { c }
439 }
440}
441
442pub fn shift_region<I: Interner>(cx: I, region: Region<I>, amount: u32) -> Region<I> {
443 match region.kind() {
444 ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br) if amount > 0 => {
445 Region::new_bound(cx, debruijn.shifted_in(amount), br)
446 }
447 _ => region,
448 }
449}
450
451{}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() || { false }
{
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("shift_vars",
"rustc_type_ir::fold", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5a2be9f5f075d31e3ca5526b5b029881ce441253/compiler/rustc_type_ir/src/fold.rs"),
::tracing_core::__macro_support::Option::Some(451u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::fold"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("value")
}> =
::tracing::__macro_support::FieldName::new("value");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("amount")
}> =
::tracing::__macro_support::FieldName::new("amount");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&value)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&amount as
&dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: T = loop {};
return __tracing_attr_fake_return;
}
{
if amount == 0 || !value.has_escaping_bound_vars() {
value
} else { value.fold_with(&mut Shifter::new(cx, amount)) }
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5a2be9f5f075d31e3ca5526b5b029881ce441253/compiler/rustc_type_ir/src/fold.rs:451",
"rustc_type_ir::fold", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5a2be9f5f075d31e3ca5526b5b029881ce441253/compiler/rustc_type_ir/src/fold.rs"),
::tracing_core::__macro_support::Option::Some(451u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::fold"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(level = "trace", skip(cx), ret)]
452pub fn shift_vars<I: Interner, T>(cx: I, value: T, amount: u32) -> T
453where
454 T: TypeFoldable<I>,
455{
456 if amount == 0 || !value.has_escaping_bound_vars() {
457 value
458 } else {
459 value.fold_with(&mut Shifter::new(cx, amount))
460 }
461}
462
463pub fn fold_regions<I: Interner, T>(
467 cx: I,
468 value: T,
469 f: impl FnMut(Region<I>, ty::DebruijnIndex) -> Region<I>,
470) -> T
471where
472 T: TypeFoldable<I>,
473{
474 value.fold_with(&mut RegionFolder::new(cx, f))
475}
476
477pub struct RegionFolder<I, F> {
485 cx: I,
486
487 current_index: ty::DebruijnIndex,
491
492 fold_region_fn: F,
496}
497
498impl<I, F> RegionFolder<I, F> {
499 #[inline]
500 pub fn new(cx: I, fold_region_fn: F) -> RegionFolder<I, F> {
501 RegionFolder { cx, current_index: ty::INNERMOST, fold_region_fn }
502 }
503}
504
505impl<I, F> TypeFolder<I> for RegionFolder<I, F>
506where
507 I: Interner,
508 F: FnMut(Region<I>, ty::DebruijnIndex) -> Region<I>,
509{
510 fn cx(&self) -> I {
511 self.cx
512 }
513
514 fn fold_binder<T: TypeFoldable<I>>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T> {
515 self.current_index.shift_in(1);
516 let t = t.super_fold_with(self);
517 self.current_index.shift_out(1);
518 t
519 }
520
521 {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() || { false }
{
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("fold_region",
"rustc_type_ir::fold", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5a2be9f5f075d31e3ca5526b5b029881ce441253/compiler/rustc_type_ir/src/fold.rs"),
::tracing_core::__macro_support::Option::Some(521u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::fold"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("r")
}> =
::tracing::__macro_support::FieldName::new("r");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&r)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Region<I> = loop {};
return __tracing_attr_fake_return;
}
{
match r.kind() {
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) if
debruijn < self.current_index => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5a2be9f5f075d31e3ca5526b5b029881ce441253/compiler/rustc_type_ir/src/fold.rs:527",
"rustc_type_ir::fold", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5a2be9f5f075d31e3ca5526b5b029881ce441253/compiler/rustc_type_ir/src/fold.rs"),
::tracing_core::__macro_support::Option::Some(527u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::fold"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("self.current_index")
}> =
::tracing::__macro_support::FieldName::new("self.current_index");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("skipped bound region")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&self.current_index)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
r
}
ty::ReBound(ty::BoundVarIndexKind::Canonical, _) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5a2be9f5f075d31e3ca5526b5b029881ce441253/compiler/rustc_type_ir/src/fold.rs:531",
"rustc_type_ir::fold", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5a2be9f5f075d31e3ca5526b5b029881ce441253/compiler/rustc_type_ir/src/fold.rs"),
::tracing_core::__macro_support::Option::Some(531u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::fold"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("self.current_index")
}> =
::tracing::__macro_support::FieldName::new("self.current_index");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("skipped bound region")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&self.current_index)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
r
}
_ => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5a2be9f5f075d31e3ca5526b5b029881ce441253/compiler/rustc_type_ir/src/fold.rs:535",
"rustc_type_ir::fold", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5a2be9f5f075d31e3ca5526b5b029881ce441253/compiler/rustc_type_ir/src/fold.rs"),
::tracing_core::__macro_support::Option::Some(535u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::fold"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("self.current_index")
}> =
::tracing::__macro_support::FieldName::new("self.current_index");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("folding free region")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&self.current_index)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
(self.fold_region_fn)(r, self.current_index)
}
}
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5a2be9f5f075d31e3ca5526b5b029881ce441253/compiler/rustc_type_ir/src/fold.rs:521",
"rustc_type_ir::fold", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5a2be9f5f075d31e3ca5526b5b029881ce441253/compiler/rustc_type_ir/src/fold.rs"),
::tracing_core::__macro_support::Option::Some(521u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::fold"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(skip(self), level = "debug", ret)]
522 fn fold_region(&mut self, r: Region<I>) -> Region<I> {
523 match r.kind() {
524 ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _)
525 if debruijn < self.current_index =>
526 {
527 debug!(?self.current_index, "skipped bound region");
528 r
529 }
530 ty::ReBound(ty::BoundVarIndexKind::Canonical, _) => {
531 debug!(?self.current_index, "skipped bound region");
532 r
533 }
534 _ => {
535 debug!(?self.current_index, "folding free region");
536 (self.fold_region_fn)(r, self.current_index)
537 }
538 }
539 }
540
541 fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
542 if t.has_regions() { t.super_fold_with(self) } else { t }
543 }
544
545 fn fold_const(&mut self, ct: I::Const) -> I::Const {
546 if ct.has_regions() { ct.super_fold_with(self) } else { ct }
547 }
548
549 fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
550 if p.has_regions() { p.super_fold_with(self) } else { p }
551 }
552
553 fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses {
554 if c.has_regions() { c.super_fold_with(self) } else { c }
555 }
556}
557
558pub fn set_aliases_to_non_rigid<I: Interner, T>(cx: I, value: T) -> ty::Unnormalized<I, T>
565where
566 T: TypeFoldable<I>,
567{
568 let folded = set_aliases_rigidness_with_mode(cx, value, RigidnessFoldMode::AllToNonRigid);
569 ty::Unnormalized::new(folded)
570}
571
572pub fn set_opaques_to_non_rigid<I: Interner, T>(cx: I, value: T) -> ty::Unnormalized<I, T>
573where
574 T: TypeFoldable<I>,
575{
576 let folded = set_aliases_rigidness_with_mode(cx, value, RigidnessFoldMode::OpaqueToNonRigid);
577 ty::Unnormalized::new(folded)
578}
579
580pub fn set_aliases_to_rigid<I: Interner, T>(cx: I, value: T) -> T
581where
582 T: TypeFoldable<I>,
583{
584 set_aliases_rigidness_with_mode(cx, value, RigidnessFoldMode::AllToRigid)
585}
586
587pub fn set_type_aliases_to_rigid<I: Interner, T>(cx: I, value: T) -> T
588where
589 T: TypeFoldable<I>,
590{
591 set_aliases_rigidness_with_mode(cx, value, RigidnessFoldMode::TypeToRigid)
592}
593
594fn set_aliases_rigidness_with_mode<I: Interner, T>(cx: I, value: T, mode: RigidnessFoldMode) -> T
595where
596 T: TypeFoldable<I>,
597{
598 if !mode.needs_change(&value) {
599 return value;
600 }
601
602 let mut folder = RigidnessFolder { cx, mode };
603 value.fold_with(&mut folder)
604}
605
606enum RigidnessFoldMode {
607 AllToRigid,
608 AllToNonRigid,
609 TypeToRigid,
610 OpaqueToNonRigid,
611}
612
613impl RigidnessFoldMode {
614 fn needs_change<I: Interner, T: TypeVisitable<I>>(&self, v: &T) -> bool {
615 match self {
616 RigidnessFoldMode::AllToRigid => v.has_non_rigid_aliases(),
617 RigidnessFoldMode::AllToNonRigid => v.has_rigid_aliases(),
618 RigidnessFoldMode::TypeToRigid => {
619 v.has_non_rigid_aliases()
620 && v.has_type_flags(ty::TypeFlags::HAS_ALIAS - ty::TypeFlags::HAS_CONST_ALIAS)
621 }
622 RigidnessFoldMode::OpaqueToNonRigid => v.has_rigid_aliases() && v.has_opaque_types(),
623 }
624 }
625}
626
627struct RigidnessFolder<I: Interner> {
629 cx: I,
630 mode: RigidnessFoldMode,
631}
632
633impl<I: Interner> TypeFolder<I> for RigidnessFolder<I> {
634 #[inline]
635 fn cx(&self) -> I {
636 self.cx
637 }
638
639 fn fold_binder<T: TypeFoldable<I>>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T> {
640 if self.mode.needs_change(&t) { t.super_fold_with(self) } else { t }
641 }
642
643 fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
644 if !self.mode.needs_change(&t) {
645 return t;
646 }
647
648 match t.kind() {
649 ty::Alias(is_rigid, alias_ty) => {
650 let alias_ty = alias_ty.fold_with(self);
651 match self.mode {
652 RigidnessFoldMode::AllToRigid | RigidnessFoldMode::TypeToRigid => {
653 I::Ty::new_alias(self.cx(), ty::IsRigid::Yes, alias_ty)
654 }
655 RigidnessFoldMode::AllToNonRigid => {
656 I::Ty::new_alias(self.cx(), ty::IsRigid::No, alias_ty)
657 }
658 RigidnessFoldMode::OpaqueToNonRigid => {
659 if let ty::AliasTyKind::Opaque { .. } = alias_ty.kind {
660 I::Ty::new_alias(self.cx(), ty::IsRigid::No, alias_ty)
661 } else {
662 I::Ty::new_alias(self.cx(), is_rigid, alias_ty)
663 }
664 }
665 }
666 }
667 _ => t.super_fold_with(self),
668 }
669 }
670
671 fn fold_const(&mut self, c: I::Const) -> I::Const {
672 if !self.mode.needs_change(&c) {
673 return c;
674 }
675
676 match c.kind() {
677 ty::ConstKind::Alias(is_rigid, alias_const) => {
678 let alias_const = alias_const.fold_with(self);
679 match self.mode {
680 RigidnessFoldMode::AllToRigid => {
681 I::Const::new_alias(self.cx, ty::IsRigid::Yes, alias_const)
682 }
683 RigidnessFoldMode::AllToNonRigid => {
684 I::Const::new_alias(self.cx(), ty::IsRigid::No, alias_const)
685 }
686 RigidnessFoldMode::OpaqueToNonRigid | RigidnessFoldMode::TypeToRigid => {
687 I::Const::new_alias(self.cx(), is_rigid, alias_const)
688 }
689 }
690 }
691 _ => c.super_fold_with(self),
692 }
693 }
694
695 fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
696 if self.mode.needs_change(&p) { p.super_fold_with(self) } else { p }
697 }
698
699 fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses {
700 if self.mode.needs_change(&c) { c.super_fold_with(self) } else { c }
701 }
702}