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