Skip to main content

rustc_middle/ty/
generic_args.rs

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