Skip to main content

rustc_middle/ty/
generic_args.rs

1// Generic arguments.
2
3use core::intrinsics;
4use std::marker::PhantomData;
5use std::num::NonZero;
6use std::ptr::NonNull;
7
8use rustc_data_structures::intern::Interned;
9use rustc_errors::{DiagArgValue, IntoDiagArg};
10use rustc_hir::def_id::DefId;
11use rustc_macros::{Lift, StableHash, TyDecodable, TyEncodable, extension};
12use rustc_serialize::{Decodable, Encodable};
13use rustc_type_ir::WithCachedTypeInfo;
14use rustc_type_ir::walk::TypeWalker;
15use smallvec::SmallVec;
16
17use crate::ty::codec::{TyDecoder, TyEncoder};
18use crate::ty::{
19    self, ClosureArgs, CoroutineArgs, CoroutineClosureArgs, FallibleTypeFolder, InlineConstArgs,
20    Lift, List, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, VisitorResult,
21    walk_visitable_list,
22};
23
24pub type GenericArgKind<'tcx> = rustc_type_ir::GenericArgKind<TyCtxt<'tcx>>;
25pub type TermKind<'tcx> = rustc_type_ir::TermKind<TyCtxt<'tcx>>;
26
27/// An entity in the Rust type system, which can be one of
28/// several kinds (types, lifetimes, and consts).
29/// To reduce memory usage, a `GenericArg` is an interned pointer,
30/// with the lowest 2 bits being reserved for a tag to
31/// indicate the type (`Ty`, `Region`, or `Const`) it points to.
32///
33/// Note: the `PartialEq`, `Eq` and `Hash` derives are only valid because `Ty`,
34/// `Region` and `Const` are all interned.
35#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for GenericArg<'tcx> { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for GenericArg<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for GenericArg<'tcx> {
    #[inline]
    fn clone(&self) -> GenericArg<'tcx> {
        let _: ::core::clone::AssertParamIsClone<NonNull<()>>;
        let _:
                ::core::clone::AssertParamIsClone<PhantomData<(Ty<'tcx>,
                ty::Region<'tcx>, ty::Const<'tcx>)>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::marker::StructuralPartialEq for GenericArg<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for GenericArg<'tcx> {
    #[inline]
    fn eq(&self, other: &GenericArg<'tcx>) -> bool {
        self.ptr == other.ptr && self.marker == other.marker
    }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for GenericArg<'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<NonNull<()>>;
        let _:
                ::core::cmp::AssertParamIsEq<PhantomData<(Ty<'tcx>,
                ty::Region<'tcx>, ty::Const<'tcx>)>>;
    }
}Eq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for GenericArg<'tcx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.ptr, state);
        ::core::hash::Hash::hash(&self.marker, state)
    }
}Hash)]
36pub struct GenericArg<'tcx> {
37    ptr: NonNull<()>,
38    marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
39}
40
41impl<'tcx> rustc_type_ir::inherent::GenericArg<TyCtxt<'tcx>> for GenericArg<'tcx> {}
42
43impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArgsRef<'tcx> {
44    fn rebase_onto(
45        self,
46        tcx: TyCtxt<'tcx>,
47        source_ancestor: DefId,
48        target_args: GenericArgsRef<'tcx>,
49    ) -> GenericArgsRef<'tcx> {
50        self.rebase_onto(tcx, source_ancestor, target_args)
51    }
52
53    #[track_caller]
54    fn type_at(self, i: usize) -> Ty<'tcx> {
55        self.type_at(i)
56    }
57
58    #[track_caller]
59    fn region_at(self, i: usize) -> ty::Region<'tcx> {
60        self.region_at(i)
61    }
62
63    #[track_caller]
64    fn const_at(self, i: usize) -> ty::Const<'tcx> {
65        self.const_at(i)
66    }
67
68    fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
69        GenericArgs::identity_for_item(tcx, def_id)
70    }
71
72    fn extend_with_error(
73        tcx: TyCtxt<'tcx>,
74        def_id: DefId,
75        original_args: &[ty::GenericArg<'tcx>],
76    ) -> ty::GenericArgsRef<'tcx> {
77        ty::GenericArgs::extend_with_error(tcx, def_id, original_args)
78    }
79
80    fn split_closure_args(self) -> ty::ClosureArgsParts<TyCtxt<'tcx>> {
81        match self[..] {
82            [ref parent_args @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
83                ty::ClosureArgsParts {
84                    parent_args,
85                    closure_kind_ty: closure_kind_ty.expect_ty(),
86                    closure_sig_as_fn_ptr_ty: closure_sig_as_fn_ptr_ty.expect_ty(),
87                    tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
88                }
89            }
90            _ => crate::util::bug::bug_fmt(format_args!("closure args missing synthetics"))bug!("closure args missing synthetics"),
91        }
92    }
93
94    fn split_coroutine_closure_args(self) -> ty::CoroutineClosureArgsParts<TyCtxt<'tcx>> {
95        match self[..] {
96            [
97                ref parent_args @ ..,
98                closure_kind_ty,
99                signature_parts_ty,
100                tupled_upvars_ty,
101                coroutine_captures_by_ref_ty,
102            ] => ty::CoroutineClosureArgsParts {
103                parent_args,
104                closure_kind_ty: closure_kind_ty.expect_ty(),
105                signature_parts_ty: signature_parts_ty.expect_ty(),
106                tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
107                coroutine_captures_by_ref_ty: coroutine_captures_by_ref_ty.expect_ty(),
108            },
109            _ => crate::util::bug::bug_fmt(format_args!("closure args missing synthetics"))bug!("closure args missing synthetics"),
110        }
111    }
112
113    fn split_coroutine_args(self) -> ty::CoroutineArgsParts<TyCtxt<'tcx>> {
114        match self[..] {
115            [ref parent_args @ .., kind_ty, resume_ty, yield_ty, return_ty, tupled_upvars_ty] => {
116                ty::CoroutineArgsParts {
117                    parent_args,
118                    kind_ty: kind_ty.expect_ty(),
119                    resume_ty: resume_ty.expect_ty(),
120                    yield_ty: yield_ty.expect_ty(),
121                    return_ty: return_ty.expect_ty(),
122                    tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
123                }
124            }
125            _ => crate::util::bug::bug_fmt(format_args!("coroutine args missing synthetics"))bug!("coroutine args missing synthetics"),
126        }
127    }
128}
129
130impl<'tcx> rustc_type_ir::inherent::IntoKind for GenericArg<'tcx> {
131    type Kind = GenericArgKind<'tcx>;
132
133    #[inline]
134    fn kind(self) -> Self::Kind {
135        self.kind()
136    }
137}
138
139unsafe impl<'tcx> rustc_data_structures::sync::DynSend for GenericArg<'tcx> where
140    &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSend
141{
142}
143unsafe impl<'tcx> rustc_data_structures::sync::DynSync for GenericArg<'tcx> where
144    &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSync
145{
146}
147unsafe impl<'tcx> Send for GenericArg<'tcx> where
148    &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): Send
149{
150}
151unsafe impl<'tcx> Sync for GenericArg<'tcx> where
152    &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): Sync
153{
154}
155
156impl<'tcx> IntoDiagArg for GenericArg<'tcx> {
157    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
158        self.to_string().into_diag_arg(&mut None)
159    }
160}
161
162const TAG_MASK: usize = 0b11;
163const TYPE_TAG: usize = 0b00;
164const REGION_TAG: usize = 0b01;
165const CONST_TAG: usize = 0b10;
166
167trait GenericArgPackExt<'tcx> {
    fn pack(self)
    -> GenericArg<'tcx>;
}
impl<'tcx> GenericArgPackExt<'tcx> for GenericArgKind<'tcx> {
    #[inline]
    fn pack(self) -> GenericArg<'tcx> {
        let (tag, ptr) =
            match self {
                GenericArgKind::Lifetime(lt) => {
                    {
                        match (&(align_of_val(&*lt.0.0) & TAG_MASK), &0) {
                            (left_val, right_val) => {
                                if !(*left_val == *right_val) {
                                    let kind = ::core::panicking::AssertKind::Eq;
                                    ::core::panicking::assert_failed(kind, &*left_val,
                                        &*right_val, ::core::option::Option::None);
                                }
                            }
                        }
                    };
                    (REGION_TAG, NonNull::from(lt.0.0).cast())
                }
                GenericArgKind::Type(ty) => {
                    {
                        match (&(align_of_val(&*ty.0.0) & TAG_MASK), &0) {
                            (left_val, right_val) => {
                                if !(*left_val == *right_val) {
                                    let kind = ::core::panicking::AssertKind::Eq;
                                    ::core::panicking::assert_failed(kind, &*left_val,
                                        &*right_val, ::core::option::Option::None);
                                }
                            }
                        }
                    };
                    (TYPE_TAG, NonNull::from(ty.0.0).cast())
                }
                GenericArgKind::Const(ct) => {
                    {
                        match (&(align_of_val(&*ct.0.0) & TAG_MASK), &0) {
                            (left_val, right_val) => {
                                if !(*left_val == *right_val) {
                                    let kind = ::core::panicking::AssertKind::Eq;
                                    ::core::panicking::assert_failed(kind, &*left_val,
                                        &*right_val, ::core::option::Option::None);
                                }
                            }
                        }
                    };
                    (CONST_TAG, NonNull::from(ct.0.0).cast())
                }
            };
        GenericArg {
            ptr: ptr.map_addr(|addr| addr | tag),
            marker: PhantomData,
        }
    }
}#[extension(trait GenericArgPackExt<'tcx>)]
168impl<'tcx> GenericArgKind<'tcx> {
169    #[inline]
170    fn pack(self) -> GenericArg<'tcx> {
171        let (tag, ptr) = match self {
172            GenericArgKind::Lifetime(lt) => {
173                // Ensure we can use the tag bits.
174                assert_eq!(align_of_val(&*lt.0.0) & TAG_MASK, 0);
175                (REGION_TAG, NonNull::from(lt.0.0).cast())
176            }
177            GenericArgKind::Type(ty) => {
178                // Ensure we can use the tag bits.
179                assert_eq!(align_of_val(&*ty.0.0) & TAG_MASK, 0);
180                (TYPE_TAG, NonNull::from(ty.0.0).cast())
181            }
182            GenericArgKind::Const(ct) => {
183                // Ensure we can use the tag bits.
184                assert_eq!(align_of_val(&*ct.0.0) & TAG_MASK, 0);
185                (CONST_TAG, NonNull::from(ct.0.0).cast())
186            }
187        };
188
189        GenericArg { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData }
190    }
191}
192
193impl<'tcx> From<ty::Region<'tcx>> for GenericArg<'tcx> {
194    #[inline]
195    fn from(r: ty::Region<'tcx>) -> GenericArg<'tcx> {
196        GenericArgKind::Lifetime(r).pack()
197    }
198}
199
200impl<'tcx> From<Ty<'tcx>> for GenericArg<'tcx> {
201    #[inline]
202    fn from(ty: Ty<'tcx>) -> GenericArg<'tcx> {
203        GenericArgKind::Type(ty).pack()
204    }
205}
206
207impl<'tcx> From<ty::Const<'tcx>> for GenericArg<'tcx> {
208    #[inline]
209    fn from(c: ty::Const<'tcx>) -> GenericArg<'tcx> {
210        GenericArgKind::Const(c).pack()
211    }
212}
213
214impl<'tcx> From<ty::Term<'tcx>> for GenericArg<'tcx> {
215    fn from(value: ty::Term<'tcx>) -> Self {
216        match value.kind() {
217            ty::TermKind::Ty(t) => t.into(),
218            ty::TermKind::Const(c) => c.into(),
219        }
220    }
221}
222
223impl<'tcx> GenericArg<'tcx> {
224    #[inline]
225    pub fn kind(self) -> GenericArgKind<'tcx> {
226        let ptr =
227            unsafe { self.ptr.map_addr(|addr| NonZero::new_unchecked(addr.get() & !TAG_MASK)) };
228        // SAFETY: use of `Interned::new_unchecked` here is ok because these
229        // pointers were originally created from `Interned` types in `pack()`,
230        // and this is just going in the other direction.
231        unsafe {
232            match self.ptr.addr().get() & TAG_MASK {
233                REGION_TAG => GenericArgKind::Lifetime(ty::Region(Interned::new_unchecked(
234                    ptr.cast::<ty::RegionKind<'tcx>>().as_ref(),
235                ))),
236                TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
237                    ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
238                ))),
239                CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
240                    ptr.cast::<WithCachedTypeInfo<ty::ConstKind<'tcx>>>().as_ref(),
241                ))),
242                _ => intrinsics::unreachable(),
243            }
244        }
245    }
246
247    #[inline]
248    pub fn as_region(self) -> Option<ty::Region<'tcx>> {
249        match self.kind() {
250            GenericArgKind::Lifetime(re) => Some(re),
251            _ => None,
252        }
253    }
254
255    #[inline]
256    pub fn as_type(self) -> Option<Ty<'tcx>> {
257        match self.kind() {
258            GenericArgKind::Type(ty) => Some(ty),
259            _ => None,
260        }
261    }
262
263    #[inline]
264    pub fn as_const(self) -> Option<ty::Const<'tcx>> {
265        match self.kind() {
266            GenericArgKind::Const(ct) => Some(ct),
267            _ => None,
268        }
269    }
270
271    #[inline]
272    pub fn as_term(self) -> Option<ty::Term<'tcx>> {
273        match self.kind() {
274            GenericArgKind::Lifetime(_) => None,
275            GenericArgKind::Type(ty) => Some(ty.into()),
276            GenericArgKind::Const(ct) => Some(ct.into()),
277        }
278    }
279
280    /// Unpack the `GenericArg` as a region when it is known certainly to be a region.
281    pub fn expect_region(self) -> ty::Region<'tcx> {
282        self.as_region().unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("expected a region, but found another kind"))bug!("expected a region, but found another kind"))
283    }
284
285    /// Unpack the `GenericArg` as a type when it is known certainly to be a type.
286    /// This is true in cases where `GenericArgs` is used in places where the kinds are known
287    /// to be limited (e.g. in tuples, where the only parameters are type parameters).
288    pub fn expect_ty(self) -> Ty<'tcx> {
289        self.as_type().unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("expected a type, but found another kind"))bug!("expected a type, but found another kind"))
290    }
291
292    /// Unpack the `GenericArg` as a const when it is known certainly to be a const.
293    pub fn expect_const(self) -> ty::Const<'tcx> {
294        self.as_const().unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("expected a const, but found another kind"))bug!("expected a const, but found another kind"))
295    }
296
297    pub fn is_non_region_infer(self) -> bool {
298        match self.kind() {
299            GenericArgKind::Lifetime(_) => false,
300            // FIXME: This shouldn't return numerical/float.
301            GenericArgKind::Type(ty) => ty.is_ty_or_numeric_infer(),
302            GenericArgKind::Const(ct) => ct.is_ct_infer(),
303        }
304    }
305
306    /// Iterator that walks `self` and any types reachable from
307    /// `self`, in depth-first order. Note that just walks the types
308    /// that appear in `self`, it does not descend into the fields of
309    /// structs or variants. For example:
310    ///
311    /// ```text
312    /// isize => { isize }
313    /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
314    /// [isize] => { [isize], isize }
315    /// ```
316    pub fn walk(self) -> TypeWalker<TyCtxt<'tcx>> {
317        TypeWalker::new(self)
318    }
319}
320
321impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for GenericArg<'a> {
322    type Lifted = GenericArg<'tcx>;
323
324    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
325        match self.kind() {
326            GenericArgKind::Lifetime(lt) => tcx.lift(lt).into(),
327            GenericArgKind::Type(ty) => tcx.lift(ty).into(),
328            GenericArgKind::Const(ct) => tcx.lift(ct).into(),
329        }
330    }
331}
332
333impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for GenericArg<'tcx> {
334    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
335        self,
336        folder: &mut F,
337    ) -> Result<Self, F::Error> {
338        match self.kind() {
339            GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into),
340            GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into),
341            GenericArgKind::Const(ct) => ct.try_fold_with(folder).map(Into::into),
342        }
343    }
344
345    fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
346        match self.kind() {
347            GenericArgKind::Lifetime(lt) => lt.fold_with(folder).into(),
348            GenericArgKind::Type(ty) => ty.fold_with(folder).into(),
349            GenericArgKind::Const(ct) => ct.fold_with(folder).into(),
350        }
351    }
352}
353
354impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for GenericArg<'tcx> {
355    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
356        match self.kind() {
357            GenericArgKind::Lifetime(lt) => lt.visit_with(visitor),
358            GenericArgKind::Type(ty) => ty.visit_with(visitor),
359            GenericArgKind::Const(ct) => ct.visit_with(visitor),
360        }
361    }
362}
363
364impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for GenericArg<'tcx> {
365    fn encode(&self, e: &mut E) {
366        self.kind().encode(e)
367    }
368}
369
370impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for GenericArg<'tcx> {
371    fn decode(d: &mut D) -> GenericArg<'tcx> {
372        GenericArgKind::decode(d).pack()
373    }
374}
375
376/// List of generic arguments that are gonna be used to replace generic parameters.
377pub type GenericArgs<'tcx> = List<GenericArg<'tcx>>;
378
379pub type GenericArgsRef<'tcx> = &'tcx GenericArgs<'tcx>;
380
381impl<'tcx> GenericArgs<'tcx> {
382    /// Converts generic args to a type list.
383    ///
384    /// # Panics
385    ///
386    /// If any of the generic arguments are not types.
387    pub fn into_type_list(&self, tcx: TyCtxt<'tcx>) -> &'tcx List<Ty<'tcx>> {
388        tcx.mk_type_list_from_iter(self.iter().map(|arg| match arg.kind() {
389            GenericArgKind::Type(ty) => ty,
390            _ => crate::util::bug::bug_fmt(format_args!("`into_type_list` called on generic arg with non-types"))bug!("`into_type_list` called on generic arg with non-types"),
391        }))
392    }
393
394    /// Interpret these generic args as the args of a closure type.
395    /// Closure args have a particular structure controlled by the
396    /// compiler that encodes information like the signature and closure kind;
397    /// see `ty::ClosureArgs` struct for more comments.
398    pub fn as_closure(&'tcx self) -> ClosureArgs<TyCtxt<'tcx>> {
399        ClosureArgs { args: self }
400    }
401
402    /// Interpret these generic args as the args of a coroutine-closure type.
403    /// Coroutine-closure args have a particular structure controlled by the
404    /// compiler that encodes information like the signature and closure kind;
405    /// see `ty::CoroutineClosureArgs` struct for more comments.
406    pub fn as_coroutine_closure(&'tcx self) -> CoroutineClosureArgs<TyCtxt<'tcx>> {
407        CoroutineClosureArgs { args: self }
408    }
409
410    /// Interpret these generic args as the args of a coroutine type.
411    /// Coroutine args have a particular structure controlled by the
412    /// compiler that encodes information like the signature and coroutine kind;
413    /// see `ty::CoroutineArgs` struct for more comments.
414    pub fn as_coroutine(&'tcx self) -> CoroutineArgs<TyCtxt<'tcx>> {
415        CoroutineArgs { args: self }
416    }
417
418    /// Interpret these generic args as the args of an inline const.
419    /// Inline const args have a particular structure controlled by the
420    /// compiler that encodes information like the inferred type;
421    /// see `ty::InlineConstArgs` struct for more comments.
422    pub fn as_inline_const(&'tcx self) -> InlineConstArgs<'tcx> {
423        InlineConstArgs { args: self }
424    }
425
426    /// Creates a [`GenericArgs`] that maps each generic parameter to itself.
427    pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: impl Into<DefId>) -> GenericArgsRef<'tcx> {
428        Self::for_item(tcx, def_id.into(), |param, _| tcx.mk_param_from_def(param))
429    }
430
431    /// Creates a [`GenericArgs`] for generic parameter definitions,
432    /// by calling closures to obtain each kind.
433    /// The closures get to observe the [`GenericArgs`] as they're
434    /// being built, which can be used to correctly
435    /// replace defaults of generic parameters.
436    pub fn for_item<F>(tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> GenericArgsRef<'tcx>
437    where
438        F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
439    {
440        let defs = tcx.generics_of(def_id);
441        let count = defs.count();
442        let mut args = SmallVec::with_capacity(count);
443        Self::fill_item(&mut args, tcx, defs, &mut mk_kind);
444        tcx.mk_args(&args)
445    }
446
447    pub fn extend_to<F>(
448        &self,
449        tcx: TyCtxt<'tcx>,
450        def_id: DefId,
451        mut mk_kind: F,
452    ) -> GenericArgsRef<'tcx>
453    where
454        F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
455    {
456        Self::for_item(tcx, def_id, |param, args| {
457            self.get(param.index as usize).cloned().unwrap_or_else(|| mk_kind(param, args))
458        })
459    }
460
461    pub fn fill_item<F>(
462        args: &mut SmallVec<[GenericArg<'tcx>; 8]>,
463        tcx: TyCtxt<'tcx>,
464        defs: &ty::Generics,
465        mk_kind: &mut F,
466    ) where
467        F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
468    {
469        if let Some(def_id) = defs.parent {
470            let parent_defs = tcx.generics_of(def_id);
471            Self::fill_item(args, tcx, parent_defs, mk_kind);
472        }
473        Self::fill_single(args, defs, mk_kind)
474    }
475
476    pub fn fill_single<F>(
477        args: &mut SmallVec<[GenericArg<'tcx>; 8]>,
478        defs: &ty::Generics,
479        mk_kind: &mut F,
480    ) where
481        F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
482    {
483        args.reserve(defs.own_params.len());
484        for param in &defs.own_params {
485            let kind = mk_kind(param, args);
486            {
    match (&(param.index as usize), &args.len()) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val,
                    ::core::option::Option::Some(format_args!("{0:#?}, {1:#?}",
                            args, defs)));
            }
        }
    }
};assert_eq!(param.index as usize, args.len(), "{args:#?}, {defs:#?}");
487            args.push(kind);
488        }
489    }
490
491    // Extend an `original_args` list to the full number of args expected by `def_id`,
492    // filling in the missing parameters with error ty/ct or 'static regions.
493    pub fn extend_with_error(
494        tcx: TyCtxt<'tcx>,
495        def_id: DefId,
496        original_args: &[GenericArg<'tcx>],
497    ) -> GenericArgsRef<'tcx> {
498        ty::GenericArgs::for_item(tcx, def_id, |def, _| {
499            if let Some(arg) = original_args.get(def.index as usize) {
500                *arg
501            } else {
502                def.to_error(tcx)
503            }
504        })
505    }
506
507    #[inline]
508    pub fn types(&self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> {
509        self.iter().filter_map(|k| k.as_type())
510    }
511
512    #[inline]
513    pub fn regions(&self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> {
514        self.iter().filter_map(|k| k.as_region())
515    }
516
517    #[inline]
518    pub fn consts(&self) -> impl DoubleEndedIterator<Item = ty::Const<'tcx>> {
519        self.iter().filter_map(|k| k.as_const())
520    }
521
522    #[inline]
523    pub fn terms(&self) -> impl DoubleEndedIterator<Item = ty::Term<'tcx>> {
524        self.iter().filter_map(|k| k.as_term())
525    }
526
527    /// Returns generic arguments that are not lifetimes.
528    #[inline]
529    pub fn non_erasable_generics(&self) -> impl DoubleEndedIterator<Item = GenericArgKind<'tcx>> {
530        self.iter().filter_map(|arg| match arg.kind() {
531            ty::GenericArgKind::Lifetime(_) => None,
532            generic => Some(generic),
533        })
534    }
535
536    #[inline]
537    #[track_caller]
538    pub fn type_at(&self, i: usize) -> Ty<'tcx> {
539        self[i].as_type().unwrap_or_else(
540            #[track_caller]
541            || crate::util::bug::bug_fmt(format_args!("expected type for param #{0} in {1:?}",
        i, self))bug!("expected type for param #{} in {:?}", i, self),
542        )
543    }
544
545    #[inline]
546    #[track_caller]
547    pub fn region_at(&self, i: usize) -> ty::Region<'tcx> {
548        self[i].as_region().unwrap_or_else(
549            #[track_caller]
550            || crate::util::bug::bug_fmt(format_args!("expected region for param #{0} in {1:?}",
        i, self))bug!("expected region for param #{} in {:?}", i, self),
551        )
552    }
553
554    #[inline]
555    #[track_caller]
556    pub fn const_at(&self, i: usize) -> ty::Const<'tcx> {
557        self[i].as_const().unwrap_or_else(
558            #[track_caller]
559            || crate::util::bug::bug_fmt(format_args!("expected const for param #{0} in {1:?}",
        i, self))bug!("expected const for param #{} in {:?}", i, self),
560        )
561    }
562
563    #[inline]
564    #[track_caller]
565    pub fn type_for_def(&self, def: &ty::GenericParamDef) -> GenericArg<'tcx> {
566        self.type_at(def.index as usize).into()
567    }
568
569    /// Transform from generic args for a child of `source_ancestor`
570    /// (e.g., a trait or impl) to args for the same child
571    /// in a different item, with `target_args` as the base for
572    /// the target impl/trait, with the source child-specific
573    /// parameters (e.g., method parameters) on top of that base.
574    ///
575    /// For example given:
576    ///
577    /// ```no_run
578    /// trait X<S> { fn f<T>(); }
579    /// impl<U> X<U> for U { fn f<V>() {} }
580    /// ```
581    ///
582    /// * If `self` is `[Self, S, T]`: the identity args of `f` in the trait.
583    /// * If `source_ancestor` is the def_id of the trait.
584    /// * If `target_args` is `[U]`, the args for the impl.
585    /// * Then we will return `[U, T]`, the arg for `f` in the impl that
586    ///   are needed for it to match the trait.
587    pub fn rebase_onto(
588        &self,
589        tcx: TyCtxt<'tcx>,
590        source_ancestor: DefId,
591        target_args: GenericArgsRef<'tcx>,
592    ) -> GenericArgsRef<'tcx> {
593        let defs = tcx.generics_of(source_ancestor);
594        tcx.mk_args_from_iter(target_args.iter().chain(self.iter().skip(defs.count())))
595    }
596
597    /// Truncates this list of generic args to have at most the number of args in `generics`.
598    ///
599    /// You might be looking for [`TraitRef::from_assoc`](super::TraitRef::from_assoc).
600    pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> GenericArgsRef<'tcx> {
601        tcx.mk_args(&self[..generics.count()])
602    }
603
604    pub fn print_as_list(&self) -> String {
605        let v = self.iter().map(|arg| arg.to_string()).collect::<Vec<_>>();
606        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("[{0}]", v.join(", ")))
    })format!("[{}]", v.join(", "))
607    }
608}
609
610impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for GenericArgsRef<'tcx> {
611    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
612        self,
613        folder: &mut F,
614    ) -> Result<Self, F::Error> {
615        // This code is hot enough that it's worth specializing for the most
616        // common length lists, to avoid the overhead of `SmallVec` creation.
617        // The match arms are in order of frequency. The 1, 2, and 0 cases are
618        // typically hit in 90--99.99% of cases. When folding doesn't change
619        // the args, it's faster to reuse the existing args rather than
620        // calling `mk_args`.
621        match self.len() {
622            1 => {
623                let param0 = self[0].try_fold_with(folder)?;
624                if param0 == self[0] { Ok(self) } else { Ok(folder.cx().mk_args(&[param0])) }
625            }
626            2 => {
627                let param0 = self[0].try_fold_with(folder)?;
628                let param1 = self[1].try_fold_with(folder)?;
629                if param0 == self[0] && param1 == self[1] {
630                    Ok(self)
631                } else {
632                    Ok(folder.cx().mk_args(&[param0, param1]))
633                }
634            }
635            0 => Ok(self),
636            _ => ty::util::try_fold_list(self, folder, |tcx, v| tcx.mk_args(v)),
637        }
638    }
639
640    fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
641        // See justification for this behavior in `try_fold_with`.
642        match self.len() {
643            1 => {
644                let param0 = self[0].fold_with(folder);
645                if param0 == self[0] { self } else { folder.cx().mk_args(&[param0]) }
646            }
647            2 => {
648                let param0 = self[0].fold_with(folder);
649                let param1 = self[1].fold_with(folder);
650                if param0 == self[0] && param1 == self[1] {
651                    self
652                } else {
653                    folder.cx().mk_args(&[param0, param1])
654                }
655            }
656            0 => self,
657            _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_args(v)),
658        }
659    }
660}
661
662impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> {
663    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
664        self,
665        folder: &mut F,
666    ) -> Result<Self, F::Error> {
667        // This code is fairly hot, though not as hot as `GenericArgsRef`.
668        //
669        // When compiling stage 2, I get the following results:
670        //
671        // len |   total   |   %
672        // --- | --------- | -----
673        //  2  |  15083590 |  48.1
674        //  3  |   7540067 |  24.0
675        //  1  |   5300377 |  16.9
676        //  4  |   1351897 |   4.3
677        //  0  |   1256849 |   4.0
678        //
679        // I've tried it with some private repositories and got
680        // close to the same result, with 4 and 0 swapping places
681        // sometimes.
682        match self.len() {
683            2 => {
684                let param0 = self[0].try_fold_with(folder)?;
685                let param1 = self[1].try_fold_with(folder)?;
686                if param0 == self[0] && param1 == self[1] {
687                    Ok(self)
688                } else {
689                    Ok(folder.cx().mk_type_list(&[param0, param1]))
690                }
691            }
692            _ => ty::util::try_fold_list(self, folder, |tcx, v| tcx.mk_type_list(v)),
693        }
694    }
695
696    fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
697        // See comment justifying behavior in `try_fold_with`.
698        match self.len() {
699            2 => {
700                let param0 = self[0].fold_with(folder);
701                let param1 = self[1].fold_with(folder);
702                if param0 == self[0] && param1 == self[1] {
703                    self
704                } else {
705                    folder.cx().mk_type_list(&[param0, param1])
706                }
707            }
708            _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_type_list(v)),
709        }
710    }
711}
712
713impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for &'tcx ty::List<T> {
714    #[inline]
715    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
716        for elem in self.iter() {
    match ::rustc_ast_ir::visit::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(elem,
                visitor)) {
        core::ops::ControlFlow::Continue(()) =>
            (),
            #[allow(unreachable_code)]
            core::ops::ControlFlow::Break(r) => {
            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
        }
    };
};walk_visitable_list!(visitor, self.iter());
717        V::Result::output()
718    }
719}
720
721/// Stores the user-given args to reach some fully qualified path
722/// (e.g., `<T>::Item` or `<T as Trait>::Item`).
723#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for UserArgs<'tcx> { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for UserArgs<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for UserArgs<'tcx> {
    #[inline]
    fn clone(&self) -> UserArgs<'tcx> {
        let _: ::core::clone::AssertParamIsClone<GenericArgsRef<'tcx>>;
        let _: ::core::clone::AssertParamIsClone<Option<UserSelfTy<'tcx>>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for UserArgs<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "UserArgs",
            "args", &self.args, "user_self_ty", &&self.user_self_ty)
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::marker::StructuralPartialEq for UserArgs<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for UserArgs<'tcx> {
    #[inline]
    fn eq(&self, other: &UserArgs<'tcx>) -> bool {
        self.args == other.args && self.user_self_ty == other.user_self_ty
    }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for UserArgs<'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<GenericArgsRef<'tcx>>;
        let _: ::core::cmp::AssertParamIsEq<Option<UserSelfTy<'tcx>>>;
    }
}Eq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for UserArgs<'tcx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.args, state);
        ::core::hash::Hash::hash(&self.user_self_ty, state)
    }
}Hash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for UserArgs<'tcx> {
            fn encode(&self, __encoder: &mut __E) {
                let UserArgs {
                        args: ref __binding_0, user_self_ty: ref __binding_1 } =
                    *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                    __encoder);
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for UserArgs<'tcx> {
            fn decode(__decoder: &mut __D) -> Self {
                UserArgs {
                    args: ::rustc_serialize::Decodable::decode(__decoder),
                    user_self_ty: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable)]
724#[derive(const _: () =
    {
        impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
            UserArgs<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    UserArgs {
                        args: ref __binding_0, user_self_ty: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for UserArgs<'tcx> {
            fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        UserArgs { args: __binding_0, user_self_ty: __binding_1 } =>
                            {
                            UserArgs {
                                args: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                user_self_ty: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    UserArgs { args: __binding_0, user_self_ty: __binding_1 } =>
                        {
                        UserArgs {
                            args: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            user_self_ty: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for UserArgs<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    UserArgs {
                        args: ref __binding_0, user_self_ty: ref __binding_1 } => {
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_middle::ty::VisitorResult>::output()
            }
        }
    };TypeVisitable, const _: () =
    {
        impl<'tcx, '__lifted>
            ::rustc_middle::ty::Lift<::rustc_middle::ty::TyCtxt<'__lifted>>
            for UserArgs<'tcx> {
            type Lifted = UserArgs<'__lifted>;
            fn lift_to_interner(self,
                __tcx: ::rustc_middle::ty::TyCtxt<'__lifted>)
                -> UserArgs<'__lifted> {
                match self {
                    UserArgs { args: __binding_0, user_self_ty: __binding_1 } =>
                        {
                        UserArgs {
                            args: __tcx.lift(__binding_0),
                            user_self_ty: __tcx.lift(__binding_1),
                        }
                    }
                }
            }
        }
    };Lift)]
725pub struct UserArgs<'tcx> {
726    /// The args for the item as given by the user.
727    pub args: GenericArgsRef<'tcx>,
728
729    /// The self type, in the case of a `<T>::Item` path (when applied
730    /// to an inherent impl). See `UserSelfTy` below.
731    pub user_self_ty: Option<UserSelfTy<'tcx>>,
732}
733
734/// Specifies the user-given self type. In the case of a path that
735/// refers to a member in an inherent impl, this self type is
736/// sometimes needed to constrain the type parameters on the impl. For
737/// example, in this code:
738///
739/// ```ignore (illustrative)
740/// struct Foo<T> { }
741/// impl<A> Foo<A> { fn method() { } }
742/// ```
743///
744/// when you then have a path like `<Foo<&'static u32>>::method`,
745/// this struct would carry the `DefId` of the impl along with the
746/// self type `Foo<u32>`. Then we can instantiate the parameters of
747/// the impl (with the args from `UserArgs`) and apply those to
748/// the self type, giving `Foo<?A>`. Finally, we unify that with
749/// the self type here, which contains `?A` to be `&'static u32`
750#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for UserSelfTy<'tcx> { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for UserSelfTy<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for UserSelfTy<'tcx> {
    #[inline]
    fn clone(&self) -> UserSelfTy<'tcx> {
        let _: ::core::clone::AssertParamIsClone<DefId>;
        let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for UserSelfTy<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "UserSelfTy",
            "impl_def_id", &self.impl_def_id, "self_ty", &&self.self_ty)
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::marker::StructuralPartialEq for UserSelfTy<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for UserSelfTy<'tcx> {
    #[inline]
    fn eq(&self, other: &UserSelfTy<'tcx>) -> bool {
        self.impl_def_id == other.impl_def_id && self.self_ty == other.self_ty
    }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for UserSelfTy<'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<DefId>;
        let _: ::core::cmp::AssertParamIsEq<Ty<'tcx>>;
    }
}Eq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for UserSelfTy<'tcx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.impl_def_id, state);
        ::core::hash::Hash::hash(&self.self_ty, state)
    }
}Hash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for UserSelfTy<'tcx> {
            fn encode(&self, __encoder: &mut __E) {
                let UserSelfTy {
                        impl_def_id: ref __binding_0, self_ty: ref __binding_1 } =
                    *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                    __encoder);
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for UserSelfTy<'tcx> {
            fn decode(__decoder: &mut __D) -> Self {
                UserSelfTy {
                    impl_def_id: ::rustc_serialize::Decodable::decode(__decoder),
                    self_ty: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable)]
751#[derive(const _: () =
    {
        impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
            UserSelfTy<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    UserSelfTy {
                        impl_def_id: ref __binding_0, self_ty: ref __binding_1 } =>
                        {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for UserSelfTy<'tcx> {
            fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        UserSelfTy { impl_def_id: __binding_0, self_ty: __binding_1
                            } => {
                            UserSelfTy {
                                impl_def_id: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                self_ty: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    UserSelfTy { impl_def_id: __binding_0, self_ty: __binding_1
                        } => {
                        UserSelfTy {
                            impl_def_id: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            self_ty: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for UserSelfTy<'tcx> {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    UserSelfTy {
                        impl_def_id: ref __binding_0, self_ty: ref __binding_1 } =>
                        {
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_middle::ty::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_middle::ty::VisitorResult>::output()
            }
        }
    };TypeVisitable, const _: () =
    {
        impl<'tcx, '__lifted>
            ::rustc_middle::ty::Lift<::rustc_middle::ty::TyCtxt<'__lifted>>
            for UserSelfTy<'tcx> {
            type Lifted = UserSelfTy<'__lifted>;
            fn lift_to_interner(self,
                __tcx: ::rustc_middle::ty::TyCtxt<'__lifted>)
                -> UserSelfTy<'__lifted> {
                match self {
                    UserSelfTy { impl_def_id: __binding_0, self_ty: __binding_1
                        } => {
                        UserSelfTy {
                            impl_def_id: __tcx.lift(__binding_0),
                            self_ty: __tcx.lift(__binding_1),
                        }
                    }
                }
            }
        }
    };Lift)]
752pub struct UserSelfTy<'tcx> {
753    pub impl_def_id: DefId,
754    pub self_ty: Ty<'tcx>,
755}