]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/ty/structural_impls.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / compiler / rustc_middle / src / ty / structural_impls.rs
CommitLineData
ff7c6d11
XL
1//! This module contains implements of the `Lift` and `TypeFoldable`
2//! traits for various types in the Rust compiler. Most are written by
60c5eb7d 3//! hand, though we've recently added some macros and proc-macros to help with the tedium.
ff7c6d11 4
60c5eb7d 5use crate::mir::interpret;
f2b60f7d 6use crate::mir::{Field, ProjectionKind};
064997fb 7use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
1b1a35ee 8use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
064997fb 9use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
9c376795 10use crate::ty::{self, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
fc512014 11use rustc_data_structures::functor::IdFunctor;
dfeec247 12use rustc_hir::def::Namespace;
dfeec247 13use rustc_index::vec::{Idx, IndexVec};
60c5eb7d 14
532ac7d7 15use std::fmt;
a2a8927a 16use std::mem::ManuallyDrop;
29967ef6 17use std::ops::ControlFlow;
e9174d1e 18use std::rc::Rc;
dc9dc135 19use std::sync::Arc;
532ac7d7
XL
20
21impl fmt::Debug for ty::TraitDef {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 ty::tls::with(|tcx| {
5e7ed085
FG
24 with_no_trimmed_paths!({
25 f.write_str(
26 &FmtPrinter::new(tcx, Namespace::TypeNS)
27 .print_def_path(self.def_id, &[])?
28 .into_buffer(),
29 )
30 })
532ac7d7
XL
31 })
32 }
33}
34
5e7ed085 35impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> {
532ac7d7
XL
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 ty::tls::with(|tcx| {
5e7ed085
FG
38 with_no_trimmed_paths!({
39 f.write_str(
40 &FmtPrinter::new(tcx, Namespace::TypeNS)
41 .print_def_path(self.did(), &[])?
42 .into_buffer(),
43 )
44 })
532ac7d7
XL
45 })
46 }
47}
48
532ac7d7
XL
49impl fmt::Debug for ty::UpvarId {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
dfeec247
XL
51 let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id));
52 write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id)
532ac7d7
XL
53 }
54}
55
a2a8927a 56impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> {
532ac7d7 57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5e7ed085 58 with_no_trimmed_paths!(fmt::Display::fmt(self, f))
532ac7d7
XL
59 }
60}
61
a2a8927a 62impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> {
532ac7d7
XL
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 write!(f, "{:?} -> {}", self.kind, self.target)
65 }
66}
67
fc512014 68impl fmt::Debug for ty::BoundRegionKind {
532ac7d7
XL
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 match *self {
487cf647 71 ty::BrAnon(n, span) => write!(f, "BrAnon({n:?}, {span:?})"),
532ac7d7 72 ty::BrNamed(did, name) => {
04454e1e 73 if did.is_crate_root() {
60c5eb7d
XL
74 write!(f, "BrNamed({})", name)
75 } else {
76 write!(f, "BrNamed({:?}, {})", did, name)
77 }
532ac7d7
XL
78 }
79 ty::BrEnv => write!(f, "BrEnv"),
80 }
81 }
82}
83
532ac7d7
XL
84impl fmt::Debug for ty::FreeRegion {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region)
87 }
88}
89
a2a8927a 90impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
532ac7d7 91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
dfeec247 92 write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output())
532ac7d7
XL
93 }
94}
95
532ac7d7
XL
96impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 write!(f, "_#{}c", self.index)
99 }
100}
101
a2a8927a 102impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
532ac7d7 103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5e7ed085 104 with_no_trimmed_paths!(fmt::Display::fmt(self, f))
532ac7d7
XL
105 }
106}
107
a2a8927a 108impl<'tcx> fmt::Debug for Ty<'tcx> {
532ac7d7 109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5e7ed085 110 with_no_trimmed_paths!(fmt::Display::fmt(self, f))
532ac7d7
XL
111 }
112}
113
114impl fmt::Debug for ty::ParamTy {
115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48663c56 116 write!(f, "{}/#{}", self.name, self.index)
532ac7d7
XL
117 }
118}
119
120impl fmt::Debug for ty::ParamConst {
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 write!(f, "{}/#{}", self.name, self.index)
123 }
124}
125
a2a8927a 126impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
532ac7d7 127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94222f64
XL
128 if let ty::BoundConstness::ConstIfConst = self.constness {
129 write!(f, "~const ")?;
130 }
3c0e092e 131 write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)
532ac7d7
XL
132 }
133}
134
a2a8927a 135impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
532ac7d7 136 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5099ac24 137 write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term)
532ac7d7
XL
138 }
139}
140
a2a8927a 141impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
f9f354fc
XL
142 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143 write!(f, "{:?}", self.kind())
144 }
145}
146
487cf647
FG
147impl<'tcx> fmt::Debug for ty::Clause<'tcx> {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149 match *self {
150 ty::Clause::Trait(ref a) => a.fmt(f),
151 ty::Clause::RegionOutlives(ref pair) => pair.fmt(f),
152 ty::Clause::TypeOutlives(ref pair) => pair.fmt(f),
153 ty::Clause::Projection(ref pair) => pair.fmt(f),
154 }
155 }
156}
157
a2a8927a 158impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> {
532ac7d7
XL
159 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160 match *self {
487cf647 161 ty::PredicateKind::Clause(ref a) => a.fmt(f),
5869c6ff 162 ty::PredicateKind::Subtype(ref pair) => pair.fmt(f),
94222f64 163 ty::PredicateKind::Coerce(ref pair) => pair.fmt(f),
5869c6ff
XL
164 ty::PredicateKind::WellFormed(data) => write!(f, "WellFormed({:?})", data),
165 ty::PredicateKind::ObjectSafe(trait_def_id) => {
f9f354fc
XL
166 write!(f, "ObjectSafe({:?})", trait_def_id)
167 }
5869c6ff 168 ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
dfeec247 169 write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind)
532ac7d7 170 }
2b03887a
FG
171 ty::PredicateKind::ConstEvaluatable(ct) => {
172 write!(f, "ConstEvaluatable({ct:?})")
532ac7d7 173 }
5869c6ff
XL
174 ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
175 ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
1b1a35ee
XL
176 write!(f, "TypeWellFormedFromEnv({:?})", ty)
177 }
487cf647 178 ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"),
532ac7d7
XL
179 }
180 }
181}
182
9c376795
FG
183impl<'tcx> fmt::Debug for AliasTy<'tcx> {
184 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
185 f.debug_struct("AliasTy")
186 .field("substs", &self.substs)
187 .field("def_id", &self.def_id)
188 .finish()
189 }
190}
191
ff7c6d11
XL
192///////////////////////////////////////////////////////////////////////////
193// Atomic structs
194//
195// For things that don't carry any arena-allocated data (and are
196// copy...), just add them to this list.
197
064997fb 198TrivialTypeTraversalAndLiftImpls! {
ff7c6d11 199 (),
0531ce1d
XL
200 bool,
201 usize,
ba9703b0 202 ::rustc_target::abi::VariantIdx,
3dfed10e 203 u32,
0531ce1d 204 u64,
0731742a 205 String,
9fa01778 206 crate::middle::region::Scope,
5869c6ff 207 crate::ty::FloatTy,
3dfed10e
XL
208 ::rustc_ast::InlineAsmOptions,
209 ::rustc_ast::InlineAsmTemplatePiece,
210 ::rustc_ast::NodeId,
dfeec247
XL
211 ::rustc_span::symbol::Symbol,
212 ::rustc_hir::def::Res,
213 ::rustc_hir::def_id::DefId,
3dfed10e
XL
214 ::rustc_hir::def_id::LocalDefId,
215 ::rustc_hir::HirId,
dfeec247
XL
216 ::rustc_hir::MatchSource,
217 ::rustc_hir::Mutability,
218 ::rustc_hir::Unsafety,
f9f354fc 219 ::rustc_target::asm::InlineAsmRegOrRegClass,
83c7162d 220 ::rustc_target::spec::abi::Abi,
3dfed10e
XL
221 crate::mir::coverage::ExpressionOperandId,
222 crate::mir::coverage::CounterValueReference,
29967ef6 223 crate::mir::coverage::InjectedExpressionId,
3dfed10e
XL
224 crate::mir::coverage::InjectedExpressionIndex,
225 crate::mir::coverage::MappedExpressionIndex,
9fa01778
XL
226 crate::mir::Local,
227 crate::mir::Promoted,
228 crate::traits::Reveal,
229 crate::ty::adjustment::AutoBorrowMutability,
230 crate::ty::AdtKind,
94222f64 231 crate::ty::BoundConstness,
fc512014 232 // Including `BoundRegionKind` is a *bit* dubious, but direct
0531ce1d
XL
233 // references to bound region appear in `ty::Error`, and aren't
234 // really meant to be folded. In general, we can only fold a fully
235 // general `Region`.
fc512014 236 crate::ty::BoundRegionKind,
3dfed10e 237 crate::ty::AssocItem,
064997fb 238 crate::ty::AssocKind,
9c376795 239 crate::ty::AliasKind,
fc512014 240 crate::ty::Placeholder<crate::ty::BoundRegionKind>,
9fa01778 241 crate::ty::ClosureKind,
532ac7d7
XL
242 crate::ty::FreeRegion,
243 crate::ty::InferTy,
9fa01778 244 crate::ty::IntVarValue,
532ac7d7 245 crate::ty::ParamConst,
9fa01778 246 crate::ty::ParamTy,
48663c56 247 crate::ty::adjustment::PointerCast,
532ac7d7 248 crate::ty::RegionVid,
9fa01778
XL
249 crate::ty::UniverseIndex,
250 crate::ty::Variance,
dfeec247 251 ::rustc_span::Span,
5e7ed085 252 ::rustc_errors::ErrorGuaranteed,
f2b60f7d
FG
253 Field,
254 interpret::Scalar,
255 rustc_target::abi::Size,
f2b60f7d
FG
256 rustc_type_ir::DebruijnIndex,
257 ty::BoundVar,
258 ty::Placeholder<ty::BoundVar>,
259}
260
261TrivialTypeTraversalAndLiftImpls! {
262 for<'tcx> {
263 ty::ValTree<'tcx>,
264 }
ff7c6d11
XL
265}
266
e9174d1e
SL
267///////////////////////////////////////////////////////////////////////////
268// Lift implementations
269
270impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
271 type Lifted = (A::Lifted, B::Lifted);
29967ef6
XL
272 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
273 Some((tcx.lift(self.0)?, tcx.lift(self.1)?))
e9174d1e
SL
274 }
275}
276
ea8adc8c
XL
277impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) {
278 type Lifted = (A::Lifted, B::Lifted, C::Lifted);
29967ef6
XL
279 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
280 Some((tcx.lift(self.0)?, tcx.lift(self.1)?, tcx.lift(self.2)?))
dfeec247 281 }
ea8adc8c
XL
282}
283
a7813a04
XL
284impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
285 type Lifted = Option<T::Lifted>;
29967ef6 286 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
f2b60f7d
FG
287 Some(match self {
288 Some(x) => Some(tcx.lift(x)?),
289 None => None,
290 })
a7813a04
XL
291 }
292}
293
294impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
295 type Lifted = Result<T::Lifted, E::Lifted>;
29967ef6
XL
296 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
297 match self {
298 Ok(x) => tcx.lift(x).map(Ok),
299 Err(e) => tcx.lift(e).map(Err),
a7813a04
XL
300 }
301 }
302}
303
ea8adc8c
XL
304impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
305 type Lifted = Box<T::Lifted>;
29967ef6 306 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
f2b60f7d 307 Some(Box::new(tcx.lift(*self)?))
ea8adc8c
XL
308 }
309}
310
29967ef6 311impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Rc<T> {
dc9dc135 312 type Lifted = Rc<T::Lifted>;
29967ef6 313 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
f2b60f7d 314 Some(Rc::new(tcx.lift(self.as_ref().clone())?))
dc9dc135
XL
315 }
316}
317
29967ef6 318impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Arc<T> {
dc9dc135 319 type Lifted = Arc<T::Lifted>;
29967ef6 320 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
f2b60f7d 321 Some(Arc::new(tcx.lift(self.as_ref().clone())?))
e9174d1e
SL
322 }
323}
a7813a04
XL
324impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
325 type Lifted = Vec<T::Lifted>;
29967ef6
XL
326 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
327 self.into_iter().map(|v| tcx.lift(v)).collect()
a7813a04
XL
328 }
329}
330
ff7c6d11
XL
331impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
332 type Lifted = IndexVec<I, T::Lifted>;
29967ef6
XL
333 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
334 self.into_iter().map(|e| tcx.lift(e)).collect()
ff7c6d11
XL
335 }
336}
337
5099ac24
FG
338impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
339 type Lifted = ty::Term<'tcx>;
340 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
f2b60f7d
FG
341 Some(
342 match self.unpack() {
343 TermKind::Ty(ty) => TermKind::Ty(tcx.lift(ty)?),
344 TermKind::Const(c) => TermKind::Const(tcx.lift(c)?),
1b1a35ee 345 }
f2b60f7d
FG
346 .pack(),
347 )
a7813a04
XL
348 }
349}
ea8adc8c
XL
350impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
351 type Lifted = ty::ParamEnv<'tcx>;
29967ef6
XL
352 fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
353 tcx.lift(self.caller_bounds())
a2a8927a 354 .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness()))
ea8adc8c
XL
355 }
356}
357
e9174d1e
SL
358///////////////////////////////////////////////////////////////////////////
359// TypeFoldable implementations.
e9174d1e 360
0531ce1d 361/// AdtDefs are basically the same as a DefId.
5e7ed085 362impl<'tcx> TypeFoldable<'tcx> for ty::AdtDef<'tcx> {
923072b8 363 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
a2a8927a 364 Ok(self)
0531ce1d 365 }
064997fb 366}
0531ce1d 367
064997fb 368impl<'tcx> TypeVisitable<'tcx> for ty::AdtDef<'tcx> {
923072b8 369 fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
9c376795 370 ControlFlow::Continue(())
0531ce1d
XL
371 }
372}
373
dc9dc135 374impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
923072b8 375 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
a2a8927a
XL
376 self,
377 folder: &mut F,
378 ) -> Result<(T, U), F::Error> {
379 Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?))
e9174d1e 380 }
064997fb 381}
9cc50fc6 382
064997fb 383impl<'tcx, T: TypeVisitable<'tcx>, U: TypeVisitable<'tcx>> TypeVisitable<'tcx> for (T, U) {
923072b8 384 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
29967ef6
XL
385 self.0.visit_with(visitor)?;
386 self.1.visit_with(visitor)
9cc50fc6 387 }
e9174d1e
SL
388}
389
3dfed10e
XL
390impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx>
391 for (A, B, C)
392{
923072b8 393 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
a2a8927a
XL
394 self,
395 folder: &mut F,
396 ) -> Result<(A, B, C), F::Error> {
397 Ok((
398 self.0.try_fold_with(folder)?,
399 self.1.try_fold_with(folder)?,
400 self.2.try_fold_with(folder)?,
401 ))
3dfed10e 402 }
064997fb 403}
3dfed10e 404
064997fb
FG
405impl<'tcx, A: TypeVisitable<'tcx>, B: TypeVisitable<'tcx>, C: TypeVisitable<'tcx>>
406 TypeVisitable<'tcx> for (A, B, C)
407{
923072b8 408 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
29967ef6
XL
409 self.0.visit_with(visitor)?;
410 self.1.visit_with(visitor)?;
411 self.2.visit_with(visitor)
3dfed10e
XL
412 }
413}
414
064997fb 415EnumTypeTraversalImpl! {
0531ce1d
XL
416 impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
417 (Some)(a),
418 (None),
419 } where T: TypeFoldable<'tcx>
e9174d1e 420}
064997fb
FG
421EnumTypeTraversalImpl! {
422 impl<'tcx, T> TypeVisitable<'tcx> for Option<T> {
423 (Some)(a),
424 (None),
425 } where T: TypeVisitable<'tcx>
426}
e9174d1e 427
064997fb 428EnumTypeTraversalImpl! {
dc9dc135
XL
429 impl<'tcx, T, E> TypeFoldable<'tcx> for Result<T, E> {
430 (Ok)(a),
431 (Err)(a),
432 } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>,
433}
064997fb
FG
434EnumTypeTraversalImpl! {
435 impl<'tcx, T, E> TypeVisitable<'tcx> for Result<T, E> {
436 (Ok)(a),
437 (Err)(a),
438 } where T: TypeVisitable<'tcx>, E: TypeVisitable<'tcx>,
439}
dc9dc135 440
e9174d1e 441impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
923072b8 442 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
a2a8927a
XL
443 mut self,
444 folder: &mut F,
445 ) -> Result<Self, F::Error> {
446 // We merely want to replace the contained `T`, if at all possible,
447 // so that we don't needlessly allocate a new `Rc` or indeed clone
448 // the contained type.
449 unsafe {
450 // First step is to ensure that we have a unique reference to
451 // the contained type, which `Rc::make_mut` will accomplish (by
452 // allocating a new `Rc` and cloning the `T` only if required).
453 // This is done *before* casting to `Rc<ManuallyDrop<T>>` so that
454 // panicking during `make_mut` does not leak the `T`.
455 Rc::make_mut(&mut self);
456
457 // Casting to `Rc<ManuallyDrop<T>>` is safe because `ManuallyDrop`
458 // is `repr(transparent)`.
459 let ptr = Rc::into_raw(self).cast::<ManuallyDrop<T>>();
460 let mut unique = Rc::from_raw(ptr);
461
462 // Call to `Rc::make_mut` above guarantees that `unique` is the
463 // sole reference to the contained value, so we can avoid doing
464 // a checked `get_mut` here.
465 let slot = Rc::get_mut_unchecked(&mut unique);
466
467 // Semantically move the contained type out from `unique`, fold
9c376795 468 // it, then move the folded value back into `unique`. Should
a2a8927a
XL
469 // folding fail, `ManuallyDrop` ensures that the "moved-out"
470 // value is not re-dropped.
471 let owned = ManuallyDrop::take(slot);
472 let folded = owned.try_fold_with(folder)?;
473 *slot = ManuallyDrop::new(folded);
474
475 // Cast back to `Rc<T>`.
476 Ok(Rc::from_raw(Rc::into_raw(unique).cast()))
477 }
e9174d1e 478 }
064997fb 479}
9cc50fc6 480
064997fb 481impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Rc<T> {
923072b8 482 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
9cc50fc6
SL
483 (**self).visit_with(visitor)
484 }
e9174d1e
SL
485}
486
dc9dc135 487impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
923072b8 488 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
a2a8927a
XL
489 mut self,
490 folder: &mut F,
491 ) -> Result<Self, F::Error> {
492 // We merely want to replace the contained `T`, if at all possible,
493 // so that we don't needlessly allocate a new `Arc` or indeed clone
494 // the contained type.
495 unsafe {
496 // First step is to ensure that we have a unique reference to
497 // the contained type, which `Arc::make_mut` will accomplish (by
498 // allocating a new `Arc` and cloning the `T` only if required).
499 // This is done *before* casting to `Arc<ManuallyDrop<T>>` so that
500 // panicking during `make_mut` does not leak the `T`.
501 Arc::make_mut(&mut self);
502
503 // Casting to `Arc<ManuallyDrop<T>>` is safe because `ManuallyDrop`
504 // is `repr(transparent)`.
505 let ptr = Arc::into_raw(self).cast::<ManuallyDrop<T>>();
506 let mut unique = Arc::from_raw(ptr);
507
508 // Call to `Arc::make_mut` above guarantees that `unique` is the
509 // sole reference to the contained value, so we can avoid doing
510 // a checked `get_mut` here.
511 let slot = Arc::get_mut_unchecked(&mut unique);
512
513 // Semantically move the contained type out from `unique`, fold
9c376795 514 // it, then move the folded value back into `unique`. Should
a2a8927a
XL
515 // folding fail, `ManuallyDrop` ensures that the "moved-out"
516 // value is not re-dropped.
517 let owned = ManuallyDrop::take(slot);
518 let folded = owned.try_fold_with(folder)?;
519 *slot = ManuallyDrop::new(folded);
520
521 // Cast back to `Arc<T>`.
522 Ok(Arc::from_raw(Arc::into_raw(unique).cast()))
523 }
dc9dc135 524 }
064997fb 525}
dc9dc135 526
064997fb 527impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Arc<T> {
923072b8 528 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
dc9dc135
XL
529 (**self).visit_with(visitor)
530 }
531}
532
e9174d1e 533impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
923072b8 534 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
a2a8927a 535 self.try_map_id(|value| value.try_fold_with(folder))
e9174d1e 536 }
064997fb 537}
9cc50fc6 538
064997fb 539impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Box<T> {
923072b8 540 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
9cc50fc6
SL
541 (**self).visit_with(visitor)
542 }
e9174d1e
SL
543}
544
545impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
923072b8 546 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
a2a8927a 547 self.try_map_id(|t| t.try_fold_with(folder))
e9174d1e 548 }
064997fb 549}
9cc50fc6 550
064997fb 551impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Vec<T> {
923072b8 552 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
29967ef6 553 self.iter().try_for_each(|t| t.visit_with(visitor))
9cc50fc6 554 }
e9174d1e
SL
555}
556
f2b60f7d
FG
557impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &[T] {
558 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
559 self.iter().try_for_each(|t| t.visit_with(visitor))
560 }
561}
562
0bf4aa26 563impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
923072b8 564 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
a2a8927a 565 self.try_map_id(|t| t.try_fold_with(folder))
0bf4aa26 566 }
064997fb 567}
0bf4aa26 568
064997fb 569impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Box<[T]> {
923072b8 570 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
29967ef6 571 self.iter().try_for_each(|t| t.visit_with(visitor))
0bf4aa26
XL
572 }
573}
574
923072b8
FG
575impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> {
576 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
577 folder.try_fold_binder(self)
578 }
064997fb 579}
04454e1e 580
064997fb 581impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for ty::Binder<'tcx, T> {
04454e1e 582 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
923072b8 583 visitor.visit_binder(self)
04454e1e
FG
584 }
585}
586
923072b8 587impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<'tcx> for ty::Binder<'tcx, T> {
a2a8927a
XL
588 fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
589 self,
590 folder: &mut F,
591 ) -> Result<Self, F::Error> {
592 self.try_map_bound(|ty| ty.try_fold_with(folder))
9cc50fc6 593 }
064997fb 594}
9cc50fc6 595
064997fb 596impl<'tcx, T: TypeVisitable<'tcx>> TypeSuperVisitable<'tcx> for ty::Binder<'tcx, T> {
fc512014 597 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
f035d41b 598 self.as_ref().skip_binder().visit_with(visitor)
54a0048b 599 }
e9174d1e
SL
600}
601
487cf647 602impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
923072b8 603 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
fc512014 604 ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v))
476ff2be 605 }
064997fb 606}
476ff2be 607
487cf647
FG
608impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Const<'tcx>> {
609 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
610 ty::util::fold_list(self, folder, |tcx, v| tcx.mk_const_list(v.iter()))
611 }
612}
613
532ac7d7 614impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
923072b8 615 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
fc512014 616 ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
0bf4aa26 617 }
064997fb 618}
0bf4aa26 619
e9174d1e 620impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
923072b8
FG
621 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
622 folder.try_fold_ty(self)
623 }
064997fb 624}
923072b8 625
064997fb 626impl<'tcx> TypeVisitable<'tcx> for Ty<'tcx> {
923072b8
FG
627 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
628 visitor.visit_ty(*self)
629 }
630}
631
632impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> {
a2a8927a
XL
633 fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
634 self,
635 folder: &mut F,
636 ) -> Result<Self, F::Error> {
fc512014 637 let kind = match *self.kind() {
a2a8927a
XL
638 ty::RawPtr(tm) => ty::RawPtr(tm.try_fold_with(folder)?),
639 ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?),
640 ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?),
641 ty::Adt(tid, substs) => ty::Adt(tid, substs.try_fold_with(folder)?),
f2b60f7d
FG
642 ty::Dynamic(trait_ty, region, representation) => ty::Dynamic(
643 trait_ty.try_fold_with(folder)?,
644 region.try_fold_with(folder)?,
645 representation,
646 ),
a2a8927a
XL
647 ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
648 ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.try_fold_with(folder)?),
649 ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?),
650 ty::Ref(r, ty, mutbl) => {
651 ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
9cc50fc6 652 }
b7449926 653 ty::Generator(did, substs, movability) => {
a2a8927a 654 ty::Generator(did, substs.try_fold_with(folder)?, movability)
ea8adc8c 655 }
a2a8927a
XL
656 ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?),
657 ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?),
9c376795 658 ty::Alias(kind, data) => ty::Alias(kind, data.try_fold_with(folder)?),
a1dfa0c6 659
dfeec247
XL
660 ty::Bool
661 | ty::Char
662 | ty::Str
663 | ty::Int(_)
664 | ty::Uint(_)
665 | ty::Float(_)
f035d41b 666 | ty::Error(_)
dfeec247
XL
667 | ty::Infer(_)
668 | ty::Param(..)
669 | ty::Bound(..)
670 | ty::Placeholder(..)
671 | ty::Never
a2a8927a 672 | ty::Foreign(..) => return Ok(self),
9cc50fc6 673 };
476ff2be 674
a2a8927a 675 Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) })
9cc50fc6 676 }
064997fb 677}
9cc50fc6 678
064997fb 679impl<'tcx> TypeSuperVisitable<'tcx> for Ty<'tcx> {
fc512014 680 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1b1a35ee 681 match self.kind() {
b7449926 682 ty::RawPtr(ref tm) => tm.visit_with(visitor),
29967ef6
XL
683 ty::Array(typ, sz) => {
684 typ.visit_with(visitor)?;
685 sz.visit_with(visitor)
686 }
b7449926
XL
687 ty::Slice(typ) => typ.visit_with(visitor),
688 ty::Adt(_, substs) => substs.visit_with(visitor),
f2b60f7d 689 ty::Dynamic(ref trait_ty, ref reg, _) => {
29967ef6
XL
690 trait_ty.visit_with(visitor)?;
691 reg.visit_with(visitor)
dfeec247 692 }
b7449926
XL
693 ty::Tuple(ts) => ts.visit_with(visitor),
694 ty::FnDef(_, substs) => substs.visit_with(visitor),
695 ty::FnPtr(ref f) => f.visit_with(visitor),
29967ef6
XL
696 ty::Ref(r, ty, _) => {
697 r.visit_with(visitor)?;
698 ty.visit_with(visitor)
699 }
dfeec247 700 ty::Generator(_did, ref substs, _) => substs.visit_with(visitor),
b7449926
XL
701 ty::GeneratorWitness(ref types) => types.visit_with(visitor),
702 ty::Closure(_did, ref substs) => substs.visit_with(visitor),
9c376795 703 ty::Alias(_, ref data) => data.visit_with(visitor),
a1dfa0c6 704
dfeec247
XL
705 ty::Bool
706 | ty::Char
707 | ty::Str
708 | ty::Int(_)
709 | ty::Uint(_)
710 | ty::Float(_)
f035d41b 711 | ty::Error(_)
dfeec247
XL
712 | ty::Infer(_)
713 | ty::Bound(..)
714 | ty::Placeholder(..)
715 | ty::Param(..)
716 | ty::Never
9c376795 717 | ty::Foreign(..) => ControlFlow::Continue(()),
9cc50fc6
SL
718 }
719 }
923072b8
FG
720}
721
722impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
723 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
724 folder.try_fold_region(self)
725 }
064997fb 726}
9cc50fc6 727
064997fb 728impl<'tcx> TypeVisitable<'tcx> for ty::Region<'tcx> {
fc512014 729 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
923072b8 730 visitor.visit_region(*self)
9cc50fc6 731 }
e9174d1e
SL
732}
733
923072b8 734impl<'tcx> TypeSuperFoldable<'tcx> for ty::Region<'tcx> {
a2a8927a
XL
735 fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
736 self,
737 _folder: &mut F,
738 ) -> Result<Self, F::Error> {
739 Ok(self)
9cc50fc6 740 }
064997fb 741}
9cc50fc6 742
064997fb 743impl<'tcx> TypeSuperVisitable<'tcx> for ty::Region<'tcx> {
fc512014 744 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
9c376795 745 ControlFlow::Continue(())
9cc50fc6 746 }
e9174d1e
SL
747}
748
f9f354fc 749impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
a2a8927a
XL
750 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
751 folder.try_fold_predicate(self)
94222f64 752 }
064997fb 753}
94222f64 754
064997fb 755impl<'tcx> TypeVisitable<'tcx> for ty::Predicate<'tcx> {
fc512014 756 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
f035d41b
XL
757 visitor.visit_predicate(*self)
758 }
759
064997fb 760 #[inline]
f035d41b 761 fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
5099ac24 762 self.outer_exclusive_binder() > binder
f035d41b
XL
763 }
764
064997fb 765 #[inline]
f035d41b 766 fn has_type_flags(&self, flags: ty::TypeFlags) -> bool {
5099ac24 767 self.flags().intersects(flags)
f035d41b
XL
768 }
769}
770
923072b8 771impl<'tcx> TypeSuperFoldable<'tcx> for ty::Predicate<'tcx> {
a2a8927a
XL
772 fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
773 self,
774 folder: &mut F,
775 ) -> Result<Self, F::Error> {
923072b8
FG
776 let new = self.kind().try_fold_with(folder)?;
777 Ok(folder.tcx().reuse_or_mk_predicate(self, new))
7cac9316 778 }
064997fb 779}
7cac9316 780
064997fb 781impl<'tcx> TypeSuperVisitable<'tcx> for ty::Predicate<'tcx> {
fc512014 782 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
923072b8
FG
783 self.kind().visit_with(visitor)
784 }
785}
786
787impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
788 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
789 ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v))
790 }
064997fb 791}
923072b8 792
8bb4bdeb 793impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
923072b8 794 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
a2a8927a 795 self.try_map_id(|x| x.try_fold_with(folder))
8bb4bdeb 796 }
064997fb 797}
8bb4bdeb 798
064997fb 799impl<'tcx, T: TypeVisitable<'tcx>, I: Idx> TypeVisitable<'tcx> for IndexVec<I, T> {
923072b8 800 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
29967ef6 801 self.iter().try_for_each(|t| t.visit_with(visitor))
8bb4bdeb
XL
802 }
803}
041b39d2 804
5099ac24 805impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
923072b8
FG
806 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
807 folder.try_fold_const(self)
808 }
064997fb 809}
923072b8 810
064997fb 811impl<'tcx> TypeVisitable<'tcx> for ty::Const<'tcx> {
923072b8
FG
812 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
813 visitor.visit_const(*self)
814 }
815}
816
817impl<'tcx> TypeSuperFoldable<'tcx> for ty::Const<'tcx> {
a2a8927a
XL
818 fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
819 self,
820 folder: &mut F,
821 ) -> Result<Self, F::Error> {
5099ac24 822 let ty = self.ty().try_fold_with(folder)?;
923072b8
FG
823 let kind = self.kind().try_fold_with(folder)?;
824 if ty != self.ty() || kind != self.kind() {
487cf647 825 Ok(folder.tcx().mk_const(kind, ty))
f9f354fc 826 } else {
a2a8927a 827 Ok(self)
f9f354fc 828 }
0731742a 829 }
064997fb 830}
0731742a 831
064997fb 832impl<'tcx> TypeSuperVisitable<'tcx> for ty::Const<'tcx> {
fc512014 833 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
5099ac24 834 self.ty().visit_with(visitor)?;
923072b8 835 self.kind().visit_with(visitor)
0731742a 836 }
ea8adc8c
XL
837}
838
48663c56 839impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
923072b8 840 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
a2a8927a 841 Ok(self)
48663c56 842 }
064997fb 843}
48663c56 844
064997fb 845impl<'tcx> TypeVisitable<'tcx> for InferConst<'tcx> {
923072b8 846 fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
9c376795 847 ControlFlow::Continue(())
48663c56
XL
848 }
849}
94222f64 850
2b03887a 851impl<'tcx> TypeSuperVisitable<'tcx> for ty::UnevaluatedConst<'tcx> {
94222f64 852 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
5099ac24 853 self.substs.visit_with(visitor)
94222f64
XL
854 }
855}