1 //! This module contains implements of the `Lift` and `TypeFoldable`
2 //! traits for various types in the Rust compiler. Most are written by
3 //! hand, though we've recently added some macros (e.g.,
4 //! `BraceStructLiftImpl!`) to help with the tedium.
6 use crate::mir::ProjectionKind;
7 use crate::mir::interpret::ConstValue;
8 use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst};
9 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
10 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
11 use smallvec::SmallVec;
12 use crate::mir::interpret;
14 use std::marker::PhantomData;
17 ///////////////////////////////////////////////////////////////////////////
20 // For things that don't carry any arena-allocated data (and are
21 // copy...), just add them to this list.
23 CloneTypeFoldableAndLiftImpls! {
27 crate::ty::layout::VariantIdx,
30 crate::middle::region::Scope,
31 ::syntax::ast::FloatTy,
32 ::syntax::ast::NodeId,
33 ::syntax_pos::symbol::Symbol,
35 crate::hir::def_id::DefId,
36 crate::hir::InlineAsm,
37 crate::hir::MatchSource,
38 crate::hir::Mutability,
40 ::rustc_target::spec::abi::Abi,
43 crate::traits::Reveal,
44 crate::ty::adjustment::AutoBorrowMutability,
46 // Including `BoundRegion` is a *bit* dubious, but direct
47 // references to bound region appear in `ty::Error`, and aren't
48 // really meant to be folded. In general, we can only fold a fully
50 crate::ty::BoundRegion,
51 crate::ty::Placeholder<crate::ty::BoundRegion>,
52 crate::ty::ClosureKind,
53 crate::ty::FreeRegion,
55 crate::ty::IntVarValue,
56 crate::ty::ParamConst,
58 crate::ty::UniverseIndex,
63 ///////////////////////////////////////////////////////////////////////////
64 // Lift implementations
66 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
67 type Lifted = (A::Lifted, B::Lifted);
68 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
69 tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b)))
73 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) {
74 type Lifted = (A::Lifted, B::Lifted, C::Lifted);
75 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
76 tcx.lift(&self.0).and_then(|a| {
77 tcx.lift(&self.1).and_then(|b| tcx.lift(&self.2).map(|c| (a, b, c)))
82 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
83 type Lifted = Option<T::Lifted>;
84 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
86 Some(ref x) => tcx.lift(x).map(Some),
92 impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
93 type Lifted = Result<T::Lifted, E::Lifted>;
94 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
96 Ok(ref x) => tcx.lift(x).map(Ok),
97 Err(ref e) => tcx.lift(e).map(Err)
102 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
103 type Lifted = Box<T::Lifted>;
104 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
105 tcx.lift(&**self).map(Box::new)
109 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
110 type Lifted = Vec<T::Lifted>;
111 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
112 // type annotation needed to inform `projection_must_outlive`
113 let mut result : Vec<<T as Lift<'tcx>>::Lifted>
114 = Vec::with_capacity(self.len());
116 if let Some(value) = tcx.lift(x) {
126 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
127 type Lifted = Vec<T::Lifted>;
128 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
133 impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
134 type Lifted = IndexVec<I, T::Lifted>;
135 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
137 .map(|e| tcx.lift(e))
142 impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
143 type Lifted = ty::TraitRef<'tcx>;
144 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
145 tcx.lift(&self.substs).map(|substs| ty::TraitRef {
152 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
153 type Lifted = ty::ExistentialTraitRef<'tcx>;
154 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
155 tcx.lift(&self.substs).map(|substs| ty::ExistentialTraitRef {
162 impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
163 type Lifted = ty::TraitPredicate<'tcx>;
164 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
165 -> Option<ty::TraitPredicate<'tcx>> {
166 tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate {
172 impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
173 type Lifted = ty::SubtypePredicate<'tcx>;
174 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
175 -> Option<ty::SubtypePredicate<'tcx>> {
176 tcx.lift(&(self.a, self.b)).map(|(a, b)| ty::SubtypePredicate {
177 a_is_expected: self.a_is_expected,
184 impl<'tcx, A: Copy+Lift<'tcx>, B: Copy+Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
185 type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
186 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
187 tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b))
191 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
192 type Lifted = ty::ProjectionTy<'tcx>;
193 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
194 -> Option<ty::ProjectionTy<'tcx>> {
195 tcx.lift(&self.substs).map(|substs| {
197 item_def_id: self.item_def_id,
204 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
205 type Lifted = ty::ProjectionPredicate<'tcx>;
206 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
207 -> Option<ty::ProjectionPredicate<'tcx>> {
208 tcx.lift(&(self.projection_ty, self.ty)).map(|(projection_ty, ty)| {
209 ty::ProjectionPredicate {
217 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
218 type Lifted = ty::ExistentialProjection<'tcx>;
219 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
220 tcx.lift(&self.substs).map(|substs| {
221 ty::ExistentialProjection {
223 ty: tcx.lift(&self.ty).expect("type must lift when substs do"),
224 item_def_id: self.item_def_id,
230 impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
231 type Lifted = ty::Predicate<'tcx>;
232 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
234 ty::Predicate::Trait(ref binder) => {
235 tcx.lift(binder).map(ty::Predicate::Trait)
237 ty::Predicate::Subtype(ref binder) => {
238 tcx.lift(binder).map(ty::Predicate::Subtype)
240 ty::Predicate::RegionOutlives(ref binder) => {
241 tcx.lift(binder).map(ty::Predicate::RegionOutlives)
243 ty::Predicate::TypeOutlives(ref binder) => {
244 tcx.lift(binder).map(ty::Predicate::TypeOutlives)
246 ty::Predicate::Projection(ref binder) => {
247 tcx.lift(binder).map(ty::Predicate::Projection)
249 ty::Predicate::WellFormed(ty) => {
250 tcx.lift(&ty).map(ty::Predicate::WellFormed)
252 ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
253 tcx.lift(&closure_substs)
254 .map(|closure_substs| ty::Predicate::ClosureKind(closure_def_id,
258 ty::Predicate::ObjectSafe(trait_def_id) => {
259 Some(ty::Predicate::ObjectSafe(trait_def_id))
261 ty::Predicate::ConstEvaluatable(def_id, substs) => {
262 tcx.lift(&substs).map(|substs| {
263 ty::Predicate::ConstEvaluatable(def_id, substs)
270 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
271 type Lifted = ty::Binder<T::Lifted>;
272 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
273 tcx.lift(self.skip_binder()).map(ty::Binder::bind)
277 impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
278 type Lifted = ty::ParamEnv<'tcx>;
279 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
280 tcx.lift(&self.caller_bounds).map(|caller_bounds| {
290 impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> {
291 type Lifted = ty::ParamEnvAnd<'tcx, T::Lifted>;
292 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
293 tcx.lift(&self.param_env).and_then(|param_env| {
294 tcx.lift(&self.value).map(|value| {
304 impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
305 type Lifted = ty::ClosureSubsts<'tcx>;
306 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
307 tcx.lift(&self.substs).map(|substs| {
308 ty::ClosureSubsts { substs }
313 impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> {
314 type Lifted = ty::GeneratorSubsts<'tcx>;
315 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
316 tcx.lift(&self.substs).map(|substs| {
317 ty::GeneratorSubsts { substs }
322 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> {
323 type Lifted = ty::adjustment::Adjustment<'tcx>;
324 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
325 tcx.lift(&self.kind).and_then(|kind| {
326 tcx.lift(&self.target).map(|target| {
327 ty::adjustment::Adjustment { kind, target }
333 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> {
334 type Lifted = ty::adjustment::Adjust<'tcx>;
335 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
337 ty::adjustment::Adjust::NeverToAny =>
338 Some(ty::adjustment::Adjust::NeverToAny),
339 ty::adjustment::Adjust::ReifyFnPointer =>
340 Some(ty::adjustment::Adjust::ReifyFnPointer),
341 ty::adjustment::Adjust::UnsafeFnPointer =>
342 Some(ty::adjustment::Adjust::UnsafeFnPointer),
343 ty::adjustment::Adjust::ClosureFnPointer =>
344 Some(ty::adjustment::Adjust::ClosureFnPointer),
345 ty::adjustment::Adjust::MutToConstPointer =>
346 Some(ty::adjustment::Adjust::MutToConstPointer),
347 ty::adjustment::Adjust::Unsize =>
348 Some(ty::adjustment::Adjust::Unsize),
349 ty::adjustment::Adjust::Deref(ref overloaded) => {
350 tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref)
352 ty::adjustment::Adjust::Borrow(ref autoref) => {
353 tcx.lift(autoref).map(ty::adjustment::Adjust::Borrow)
359 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> {
360 type Lifted = ty::adjustment::OverloadedDeref<'tcx>;
361 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
362 tcx.lift(&self.region).map(|region| {
363 ty::adjustment::OverloadedDeref {
371 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
372 type Lifted = ty::adjustment::AutoBorrow<'tcx>;
373 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
375 ty::adjustment::AutoBorrow::Ref(r, m) => {
376 tcx.lift(&r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m))
378 ty::adjustment::AutoBorrow::RawPtr(m) => {
379 Some(ty::adjustment::AutoBorrow::RawPtr(m))
385 impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> {
386 type Lifted = ty::GenSig<'tcx>;
387 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
388 tcx.lift(&(self.yield_ty, self.return_ty))
389 .map(|(yield_ty, return_ty)| {
398 impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
399 type Lifted = ty::FnSig<'tcx>;
400 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
401 tcx.lift(&self.inputs_and_output).map(|x| {
403 inputs_and_output: x,
404 c_variadic: self.c_variadic,
405 unsafety: self.unsafety,
412 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> {
413 type Lifted = ty::error::ExpectedFound<T::Lifted>;
414 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
415 tcx.lift(&self.expected).and_then(|expected| {
416 tcx.lift(&self.found).map(|found| {
417 ty::error::ExpectedFound {
426 impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
427 type Lifted = ty::error::TypeError<'tcx>;
428 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
429 use crate::ty::error::TypeError::*;
432 Mismatch => Mismatch,
433 UnsafetyMismatch(x) => UnsafetyMismatch(x),
434 AbiMismatch(x) => AbiMismatch(x),
435 Mutability => Mutability,
436 TupleSize(x) => TupleSize(x),
437 FixedArraySize(x) => FixedArraySize(x),
438 ArgCount => ArgCount,
439 RegionsDoesNotOutlive(a, b) => {
440 return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b))
442 RegionsInsufficientlyPolymorphic(a, b) => {
443 return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b))
445 RegionsOverlyPolymorphic(a, b) => {
446 return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b))
448 RegionsPlaceholderMismatch => RegionsPlaceholderMismatch,
449 IntMismatch(x) => IntMismatch(x),
450 FloatMismatch(x) => FloatMismatch(x),
451 Traits(x) => Traits(x),
452 VariadicMismatch(x) => VariadicMismatch(x),
453 CyclicTy(t) => return tcx.lift(&t).map(|t| CyclicTy(t)),
454 ProjectionMismatched(x) => ProjectionMismatched(x),
455 ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
456 Sorts(ref x) => return tcx.lift(x).map(Sorts),
457 ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch)
462 impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
463 type Lifted = ty::InstanceDef<'tcx>;
464 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
466 ty::InstanceDef::Item(def_id) =>
467 Some(ty::InstanceDef::Item(def_id)),
468 ty::InstanceDef::VtableShim(def_id) =>
469 Some(ty::InstanceDef::VtableShim(def_id)),
470 ty::InstanceDef::Intrinsic(def_id) =>
471 Some(ty::InstanceDef::Intrinsic(def_id)),
472 ty::InstanceDef::FnPtrShim(def_id, ref ty) =>
473 Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?)),
474 ty::InstanceDef::Virtual(def_id, n) =>
475 Some(ty::InstanceDef::Virtual(def_id, n)),
476 ty::InstanceDef::ClosureOnceShim { call_once } =>
477 Some(ty::InstanceDef::ClosureOnceShim { call_once }),
478 ty::InstanceDef::DropGlue(def_id, ref ty) =>
479 Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?)),
480 ty::InstanceDef::CloneShim(def_id, ref ty) =>
481 Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?)),
486 BraceStructLiftImpl! {
487 impl<'a, 'tcx> Lift<'tcx> for ty::TypeAndMut<'a> {
488 type Lifted = ty::TypeAndMut<'tcx>;
493 BraceStructLiftImpl! {
494 impl<'a, 'tcx> Lift<'tcx> for ty::Instance<'a> {
495 type Lifted = ty::Instance<'tcx>;
500 BraceStructLiftImpl! {
501 impl<'a, 'tcx> Lift<'tcx> for interpret::GlobalId<'a> {
502 type Lifted = interpret::GlobalId<'tcx>;
507 // FIXME(eddyb) this is like what some of the macros above generate,
508 // except that macros *also* generate a foldable impl, which we don't
509 // want (with it we'd risk bypassing `fold_region` / `fold_const`).
510 impl<'tcx> Lift<'tcx> for ty::RegionKind {
511 type Lifted = ty::RegionKind;
512 fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
517 impl<'a, 'tcx> Lift<'tcx> for ty::LazyConst<'a> {
518 type Lifted = ty::LazyConst<'tcx>;
519 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
521 ty::LazyConst::Evaluated(v) => Some(ty::LazyConst::Evaluated(tcx.lift(v)?)),
522 ty::LazyConst::Unevaluated(def_id, substs) => {
523 Some(ty::LazyConst::Unevaluated(*def_id, tcx.lift(substs)?))
529 BraceStructLiftImpl! {
530 impl<'a, 'tcx> Lift<'tcx> for ty::Const<'a> {
531 type Lifted = ty::Const<'tcx>;
536 impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
537 type Lifted = ConstValue<'tcx>;
538 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
540 ConstValue::Param(param) => Some(ConstValue::Param(param)),
541 ConstValue::Infer(infer) => {
542 Some(ConstValue::Infer(match infer {
543 InferConst::Var(vid) => InferConst::Var(vid.lift_to_tcx(tcx)?),
544 InferConst::Fresh(i) => InferConst::Fresh(i),
545 InferConst::Canonical(debrujin, var) => InferConst::Canonical(debrujin, var),
548 ConstValue::Scalar(x) => Some(ConstValue::Scalar(x)),
549 ConstValue::Slice(x, y) => Some(ConstValue::Slice(x, y)),
550 ConstValue::ByRef(ptr, alloc) => Some(ConstValue::ByRef(
551 ptr, alloc.lift_to_tcx(tcx)?,
557 impl<'a, 'tcx> Lift<'tcx> for ConstVid<'a> {
558 type Lifted = ConstVid<'tcx>;
559 fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
562 phantom: PhantomData,
567 ///////////////////////////////////////////////////////////////////////////
568 // TypeFoldable implementations.
570 // Ideally, each type should invoke `folder.fold_foo(self)` and
571 // nothing else. In some cases, though, we haven't gotten around to
572 // adding methods on the `folder` yet, and thus the folding is
573 // hard-coded here. This is less-flexible, because folders cannot
574 // override the behavior, but there are a lot of random types and one
575 // can easily refactor the folding into the TypeFolder trait as
578 /// AdtDefs are basically the same as a DefId.
579 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
580 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
584 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
589 impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
590 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
591 (self.0.fold_with(folder), self.1.fold_with(folder))
594 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
595 self.0.visit_with(visitor) || self.1.visit_with(visitor)
599 EnumTypeFoldableImpl! {
600 impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
603 } where T: TypeFoldable<'tcx>
606 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
607 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
608 Rc::new((**self).fold_with(folder))
611 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
612 (**self).visit_with(visitor)
616 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
617 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
618 let content: T = (**self).fold_with(folder);
622 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
623 (**self).visit_with(visitor)
627 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
628 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
629 self.iter().map(|t| t.fold_with(folder)).collect()
632 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
633 self.iter().any(|t| t.visit_with(visitor))
637 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
638 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
639 self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>().into_boxed_slice()
642 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
643 self.iter().any(|t| t.visit_with(visitor))
647 impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
648 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
649 self.map_bound_ref(|ty| ty.fold_with(folder))
652 fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
653 folder.fold_binder(self)
656 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
657 self.skip_binder().visit_with(visitor)
660 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
661 visitor.visit_binder(self)
665 BraceStructTypeFoldableImpl! {
666 impl<'tcx> TypeFoldable<'tcx> for ty::ParamEnv<'tcx> { reveal, caller_bounds, def_id }
669 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
670 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
671 let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
672 folder.tcx().intern_existential_predicates(&v)
675 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
676 self.iter().any(|p| p.visit_with(visitor))
680 EnumTypeFoldableImpl! {
681 impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> {
682 (ty::ExistentialPredicate::Trait)(a),
683 (ty::ExistentialPredicate::Projection)(a),
684 (ty::ExistentialPredicate::AutoTrait)(a),
688 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
689 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
690 let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
691 folder.tcx().intern_type_list(&v)
694 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
695 self.iter().any(|t| t.visit_with(visitor))
699 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind<'tcx>> {
700 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
701 let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
702 folder.tcx().intern_projs(&v)
705 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
706 self.iter().any(|t| t.visit_with(visitor))
710 impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
711 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
712 use crate::ty::InstanceDef::*;
714 substs: self.substs.fold_with(folder),
715 def: match self.def {
716 Item(did) => Item(did.fold_with(folder)),
717 VtableShim(did) => VtableShim(did.fold_with(folder)),
718 Intrinsic(did) => Intrinsic(did.fold_with(folder)),
719 FnPtrShim(did, ty) => FnPtrShim(
720 did.fold_with(folder),
721 ty.fold_with(folder),
723 Virtual(did, i) => Virtual(
724 did.fold_with(folder),
727 ClosureOnceShim { call_once } => ClosureOnceShim {
728 call_once: call_once.fold_with(folder),
730 DropGlue(did, ty) => DropGlue(
731 did.fold_with(folder),
732 ty.fold_with(folder),
734 CloneShim(did, ty) => CloneShim(
735 did.fold_with(folder),
736 ty.fold_with(folder),
742 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
743 use crate::ty::InstanceDef::*;
744 self.substs.visit_with(visitor) ||
746 Item(did) | VtableShim(did) | Intrinsic(did) | Virtual(did, _) => {
747 did.visit_with(visitor)
749 FnPtrShim(did, ty) | CloneShim(did, ty) => {
750 did.visit_with(visitor) || ty.visit_with(visitor)
752 DropGlue(did, ty) => {
753 did.visit_with(visitor) || ty.visit_with(visitor)
755 ClosureOnceShim { call_once } => call_once.visit_with(visitor),
760 impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
761 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
763 instance: self.instance.fold_with(folder),
764 promoted: self.promoted
768 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
769 self.instance.visit_with(visitor)
773 impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
774 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
775 let sty = match self.sty {
776 ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)),
777 ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)),
778 ty::Slice(typ) => ty::Slice(typ.fold_with(folder)),
779 ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)),
780 ty::Dynamic(ref trait_ty, ref region) =>
781 ty::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder)),
782 ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)),
783 ty::FnDef(def_id, substs) => {
784 ty::FnDef(def_id, substs.fold_with(folder))
786 ty::FnPtr(f) => ty::FnPtr(f.fold_with(folder)),
787 ty::Ref(ref r, ty, mutbl) => {
788 ty::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl)
790 ty::Generator(did, substs, movability) => {
793 substs.fold_with(folder),
796 ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)),
797 ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)),
798 ty::Projection(ref data) => ty::Projection(data.fold_with(folder)),
799 ty::UnnormalizedProjection(ref data) => {
800 ty::UnnormalizedProjection(data.fold_with(folder))
802 ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)),
814 ty::Placeholder(..) |
816 ty::Foreign(..) => return self
822 folder.tcx().mk_ty(sty)
826 fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
827 folder.fold_ty(*self)
830 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
832 ty::RawPtr(ref tm) => tm.visit_with(visitor),
833 ty::Array(typ, sz) => typ.visit_with(visitor) || sz.visit_with(visitor),
834 ty::Slice(typ) => typ.visit_with(visitor),
835 ty::Adt(_, substs) => substs.visit_with(visitor),
836 ty::Dynamic(ref trait_ty, ref reg) =>
837 trait_ty.visit_with(visitor) || reg.visit_with(visitor),
838 ty::Tuple(ts) => ts.visit_with(visitor),
839 ty::FnDef(_, substs) => substs.visit_with(visitor),
840 ty::FnPtr(ref f) => f.visit_with(visitor),
841 ty::Ref(r, ty, _) => r.visit_with(visitor) || ty.visit_with(visitor),
842 ty::Generator(_did, ref substs, _) => {
843 substs.visit_with(visitor)
845 ty::GeneratorWitness(ref types) => types.visit_with(visitor),
846 ty::Closure(_did, ref substs) => substs.visit_with(visitor),
847 ty::Projection(ref data) | ty::UnnormalizedProjection(ref data) => {
848 data.visit_with(visitor)
850 ty::Opaque(_, ref substs) => substs.visit_with(visitor),
861 ty::Placeholder(..) |
864 ty::Foreign(..) => false,
868 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
869 visitor.visit_ty(self)
873 BraceStructTypeFoldableImpl! {
874 impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
879 BraceStructTypeFoldableImpl! {
880 impl<'tcx> TypeFoldable<'tcx> for ty::GenSig<'tcx> {
885 BraceStructTypeFoldableImpl! {
886 impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
887 inputs_and_output, c_variadic, unsafety, abi
891 BraceStructTypeFoldableImpl! {
892 impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> { def_id, substs }
895 BraceStructTypeFoldableImpl! {
896 impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialTraitRef<'tcx> { def_id, substs }
899 BraceStructTypeFoldableImpl! {
900 impl<'tcx> TypeFoldable<'tcx> for ty::ImplHeader<'tcx> {
908 impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
909 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
913 fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
914 folder.fold_region(*self)
917 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
921 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
922 visitor.visit_region(*self)
926 BraceStructTypeFoldableImpl! {
927 impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
932 BraceStructTypeFoldableImpl! {
933 impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorSubsts<'tcx> {
938 BraceStructTypeFoldableImpl! {
939 impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjustment<'tcx> {
945 EnumTypeFoldableImpl! {
946 impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjust<'tcx> {
947 (ty::adjustment::Adjust::NeverToAny),
948 (ty::adjustment::Adjust::ReifyFnPointer),
949 (ty::adjustment::Adjust::UnsafeFnPointer),
950 (ty::adjustment::Adjust::ClosureFnPointer),
951 (ty::adjustment::Adjust::MutToConstPointer),
952 (ty::adjustment::Adjust::Unsize),
953 (ty::adjustment::Adjust::Deref)(a),
954 (ty::adjustment::Adjust::Borrow)(a),
958 BraceStructTypeFoldableImpl! {
959 impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> {
964 EnumTypeFoldableImpl! {
965 impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
966 (ty::adjustment::AutoBorrow::Ref)(a, b),
967 (ty::adjustment::AutoBorrow::RawPtr)(m),
971 BraceStructTypeFoldableImpl! {
972 impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
977 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
978 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
979 let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
980 folder.tcx().intern_predicates(&v)
983 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
984 self.iter().any(|p| p.visit_with(visitor))
988 EnumTypeFoldableImpl! {
989 impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
990 (ty::Predicate::Trait)(a),
991 (ty::Predicate::Subtype)(a),
992 (ty::Predicate::RegionOutlives)(a),
993 (ty::Predicate::TypeOutlives)(a),
994 (ty::Predicate::Projection)(a),
995 (ty::Predicate::WellFormed)(a),
996 (ty::Predicate::ClosureKind)(a, b, c),
997 (ty::Predicate::ObjectSafe)(a),
998 (ty::Predicate::ConstEvaluatable)(a, b),
1002 BraceStructTypeFoldableImpl! {
1003 impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionPredicate<'tcx> {
1008 BraceStructTypeFoldableImpl! {
1009 impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialProjection<'tcx> {
1010 ty, substs, item_def_id
1014 BraceStructTypeFoldableImpl! {
1015 impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> {
1020 BraceStructTypeFoldableImpl! {
1021 impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> {
1026 BraceStructTypeFoldableImpl! {
1027 impl<'tcx, T> TypeFoldable<'tcx> for ty::ParamEnvAnd<'tcx, T> {
1029 } where T: TypeFoldable<'tcx>
1032 BraceStructTypeFoldableImpl! {
1033 impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> {
1038 BraceStructTypeFoldableImpl! {
1039 impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> {
1044 TupleStructTypeFoldableImpl! {
1045 impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U> {
1047 } where T : TypeFoldable<'tcx>, U : TypeFoldable<'tcx>,
1050 BraceStructTypeFoldableImpl! {
1051 impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
1056 BraceStructTypeFoldableImpl! {
1057 impl<'tcx, T> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
1059 } where T: TypeFoldable<'tcx>
1062 impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
1063 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1064 self.iter().map(|x| x.fold_with(folder)).collect()
1067 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1068 self.iter().any(|t| t.visit_with(visitor))
1072 EnumTypeFoldableImpl! {
1073 impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> {
1074 (ty::error::TypeError::Mismatch),
1075 (ty::error::TypeError::UnsafetyMismatch)(x),
1076 (ty::error::TypeError::AbiMismatch)(x),
1077 (ty::error::TypeError::Mutability),
1078 (ty::error::TypeError::TupleSize)(x),
1079 (ty::error::TypeError::FixedArraySize)(x),
1080 (ty::error::TypeError::ArgCount),
1081 (ty::error::TypeError::RegionsDoesNotOutlive)(a, b),
1082 (ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b),
1083 (ty::error::TypeError::RegionsOverlyPolymorphic)(a, b),
1084 (ty::error::TypeError::RegionsPlaceholderMismatch),
1085 (ty::error::TypeError::IntMismatch)(x),
1086 (ty::error::TypeError::FloatMismatch)(x),
1087 (ty::error::TypeError::Traits)(x),
1088 (ty::error::TypeError::VariadicMismatch)(x),
1089 (ty::error::TypeError::CyclicTy)(t),
1090 (ty::error::TypeError::ProjectionMismatched)(x),
1091 (ty::error::TypeError::ProjectionBoundsLength)(x),
1092 (ty::error::TypeError::Sorts)(x),
1093 (ty::error::TypeError::ExistentialMismatch)(x),
1097 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::LazyConst<'tcx> {
1098 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1099 let new = match self {
1100 ty::LazyConst::Evaluated(v) => ty::LazyConst::Evaluated(v.fold_with(folder)),
1101 ty::LazyConst::Unevaluated(def_id, substs) => {
1102 ty::LazyConst::Unevaluated(*def_id, substs.fold_with(folder))
1105 folder.tcx().mk_lazy_const(new)
1108 fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1109 folder.fold_const(*self)
1112 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1114 ty::LazyConst::Evaluated(c) => c.visit_with(visitor),
1115 ty::LazyConst::Unevaluated(_, substs) => substs.visit_with(visitor),
1119 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1120 visitor.visit_const(self)
1124 impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
1125 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1126 let ty = self.ty.fold_with(folder);
1127 let val = self.val.fold_with(folder);
1134 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1135 self.ty.visit_with(visitor) || self.val.visit_with(visitor)
1139 impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
1140 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
1144 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {