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