1use 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_span::bug;
14use rustc_type_ir::WithCachedTypeInfo;
15use rustc_type_ir::walk::TypeWalker;
16use smallvec::SmallVec;
17
18use crate::ty::codec::{TyDecoder, TyEncoder};
19use crate::ty::{
20 self, ClosureArgs, CoroutineArgs, CoroutineClosureArgs, FallibleTypeFolder, InlineConstArgs,
21 Lift, List, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, VisitorResult,
22 walk_visitable_list,
23};
24
25pub type GenericArgKind<'tcx> = rustc_type_ir::GenericArgKind<TyCtxt<'tcx>>;
26pub type TermKind<'tcx> = rustc_type_ir::TermKind<TyCtxt<'tcx>>;
27
28#[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)]
37pub struct GenericArg<'tcx> {
38 ptr: NonNull<()>,
39 marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
40}
41
42impl<'tcx> rustc_type_ir::inherent::GenericArg<TyCtxt<'tcx>> for GenericArg<'tcx> {}
43
44impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArgsRef<'tcx> {
45 fn rebase_onto(
46 self,
47 tcx: TyCtxt<'tcx>,
48 source_ancestor: DefId,
49 target_args: GenericArgsRef<'tcx>,
50 ) -> GenericArgsRef<'tcx> {
51 self.rebase_onto(tcx, source_ancestor, target_args)
52 }
53
54 #[track_caller]
55 fn type_at(self, i: usize) -> Ty<'tcx> {
56 self.type_at(i)
57 }
58
59 #[track_caller]
60 fn region_at(self, i: usize) -> ty::Region<'tcx> {
61 self.region_at(i)
62 }
63
64 #[track_caller]
65 fn const_at(self, i: usize) -> ty::Const<'tcx> {
66 self.const_at(i)
67 }
68
69 fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
70 GenericArgs::identity_for_item(tcx, def_id)
71 }
72
73 fn extend_with_error(
74 tcx: TyCtxt<'tcx>,
75 def_id: DefId,
76 original_args: &[ty::GenericArg<'tcx>],
77 ) -> ty::GenericArgsRef<'tcx> {
78 ty::GenericArgs::extend_with_error(tcx, def_id, original_args)
79 }
80
81 fn split_closure_args(self) -> ty::ClosureArgsParts<TyCtxt<'tcx>> {
82 match self[..] {
83 [ref parent_args @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
84 ty::ClosureArgsParts {
85 parent_args,
86 closure_kind_ty: closure_kind_ty.expect_ty(),
87 closure_sig_as_fn_ptr_ty: closure_sig_as_fn_ptr_ty.expect_ty(),
88 tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
89 }
90 }
91 _ => ::rustc_span::macros::bug_impl(None,
format_args!("closure args missing synthetics"), Location::caller())bug!("closure args missing synthetics"),
92 }
93 }
94
95 fn split_coroutine_closure_args(self) -> ty::CoroutineClosureArgsParts<TyCtxt<'tcx>> {
96 match self[..] {
97 [
98 ref parent_args @ ..,
99 closure_kind_ty,
100 signature_parts_ty,
101 tupled_upvars_ty,
102 coroutine_captures_by_ref_ty,
103 ] => ty::CoroutineClosureArgsParts {
104 parent_args,
105 closure_kind_ty: closure_kind_ty.expect_ty(),
106 signature_parts_ty: signature_parts_ty.expect_ty(),
107 tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
108 coroutine_captures_by_ref_ty: coroutine_captures_by_ref_ty.expect_ty(),
109 },
110 _ => ::rustc_span::macros::bug_impl(None,
format_args!("closure args missing synthetics"), Location::caller())bug!("closure args missing synthetics"),
111 }
112 }
113
114 fn split_coroutine_args(self) -> ty::CoroutineArgsParts<TyCtxt<'tcx>> {
115 match self[..] {
116 [ref parent_args @ .., kind_ty, resume_ty, yield_ty, return_ty, tupled_upvars_ty] => {
117 ty::CoroutineArgsParts {
118 parent_args,
119 kind_ty: kind_ty.expect_ty(),
120 resume_ty: resume_ty.expect_ty(),
121 yield_ty: yield_ty.expect_ty(),
122 return_ty: return_ty.expect_ty(),
123 tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
124 }
125 }
126 _ => ::rustc_span::macros::bug_impl(None,
format_args!("coroutine args missing synthetics"), Location::caller())bug!("coroutine args missing synthetics"),
127 }
128 }
129}
130
131impl<'tcx> rustc_type_ir::inherent::IntoKind for GenericArg<'tcx> {
132 type Kind = GenericArgKind<'tcx>;
133
134 #[inline]
135 fn kind(self) -> Self::Kind {
136 self.kind()
137 }
138}
139
140unsafe impl<'tcx> rustc_data_structures::sync::DynSend for GenericArg<'tcx> where
141 &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSend
142{
143}
144unsafe impl<'tcx> rustc_data_structures::sync::DynSync for GenericArg<'tcx> where
145 &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSync
146{
147}
148unsafe impl<'tcx> Send for GenericArg<'tcx> where
149 &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): Send
150{
151}
152unsafe impl<'tcx> Sync for GenericArg<'tcx> where
153 &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): Sync
154{
155}
156
157impl<'tcx> IntoDiagArg for GenericArg<'tcx> {
158 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
159 self.to_string().into_diag_arg(&mut None)
160 }
161}
162
163const TAG_MASK: usize = 0b11;
164const TYPE_TAG: usize = 0b00;
165const REGION_TAG: usize = 0b01;
166const CONST_TAG: usize = 0b10;
167
168trait 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>)]
169impl<'tcx> GenericArgKind<'tcx> {
170 #[inline]
171 fn pack(self) -> GenericArg<'tcx> {
172 let (tag, ptr) = match self {
173 GenericArgKind::Lifetime(lt) => {
174 assert_eq!(align_of_val(&*lt.0.0) & TAG_MASK, 0);
176 (REGION_TAG, NonNull::from(lt.0.0).cast())
177 }
178 GenericArgKind::Type(ty) => {
179 assert_eq!(align_of_val(&*ty.0.0) & TAG_MASK, 0);
181 (TYPE_TAG, NonNull::from(ty.0.0).cast())
182 }
183 GenericArgKind::Const(ct) => {
184 assert_eq!(align_of_val(&*ct.0.0) & TAG_MASK, 0);
186 (CONST_TAG, NonNull::from(ct.0.0).cast())
187 }
188 };
189
190 GenericArg { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData }
191 }
192}
193
194impl<'tcx> From<ty::Region<'tcx>> for GenericArg<'tcx> {
195 #[inline]
196 fn from(r: ty::Region<'tcx>) -> GenericArg<'tcx> {
197 GenericArgKind::Lifetime(r).pack()
198 }
199}
200
201impl<'tcx> From<Ty<'tcx>> for GenericArg<'tcx> {
202 #[inline]
203 fn from(ty: Ty<'tcx>) -> GenericArg<'tcx> {
204 GenericArgKind::Type(ty).pack()
205 }
206}
207
208impl<'tcx> From<ty::Const<'tcx>> for GenericArg<'tcx> {
209 #[inline]
210 fn from(c: ty::Const<'tcx>) -> GenericArg<'tcx> {
211 GenericArgKind::Const(c).pack()
212 }
213}
214
215impl<'tcx> From<ty::Term<'tcx>> for GenericArg<'tcx> {
216 fn from(value: ty::Term<'tcx>) -> Self {
217 match value.kind() {
218 ty::TermKind::Ty(t) => t.into(),
219 ty::TermKind::Const(c) => c.into(),
220 }
221 }
222}
223
224impl<'tcx> GenericArg<'tcx> {
225 #[inline]
226 pub fn kind(self) -> GenericArgKind<'tcx> {
227 let ptr =
228 unsafe { self.ptr.map_addr(|addr| NonZero::new_unchecked(addr.get() & !TAG_MASK)) };
229 unsafe {
233 match self.ptr.addr().get() & TAG_MASK {
234 REGION_TAG => GenericArgKind::Lifetime(ty::Region(Interned::new_unchecked(
235 ptr.cast::<ty::RegionKind<'tcx>>().as_ref(),
236 ))),
237 TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
238 ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
239 ))),
240 CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
241 ptr.cast::<WithCachedTypeInfo<ty::ConstKind<'tcx>>>().as_ref(),
242 ))),
243 _ => intrinsics::unreachable(),
244 }
245 }
246 }
247
248 #[inline]
249 pub fn as_region(self) -> Option<ty::Region<'tcx>> {
250 match self.kind() {
251 GenericArgKind::Lifetime(re) => Some(re),
252 _ => None,
253 }
254 }
255
256 #[inline]
257 pub fn as_type(self) -> Option<Ty<'tcx>> {
258 match self.kind() {
259 GenericArgKind::Type(ty) => Some(ty),
260 _ => None,
261 }
262 }
263
264 #[inline]
265 pub fn as_const(self) -> Option<ty::Const<'tcx>> {
266 match self.kind() {
267 GenericArgKind::Const(ct) => Some(ct),
268 _ => None,
269 }
270 }
271
272 #[inline]
273 pub fn as_term(self) -> Option<ty::Term<'tcx>> {
274 match self.kind() {
275 GenericArgKind::Lifetime(_) => None,
276 GenericArgKind::Type(ty) => Some(ty.into()),
277 GenericArgKind::Const(ct) => Some(ct.into()),
278 }
279 }
280
281 pub fn expect_region(self) -> ty::Region<'tcx> {
283 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"))
284 }
285
286 pub fn expect_ty(self) -> Ty<'tcx> {
290 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"))
291 }
292
293 pub fn expect_const(self) -> ty::Const<'tcx> {
295 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"))
296 }
297
298 pub fn is_non_region_infer(self) -> bool {
299 match self.kind() {
300 GenericArgKind::Lifetime(_) => false,
301 GenericArgKind::Type(ty) => ty.is_ty_or_numeric_infer(),
303 GenericArgKind::Const(ct) => ct.is_ct_infer(),
304 }
305 }
306
307 pub fn walk(self) -> TypeWalker<TyCtxt<'tcx>> {
318 TypeWalker::new(self)
319 }
320}
321
322impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for GenericArg<'a> {
323 type Lifted = GenericArg<'tcx>;
324
325 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
326 match self.kind() {
327 GenericArgKind::Lifetime(lt) => tcx.lift(lt).into(),
328 GenericArgKind::Type(ty) => tcx.lift(ty).into(),
329 GenericArgKind::Const(ct) => tcx.lift(ct).into(),
330 }
331 }
332}
333
334impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for GenericArg<'tcx> {
335 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
336 self,
337 folder: &mut F,
338 ) -> Result<Self, F::Error> {
339 match self.kind() {
340 GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into),
341 GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into),
342 GenericArgKind::Const(ct) => ct.try_fold_with(folder).map(Into::into),
343 }
344 }
345
346 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
347 match self.kind() {
348 GenericArgKind::Lifetime(lt) => lt.fold_with(folder).into(),
349 GenericArgKind::Type(ty) => ty.fold_with(folder).into(),
350 GenericArgKind::Const(ct) => ct.fold_with(folder).into(),
351 }
352 }
353}
354
355impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for GenericArg<'tcx> {
356 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
357 match self.kind() {
358 GenericArgKind::Lifetime(lt) => lt.visit_with(visitor),
359 GenericArgKind::Type(ty) => ty.visit_with(visitor),
360 GenericArgKind::Const(ct) => ct.visit_with(visitor),
361 }
362 }
363}
364
365impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for GenericArg<'tcx> {
366 fn encode(&self, e: &mut E) {
367 self.kind().encode(e)
368 }
369}
370
371impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for GenericArg<'tcx> {
372 fn decode(d: &mut D) -> GenericArg<'tcx> {
373 GenericArgKind::decode(d).pack()
374 }
375}
376
377pub type GenericArgs<'tcx> = List<GenericArg<'tcx>>;
379
380pub type GenericArgsRef<'tcx> = &'tcx GenericArgs<'tcx>;
381
382impl<'tcx> GenericArgs<'tcx> {
383 pub fn into_type_list(&self, tcx: TyCtxt<'tcx>) -> &'tcx List<Ty<'tcx>> {
389 tcx.mk_type_list_from_iter(self.iter().map(|arg| match arg.kind() {
390 GenericArgKind::Type(ty) => ty,
391 _ => ::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"),
392 }))
393 }
394
395 pub fn as_closure(&'tcx self) -> ClosureArgs<TyCtxt<'tcx>> {
400 ClosureArgs { args: self }
401 }
402
403 pub fn as_coroutine_closure(&'tcx self) -> CoroutineClosureArgs<TyCtxt<'tcx>> {
408 CoroutineClosureArgs { args: self }
409 }
410
411 pub fn as_coroutine(&'tcx self) -> CoroutineArgs<TyCtxt<'tcx>> {
416 CoroutineArgs { args: self }
417 }
418
419 pub fn as_inline_const(&'tcx self) -> InlineConstArgs<'tcx> {
424 InlineConstArgs { args: self }
425 }
426
427 pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: impl Into<DefId>) -> GenericArgsRef<'tcx> {
429 Self::for_item(tcx, def_id.into(), |param, _| tcx.mk_param_from_def(param))
430 }
431
432 pub fn for_item<F>(tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> GenericArgsRef<'tcx>
438 where
439 F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
440 {
441 let defs = tcx.generics_of(def_id);
442 let count = defs.count();
443 let mut args = SmallVec::with_capacity(count);
444 Self::fill_item(&mut args, tcx, defs, &mut mk_kind);
445 tcx.mk_args(&args)
446 }
447
448 pub fn extend_to<F>(
449 &self,
450 tcx: TyCtxt<'tcx>,
451 def_id: DefId,
452 mut mk_kind: F,
453 ) -> GenericArgsRef<'tcx>
454 where
455 F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
456 {
457 Self::for_item(tcx, def_id, |param, args| {
458 self.get(param.index as usize).cloned().unwrap_or_else(|| mk_kind(param, args))
459 })
460 }
461
462 pub fn fill_item<F>(
463 args: &mut SmallVec<[GenericArg<'tcx>; 8]>,
464 tcx: TyCtxt<'tcx>,
465 defs: &ty::Generics,
466 mk_kind: &mut F,
467 ) where
468 F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
469 {
470 if let Some(def_id) = defs.parent {
471 let parent_defs = tcx.generics_of(def_id);
472 Self::fill_item(args, tcx, parent_defs, mk_kind);
473 }
474 Self::fill_single(args, defs, mk_kind)
475 }
476
477 pub fn fill_single<F>(
478 args: &mut SmallVec<[GenericArg<'tcx>; 8]>,
479 defs: &ty::Generics,
480 mk_kind: &mut F,
481 ) where
482 F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
483 {
484 args.reserve(defs.own_params.len());
485 for param in &defs.own_params {
486 let kind = mk_kind(param, args);
487 {
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:#?}");
488 args.push(kind);
489 }
490 }
491
492 pub fn extend_with_error(
495 tcx: TyCtxt<'tcx>,
496 def_id: DefId,
497 original_args: &[GenericArg<'tcx>],
498 ) -> GenericArgsRef<'tcx> {
499 ty::GenericArgs::for_item(tcx, def_id, |def, _| {
500 if let Some(arg) = original_args.get(def.index as usize) {
501 *arg
502 } else {
503 def.to_error(tcx)
504 }
505 })
506 }
507
508 #[inline]
509 pub fn types(&self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> {
510 self.iter().filter_map(|k| k.as_type())
511 }
512
513 #[inline]
514 pub fn regions(&self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> {
515 self.iter().filter_map(|k| k.as_region())
516 }
517
518 #[inline]
519 pub fn consts(&self) -> impl DoubleEndedIterator<Item = ty::Const<'tcx>> {
520 self.iter().filter_map(|k| k.as_const())
521 }
522
523 #[inline]
524 pub fn terms(&self) -> impl DoubleEndedIterator<Item = ty::Term<'tcx>> {
525 self.iter().filter_map(|k| k.as_term())
526 }
527
528 #[inline]
530 pub fn non_erasable_generics(&self) -> impl DoubleEndedIterator<Item = GenericArgKind<'tcx>> {
531 self.iter().filter_map(|arg| match arg.kind() {
532 ty::GenericArgKind::Lifetime(_) => None,
533 generic => Some(generic),
534 })
535 }
536
537 #[inline]
538 #[track_caller]
539 pub fn type_at(&self, i: usize) -> Ty<'tcx> {
540 self[i].as_type().unwrap_or_else(
541 #[track_caller]
542 || ::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),
543 )
544 }
545
546 #[inline]
547 #[track_caller]
548 pub fn region_at(&self, i: usize) -> ty::Region<'tcx> {
549 self[i].as_region().unwrap_or_else(
550 #[track_caller]
551 || ::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),
552 )
553 }
554
555 #[inline]
556 #[track_caller]
557 pub fn const_at(&self, i: usize) -> ty::Const<'tcx> {
558 self[i].as_const().unwrap_or_else(
559 #[track_caller]
560 || ::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),
561 )
562 }
563
564 #[inline]
565 #[track_caller]
566 pub fn type_for_def(&self, def: &ty::GenericParamDef) -> GenericArg<'tcx> {
567 self.type_at(def.index as usize).into()
568 }
569
570 pub fn rebase_onto(
589 &self,
590 tcx: TyCtxt<'tcx>,
591 source_ancestor: DefId,
592 target_args: GenericArgsRef<'tcx>,
593 ) -> GenericArgsRef<'tcx> {
594 let defs = tcx.generics_of(source_ancestor);
595 tcx.mk_args_from_iter(target_args.iter().chain(self.iter().skip(defs.count())))
596 }
597
598 pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> GenericArgsRef<'tcx> {
602 tcx.mk_args(&self[..generics.count()])
603 }
604
605 pub fn print_as_list(&self) -> String {
606 let v = self.iter().map(|arg| arg.to_string()).collect::<Vec<_>>();
607 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("[{0}]", v.join(", ")))
})format!("[{}]", v.join(", "))
608 }
609}
610
611impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for GenericArgsRef<'tcx> {
612 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
613 self,
614 folder: &mut F,
615 ) -> Result<Self, F::Error> {
616 match self.len() {
623 1 => {
624 let param0 = self[0].try_fold_with(folder)?;
625 if param0 == self[0] { Ok(self) } else { Ok(folder.cx().mk_args(&[param0])) }
626 }
627 2 => {
628 let param0 = self[0].try_fold_with(folder)?;
629 let param1 = self[1].try_fold_with(folder)?;
630 if param0 == self[0] && param1 == self[1] {
631 Ok(self)
632 } else {
633 Ok(folder.cx().mk_args(&[param0, param1]))
634 }
635 }
636 0 => Ok(self),
637 _ => ty::util::try_fold_list(self, folder, |tcx, v| tcx.mk_args(v)),
638 }
639 }
640
641 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
642 match self.len() {
644 1 => {
645 let param0 = self[0].fold_with(folder);
646 if param0 == self[0] { self } else { folder.cx().mk_args(&[param0]) }
647 }
648 2 => {
649 let param0 = self[0].fold_with(folder);
650 let param1 = self[1].fold_with(folder);
651 if param0 == self[0] && param1 == self[1] {
652 self
653 } else {
654 folder.cx().mk_args(&[param0, param1])
655 }
656 }
657 0 => self,
658 _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_args(v)),
659 }
660 }
661}
662
663impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> {
664 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
665 self,
666 folder: &mut F,
667 ) -> Result<Self, F::Error> {
668 match self.len() {
684 2 => {
685 let param0 = self[0].try_fold_with(folder)?;
686 let param1 = self[1].try_fold_with(folder)?;
687 if param0 == self[0] && param1 == self[1] {
688 Ok(self)
689 } else {
690 Ok(folder.cx().mk_type_list(&[param0, param1]))
691 }
692 }
693 _ => ty::util::try_fold_list(self, folder, |tcx, v| tcx.mk_type_list(v)),
694 }
695 }
696
697 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
698 match self.len() {
700 2 => {
701 let param0 = self[0].fold_with(folder);
702 let param1 = self[1].fold_with(folder);
703 if param0 == self[0] && param1 == self[1] {
704 self
705 } else {
706 folder.cx().mk_type_list(&[param0, param1])
707 }
708 }
709 _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_type_list(v)),
710 }
711 }
712}
713
714impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for &'tcx ty::List<T> {
715 #[inline]
716 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
717 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());
718 V::Result::output()
719 }
720}
721
722#[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<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: &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<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)]
725#[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)]
726pub struct UserArgs<'tcx> {
727 pub args: GenericArgsRef<'tcx>,
729
730 pub user_self_ty: Option<UserSelfTy<'tcx>>,
733}
734
735#[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.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: &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)]
752#[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)]
753pub struct UserSelfTy<'tcx> {
754 pub impl_def_id: DefId,
755 pub self_ty: Ty<'tcx>,
756}