]>
Commit | Line | Data |
---|---|---|
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 | 5 | use crate::mir::interpret; |
dfeec247 | 6 | use crate::mir::ProjectionKind; |
a2a8927a | 7 | use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor}; |
1b1a35ee | 8 | use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; |
5099ac24 | 9 | use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt}; |
fc512014 | 10 | use rustc_data_structures::functor::IdFunctor; |
5099ac24 | 11 | use rustc_hir as hir; |
dfeec247 XL |
12 | use rustc_hir::def::Namespace; |
13 | use rustc_hir::def_id::CRATE_DEF_INDEX; | |
14 | use rustc_index::vec::{Idx, IndexVec}; | |
60c5eb7d | 15 | |
532ac7d7 | 16 | use std::fmt; |
a2a8927a | 17 | use std::mem::ManuallyDrop; |
29967ef6 | 18 | use std::ops::ControlFlow; |
e9174d1e | 19 | use std::rc::Rc; |
dc9dc135 | 20 | use std::sync::Arc; |
532ac7d7 XL |
21 | |
22 | impl fmt::Debug for ty::TraitDef { | |
23 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
24 | ty::tls::with(|tcx| { | |
5e7ed085 FG |
25 | with_no_trimmed_paths!({ |
26 | f.write_str( | |
27 | &FmtPrinter::new(tcx, Namespace::TypeNS) | |
28 | .print_def_path(self.def_id, &[])? | |
29 | .into_buffer(), | |
30 | ) | |
31 | }) | |
532ac7d7 XL |
32 | }) |
33 | } | |
34 | } | |
35 | ||
5e7ed085 | 36 | impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> { |
532ac7d7 XL |
37 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
38 | ty::tls::with(|tcx| { | |
5e7ed085 FG |
39 | with_no_trimmed_paths!({ |
40 | f.write_str( | |
41 | &FmtPrinter::new(tcx, Namespace::TypeNS) | |
42 | .print_def_path(self.did(), &[])? | |
43 | .into_buffer(), | |
44 | ) | |
45 | }) | |
532ac7d7 XL |
46 | }) |
47 | } | |
48 | } | |
49 | ||
532ac7d7 XL |
50 | impl fmt::Debug for ty::UpvarId { |
51 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
dfeec247 XL |
52 | let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id)); |
53 | write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id) | |
532ac7d7 XL |
54 | } |
55 | } | |
56 | ||
a2a8927a | 57 | impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> { |
532ac7d7 | 58 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
5e7ed085 | 59 | with_no_trimmed_paths!(fmt::Display::fmt(self, f)) |
532ac7d7 XL |
60 | } |
61 | } | |
62 | ||
a2a8927a | 63 | impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> { |
532ac7d7 XL |
64 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
65 | write!(f, "{:?} -> {}", self.kind, self.target) | |
66 | } | |
67 | } | |
68 | ||
fc512014 | 69 | impl fmt::Debug for ty::BoundRegionKind { |
532ac7d7 XL |
70 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
71 | match *self { | |
72 | ty::BrAnon(n) => write!(f, "BrAnon({:?})", n), | |
532ac7d7 | 73 | ty::BrNamed(did, name) => { |
60c5eb7d XL |
74 | if did.index == CRATE_DEF_INDEX { |
75 | write!(f, "BrNamed({})", name) | |
76 | } else { | |
77 | write!(f, "BrNamed({:?}, {})", did, name) | |
78 | } | |
532ac7d7 XL |
79 | } |
80 | ty::BrEnv => write!(f, "BrEnv"), | |
81 | } | |
82 | } | |
83 | } | |
84 | ||
85 | impl fmt::Debug for ty::RegionKind { | |
86 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
87 | match *self { | |
dfeec247 | 88 | ty::ReEarlyBound(ref data) => write!(f, "ReEarlyBound({}, {})", data.index, data.name), |
532ac7d7 | 89 | |
532ac7d7 XL |
90 | ty::ReLateBound(binder_id, ref bound_region) => { |
91 | write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region) | |
92 | } | |
93 | ||
94 | ty::ReFree(ref fr) => fr.fmt(f), | |
95 | ||
532ac7d7 XL |
96 | ty::ReStatic => write!(f, "ReStatic"), |
97 | ||
98 | ty::ReVar(ref vid) => vid.fmt(f), | |
99 | ||
dfeec247 | 100 | ty::RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder), |
532ac7d7 | 101 | |
74b04a01 | 102 | ty::ReEmpty(ui) => write!(f, "ReEmpty({:?})", ui), |
532ac7d7 XL |
103 | |
104 | ty::ReErased => write!(f, "ReErased"), | |
105 | } | |
106 | } | |
107 | } | |
108 | ||
109 | impl fmt::Debug for ty::FreeRegion { | |
110 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
111 | write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region) | |
112 | } | |
113 | } | |
114 | ||
a2a8927a | 115 | impl<'tcx> fmt::Debug for ty::FnSig<'tcx> { |
532ac7d7 | 116 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
dfeec247 | 117 | write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output()) |
532ac7d7 XL |
118 | } |
119 | } | |
120 | ||
532ac7d7 XL |
121 | impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> { |
122 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
123 | write!(f, "_#{}c", self.index) | |
124 | } | |
125 | } | |
126 | ||
532ac7d7 XL |
127 | impl fmt::Debug for ty::RegionVid { |
128 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
129 | write!(f, "'_#{}r", self.index()) | |
130 | } | |
131 | } | |
132 | ||
a2a8927a | 133 | impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> { |
532ac7d7 | 134 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
5e7ed085 | 135 | with_no_trimmed_paths!(fmt::Display::fmt(self, f)) |
532ac7d7 XL |
136 | } |
137 | } | |
138 | ||
a2a8927a | 139 | impl<'tcx> fmt::Debug for Ty<'tcx> { |
532ac7d7 | 140 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
5e7ed085 | 141 | with_no_trimmed_paths!(fmt::Display::fmt(self, f)) |
532ac7d7 XL |
142 | } |
143 | } | |
144 | ||
145 | impl fmt::Debug for ty::ParamTy { | |
146 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
48663c56 | 147 | write!(f, "{}/#{}", self.name, self.index) |
532ac7d7 XL |
148 | } |
149 | } | |
150 | ||
151 | impl fmt::Debug for ty::ParamConst { | |
152 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
153 | write!(f, "{}/#{}", self.name, self.index) | |
154 | } | |
155 | } | |
156 | ||
a2a8927a | 157 | impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> { |
532ac7d7 | 158 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
94222f64 XL |
159 | if let ty::BoundConstness::ConstIfConst = self.constness { |
160 | write!(f, "~const ")?; | |
161 | } | |
3c0e092e | 162 | write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) |
532ac7d7 XL |
163 | } |
164 | } | |
165 | ||
a2a8927a | 166 | impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> { |
532ac7d7 | 167 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
5099ac24 | 168 | write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term) |
532ac7d7 XL |
169 | } |
170 | } | |
171 | ||
a2a8927a | 172 | impl<'tcx> fmt::Debug for ty::Predicate<'tcx> { |
f9f354fc XL |
173 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
174 | write!(f, "{:?}", self.kind()) | |
175 | } | |
176 | } | |
177 | ||
a2a8927a | 178 | impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> { |
532ac7d7 XL |
179 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
180 | match *self { | |
94222f64 | 181 | ty::PredicateKind::Trait(ref a) => a.fmt(f), |
5869c6ff | 182 | ty::PredicateKind::Subtype(ref pair) => pair.fmt(f), |
94222f64 | 183 | ty::PredicateKind::Coerce(ref pair) => pair.fmt(f), |
5869c6ff XL |
184 | ty::PredicateKind::RegionOutlives(ref pair) => pair.fmt(f), |
185 | ty::PredicateKind::TypeOutlives(ref pair) => pair.fmt(f), | |
186 | ty::PredicateKind::Projection(ref pair) => pair.fmt(f), | |
187 | ty::PredicateKind::WellFormed(data) => write!(f, "WellFormed({:?})", data), | |
188 | ty::PredicateKind::ObjectSafe(trait_def_id) => { | |
f9f354fc XL |
189 | write!(f, "ObjectSafe({:?})", trait_def_id) |
190 | } | |
5869c6ff | 191 | ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => { |
dfeec247 | 192 | write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind) |
532ac7d7 | 193 | } |
94222f64 | 194 | ty::PredicateKind::ConstEvaluatable(uv) => { |
5099ac24 | 195 | write!(f, "ConstEvaluatable({:?}, {:?})", uv.def, uv.substs) |
532ac7d7 | 196 | } |
5869c6ff XL |
197 | ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2), |
198 | ty::PredicateKind::TypeWellFormedFromEnv(ty) => { | |
1b1a35ee XL |
199 | write!(f, "TypeWellFormedFromEnv({:?})", ty) |
200 | } | |
532ac7d7 XL |
201 | } |
202 | } | |
203 | } | |
204 | ||
ff7c6d11 XL |
205 | /////////////////////////////////////////////////////////////////////////// |
206 | // Atomic structs | |
207 | // | |
208 | // For things that don't carry any arena-allocated data (and are | |
209 | // copy...), just add them to this list. | |
210 | ||
fc512014 | 211 | TrivialTypeFoldableAndLiftImpls! { |
ff7c6d11 | 212 | (), |
0531ce1d XL |
213 | bool, |
214 | usize, | |
ba9703b0 | 215 | ::rustc_target::abi::VariantIdx, |
3dfed10e | 216 | u32, |
0531ce1d | 217 | u64, |
0731742a | 218 | String, |
9fa01778 | 219 | crate::middle::region::Scope, |
5869c6ff | 220 | crate::ty::FloatTy, |
3dfed10e XL |
221 | ::rustc_ast::InlineAsmOptions, |
222 | ::rustc_ast::InlineAsmTemplatePiece, | |
223 | ::rustc_ast::NodeId, | |
dfeec247 XL |
224 | ::rustc_span::symbol::Symbol, |
225 | ::rustc_hir::def::Res, | |
226 | ::rustc_hir::def_id::DefId, | |
3dfed10e XL |
227 | ::rustc_hir::def_id::LocalDefId, |
228 | ::rustc_hir::HirId, | |
dfeec247 XL |
229 | ::rustc_hir::MatchSource, |
230 | ::rustc_hir::Mutability, | |
231 | ::rustc_hir::Unsafety, | |
f9f354fc | 232 | ::rustc_target::asm::InlineAsmRegOrRegClass, |
83c7162d | 233 | ::rustc_target::spec::abi::Abi, |
3dfed10e XL |
234 | crate::mir::coverage::ExpressionOperandId, |
235 | crate::mir::coverage::CounterValueReference, | |
29967ef6 | 236 | crate::mir::coverage::InjectedExpressionId, |
3dfed10e XL |
237 | crate::mir::coverage::InjectedExpressionIndex, |
238 | crate::mir::coverage::MappedExpressionIndex, | |
9fa01778 XL |
239 | crate::mir::Local, |
240 | crate::mir::Promoted, | |
241 | crate::traits::Reveal, | |
242 | crate::ty::adjustment::AutoBorrowMutability, | |
243 | crate::ty::AdtKind, | |
94222f64 | 244 | crate::ty::BoundConstness, |
fc512014 | 245 | // Including `BoundRegionKind` is a *bit* dubious, but direct |
0531ce1d XL |
246 | // references to bound region appear in `ty::Error`, and aren't |
247 | // really meant to be folded. In general, we can only fold a fully | |
248 | // general `Region`. | |
fc512014 | 249 | crate::ty::BoundRegionKind, |
3dfed10e | 250 | crate::ty::AssocItem, |
fc512014 | 251 | crate::ty::Placeholder<crate::ty::BoundRegionKind>, |
9fa01778 | 252 | crate::ty::ClosureKind, |
532ac7d7 XL |
253 | crate::ty::FreeRegion, |
254 | crate::ty::InferTy, | |
9fa01778 | 255 | crate::ty::IntVarValue, |
532ac7d7 | 256 | crate::ty::ParamConst, |
9fa01778 | 257 | crate::ty::ParamTy, |
48663c56 | 258 | crate::ty::adjustment::PointerCast, |
532ac7d7 | 259 | crate::ty::RegionVid, |
9fa01778 XL |
260 | crate::ty::UniverseIndex, |
261 | crate::ty::Variance, | |
dfeec247 | 262 | ::rustc_span::Span, |
5e7ed085 | 263 | ::rustc_errors::ErrorGuaranteed, |
ff7c6d11 XL |
264 | } |
265 | ||
e9174d1e SL |
266 | /////////////////////////////////////////////////////////////////////////// |
267 | // Lift implementations | |
268 | ||
532ac7d7 | 269 | // FIXME(eddyb) replace all the uses of `Option::map` with `?`. |
e9174d1e SL |
270 | impl<'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 |
277 | impl<'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 |
284 | impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> { |
285 | type Lifted = Option<T::Lifted>; | |
29967ef6 XL |
286 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
287 | match self { | |
288 | Some(x) => tcx.lift(x).map(Some), | |
dfeec247 | 289 | None => Some(None), |
a7813a04 XL |
290 | } |
291 | } | |
292 | } | |
293 | ||
294 | impl<'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 |
304 | impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> { |
305 | type Lifted = Box<T::Lifted>; | |
29967ef6 XL |
306 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
307 | tcx.lift(*self).map(Box::new) | |
ea8adc8c XL |
308 | } |
309 | } | |
310 | ||
29967ef6 | 311 | impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Rc<T> { |
dc9dc135 | 312 | type Lifted = Rc<T::Lifted>; |
29967ef6 XL |
313 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
314 | tcx.lift(self.as_ref().clone()).map(Rc::new) | |
dc9dc135 XL |
315 | } |
316 | } | |
317 | ||
29967ef6 | 318 | impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Arc<T> { |
dc9dc135 | 319 | type Lifted = Arc<T::Lifted>; |
29967ef6 XL |
320 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
321 | tcx.lift(self.as_ref().clone()).map(Arc::new) | |
e9174d1e SL |
322 | } |
323 | } | |
a7813a04 XL |
324 | impl<'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 |
331 | impl<'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 | ||
9e0c209e SL |
338 | impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> { |
339 | type Lifted = ty::TraitRef<'tcx>; | |
29967ef6 XL |
340 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
341 | tcx.lift(self.substs).map(|substs| ty::TraitRef { def_id: self.def_id, substs }) | |
e9174d1e SL |
342 | } |
343 | } | |
344 | ||
9e0c209e SL |
345 | impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> { |
346 | type Lifted = ty::ExistentialTraitRef<'tcx>; | |
29967ef6 XL |
347 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
348 | tcx.lift(self.substs).map(|substs| ty::ExistentialTraitRef { def_id: self.def_id, substs }) | |
e9174d1e SL |
349 | } |
350 | } | |
351 | ||
532ac7d7 XL |
352 | impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> { |
353 | type Lifted = ty::ExistentialPredicate<'tcx>; | |
29967ef6 | 354 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
532ac7d7 | 355 | match self { |
dfeec247 | 356 | ty::ExistentialPredicate::Trait(x) => tcx.lift(x).map(ty::ExistentialPredicate::Trait), |
532ac7d7 XL |
357 | ty::ExistentialPredicate::Projection(x) => { |
358 | tcx.lift(x).map(ty::ExistentialPredicate::Projection) | |
359 | } | |
360 | ty::ExistentialPredicate::AutoTrait(def_id) => { | |
29967ef6 | 361 | Some(ty::ExistentialPredicate::AutoTrait(def_id)) |
532ac7d7 XL |
362 | } |
363 | } | |
364 | } | |
365 | } | |
366 | ||
5099ac24 FG |
367 | impl<'a, 'tcx> Lift<'tcx> for Term<'a> { |
368 | type Lifted = ty::Term<'tcx>; | |
369 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { | |
370 | Some(match self { | |
371 | Term::Ty(ty) => Term::Ty(tcx.lift(ty)?), | |
372 | Term::Const(c) => Term::Const(tcx.lift(c)?), | |
373 | }) | |
374 | } | |
375 | } | |
376 | ||
e9174d1e SL |
377 | impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> { |
378 | type Lifted = ty::TraitPredicate<'tcx>; | |
29967ef6 | 379 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::TraitPredicate<'tcx>> { |
3c0e092e XL |
380 | tcx.lift(self.trait_ref).map(|trait_ref| ty::TraitPredicate { |
381 | trait_ref, | |
382 | constness: self.constness, | |
383 | polarity: self.polarity, | |
384 | }) | |
e9174d1e SL |
385 | } |
386 | } | |
387 | ||
cc61c64b XL |
388 | impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> { |
389 | type Lifted = ty::SubtypePredicate<'tcx>; | |
29967ef6 XL |
390 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::SubtypePredicate<'tcx>> { |
391 | tcx.lift((self.a, self.b)).map(|(a, b)| ty::SubtypePredicate { | |
cc61c64b | 392 | a_is_expected: self.a_is_expected, |
041b39d2 XL |
393 | a, |
394 | b, | |
cc61c64b XL |
395 | }) |
396 | } | |
397 | } | |
398 | ||
94222f64 XL |
399 | impl<'a, 'tcx> Lift<'tcx> for ty::CoercePredicate<'a> { |
400 | type Lifted = ty::CoercePredicate<'tcx>; | |
401 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::CoercePredicate<'tcx>> { | |
402 | tcx.lift((self.a, self.b)).map(|(a, b)| ty::CoercePredicate { a, b }) | |
403 | } | |
404 | } | |
405 | ||
dc9dc135 | 406 | impl<'tcx, A: Copy + Lift<'tcx>, B: Copy + Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> { |
e9174d1e | 407 | type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>; |
29967ef6 XL |
408 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
409 | tcx.lift((self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b)) | |
e9174d1e SL |
410 | } |
411 | } | |
412 | ||
5bcae85e SL |
413 | impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> { |
414 | type Lifted = ty::ProjectionTy<'tcx>; | |
29967ef6 XL |
415 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionTy<'tcx>> { |
416 | tcx.lift(self.substs) | |
dfeec247 | 417 | .map(|substs| ty::ProjectionTy { item_def_id: self.item_def_id, substs }) |
5bcae85e SL |
418 | } |
419 | } | |
420 | ||
e9174d1e SL |
421 | impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> { |
422 | type Lifted = ty::ProjectionPredicate<'tcx>; | |
29967ef6 | 423 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> { |
5099ac24 FG |
424 | tcx.lift((self.projection_ty, self.term)) |
425 | .map(|(projection_ty, term)| ty::ProjectionPredicate { projection_ty, term }) | |
e9174d1e SL |
426 | } |
427 | } | |
428 | ||
9e0c209e SL |
429 | impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> { |
430 | type Lifted = ty::ExistentialProjection<'tcx>; | |
29967ef6 XL |
431 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
432 | tcx.lift(self.substs).map(|substs| ty::ExistentialProjection { | |
dfeec247 | 433 | substs, |
5099ac24 | 434 | term: tcx.lift(self.term).expect("type must lift when substs do"), |
dfeec247 | 435 | item_def_id: self.item_def_id, |
9e0c209e SL |
436 | }) |
437 | } | |
438 | } | |
439 | ||
f9f354fc XL |
440 | impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> { |
441 | type Lifted = ty::PredicateKind<'tcx>; | |
29967ef6 | 442 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
3dfed10e | 443 | match self { |
94222f64 | 444 | ty::PredicateKind::Trait(data) => tcx.lift(data).map(ty::PredicateKind::Trait), |
5869c6ff | 445 | ty::PredicateKind::Subtype(data) => tcx.lift(data).map(ty::PredicateKind::Subtype), |
94222f64 | 446 | ty::PredicateKind::Coerce(data) => tcx.lift(data).map(ty::PredicateKind::Coerce), |
5869c6ff XL |
447 | ty::PredicateKind::RegionOutlives(data) => { |
448 | tcx.lift(data).map(ty::PredicateKind::RegionOutlives) | |
a7813a04 | 449 | } |
5869c6ff XL |
450 | ty::PredicateKind::TypeOutlives(data) => { |
451 | tcx.lift(data).map(ty::PredicateKind::TypeOutlives) | |
a7813a04 | 452 | } |
5869c6ff XL |
453 | ty::PredicateKind::Projection(data) => { |
454 | tcx.lift(data).map(ty::PredicateKind::Projection) | |
a7813a04 | 455 | } |
5869c6ff XL |
456 | ty::PredicateKind::WellFormed(ty) => tcx.lift(ty).map(ty::PredicateKind::WellFormed), |
457 | ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => { | |
29967ef6 | 458 | tcx.lift(closure_substs).map(|closure_substs| { |
5869c6ff | 459 | ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) |
dfeec247 | 460 | }) |
a7813a04 | 461 | } |
5869c6ff XL |
462 | ty::PredicateKind::ObjectSafe(trait_def_id) => { |
463 | Some(ty::PredicateKind::ObjectSafe(trait_def_id)) | |
a7813a04 | 464 | } |
94222f64 XL |
465 | ty::PredicateKind::ConstEvaluatable(uv) => { |
466 | tcx.lift(uv).map(|uv| ty::PredicateKind::ConstEvaluatable(uv)) | |
f9f354fc | 467 | } |
5869c6ff XL |
468 | ty::PredicateKind::ConstEquate(c1, c2) => { |
469 | tcx.lift((c1, c2)).map(|(c1, c2)| ty::PredicateKind::ConstEquate(c1, c2)) | |
ea8adc8c | 470 | } |
5869c6ff XL |
471 | ty::PredicateKind::TypeWellFormedFromEnv(ty) => { |
472 | tcx.lift(ty).map(ty::PredicateKind::TypeWellFormedFromEnv) | |
1b1a35ee | 473 | } |
a7813a04 XL |
474 | } |
475 | } | |
476 | } | |
477 | ||
cdc7bbd5 XL |
478 | impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<'a, T> |
479 | where | |
480 | <T as Lift<'tcx>>::Lifted: TypeFoldable<'tcx>, | |
481 | { | |
482 | type Lifted = ty::Binder<'tcx, T::Lifted>; | |
29967ef6 | 483 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
cdc7bbd5 XL |
484 | let bound_vars = tcx.lift(self.bound_vars()); |
485 | tcx.lift(self.skip_binder()) | |
486 | .zip(bound_vars) | |
487 | .map(|(value, vars)| ty::Binder::bind_with_vars(value, vars)) | |
e9174d1e SL |
488 | } |
489 | } | |
490 | ||
ea8adc8c XL |
491 | impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { |
492 | type Lifted = ty::ParamEnv<'tcx>; | |
29967ef6 XL |
493 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
494 | tcx.lift(self.caller_bounds()) | |
a2a8927a | 495 | .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness())) |
ea8adc8c XL |
496 | } |
497 | } | |
498 | ||
499 | impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> { | |
500 | type Lifted = ty::ParamEnvAnd<'tcx, T::Lifted>; | |
29967ef6 XL |
501 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
502 | tcx.lift(self.param_env).and_then(|param_env| { | |
503 | tcx.lift(self.value).map(|value| ty::ParamEnvAnd { param_env, value }) | |
ea8adc8c XL |
504 | }) |
505 | } | |
506 | } | |
507 | ||
a7813a04 XL |
508 | impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> { |
509 | type Lifted = ty::ClosureSubsts<'tcx>; | |
29967ef6 XL |
510 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
511 | tcx.lift(self.substs).map(|substs| ty::ClosureSubsts { substs }) | |
a7813a04 XL |
512 | } |
513 | } | |
514 | ||
94b46f34 XL |
515 | impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> { |
516 | type Lifted = ty::GeneratorSubsts<'tcx>; | |
29967ef6 XL |
517 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
518 | tcx.lift(self.substs).map(|substs| ty::GeneratorSubsts { substs }) | |
ea8adc8c XL |
519 | } |
520 | } | |
521 | ||
7cac9316 XL |
522 | impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> { |
523 | type Lifted = ty::adjustment::Adjustment<'tcx>; | |
29967ef6 XL |
524 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
525 | let ty::adjustment::Adjustment { kind, target } = self; | |
526 | tcx.lift(kind).and_then(|kind| { | |
527 | tcx.lift(target).map(|target| ty::adjustment::Adjustment { kind, target }) | |
7cac9316 XL |
528 | }) |
529 | } | |
530 | } | |
531 | ||
532 | impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> { | |
533 | type Lifted = ty::adjustment::Adjust<'tcx>; | |
29967ef6 XL |
534 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
535 | match self { | |
dfeec247 XL |
536 | ty::adjustment::Adjust::NeverToAny => Some(ty::adjustment::Adjust::NeverToAny), |
537 | ty::adjustment::Adjust::Pointer(ptr) => Some(ty::adjustment::Adjust::Pointer(ptr)), | |
29967ef6 | 538 | ty::adjustment::Adjust::Deref(overloaded) => { |
7cac9316 XL |
539 | tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref) |
540 | } | |
29967ef6 | 541 | ty::adjustment::Adjust::Borrow(autoref) => { |
7cac9316 XL |
542 | tcx.lift(autoref).map(ty::adjustment::Adjust::Borrow) |
543 | } | |
544 | } | |
545 | } | |
546 | } | |
547 | ||
548 | impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> { | |
549 | type Lifted = ty::adjustment::OverloadedDeref<'tcx>; | |
29967ef6 XL |
550 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
551 | tcx.lift(self.region).map(|region| ty::adjustment::OverloadedDeref { | |
1b1a35ee XL |
552 | region, |
553 | mutbl: self.mutbl, | |
554 | span: self.span, | |
555 | }) | |
a7813a04 XL |
556 | } |
557 | } | |
558 | ||
c30ab7b3 SL |
559 | impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> { |
560 | type Lifted = ty::adjustment::AutoBorrow<'tcx>; | |
29967ef6 XL |
561 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
562 | match self { | |
c30ab7b3 | 563 | ty::adjustment::AutoBorrow::Ref(r, m) => { |
29967ef6 | 564 | tcx.lift(r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m)) |
a7813a04 | 565 | } |
dfeec247 | 566 | ty::adjustment::AutoBorrow::RawPtr(m) => Some(ty::adjustment::AutoBorrow::RawPtr(m)), |
a7813a04 XL |
567 | } |
568 | } | |
569 | } | |
570 | ||
ea8adc8c XL |
571 | impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> { |
572 | type Lifted = ty::GenSig<'tcx>; | |
29967ef6 XL |
573 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
574 | tcx.lift((self.resume_ty, self.yield_ty, self.return_ty)) | |
74b04a01 | 575 | .map(|(resume_ty, yield_ty, return_ty)| ty::GenSig { resume_ty, yield_ty, return_ty }) |
ea8adc8c XL |
576 | } |
577 | } | |
578 | ||
a7813a04 XL |
579 | impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> { |
580 | type Lifted = ty::FnSig<'tcx>; | |
29967ef6 XL |
581 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
582 | tcx.lift(self.inputs_and_output).map(|x| ty::FnSig { | |
dfeec247 XL |
583 | inputs_and_output: x, |
584 | c_variadic: self.c_variadic, | |
585 | unsafety: self.unsafety, | |
586 | abi: self.abi, | |
a7813a04 XL |
587 | }) |
588 | } | |
589 | } | |
590 | ||
591 | impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> { | |
592 | type Lifted = ty::error::ExpectedFound<T::Lifted>; | |
29967ef6 XL |
593 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
594 | let ty::error::ExpectedFound { expected, found } = self; | |
595 | tcx.lift(expected).and_then(|expected| { | |
596 | tcx.lift(found).map(|found| ty::error::ExpectedFound { expected, found }) | |
a7813a04 XL |
597 | }) |
598 | } | |
599 | } | |
600 | ||
a7813a04 XL |
601 | impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { |
602 | type Lifted = ty::error::TypeError<'tcx>; | |
29967ef6 | 603 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
9fa01778 | 604 | use crate::ty::error::TypeError::*; |
a7813a04 | 605 | |
29967ef6 | 606 | Some(match self { |
a7813a04 | 607 | Mismatch => Mismatch, |
94222f64 | 608 | ConstnessMismatch(x) => ConstnessMismatch(x), |
3c0e092e | 609 | PolarityMismatch(x) => PolarityMismatch(x), |
a7813a04 XL |
610 | UnsafetyMismatch(x) => UnsafetyMismatch(x), |
611 | AbiMismatch(x) => AbiMismatch(x), | |
612 | Mutability => Mutability, | |
cdc7bbd5 | 613 | ArgumentMutability(i) => ArgumentMutability(i), |
a7813a04 XL |
614 | TupleSize(x) => TupleSize(x), |
615 | FixedArraySize(x) => FixedArraySize(x), | |
a7813a04 | 616 | ArgCount => ArgCount, |
3c0e092e | 617 | FieldMisMatch(x, y) => FieldMisMatch(x, y), |
9e0c209e | 618 | RegionsDoesNotOutlive(a, b) => { |
29967ef6 | 619 | return tcx.lift((a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b)); |
9e0c209e | 620 | } |
ea8adc8c | 621 | RegionsInsufficientlyPolymorphic(a, b) => { |
29967ef6 | 622 | return tcx.lift(b).map(|b| RegionsInsufficientlyPolymorphic(a, b)); |
9e0c209e | 623 | } |
ea8adc8c | 624 | RegionsOverlyPolymorphic(a, b) => { |
29967ef6 | 625 | return tcx.lift(b).map(|b| RegionsOverlyPolymorphic(a, b)); |
a7813a04 | 626 | } |
0731742a | 627 | RegionsPlaceholderMismatch => RegionsPlaceholderMismatch, |
a7813a04 XL |
628 | IntMismatch(x) => IntMismatch(x), |
629 | FloatMismatch(x) => FloatMismatch(x), | |
630 | Traits(x) => Traits(x), | |
a7813a04 | 631 | VariadicMismatch(x) => VariadicMismatch(x), |
29967ef6 XL |
632 | CyclicTy(t) => return tcx.lift(t).map(|t| CyclicTy(t)), |
633 | CyclicConst(ct) => return tcx.lift(ct).map(|ct| CyclicConst(ct)), | |
041b39d2 | 634 | ProjectionMismatched(x) => ProjectionMismatched(x), |
cdc7bbd5 | 635 | ArgumentSorts(x, i) => return tcx.lift(x).map(|x| ArgumentSorts(x, i)), |
29967ef6 XL |
636 | Sorts(x) => return tcx.lift(x).map(Sorts), |
637 | ExistentialMismatch(x) => return tcx.lift(x).map(ExistentialMismatch), | |
638 | ConstMismatch(x) => return tcx.lift(x).map(ConstMismatch), | |
e1599b0c | 639 | IntrinsicCast => IntrinsicCast, |
29967ef6 XL |
640 | TargetFeatureCast(x) => TargetFeatureCast(x), |
641 | ObjectUnsafeCoercion(x) => return tcx.lift(x).map(ObjectUnsafeCoercion), | |
a7813a04 XL |
642 | }) |
643 | } | |
644 | } | |
645 | ||
0531ce1d XL |
646 | impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { |
647 | type Lifted = ty::InstanceDef<'tcx>; | |
29967ef6 XL |
648 | fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { |
649 | match self { | |
dfeec247 XL |
650 | ty::InstanceDef::Item(def_id) => Some(ty::InstanceDef::Item(def_id)), |
651 | ty::InstanceDef::VtableShim(def_id) => Some(ty::InstanceDef::VtableShim(def_id)), | |
652 | ty::InstanceDef::ReifyShim(def_id) => Some(ty::InstanceDef::ReifyShim(def_id)), | |
653 | ty::InstanceDef::Intrinsic(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)), | |
29967ef6 | 654 | ty::InstanceDef::FnPtrShim(def_id, ty) => { |
dfeec247 XL |
655 | Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?)) |
656 | } | |
657 | ty::InstanceDef::Virtual(def_id, n) => Some(ty::InstanceDef::Virtual(def_id, n)), | |
c295e0f8 XL |
658 | ty::InstanceDef::ClosureOnceShim { call_once, track_caller } => { |
659 | Some(ty::InstanceDef::ClosureOnceShim { call_once, track_caller }) | |
dfeec247 | 660 | } |
29967ef6 | 661 | ty::InstanceDef::DropGlue(def_id, ty) => { |
dfeec247 XL |
662 | Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?)) |
663 | } | |
29967ef6 | 664 | ty::InstanceDef::CloneShim(def_id, ty) => { |
dfeec247 XL |
665 | Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?)) |
666 | } | |
0531ce1d XL |
667 | } |
668 | } | |
669 | } | |
670 | ||
e9174d1e SL |
671 | /////////////////////////////////////////////////////////////////////////// |
672 | // TypeFoldable implementations. | |
e9174d1e | 673 | |
0531ce1d | 674 | /// AdtDefs are basically the same as a DefId. |
5e7ed085 | 675 | impl<'tcx> TypeFoldable<'tcx> for ty::AdtDef<'tcx> { |
a2a8927a XL |
676 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
677 | self, | |
678 | _folder: &mut F, | |
679 | ) -> Result<Self, F::Error> { | |
680 | Ok(self) | |
0531ce1d XL |
681 | } |
682 | ||
fc512014 | 683 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> { |
29967ef6 | 684 | ControlFlow::CONTINUE |
0531ce1d XL |
685 | } |
686 | } | |
687 | ||
dc9dc135 | 688 | impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { |
a2a8927a XL |
689 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
690 | self, | |
691 | folder: &mut F, | |
692 | ) -> Result<(T, U), F::Error> { | |
693 | Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?)) | |
e9174d1e | 694 | } |
9cc50fc6 | 695 | |
fc512014 | 696 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
29967ef6 XL |
697 | self.0.visit_with(visitor)?; |
698 | self.1.visit_with(visitor) | |
9cc50fc6 | 699 | } |
e9174d1e SL |
700 | } |
701 | ||
3dfed10e XL |
702 | impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx> |
703 | for (A, B, C) | |
704 | { | |
a2a8927a XL |
705 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
706 | self, | |
707 | folder: &mut F, | |
708 | ) -> Result<(A, B, C), F::Error> { | |
709 | Ok(( | |
710 | self.0.try_fold_with(folder)?, | |
711 | self.1.try_fold_with(folder)?, | |
712 | self.2.try_fold_with(folder)?, | |
713 | )) | |
3dfed10e XL |
714 | } |
715 | ||
fc512014 | 716 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
29967ef6 XL |
717 | self.0.visit_with(visitor)?; |
718 | self.1.visit_with(visitor)?; | |
719 | self.2.visit_with(visitor) | |
3dfed10e XL |
720 | } |
721 | } | |
722 | ||
0531ce1d XL |
723 | EnumTypeFoldableImpl! { |
724 | impl<'tcx, T> TypeFoldable<'tcx> for Option<T> { | |
725 | (Some)(a), | |
726 | (None), | |
727 | } where T: TypeFoldable<'tcx> | |
e9174d1e SL |
728 | } |
729 | ||
dc9dc135 XL |
730 | EnumTypeFoldableImpl! { |
731 | impl<'tcx, T, E> TypeFoldable<'tcx> for Result<T, E> { | |
732 | (Ok)(a), | |
733 | (Err)(a), | |
734 | } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>, | |
735 | } | |
736 | ||
e9174d1e | 737 | impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> { |
a2a8927a XL |
738 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
739 | mut self, | |
740 | folder: &mut F, | |
741 | ) -> Result<Self, F::Error> { | |
742 | // We merely want to replace the contained `T`, if at all possible, | |
743 | // so that we don't needlessly allocate a new `Rc` or indeed clone | |
744 | // the contained type. | |
745 | unsafe { | |
746 | // First step is to ensure that we have a unique reference to | |
747 | // the contained type, which `Rc::make_mut` will accomplish (by | |
748 | // allocating a new `Rc` and cloning the `T` only if required). | |
749 | // This is done *before* casting to `Rc<ManuallyDrop<T>>` so that | |
750 | // panicking during `make_mut` does not leak the `T`. | |
751 | Rc::make_mut(&mut self); | |
752 | ||
753 | // Casting to `Rc<ManuallyDrop<T>>` is safe because `ManuallyDrop` | |
754 | // is `repr(transparent)`. | |
755 | let ptr = Rc::into_raw(self).cast::<ManuallyDrop<T>>(); | |
756 | let mut unique = Rc::from_raw(ptr); | |
757 | ||
758 | // Call to `Rc::make_mut` above guarantees that `unique` is the | |
759 | // sole reference to the contained value, so we can avoid doing | |
760 | // a checked `get_mut` here. | |
761 | let slot = Rc::get_mut_unchecked(&mut unique); | |
762 | ||
763 | // Semantically move the contained type out from `unique`, fold | |
764 | // it, then move the folded value back into `unique`. Should | |
765 | // folding fail, `ManuallyDrop` ensures that the "moved-out" | |
766 | // value is not re-dropped. | |
767 | let owned = ManuallyDrop::take(slot); | |
768 | let folded = owned.try_fold_with(folder)?; | |
769 | *slot = ManuallyDrop::new(folded); | |
770 | ||
771 | // Cast back to `Rc<T>`. | |
772 | Ok(Rc::from_raw(Rc::into_raw(unique).cast())) | |
773 | } | |
e9174d1e | 774 | } |
9cc50fc6 | 775 | |
fc512014 | 776 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
9cc50fc6 SL |
777 | (**self).visit_with(visitor) |
778 | } | |
e9174d1e SL |
779 | } |
780 | ||
dc9dc135 | 781 | impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> { |
a2a8927a XL |
782 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
783 | mut self, | |
784 | folder: &mut F, | |
785 | ) -> Result<Self, F::Error> { | |
786 | // We merely want to replace the contained `T`, if at all possible, | |
787 | // so that we don't needlessly allocate a new `Arc` or indeed clone | |
788 | // the contained type. | |
789 | unsafe { | |
790 | // First step is to ensure that we have a unique reference to | |
791 | // the contained type, which `Arc::make_mut` will accomplish (by | |
792 | // allocating a new `Arc` and cloning the `T` only if required). | |
793 | // This is done *before* casting to `Arc<ManuallyDrop<T>>` so that | |
794 | // panicking during `make_mut` does not leak the `T`. | |
795 | Arc::make_mut(&mut self); | |
796 | ||
797 | // Casting to `Arc<ManuallyDrop<T>>` is safe because `ManuallyDrop` | |
798 | // is `repr(transparent)`. | |
799 | let ptr = Arc::into_raw(self).cast::<ManuallyDrop<T>>(); | |
800 | let mut unique = Arc::from_raw(ptr); | |
801 | ||
802 | // Call to `Arc::make_mut` above guarantees that `unique` is the | |
803 | // sole reference to the contained value, so we can avoid doing | |
804 | // a checked `get_mut` here. | |
805 | let slot = Arc::get_mut_unchecked(&mut unique); | |
806 | ||
807 | // Semantically move the contained type out from `unique`, fold | |
808 | // it, then move the folded value back into `unique`. Should | |
809 | // folding fail, `ManuallyDrop` ensures that the "moved-out" | |
810 | // value is not re-dropped. | |
811 | let owned = ManuallyDrop::take(slot); | |
812 | let folded = owned.try_fold_with(folder)?; | |
813 | *slot = ManuallyDrop::new(folded); | |
814 | ||
815 | // Cast back to `Arc<T>`. | |
816 | Ok(Arc::from_raw(Arc::into_raw(unique).cast())) | |
817 | } | |
dc9dc135 XL |
818 | } |
819 | ||
fc512014 | 820 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
dc9dc135 XL |
821 | (**self).visit_with(visitor) |
822 | } | |
823 | } | |
824 | ||
e9174d1e | 825 | impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> { |
a2a8927a XL |
826 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
827 | self, | |
828 | folder: &mut F, | |
829 | ) -> Result<Self, F::Error> { | |
830 | self.try_map_id(|value| value.try_fold_with(folder)) | |
e9174d1e | 831 | } |
9cc50fc6 | 832 | |
fc512014 | 833 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
9cc50fc6 SL |
834 | (**self).visit_with(visitor) |
835 | } | |
e9174d1e SL |
836 | } |
837 | ||
838 | impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> { | |
a2a8927a XL |
839 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
840 | self, | |
841 | folder: &mut F, | |
842 | ) -> Result<Self, F::Error> { | |
843 | self.try_map_id(|t| t.try_fold_with(folder)) | |
e9174d1e | 844 | } |
9cc50fc6 | 845 | |
fc512014 | 846 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
29967ef6 | 847 | self.iter().try_for_each(|t| t.visit_with(visitor)) |
9cc50fc6 | 848 | } |
e9174d1e SL |
849 | } |
850 | ||
0bf4aa26 | 851 | impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { |
a2a8927a XL |
852 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
853 | self, | |
854 | folder: &mut F, | |
855 | ) -> Result<Self, F::Error> { | |
856 | self.try_map_id(|t| t.try_fold_with(folder)) | |
0bf4aa26 XL |
857 | } |
858 | ||
fc512014 | 859 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
29967ef6 | 860 | self.iter().try_for_each(|t| t.visit_with(visitor)) |
0bf4aa26 XL |
861 | } |
862 | } | |
863 | ||
cdc7bbd5 | 864 | impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> { |
a2a8927a XL |
865 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
866 | self, | |
867 | folder: &mut F, | |
868 | ) -> Result<Self, F::Error> { | |
869 | self.try_map_bound(|ty| ty.try_fold_with(folder)) | |
9cc50fc6 SL |
870 | } |
871 | ||
a2a8927a XL |
872 | fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { |
873 | folder.try_fold_binder(self) | |
e9174d1e | 874 | } |
9cc50fc6 | 875 | |
fc512014 | 876 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
f035d41b | 877 | self.as_ref().skip_binder().visit_with(visitor) |
54a0048b SL |
878 | } |
879 | ||
fc512014 | 880 | fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
54a0048b | 881 | visitor.visit_binder(self) |
9cc50fc6 | 882 | } |
e9174d1e SL |
883 | } |
884 | ||
cdc7bbd5 | 885 | impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> { |
a2a8927a XL |
886 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
887 | self, | |
888 | folder: &mut F, | |
889 | ) -> Result<Self, F::Error> { | |
fc512014 | 890 | ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v)) |
476ff2be SL |
891 | } |
892 | ||
fc512014 | 893 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
29967ef6 | 894 | self.iter().try_for_each(|p| p.visit_with(visitor)) |
476ff2be SL |
895 | } |
896 | } | |
897 | ||
532ac7d7 | 898 | impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> { |
a2a8927a XL |
899 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
900 | self, | |
901 | folder: &mut F, | |
902 | ) -> Result<Self, F::Error> { | |
fc512014 | 903 | ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v)) |
0bf4aa26 XL |
904 | } |
905 | ||
fc512014 | 906 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
29967ef6 | 907 | self.iter().try_for_each(|t| t.visit_with(visitor)) |
0bf4aa26 XL |
908 | } |
909 | } | |
910 | ||
0531ce1d | 911 | impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { |
a2a8927a XL |
912 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
913 | self, | |
914 | folder: &mut F, | |
915 | ) -> Result<Self, F::Error> { | |
9fa01778 | 916 | use crate::ty::InstanceDef::*; |
a2a8927a XL |
917 | Ok(Self { |
918 | substs: self.substs.try_fold_with(folder)?, | |
0531ce1d | 919 | def: match self.def { |
a2a8927a XL |
920 | Item(def) => Item(def.try_fold_with(folder)?), |
921 | VtableShim(did) => VtableShim(did.try_fold_with(folder)?), | |
922 | ReifyShim(did) => ReifyShim(did.try_fold_with(folder)?), | |
923 | Intrinsic(did) => Intrinsic(did.try_fold_with(folder)?), | |
924 | FnPtrShim(did, ty) => { | |
925 | FnPtrShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?) | |
926 | } | |
927 | Virtual(did, i) => Virtual(did.try_fold_with(folder)?, i), | |
c295e0f8 | 928 | ClosureOnceShim { call_once, track_caller } => { |
a2a8927a XL |
929 | ClosureOnceShim { call_once: call_once.try_fold_with(folder)?, track_caller } |
930 | } | |
931 | DropGlue(did, ty) => { | |
932 | DropGlue(did.try_fold_with(folder)?, ty.try_fold_with(folder)?) | |
933 | } | |
934 | CloneShim(did, ty) => { | |
935 | CloneShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?) | |
dfeec247 | 936 | } |
0531ce1d | 937 | }, |
a2a8927a | 938 | }) |
9cc50fc6 SL |
939 | } |
940 | ||
fc512014 | 941 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
9fa01778 | 942 | use crate::ty::InstanceDef::*; |
29967ef6 XL |
943 | self.substs.visit_with(visitor)?; |
944 | match self.def { | |
945 | Item(def) => def.visit_with(visitor), | |
946 | VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => { | |
947 | did.visit_with(visitor) | |
948 | } | |
949 | FnPtrShim(did, ty) | CloneShim(did, ty) => { | |
950 | did.visit_with(visitor)?; | |
951 | ty.visit_with(visitor) | |
dfeec247 | 952 | } |
29967ef6 XL |
953 | DropGlue(did, ty) => { |
954 | did.visit_with(visitor)?; | |
955 | ty.visit_with(visitor) | |
956 | } | |
c295e0f8 | 957 | ClosureOnceShim { call_once, track_caller: _ } => call_once.visit_with(visitor), |
29967ef6 | 958 | } |
9cc50fc6 | 959 | } |
e9174d1e SL |
960 | } |
961 | ||
0531ce1d | 962 | impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { |
a2a8927a XL |
963 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
964 | self, | |
965 | folder: &mut F, | |
966 | ) -> Result<Self, F::Error> { | |
967 | Ok(Self { instance: self.instance.try_fold_with(folder)?, promoted: self.promoted }) | |
a7813a04 XL |
968 | } |
969 | ||
fc512014 | 970 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
0531ce1d | 971 | self.instance.visit_with(visitor) |
a7813a04 XL |
972 | } |
973 | } | |
974 | ||
e9174d1e | 975 | impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { |
a2a8927a XL |
976 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
977 | self, | |
978 | folder: &mut F, | |
979 | ) -> Result<Self, F::Error> { | |
fc512014 | 980 | let kind = match *self.kind() { |
a2a8927a XL |
981 | ty::RawPtr(tm) => ty::RawPtr(tm.try_fold_with(folder)?), |
982 | ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?), | |
983 | ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?), | |
984 | ty::Adt(tid, substs) => ty::Adt(tid, substs.try_fold_with(folder)?), | |
fc512014 | 985 | ty::Dynamic(trait_ty, region) => { |
a2a8927a XL |
986 | ty::Dynamic(trait_ty.try_fold_with(folder)?, region.try_fold_with(folder)?) |
987 | } | |
988 | ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?), | |
989 | ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.try_fold_with(folder)?), | |
990 | ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?), | |
991 | ty::Ref(r, ty, mutbl) => { | |
992 | ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl) | |
9cc50fc6 | 993 | } |
b7449926 | 994 | ty::Generator(did, substs, movability) => { |
a2a8927a | 995 | ty::Generator(did, substs.try_fold_with(folder)?, movability) |
ea8adc8c | 996 | } |
a2a8927a XL |
997 | ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?), |
998 | ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?), | |
999 | ty::Projection(data) => ty::Projection(data.try_fold_with(folder)?), | |
1000 | ty::Opaque(did, substs) => ty::Opaque(did, substs.try_fold_with(folder)?), | |
a1dfa0c6 | 1001 | |
dfeec247 XL |
1002 | ty::Bool |
1003 | | ty::Char | |
1004 | | ty::Str | |
1005 | | ty::Int(_) | |
1006 | | ty::Uint(_) | |
1007 | | ty::Float(_) | |
f035d41b | 1008 | | ty::Error(_) |
dfeec247 XL |
1009 | | ty::Infer(_) |
1010 | | ty::Param(..) | |
1011 | | ty::Bound(..) | |
1012 | | ty::Placeholder(..) | |
1013 | | ty::Never | |
a2a8927a | 1014 | | ty::Foreign(..) => return Ok(self), |
9cc50fc6 | 1015 | }; |
476ff2be | 1016 | |
a2a8927a | 1017 | Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) }) |
9cc50fc6 SL |
1018 | } |
1019 | ||
a2a8927a XL |
1020 | fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { |
1021 | folder.try_fold_ty(self) | |
e9174d1e | 1022 | } |
9cc50fc6 | 1023 | |
fc512014 | 1024 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
1b1a35ee | 1025 | match self.kind() { |
b7449926 | 1026 | ty::RawPtr(ref tm) => tm.visit_with(visitor), |
29967ef6 XL |
1027 | ty::Array(typ, sz) => { |
1028 | typ.visit_with(visitor)?; | |
1029 | sz.visit_with(visitor) | |
1030 | } | |
b7449926 XL |
1031 | ty::Slice(typ) => typ.visit_with(visitor), |
1032 | ty::Adt(_, substs) => substs.visit_with(visitor), | |
dfeec247 | 1033 | ty::Dynamic(ref trait_ty, ref reg) => { |
29967ef6 XL |
1034 | trait_ty.visit_with(visitor)?; |
1035 | reg.visit_with(visitor) | |
dfeec247 | 1036 | } |
b7449926 XL |
1037 | ty::Tuple(ts) => ts.visit_with(visitor), |
1038 | ty::FnDef(_, substs) => substs.visit_with(visitor), | |
1039 | ty::FnPtr(ref f) => f.visit_with(visitor), | |
29967ef6 XL |
1040 | ty::Ref(r, ty, _) => { |
1041 | r.visit_with(visitor)?; | |
1042 | ty.visit_with(visitor) | |
1043 | } | |
dfeec247 | 1044 | ty::Generator(_did, ref substs, _) => substs.visit_with(visitor), |
b7449926 XL |
1045 | ty::GeneratorWitness(ref types) => types.visit_with(visitor), |
1046 | ty::Closure(_did, ref substs) => substs.visit_with(visitor), | |
f9f354fc | 1047 | ty::Projection(ref data) => data.visit_with(visitor), |
b7449926 | 1048 | ty::Opaque(_, ref substs) => substs.visit_with(visitor), |
a1dfa0c6 | 1049 | |
dfeec247 XL |
1050 | ty::Bool |
1051 | | ty::Char | |
1052 | | ty::Str | |
1053 | | ty::Int(_) | |
1054 | | ty::Uint(_) | |
1055 | | ty::Float(_) | |
f035d41b | 1056 | | ty::Error(_) |
dfeec247 XL |
1057 | | ty::Infer(_) |
1058 | | ty::Bound(..) | |
1059 | | ty::Placeholder(..) | |
1060 | | ty::Param(..) | |
1061 | | ty::Never | |
29967ef6 | 1062 | | ty::Foreign(..) => ControlFlow::CONTINUE, |
9cc50fc6 SL |
1063 | } |
1064 | } | |
1065 | ||
fc512014 | 1066 | fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
5099ac24 | 1067 | visitor.visit_ty(*self) |
9cc50fc6 | 1068 | } |
e9174d1e SL |
1069 | } |
1070 | ||
7cac9316 | 1071 | impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { |
a2a8927a XL |
1072 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
1073 | self, | |
1074 | _folder: &mut F, | |
1075 | ) -> Result<Self, F::Error> { | |
1076 | Ok(self) | |
9cc50fc6 SL |
1077 | } |
1078 | ||
a2a8927a XL |
1079 | fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { |
1080 | folder.try_fold_region(self) | |
e9174d1e | 1081 | } |
9cc50fc6 | 1082 | |
fc512014 | 1083 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> { |
29967ef6 | 1084 | ControlFlow::CONTINUE |
9cc50fc6 SL |
1085 | } |
1086 | ||
fc512014 | 1087 | fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
9cc50fc6 SL |
1088 | visitor.visit_region(*self) |
1089 | } | |
e9174d1e SL |
1090 | } |
1091 | ||
f9f354fc | 1092 | impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { |
a2a8927a XL |
1093 | fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { |
1094 | folder.try_fold_predicate(self) | |
94222f64 XL |
1095 | } |
1096 | ||
a2a8927a XL |
1097 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
1098 | self, | |
1099 | folder: &mut F, | |
1100 | ) -> Result<Self, F::Error> { | |
5099ac24 | 1101 | let new = self.kind().try_fold_with(folder)?; |
a2a8927a | 1102 | Ok(folder.tcx().reuse_or_mk_predicate(self, new)) |
f9f354fc XL |
1103 | } |
1104 | ||
fc512014 | 1105 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
5099ac24 | 1106 | self.kind().visit_with(visitor) |
f035d41b XL |
1107 | } |
1108 | ||
fc512014 | 1109 | fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
f035d41b XL |
1110 | visitor.visit_predicate(*self) |
1111 | } | |
1112 | ||
1113 | fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool { | |
5099ac24 | 1114 | self.outer_exclusive_binder() > binder |
f035d41b XL |
1115 | } |
1116 | ||
1117 | fn has_type_flags(&self, flags: ty::TypeFlags) -> bool { | |
5099ac24 | 1118 | self.flags().intersects(flags) |
f035d41b XL |
1119 | } |
1120 | } | |
1121 | ||
b7449926 | 1122 | impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> { |
a2a8927a XL |
1123 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
1124 | self, | |
1125 | folder: &mut F, | |
1126 | ) -> Result<Self, F::Error> { | |
fc512014 | 1127 | ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v)) |
7cac9316 XL |
1128 | } |
1129 | ||
fc512014 | 1130 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
29967ef6 | 1131 | self.iter().try_for_each(|p| p.visit_with(visitor)) |
7cac9316 XL |
1132 | } |
1133 | } | |
1134 | ||
8bb4bdeb | 1135 | impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> { |
a2a8927a XL |
1136 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
1137 | self, | |
1138 | folder: &mut F, | |
1139 | ) -> Result<Self, F::Error> { | |
1140 | self.try_map_id(|x| x.try_fold_with(folder)) | |
8bb4bdeb XL |
1141 | } |
1142 | ||
fc512014 | 1143 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
29967ef6 | 1144 | self.iter().try_for_each(|t| t.visit_with(visitor)) |
8bb4bdeb XL |
1145 | } |
1146 | } | |
041b39d2 | 1147 | |
5099ac24 | 1148 | impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> { |
a2a8927a XL |
1149 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
1150 | self, | |
1151 | folder: &mut F, | |
1152 | ) -> Result<Self, F::Error> { | |
5099ac24 FG |
1153 | let ty = self.ty().try_fold_with(folder)?; |
1154 | let val = self.val().try_fold_with(folder)?; | |
1155 | if ty != self.ty() || val != self.val() { | |
1156 | Ok(folder.tcx().mk_const(ty::ConstS { ty, val })) | |
f9f354fc | 1157 | } else { |
a2a8927a | 1158 | Ok(self) |
f9f354fc | 1159 | } |
0731742a XL |
1160 | } |
1161 | ||
a2a8927a XL |
1162 | fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { |
1163 | folder.try_fold_const(self) | |
ea8adc8c XL |
1164 | } |
1165 | ||
fc512014 | 1166 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
5099ac24 FG |
1167 | self.ty().visit_with(visitor)?; |
1168 | self.val().visit_with(visitor) | |
ea8adc8c | 1169 | } |
0731742a | 1170 | |
fc512014 | 1171 | fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
5099ac24 | 1172 | visitor.visit_const(*self) |
0731742a | 1173 | } |
ea8adc8c XL |
1174 | } |
1175 | ||
60c5eb7d | 1176 | impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { |
a2a8927a XL |
1177 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
1178 | self, | |
1179 | folder: &mut F, | |
1180 | ) -> Result<Self, F::Error> { | |
1181 | Ok(match self { | |
1182 | ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.try_fold_with(folder)?), | |
1183 | ty::ConstKind::Param(p) => ty::ConstKind::Param(p.try_fold_with(folder)?), | |
1184 | ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.try_fold_with(folder)?), | |
ba9703b0 XL |
1185 | ty::ConstKind::Value(_) |
1186 | | ty::ConstKind::Bound(..) | |
1187 | | ty::ConstKind::Placeholder(..) | |
fc512014 | 1188 | | ty::ConstKind::Error(_) => self, |
a2a8927a | 1189 | }) |
ea8adc8c XL |
1190 | } |
1191 | ||
fc512014 | 1192 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { |
532ac7d7 | 1193 | match *self { |
60c5eb7d XL |
1194 | ty::ConstKind::Infer(ic) => ic.visit_with(visitor), |
1195 | ty::ConstKind::Param(p) => p.visit_with(visitor), | |
94222f64 | 1196 | ty::ConstKind::Unevaluated(uv) => uv.visit_with(visitor), |
ba9703b0 XL |
1197 | ty::ConstKind::Value(_) |
1198 | | ty::ConstKind::Bound(..) | |
1199 | | ty::ConstKind::Placeholder(_) | |
29967ef6 | 1200 | | ty::ConstKind::Error(_) => ControlFlow::CONTINUE, |
532ac7d7 | 1201 | } |
ea8adc8c XL |
1202 | } |
1203 | } | |
48663c56 XL |
1204 | |
1205 | impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { | |
a2a8927a XL |
1206 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
1207 | self, | |
1208 | _folder: &mut F, | |
1209 | ) -> Result<Self, F::Error> { | |
1210 | Ok(self) | |
48663c56 XL |
1211 | } |
1212 | ||
fc512014 | 1213 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> { |
29967ef6 | 1214 | ControlFlow::CONTINUE |
48663c56 XL |
1215 | } |
1216 | } | |
94222f64 XL |
1217 | |
1218 | impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> { | |
a2a8927a XL |
1219 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
1220 | self, | |
1221 | folder: &mut F, | |
1222 | ) -> Result<Self, F::Error> { | |
1223 | Ok(ty::Unevaluated { | |
94222f64 | 1224 | def: self.def, |
5099ac24 | 1225 | substs: self.substs.try_fold_with(folder)?, |
94222f64 | 1226 | promoted: self.promoted, |
a2a8927a | 1227 | }) |
94222f64 XL |
1228 | } |
1229 | ||
1230 | fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { | |
1231 | visitor.visit_unevaluated_const(*self) | |
1232 | } | |
1233 | ||
1234 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { | |
5099ac24 | 1235 | self.substs.visit_with(visitor) |
94222f64 XL |
1236 | } |
1237 | } | |
1238 | ||
1239 | impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> { | |
a2a8927a XL |
1240 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( |
1241 | self, | |
1242 | folder: &mut F, | |
1243 | ) -> Result<Self, F::Error> { | |
1244 | Ok(ty::Unevaluated { | |
94222f64 | 1245 | def: self.def, |
5099ac24 | 1246 | substs: self.substs.try_fold_with(folder)?, |
94222f64 | 1247 | promoted: self.promoted, |
a2a8927a | 1248 | }) |
94222f64 XL |
1249 | } |
1250 | ||
1251 | fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { | |
1252 | visitor.visit_unevaluated_const(self.expand()) | |
1253 | } | |
1254 | ||
1255 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { | |
5099ac24 FG |
1256 | self.substs.visit_with(visitor) |
1257 | } | |
1258 | } | |
1259 | ||
1260 | impl<'tcx> TypeFoldable<'tcx> for hir::Constness { | |
1261 | fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { | |
1262 | Ok(self) | |
1263 | } | |
1264 | ||
1265 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> { | |
1266 | ControlFlow::CONTINUE | |
94222f64 XL |
1267 | } |
1268 | } |