1use std::collections::HashMap;
4
5use crate::hax::prelude::*;
6use crate::hax::sinto_as_usize;
7use crate::hax::sinto_todo;
8
9use charon_lib::ast::HashConsed;
10use rustc_middle::ty;
11use rustc_span::def_id::DefId as RDefId;
12use rustc_type_ir::inherent::IntoKind;
13
14sinto_reexport!(rustc_abi::ExternAbi);
15
16#[derive(Clone, Debug, Hash, PartialEq, Eq)]
20pub struct Decorated<T> {
21 pub ty: Ty,
22 pub contents: Box<T>,
23}
24
25#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
28#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::ParamTy, state: S as gstate)]
29pub struct ParamTy {
30 pub index: u32,
31 pub name: Symbol,
32}
33
34#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
37#[args(<S>, from: ty::ParamConst, state: S as gstate)]
38pub struct ParamConst {
39 pub index: u32,
40 pub name: Symbol,
41}
42
43#[derive(AdtInto)]
47#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::ExistentialPredicate<'tcx>, state: S as state)]
48#[derive(Clone, Debug, Hash, PartialEq, Eq)]
49pub enum ExistentialPredicate {
50 Trait(ExistentialTraitRef),
53 Projection(ExistentialProjection),
55 AutoTrait(DefId),
57}
58
59#[derive(AdtInto)]
61#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: rustc_type_ir::ExistentialTraitRef<ty::TyCtxt<'tcx>>, state: S as state)]
62#[derive(Clone, Debug, Hash, PartialEq, Eq)]
63pub struct ExistentialTraitRef {
64 pub def_id: DefId,
65 pub args: Vec<GenericArg>,
66}
67
68#[derive(AdtInto)]
70#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: rustc_type_ir::ExistentialProjection<ty::TyCtxt<'tcx>>, state: S as state)]
71#[derive(Clone, Debug, Hash, PartialEq, Eq)]
72pub struct ExistentialProjection {
73 pub def_id: DefId,
74 pub args: Vec<GenericArg>,
75 pub term: Term,
76}
77
78#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
81#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::BoundTyKind<'tcx>, state: S as s)]
82pub enum BoundTyKind {
83 Anon,
84 #[custom_arm(&FROM_TYPE::Param(def_id) => TO_TYPE::Param(def_id.sinto(s), s.base().tcx.item_name(def_id).sinto(s)),)]
85 Param(DefId, Symbol),
86}
87
88#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
91#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::BoundTy<'tcx>, state: S as s)]
92pub struct BoundTy {
93 pub var: BoundVar,
94 pub kind: BoundTyKind,
95}
96
97sinto_as_usize!(rustc_middle::ty, BoundVar);
98
99#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
102#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::BoundRegionKind<'tcx>, state: S as s)]
103pub enum BoundRegionKind {
104 Anon,
105 NamedForPrinting(Symbol),
106 #[custom_arm(&FROM_TYPE::Named(def_id) => TO_TYPE::Named(def_id.sinto(s), s.base().tcx.item_name(def_id).sinto(s)),)]
107 Named(DefId, Symbol),
108 ClosureEnv,
109}
110
111#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
114#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::BoundRegion<'tcx>, state: S as s)]
115pub struct BoundRegion {
116 pub var: BoundVar,
117 pub kind: BoundRegionKind,
118}
119
120pub type PlaceholderRegion = Placeholder<BoundRegion>;
122pub type PlaceholderConst = Placeholder<BoundVar>;
124pub type PlaceholderType = Placeholder<BoundTy>;
126
127#[derive(Clone, Debug, Hash, PartialEq, Eq)]
130pub struct Placeholder<T> {
131 pub bound: T,
132}
133
134impl<'tcx, S: UnderOwnerState<'tcx>, T: SInto<S, U>, U> SInto<S, Placeholder<U>>
135 for ty::Placeholder<ty::TyCtxt<'tcx>, T>
136{
137 fn sinto(&self, s: &S) -> Placeholder<U> {
138 Placeholder {
139 bound: self.bound.sinto(s),
140 }
141 }
142}
143
144#[derive(Clone, Debug)]
147pub struct Canonical<T> {
148 pub value: T,
149}
150pub type CanonicalUserType = Canonical<UserType>;
152
153impl<'tcx, S: UnderOwnerState<'tcx>, T: SInto<S, U>, U> SInto<S, Canonical<U>>
154 for rustc_middle::infer::canonical::Canonical<'tcx, T>
155{
156 fn sinto(&self, s: &S) -> Canonical<U> {
157 Canonical {
158 value: self.value.sinto(s),
159 }
160 }
161}
162
163#[derive(AdtInto, Clone, Debug)]
166#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::UserSelfTy<'tcx>, state: S as gstate)]
167pub struct UserSelfTy {
168 pub impl_def_id: DefId,
169 pub self_ty: Ty,
170}
171
172#[derive(AdtInto, Clone, Debug)]
175#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::UserArgs<'tcx>, state: S as gstate)]
176pub struct UserArgs {
177 pub args: Vec<GenericArg>,
178 pub user_self_ty: Option<UserSelfTy>,
179}
180
181#[derive(AdtInto, Clone, Debug)]
186#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::UserType<'tcx>, state: S as _s)]
187pub enum UserType {
188 #[todo]
211 Todo(String),
212}
213
214#[derive(AdtInto, Clone, Debug)]
217#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::VariantDiscr, state: S as gstate)]
218pub enum DiscriminantDefinition {
219 Explicit(DefId),
220 Relative(u32),
221}
222
223#[derive(AdtInto, Clone, Debug)]
226#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::util::Discr<'tcx>, state: S as gstate)]
227pub struct DiscriminantValue {
228 pub val: u128,
229 pub ty: Ty,
230}
231
232#[derive(Clone, Debug)]
235pub enum Visibility<Id> {
236 Public,
237 Restricted(Id),
238}
239
240impl<S, T: SInto<S, U>, U> SInto<S, Visibility<U>> for ty::Visibility<T> {
241 fn sinto(&self, s: &S) -> Visibility<U> {
242 use ty::Visibility as T;
243 match self {
244 T::Public => Visibility::Public,
245 T::Restricted(id) => Visibility::Restricted(id.sinto(s)),
246 }
247 }
248}
249
250#[derive(Clone, Debug)]
253pub struct FieldDef {
254 pub did: DefId,
255 pub name: Option<Symbol>,
259 pub vis: Visibility<DefId>,
260 pub ty: Ty,
261 pub span: Span,
262}
263
264impl FieldDef {
265 pub fn sfrom<'tcx, S: UnderOwnerState<'tcx>>(
266 s: &S,
267 fdef: &ty::FieldDef,
268 instantiate: ty::GenericArgsRef<'tcx>,
269 ) -> FieldDef {
270 let tcx = s.base().tcx;
271 let ty = normalize(tcx, s.typing_env(), fdef.ty(tcx, instantiate)).sinto(s);
272 let name = {
273 let name = fdef.name.sinto(s);
274 let is_user_provided = {
275 name.to_string().parse::<usize>().is_err()
279 };
280 is_user_provided.then_some(name)
281 };
282
283 FieldDef {
284 did: fdef.did.sinto(s),
285 name,
286 vis: fdef.vis.map_id(|mod_id| mod_id.to_def_id()).sinto(s),
287 ty,
288 span: tcx.def_span(fdef.did).sinto(s),
289 }
290 }
291}
292
293#[derive(Clone, Debug)]
296pub struct VariantDef {
297 pub def_id: DefId,
298 pub ctor: Option<(CtorKind, DefId)>,
299 pub name: Symbol,
300 pub discr_def: DiscriminantDefinition,
301 pub discr_val: DiscriminantValue,
302 pub fields: IndexVec<FieldIdx, FieldDef>,
306 pub span: Span,
308}
309
310impl VariantDef {
311 pub(crate) fn sfrom<'tcx, S: UnderOwnerState<'tcx>>(
312 s: &S,
313 def: &ty::VariantDef,
314 discr_val: ty::util::Discr<'tcx>,
315 instantiate: Option<ty::GenericArgsRef<'tcx>>,
316 ) -> Self {
317 let def_id = def.def_id.sinto(s);
318 let instantiate = instantiate.unwrap_or_else(|| def_id.identity_args(s));
319 VariantDef {
320 def_id,
321 ctor: def.ctor.sinto(s),
322 name: def.name.sinto(s),
323 discr_def: def.discr.sinto(s),
324 discr_val: discr_val.sinto(s),
325 fields: def
326 .fields
327 .iter()
328 .map(|f| FieldDef::sfrom(s, f, instantiate))
329 .collect(),
330 span: s.base().tcx.def_span(def.def_id).sinto(s),
331 }
332 }
333}
334
335#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
338#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::EarlyParamRegion, state: S as s)]
339pub struct EarlyParamRegion {
340 pub index: u32,
341 pub name: Symbol,
342}
343
344#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
347#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::LateParamRegion<'tcx>, state: S as s)]
348pub struct LateParamRegion {
349 pub scope: DefId,
350 pub kind: LateParamRegionKind,
351}
352
353#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
356#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::LateParamRegionKind, state: S as s)]
357pub enum LateParamRegionKind {
358 Anon(u32),
359 NamedAnon(u32, Symbol),
360 #[custom_arm(&FROM_TYPE::Named(def_id) => TO_TYPE::Named(def_id.sinto(s), s.base().tcx.item_name(def_id).sinto(s)),)]
361 Named(DefId, Symbol),
362 ClosureEnv,
363}
364
365#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
368#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::RegionKind<'tcx>, state: S as gstate)]
369pub enum RegionKind {
370 ReEarlyParam(EarlyParamRegion),
371 ReBound(BoundVarIndexKind, BoundRegion),
372 ReLateParam(LateParamRegion),
373 ReStatic,
374 ReVar(RegionVid),
375 RePlaceholder(PlaceholderRegion),
376 ReErased,
377 ReError(ErrorGuaranteed),
378}
379
380#[derive(AdtInto, Clone, Copy, Debug, Hash, PartialEq, Eq)]
383#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::BoundVarIndexKind, state: S as gstate)]
384pub enum BoundVarIndexKind {
385 Bound(DebruijnIndex),
386 Canonical,
387}
388
389sinto_as_usize!(rustc_middle::ty, DebruijnIndex);
390sinto_as_usize!(rustc_middle::ty, RegionVid);
391
392#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
395#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::Region<'tcx>, state: S as s)]
396pub struct Region {
397 #[value(self.kind().sinto(s))]
398 pub kind: RegionKind,
399}
400
401#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
404#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::GenericArgKind<'tcx>, state: S as s)]
405pub enum GenericArg {
406 Lifetime(Region),
407 Type(Ty),
408 Const(ConstantExpr),
409}
410
411impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, GenericArg> for ty::GenericArg<'tcx> {
412 fn sinto(&self, s: &S) -> GenericArg {
413 self.kind().sinto(s)
414 }
415}
416
417impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Vec<GenericArg>> for ty::GenericArgsRef<'tcx> {
418 fn sinto(&self, s: &S) -> Vec<GenericArg> {
419 self.iter().map(|v| v.kind().sinto(s)).collect()
420 }
421}
422
423#[derive(AdtInto)]
425#[args(<'tcx, S: BaseState<'tcx>>, from: rustc_ast::ast::LitIntType, state: S as gstate)]
426#[derive(Clone, Debug, Hash, PartialEq, Eq)]
427pub enum LitIntType {
428 Signed(IntTy),
429 Unsigned(UintTy),
430 Unsuffixed,
431}
432
433#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
436#[args(<'tcx, S>, from: ty::InferTy, state: S as gstate)]
437pub enum InferTy {
438 #[custom_arm(FROM_TYPE::TyVar(..) => TO_TYPE::TyVar,)]
439 TyVar, #[custom_arm(FROM_TYPE::IntVar(..) => TO_TYPE::IntVar,)]
441 IntVar, #[custom_arm(FROM_TYPE::FloatVar(..) => TO_TYPE::FloatVar,)]
443 FloatVar, FreshTy(u32),
445 FreshIntTy(u32),
446 FreshFloatTy(u32),
447}
448
449#[derive(AdtInto)]
451#[args(<S>, from: rustc_type_ir::IntTy, state: S as _s)]
452#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
453pub enum IntTy {
454 Isize,
455 I8,
456 I16,
457 I32,
458 I64,
459 I128,
460}
461
462#[derive(AdtInto)]
464#[args(<S>, from: rustc_type_ir::FloatTy, state: S as _s)]
465#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
466pub enum FloatTy {
467 F16,
468 F32,
469 F64,
470 F128,
471}
472
473#[derive(AdtInto)]
475#[args(<S>, from: rustc_type_ir::UintTy, state: S as _s)]
476#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
477pub enum UintTy {
478 Usize,
479 U8,
480 U16,
481 U32,
482 U64,
483 U128,
484}
485
486#[allow(clippy::to_string_trait_impl)]
487impl ToString for IntTy {
488 fn to_string(&self) -> String {
489 use IntTy::*;
490 match self {
491 Isize => "isize".to_string(),
492 I8 => "i8".to_string(),
493 I16 => "i16".to_string(),
494 I32 => "i32".to_string(),
495 I64 => "i64".to_string(),
496 I128 => "i128".to_string(),
497 }
498 }
499}
500
501#[allow(clippy::to_string_trait_impl)]
502impl ToString for UintTy {
503 fn to_string(&self) -> String {
504 use UintTy::*;
505 match self {
506 Usize => "usize".to_string(),
507 U8 => "u8".to_string(),
508 U16 => "u16".to_string(),
509 U32 => "u32".to_string(),
510 U64 => "u64".to_string(),
511 U128 => "u128".to_string(),
512 }
513 }
514}
515
516#[derive(AdtInto)]
518#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::TypeAndMut<'tcx>, state: S as gstate)]
519#[derive(Clone, Debug, Hash, PartialEq, Eq)]
520pub struct TypeAndMut {
521 pub ty: Box<Ty>,
522 pub mutbl: Mutability,
523}
524
525impl<S, U, T: SInto<S, U>> SInto<S, Vec<U>> for ty::List<T> {
526 fn sinto(&self, s: &S) -> Vec<U> {
527 self.iter().map(|x| x.sinto(s)).collect()
528 }
529}
530
531#[derive(AdtInto)]
533#[args(<S>, from: ty::Variance, state: S as _s)]
534#[derive(Clone, Debug, Hash, PartialEq, Eq)]
535pub enum Variance {
536 Covariant,
537 Invariant,
538 Contravariant,
539 Bivariant,
540}
541
542#[derive(AdtInto)]
544#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::GenericParamDef, state: S as s)]
545#[derive(Clone, Debug)]
546pub struct GenericParamDef {
547 pub name: Symbol,
548 pub def_id: DefId,
549 pub index: u32,
550 pub pure_wrt_drop: bool,
551 #[value(
552 match self.kind {
553 ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime,
554 ty::GenericParamDefKind::Type { has_default, synthetic } => GenericParamDefKind::Type { has_default, synthetic },
555 ty::GenericParamDefKind::Const { has_default, .. } => {
556 let tcx = s.base().tcx;
557 let ty = tcx.type_of(self.def_id).instantiate_identity();
558 let ty = normalize(tcx, s.typing_env(), ty).sinto(s);
559 GenericParamDefKind::Const { has_default, ty }
560 },
561 }
562 )]
563 pub kind: GenericParamDefKind,
564 #[value({
566 use rustc_hir::def::DefKind::*;
567 let tcx = s.base().tcx;
568 let parent = tcx.parent(self.def_id);
569 match tcx.def_kind(parent) {
570 Fn | AssocFn | Enum | Struct | Union | Ctor(..) | OpaqueTy => {
571 tcx.variances_of(parent).get(self.index as usize).sinto(s)
572 }
573 _ => None
574 }
575 })]
576 pub variance: Option<Variance>,
577}
578
579#[derive(Clone, Debug)]
582pub enum GenericParamDefKind {
583 Lifetime,
584 Type { has_default: bool, synthetic: bool },
585 Const { has_default: bool, ty: Ty },
586}
587
588#[derive(AdtInto)]
590#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::Generics, state: S as state)]
591#[derive(Clone, Debug)]
592pub struct TyGenerics {
593 pub parent: Option<DefId>,
594 pub parent_count: usize,
595 #[from(own_params)]
596 pub params: Vec<GenericParamDef>,
597 pub has_self: bool,
599 pub has_late_bound_regions: Option<Span>,
600}
601
602#[derive(Clone, Debug, Hash, PartialEq, Eq)]
605pub struct Alias {
606 pub kind: AliasKind,
607 pub args: Vec<GenericArg>,
608 pub def_id: DefId,
609}
610
611#[derive(Clone, Debug, Hash, PartialEq, Eq)]
613pub enum AliasKind {
614 Projection(ItemRef),
616 Inherent,
618 Opaque {
620 hidden_ty: Ty,
622 },
623 Free,
625}
626
627pub fn alias_ty_kind_def_id<'tcx>(kind: ty::AliasTyKind<'tcx>) -> RDefId {
628 match kind {
629 ty::AliasTyKind::Projection { def_id }
630 | ty::AliasTyKind::Inherent { def_id }
631 | ty::AliasTyKind::Opaque { def_id }
632 | ty::AliasTyKind::Free { def_id } => def_id,
633 }
634}
635
636impl Alias {
637 #[tracing::instrument(level = "trace", skip(s))]
638 fn from<'tcx, S: UnderOwnerState<'tcx>>(s: &S, alias_ty: &ty::AliasTy<'tcx>) -> TyKind {
639 let tcx = s.base().tcx;
640 let typing_env = s.typing_env();
641 use rustc_type_ir::AliasTyKind as RustAliasKind;
642
643 let ty = ty::Ty::new_alias(tcx, ty::IsRigid::No, *alias_ty);
645 let ty = normalize(tcx, typing_env, ty::Unnormalized::new(ty));
646 let ty::Alias(_is_rigid, alias_ty) = ty.kind() else {
647 let ty: Ty = ty.sinto(s);
648 return ty.kind().clone();
649 };
650
651 let kind = match alias_ty.kind {
652 RustAliasKind::Projection { def_id } => {
653 AliasKind::Projection(ItemRef::translate_projection(s, def_id, alias_ty.args))
654 }
655 RustAliasKind::Inherent { .. } => AliasKind::Inherent,
656 RustAliasKind::Opaque { def_id } => {
657 let ty = tcx.type_of(def_id).instantiate(tcx, alias_ty.args);
659 let ty = normalize(tcx, s.typing_env(), ty);
660 AliasKind::Opaque {
661 hidden_ty: ty.sinto(s),
662 }
663 }
664 RustAliasKind::Free { .. } => AliasKind::Free,
665 };
666 TyKind::Alias(Alias {
667 kind,
668 args: alias_ty.args.sinto(s),
669 def_id: alias_ty_kind_def_id(alias_ty.kind).sinto(s),
670 })
671 }
672}
673
674impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Box<Ty>> for ty::Ty<'tcx> {
675 fn sinto(&self, s: &S) -> Box<Ty> {
676 Box::new(self.sinto(s))
677 }
678}
679
680#[derive(Clone, Debug, Hash, PartialEq, Eq)]
683pub struct Ty {
684 pub(crate) kind: HashConsed<TyKind>,
685}
686
687impl Ty {
688 pub fn new<'tcx, S: BaseState<'tcx>>(_s: &S, kind: TyKind) -> Self {
689 let kind = HashConsed::new(kind);
690 Ty { kind }
691 }
692
693 pub fn kind(&self) -> &TyKind {
694 self.kind.inner()
695 }
696}
697
698impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Ty> for rustc_middle::ty::Ty<'tcx> {
699 fn sinto(&self, s: &S) -> Ty {
700 if let Some(ty) = s.with_cache(|cache| cache.tys.get(self).cloned()) {
701 return ty;
702 }
703 let kind: TyKind = self.kind().sinto(s);
704 let ty = Ty::new(s, kind);
705 s.with_cache(|cache| {
706 cache.tys.insert(*self, ty.clone());
707 });
708 ty
709 }
710}
711
712#[derive(AdtInto)]
714#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::TyKind<'tcx>, state: S as s)]
715#[derive(Clone, Debug, Hash, PartialEq, Eq)]
716pub enum TyKind {
717 Bool,
718 Char,
719 Int(IntTy),
720 Uint(UintTy),
721 Float(FloatTy),
722
723 #[custom_arm(
724 ty::TyKind::FnDef(fun_id, generics) => {
725 let generics = generics.no_bound_vars().expect("bound variables in FnDef");
726 let item = translate_item_ref(s, *fun_id, generics);
727 let tcx = s.base().tcx;
728 let fn_sig = tcx.fn_sig(*fun_id).instantiate(tcx, generics);
729 let fn_sig = Box::new(normalize(tcx, s.typing_env(), fn_sig).sinto(s));
730 TyKind::FnDef { item, fn_sig }
731 },
732 )]
733 FnDef {
735 item: ItemRef,
736 fn_sig: Box<PolyFnSig>,
737 },
738
739 #[custom_arm(
740 ty::TyKind::FnPtr(tys, header) => {
741 let sig = tys.with(*header);
742 TyKind::Arrow(Box::new(sig.sinto(s)))
743 },
744 )]
745 Arrow(Box<PolyFnSig>),
747
748 #[custom_arm(
749 ty::TyKind::Closure (def_id, generics) => {
750 TyKind::Closure(ClosureArgs::sfrom(s, *def_id, generics))
751 },
752 )]
753 Closure(ClosureArgs),
754
755 #[custom_arm(FROM_TYPE::Adt(adt_def, generics) => TO_TYPE::Adt(translate_item_ref(s, adt_def.did(), generics)),)]
756 Adt(ItemRef),
757 #[custom_arm(FROM_TYPE::Foreign(def_id) => TO_TYPE::Foreign(translate_item_ref(s, *def_id, Default::default())),)]
758 Foreign(ItemRef),
759 #[custom_arm(FROM_TYPE::Array(ty, len) => TO_TYPE::Array({
761 let args = s.base().tcx.mk_args(&[(*ty).into(), (*len).into()]);
762 ItemRef::translate_synthetic(s, SyntheticItem::Array, args)
763 }),)]
764 Array(ItemRef),
765 Pat(Ty, Pattern),
766 #[custom_arm(FROM_TYPE::Slice(ty) => TO_TYPE::Slice({
768 let args = s.base().tcx.mk_args(&[(*ty).into()]);
769 ItemRef::translate_synthetic(s, SyntheticItem::Slice, args)
770 }),)]
771 Slice(ItemRef),
772 #[custom_arm(FROM_TYPE::Tuple(tys) => TO_TYPE::Tuple({
774 let args = s.base().tcx.mk_args_from_iter(tys.into_iter().map(ty::GenericArg::from));
775 ItemRef::translate_synthetic(s, SyntheticItem::Tuple(tys.len()), args)
776 }),)]
777 Tuple(ItemRef),
778 Str,
779 RawPtr(Box<Ty>, Mutability),
780 Ref(Region, Box<Ty>, Mutability),
781 #[custom_arm(FROM_TYPE::Dynamic(preds, region) => TyKind::Dynamic(resolve_for_dyn(s, preds, |_, _| ()), region.sinto(s)),)]
782 Dynamic(DynBinder<()>, Region),
783 #[custom_arm(FROM_TYPE::Coroutine(def_id, generics) => TO_TYPE::Coroutine(translate_item_ref(s, *def_id, generics)),)]
784 Coroutine(ItemRef),
785 Never,
786 #[custom_arm(FROM_TYPE::Alias(_is_rigid, alias_ty) => Alias::from(s, alias_ty),)]
787 Alias(Alias),
788 Param(ParamTy),
789 Bound(BoundVarIndexKind, BoundTy),
790 Placeholder(PlaceholderType),
791 Infer(InferTy),
792 #[custom_arm(FROM_TYPE::Error(..) => TO_TYPE::Error,)]
793 Error,
794 #[todo]
795 Todo(String),
796}
797
798#[derive(Clone, Debug, Hash, PartialEq, Eq)]
803pub struct DynBinder<T> {
804 pub existential_ty: ParamTy,
806 pub predicates: GenericPredicates,
809 pub val: T,
811}
812
813fn resolve_for_dyn<'tcx, S: UnderOwnerState<'tcx>, R>(
815 s: &S,
816 epreds: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
818 f: impl FnOnce(&mut PredicateSearcher<'tcx>, ty::Ty<'tcx>) -> R,
819) -> DynBinder<R> {
820 fn searcher_for_traits<'tcx, S: UnderOwnerState<'tcx>>(
821 s: &S,
822 preds: &ItemPredicates<'tcx, DefId>,
823 ) -> PredicateSearcher<'tcx> {
824 let tcx = s.base().tcx;
825 let mut predicate_searcher = s.with_predicate_searcher(|ps, _| ps.clone());
827 predicate_searcher.insert_bound_predicates(&s.base_state(), preds.iter());
828 predicate_searcher.set_param_env(param_env_from_clauses(
829 tcx,
830 s.param_env()
831 .caller_bounds()
832 .iter()
833 .chain(preds.iter().map(|pred| pred.clause)),
834 ));
835 predicate_searcher
836 }
837
838 fn fresh_param_ty<'tcx, S: UnderOwnerState<'tcx>>(s: &S) -> ty::ParamTy {
839 let generics = s.owner().generics_of(s);
840 let param_count = generics.count();
841 ty::ParamTy::new(param_count as u32 + 1, rustc_span::Symbol::intern("_dyn"))
842 }
843
844 let tcx = s.base().tcx;
845 let span = rustc_span::DUMMY_SP.sinto(s);
846
847 let new_param_ty = fresh_param_ty(s);
849 let new_ty = new_param_ty.to_ty(tcx);
850
851 let predicates = epreds.iter().map(|epred| epred.with_self_ty(tcx, new_ty));
853 let predicates: ItemPredicates<'_, DefId> = ItemPredicates::new_unmapped(span, predicates);
854
855 let mut predicate_searcher = searcher_for_traits(s, &predicates);
857 let val = f(&mut predicate_searcher, new_ty);
858
859 let predicates = predicates
862 .iter()
863 .map(|pred| {
864 match pred.clause.as_projection_clause() {
865 None => pred.sinto(s),
867 Some(proj) => {
871 let bound_vars = proj.bound_vars().sinto(s);
872 let proj = {
873 let alias_ty = &proj.skip_binder().projection_term.expect_ty();
874 let trait_proof = {
875 let poly_trait_ref = proj.rebind(alias_ty.trait_ref(tcx));
876 predicate_searcher
877 .resolve(&s.base_state(), &poly_trait_ref)
878 .sinto(s)
879 };
880 let Term::Ty(ty) = proj.skip_binder().term.sinto(s) else {
881 unreachable!()
882 };
883 let item = tcx.associated_item(alias_ty_kind_def_id(alias_ty.kind));
884 ProjectionPredicate {
885 trait_proof,
886 assoc_item: AssocItem::sfrom(s, &item),
887 ty,
888 }
889 };
890 let kind = Binder {
891 value: ClauseKind::Projection(proj),
892 bound_vars,
893 };
894 let clause = Clause { kind };
895 GenericPredicate {
896 id: pred.id.sinto(s),
897 clause,
898 span,
899 }
900 }
901 }
902 })
903 .collect();
904
905 let predicates = GenericPredicates { predicates };
906 DynBinder {
907 existential_ty: new_param_ty.sinto(s),
908 predicates,
909 val,
910 }
911}
912
913#[derive(AdtInto)]
914#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::pattern::PatternKind<'tcx>, state: S as gstate)]
915#[derive(Clone, Debug, Hash, PartialEq, Eq)]
916pub enum Pattern {
917 Range {
918 start: ConstantExpr,
919 end: ConstantExpr,
920 },
921 Or(Vec<Pattern>),
922 NotNull,
923}
924
925impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Pattern> for ty::Pattern<'tcx> {
926 fn sinto(&self, s: &S) -> Pattern {
927 self.kind().sinto(s)
928 }
929}
930#[derive(AdtInto)]
932#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::CanonicalUserTypeAnnotation<'tcx>, state: S as gstate)]
933#[derive(Clone, Debug)]
934pub struct CanonicalUserTypeAnnotation {
935 pub user_ty: CanonicalUserType,
936 pub span: Span,
937 pub inferred_ty: Ty,
938}
939
940#[derive(Copy, Clone, Debug)]
943pub enum AdtKind {
944 Struct,
945 Union,
946 Enum,
947 Array,
949 Slice,
951 Tuple,
953}
954
955impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, AdtKind> for ty::AdtKind {
956 fn sinto(&self, _s: &S) -> AdtKind {
957 match self {
958 ty::AdtKind::Struct => AdtKind::Struct,
959 ty::AdtKind::Union => AdtKind::Union,
960 ty::AdtKind::Enum => AdtKind::Enum,
961 }
962 }
963}
964
965sinto_todo!(rustc_middle::ty, AdtFlags);
966
967#[derive(AdtInto, Clone, Debug)]
970#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: rustc_abi::ReprOptions, state: S as s)]
971pub struct ReprOptions {
972 #[value(self.int.is_some())]
974 pub int_specified: bool,
975 #[value({
977 use rustc_middle::ty::util::IntTypeExt;
978 self.discr_type().to_ty(s.base().tcx).sinto(s)
979 })]
980 pub typ: Ty,
981 pub align: Option<Align>,
982 pub pack: Option<Align>,
983 #[value(ReprFlags { is_c: self.c(), is_transparent: self.transparent(), is_simd: self.simd() })]
984 pub flags: ReprFlags,
985}
986
987#[derive(Default, Clone, Debug)]
990pub struct ReprFlags {
991 pub is_c: bool,
992 pub is_transparent: bool,
993 pub is_simd: bool,
994}
995
996#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
999#[args(<'tcx, S: BaseState<'tcx>>, from: rustc_abi::Align, state: S as _s)]
1000pub struct Align {
1001 #[value({
1002 self.bytes()
1003 })]
1004 pub bytes: u64,
1005}
1006
1007#[derive(Clone, Debug)]
1009pub enum UnsizingMetadata {
1010 Length(ConstantExpr),
1012 DirectVTable(TraitProof),
1014 NestedVTable(DynBinder<TraitProof>),
1016 Unknown,
1018}
1019
1020pub fn compute_unsizing_metadata<'tcx, S: UnderOwnerState<'tcx>>(
1021 s: &S,
1022 src_ty: ty::Ty<'tcx>,
1023 tgt_ty: ty::Ty<'tcx>,
1024) -> UnsizingMetadata {
1025 let (Some(src_ty), Some(tgt_ty)) = (src_ty.builtin_deref(true), tgt_ty.builtin_deref(true))
1031 else {
1032 return UnsizingMetadata::Unknown;
1033 };
1034
1035 let tcx = s.base().tcx;
1036 let typing_env = s.typing_env();
1037 let (src_ty, tgt_ty) =
1038 tcx.struct_lockstep_tails_raw(src_ty, tgt_ty, |ty| normalize(tcx, typing_env, ty));
1039
1040 match (&src_ty.kind(), &tgt_ty.kind()) {
1041 (ty::Array(_, len), ty::Slice(_)) => {
1042 let len = len.sinto(s);
1043 UnsizingMetadata::Length(len)
1044 }
1045 (ty::Dynamic(from_preds, _), ty::Dynamic(to_preds, ..)) => {
1046 let trait_proof = resolve_for_dyn(s, from_preds, |searcher, fresh_ty| {
1047 let to_pred = if let Some(to_principal) = to_preds.principal() {
1048 to_principal.with_self_ty(tcx, fresh_ty)
1049 } else {
1050 let def_id = to_preds
1051 .iter()
1052 .find_map(|pred| match pred.skip_binder() {
1053 ty::ExistentialPredicate::AutoTrait(def_id) => Some(def_id),
1054 _ => None,
1055 })
1056 .expect("expected a trait predicate in dyn upcast target");
1057 ty::Binder::dummy(ty::TraitRef::new(tcx, def_id, [fresh_ty]))
1058 };
1059 searcher.resolve(&s.base_state(), &to_pred).sinto(s)
1060 });
1061 UnsizingMetadata::NestedVTable(trait_proof)
1062 }
1063 (_, ty::Dynamic(preds, ..)) => {
1064 let pred = preds[0].with_self_ty(tcx, src_ty);
1065 let clause = pred.as_trait_clause().expect(
1066 "the first `ExistentialPredicate` of `TyKind::Dynamic` \\
1067 should be a trait clause",
1068 );
1069 let tref = clause.rebind(clause.skip_binder().trait_ref);
1070 let trait_proof = solve_trait(s, tref);
1071
1072 UnsizingMetadata::DirectVTable(trait_proof)
1073 }
1074 _ => UnsizingMetadata::Unknown,
1075 }
1076}
1077
1078#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
1080#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::FnSig<'tcx>, state: S as s)]
1081pub struct TyFnSig {
1082 #[value(self.inputs().sinto(s))]
1083 pub inputs: Vec<Ty>,
1084 #[value(self.output().sinto(s))]
1085 pub output: Ty,
1086 #[value(self.c_variadic())]
1087 pub c_variadic: bool,
1088 #[value(self.safety())]
1089 pub safety: Safety,
1090 #[value(self.abi())]
1091 pub abi: ExternAbi,
1092}
1093
1094pub type PolyFnSig = Binder<TyFnSig>;
1096
1097pub type TraitRef = ItemRef;
1103
1104impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, TraitRef> for ty::TraitRef<'tcx> {
1105 fn sinto(&self, s: &S) -> TraitRef {
1106 translate_item_ref(s, self.def_id, self.args)
1107 }
1108}
1109
1110#[derive(AdtInto)]
1112#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::TraitPredicate<'tcx>, state: S as tcx)]
1113#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1114pub struct TraitPredicate {
1115 pub trait_ref: TraitRef,
1116 #[map(*x == ty::PredicatePolarity::Positive)]
1117 #[from(polarity)]
1118 pub is_positive: bool,
1119}
1120
1121#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1127pub struct OutlivesPredicate<T> {
1128 pub lhs: T,
1129 pub rhs: Region,
1130}
1131
1132impl<'tcx, S: UnderOwnerState<'tcx>, T, U> SInto<S, OutlivesPredicate<U>>
1133 for ty::OutlivesClause<'tcx, T>
1134where
1135 T: SInto<S, U>,
1136{
1137 fn sinto(&self, s: &S) -> OutlivesPredicate<U> where {
1138 OutlivesPredicate {
1139 lhs: self.0.sinto(s),
1140 rhs: self.1.sinto(s),
1141 }
1142 }
1143}
1144
1145pub type RegionOutlivesPredicate = OutlivesPredicate<Region>;
1147pub type TypeOutlivesPredicate = OutlivesPredicate<Ty>;
1149
1150#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1153pub enum Term {
1154 Ty(Ty),
1155 Const(ConstantExpr),
1156}
1157
1158impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Term> for ty::Term<'tcx> {
1159 fn sinto(&self, s: &S) -> Term {
1160 use ty::TermKind;
1161 match self.kind() {
1162 TermKind::Ty(ty) => Term::Ty(ty.sinto(s)),
1163 TermKind::Const(c) => Term::Const(c.sinto(s)),
1164 }
1165 }
1166}
1167
1168#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1178pub struct ProjectionPredicate {
1179 pub trait_proof: TraitProof,
1181 pub assoc_item: AssocItem,
1183 pub ty: Ty,
1185}
1186
1187impl<'tcx, S: UnderBinderState<'tcx>> SInto<S, ProjectionPredicate>
1188 for ty::ProjectionPredicate<'tcx>
1189{
1190 fn sinto(&self, s: &S) -> ProjectionPredicate {
1191 let tcx = s.base().tcx;
1192 let alias_ty = &self.projection_term.expect_ty();
1193 let poly_trait_ref = s.binder().rebind(alias_ty.trait_ref(tcx));
1194 let Term::Ty(ty) = self.term.sinto(s) else {
1195 unreachable!()
1196 };
1197 let item = tcx.associated_item(alias_ty_kind_def_id(alias_ty.kind));
1198 ProjectionPredicate {
1199 trait_proof: solve_trait(s, poly_trait_ref),
1200 assoc_item: AssocItem::sfrom(s, &item),
1201 ty,
1202 }
1203 }
1204}
1205
1206#[derive(AdtInto)]
1208#[args(<'tcx, S: UnderBinderState<'tcx>>, from: ty::ClauseKind<'tcx>, state: S as tcx)]
1209#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1210pub enum ClauseKind {
1211 Trait(TraitPredicate),
1212 RegionOutlives(RegionOutlivesPredicate),
1213 TypeOutlives(TypeOutlivesPredicate),
1214 Projection(ProjectionPredicate),
1215 ConstArgHasType(ConstantExpr, Ty),
1216 WellFormed(Term),
1217 ConstEvaluatable(ConstantExpr),
1218 HostEffect(HostEffectClause),
1219 UnstableFeature(Symbol),
1220}
1221
1222sinto_todo!(rustc_middle::ty, HostEffectClause<'tcx>);
1223
1224#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1227pub struct Clause {
1228 pub kind: Binder<ClauseKind>,
1229}
1230
1231impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Clause> for ty::Clause<'tcx> {
1232 fn sinto(&self, s: &S) -> Clause {
1233 let kind = self.kind().sinto(s);
1234 Clause { kind }
1235 }
1236}
1237
1238impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Clause> for ty::PolyTraitPredicate<'tcx> {
1239 fn sinto(&self, s: &S) -> Clause {
1240 let kind: Binder<_> = self.sinto(s);
1241 let kind: Binder<ClauseKind> = kind.map(ClauseKind::Trait);
1242 Clause { kind }
1243 }
1244}
1245
1246#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1249pub struct Predicate {
1250 pub kind: Binder<PredicateKind>,
1251}
1252
1253impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Predicate> for ty::Predicate<'tcx> {
1254 fn sinto(&self, s: &S) -> Predicate {
1255 let kind = self.kind().sinto(s);
1256 Predicate { kind }
1257 }
1258}
1259
1260#[derive(AdtInto)]
1262#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::BoundVariableKind<'tcx>, state: S as tcx)]
1263#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1264pub enum BoundVariableKind {
1265 Ty(BoundTyKind),
1266 #[custom_arm(
1267 &FROM_TYPE::Region(region) => TO_TYPE::Region(region.sinto(tcx), None),
1268 )]
1269 Region(BoundRegionKind, Option<Variance>),
1270 Const,
1271}
1272
1273#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1276pub struct Binder<T> {
1277 pub value: T,
1278 pub bound_vars: Vec<BoundVariableKind>,
1279}
1280
1281impl Binder<()> {
1282 pub fn empty() -> Self {
1283 Binder {
1284 value: (),
1285 bound_vars: vec![],
1286 }
1287 }
1288}
1289
1290impl<T> Binder<T> {
1291 pub fn as_ref(&self) -> Binder<&T> {
1292 Binder {
1293 value: &self.value,
1294 bound_vars: self.bound_vars.clone(),
1295 }
1296 }
1297
1298 pub fn hax_skip_binder(self) -> T {
1299 self.value
1300 }
1301
1302 pub fn hax_skip_binder_ref(&self) -> &T {
1303 &self.value
1304 }
1305
1306 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binder<U> {
1307 Binder {
1308 value: f(self.value),
1309 bound_vars: self.bound_vars,
1310 }
1311 }
1312
1313 pub fn inner_mut(&mut self) -> &mut T {
1314 &mut self.value
1315 }
1316
1317 pub fn rebind<U>(&self, value: U) -> Binder<U> {
1318 self.as_ref().map(|_| value)
1319 }
1320}
1321
1322#[derive(AdtInto)]
1324#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: traits::ItemPredicateId<DefId>, state: S as s)]
1325#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1326pub enum GenericPredicateId {
1327 Required(DefId, u32),
1330 Implied(DefId, u32),
1334 Unmapped(u32),
1337 TraitSelf,
1339}
1340
1341#[derive(AdtInto)]
1342#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: traits::ItemPredicate<'tcx, DefId>, state: S as s)]
1343#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1344pub struct GenericPredicate {
1345 pub id: GenericPredicateId,
1346 pub clause: Clause,
1347 pub span: Span,
1348}
1349
1350#[derive(AdtInto)]
1352#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: traits::ItemPredicates<'tcx, DefId>, state: S as s)]
1353#[derive(Clone, Debug, Default, Hash, PartialEq, Eq)]
1354pub struct GenericPredicates {
1355 pub predicates: Vec<GenericPredicate>,
1356}
1357
1358impl GenericPredicates {
1359 pub fn iter(&self) -> impl Iterator<Item = &GenericPredicate> {
1360 self.predicates.iter()
1361 }
1362 pub fn iter_trait_clauses(&self) -> impl Iterator<Item = &GenericPredicate> {
1364 self.iter()
1365 .filter(|pred| matches!(pred.clause.kind.hax_skip_binder_ref(), ClauseKind::Trait(_)))
1366 }
1367}
1368
1369trait BinderVariances<'tcx>: Sized {
1371 fn variances(
1372 _tcx: ty::TyCtxt<'tcx>,
1373 _binder: &ty::Binder<'tcx, Self>,
1374 ) -> HashMap<ty::BoundVar, ty::Variance> {
1375 HashMap::new()
1376 }
1377}
1378
1379impl<'tcx> BinderVariances<'tcx> for ty::FnSig<'tcx> {
1380 fn variances(
1381 tcx: ty::TyCtxt<'tcx>,
1382 binder: &ty::Binder<'tcx, Self>,
1383 ) -> HashMap<ty::BoundVar, ty::Variance> {
1384 fn_sig_bound_region_variances(tcx, *binder)
1385 }
1386}
1387
1388impl<'tcx> BinderVariances<'tcx> for ty::ClauseKind<'tcx> {}
1389impl<'tcx> BinderVariances<'tcx> for ty::PredicateKind<'tcx> {}
1390impl<'tcx> BinderVariances<'tcx> for ty::TraitRef<'tcx> {}
1391impl<'tcx> BinderVariances<'tcx> for ty::TraitPredicate<'tcx> {}
1392
1393impl<'tcx, S: UnderOwnerState<'tcx>, T1, T2> SInto<S, Binder<T2>> for ty::Binder<'tcx, T1>
1394where
1395 T1: SInto<StateWithBinder<'tcx>, T2> + BinderVariances<'tcx>,
1396{
1397 fn sinto(&self, s: &S) -> Binder<T2> {
1398 let variances = T1::variances(s.base().tcx, self);
1399 let mut bound_vars = self.bound_vars().sinto(s);
1400 for (index, var) in bound_vars.iter_mut().enumerate() {
1401 if let BoundVariableKind::Region(_, variance) = var {
1402 *variance = variances
1403 .get(&ty::BoundVar::from_usize(index))
1404 .copied()
1405 .sinto(s);
1406 }
1407 }
1408 let value = {
1409 let under_binder_s = &s.with_binder(self.as_ref().map_bound(|_| ()));
1410 self.as_ref().skip_binder().sinto(under_binder_s)
1411 };
1412 Binder { value, bound_vars }
1413 }
1414}
1415
1416#[derive(AdtInto)]
1418#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::SubtypePredicate<'tcx>, state: S as tcx)]
1419#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1420pub struct SubtypePredicate {
1421 pub a_is_expected: bool,
1422 pub a: Ty,
1423 pub b: Ty,
1424}
1425
1426#[derive(AdtInto)]
1428#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::CoercePredicate<'tcx>, state: S as tcx)]
1429#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1430pub struct CoercePredicate {
1431 pub a: Ty,
1432 pub b: Ty,
1433}
1434
1435#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1437
1438pub struct ClosureArgs {
1439 pub item: ItemRef,
1440 pub kind: ClosureKind,
1443 pub fn_sig: PolyFnSig,
1445 pub upvar_tys: Vec<Ty>,
1447}
1448
1449impl ClosureArgs {
1450 pub fn iter_upvar_borrows(&self) -> impl Iterator<Item = &Ty> {
1453 self.upvar_tys.iter().filter(|ty| {
1454 matches!(
1455 ty.kind(),
1456 TyKind::Ref(
1457 Region {
1458 kind: RegionKind::ReErased
1459 },
1460 ..
1461 )
1462 )
1463 })
1464 }
1465}
1466
1467impl ClosureArgs {
1468 pub fn sfrom<'tcx, S>(s: &S, def_id: RDefId, from: ty::GenericArgsRef<'tcx>) -> Self
1470 where
1471 S: UnderOwnerState<'tcx>,
1472 {
1473 use rustc_middle::ty;
1474 use rustc_type_ir::TypeFoldable;
1475 use rustc_type_ir::TypeSuperFoldable;
1476
1477 struct RegionUnEraserVisitor<'tcx> {
1478 tcx: ty::TyCtxt<'tcx>,
1479 depth: u32,
1480 bound_vars: Vec<ty::BoundVariableKind<'tcx>>,
1481 }
1482
1483 impl<'tcx> ty::TypeFolder<ty::TyCtxt<'tcx>> for RegionUnEraserVisitor<'tcx> {
1484 fn cx(&self) -> ty::TyCtxt<'tcx> {
1485 self.tcx
1486 }
1487
1488 fn fold_ty(&mut self, ty: ty::Ty<'tcx>) -> ty::Ty<'tcx> {
1489 ty.super_fold_with(self)
1490 }
1491
1492 fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
1493 where
1494 T: ty::TypeFoldable<ty::TyCtxt<'tcx>>,
1495 {
1496 self.depth += 1;
1497 let t = t.super_fold_with(self);
1498 self.depth -= 1;
1499 t
1500 }
1501
1502 fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
1503 if r.is_erased() {
1505 let bound_region = ty::BoundRegion {
1506 var: ty::BoundVar::from_usize(self.bound_vars.len()),
1507 kind: ty::BoundRegionKind::Anon,
1508 };
1509 self.bound_vars
1510 .push(ty::BoundVariableKind::Region(bound_region.kind));
1511 ty::Region::new_bound(
1512 self.tcx,
1513 ty::DebruijnIndex::from(self.depth),
1514 bound_region,
1515 )
1516 } else {
1517 r
1518 }
1519 }
1520 }
1521
1522 let tcx = s.base().tcx;
1523 let closure = from.as_closure();
1524 let item = {
1525 let parent_args = tcx.mk_args(closure.parent_args());
1528 translate_item_ref(s, def_id, parent_args)
1529 };
1530 let sig = closure.sig();
1531 let sig = tcx.signature_unclosure(sig, rustc_hir::Safety::Safe);
1532 let sig = {
1534 let mut visitor = RegionUnEraserVisitor {
1535 tcx,
1536 depth: 0,
1537 bound_vars: sig.bound_vars().iter().collect(),
1538 };
1539 let unbound_sig = sig.skip_binder().fold_with(&mut visitor);
1540 let bound_vars = tcx.mk_bound_variable_kinds(&visitor.bound_vars);
1541 ty::Binder::bind_with_vars(unbound_sig, bound_vars)
1542 };
1543 ClosureArgs {
1544 item,
1545 kind: closure.kind().sinto(s),
1546 fn_sig: sig.sinto(s),
1547 upvar_tys: closure.upvar_tys().sinto(s),
1548 }
1549 }
1550}
1551
1552#[derive(AdtInto)]
1554#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::ClosureKind, state: S as _tcx)]
1555#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1556pub enum ClosureKind {
1557 Fn,
1558 FnMut,
1559 FnOnce,
1560}
1561
1562sinto_todo!(rustc_middle::ty, NormalizesTo<'tcx>);
1563
1564#[derive(AdtInto)]
1566#[args(<'tcx, S: UnderBinderState<'tcx>>, from: ty::PredicateKind<'tcx>, state: S as tcx)]
1567#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1568pub enum PredicateKind {
1569 Clause(ClauseKind),
1570 DynCompatible(DefId),
1571 Subtype(SubtypePredicate),
1572 Coerce(CoercePredicate),
1573 ConstEquate(ConstantExpr, ConstantExpr),
1574 Ambiguous,
1575 NormalizesTo(NormalizesTo),
1576}
1577
1578#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1581pub struct AssocItem {
1582 pub def_id: DefId,
1583 pub name: Option<Symbol>,
1585 pub kind: AssocKind,
1586 pub container: AssocItemContainer,
1587 pub has_value: bool,
1590}
1591
1592impl AssocItem {
1593 pub fn sfrom<'tcx, S: BaseState<'tcx>>(s: &S, item: &ty::AssocItem) -> AssocItem {
1594 Self::sfrom_instantiated(s, item, None)
1595 }
1596
1597 pub fn sfrom_instantiated<'tcx, S: BaseState<'tcx>>(
1599 s: &S,
1600 item: &ty::AssocItem,
1601 item_args: Option<ty::GenericArgsRef<'tcx>>,
1602 ) -> AssocItem {
1603 let tcx = s.base().tcx;
1604 let item_def_id = item.def_id.sinto(s);
1606 let s = &s.with_hax_owner(&item_def_id);
1607 let item_args = item_args.unwrap_or_else(|| item_def_id.identity_args(s));
1608 let container_id = item.container_id(tcx);
1609 let container_args = item_args.truncate_to(tcx, tcx.generics_of(container_id));
1610 let container = match item.container {
1611 ty::AssocContainer::Trait => {
1612 let trait_ref =
1613 ty::TraitRef::new_from_args(tcx, container_id, container_args).sinto(s);
1614 AssocItemContainer::TraitContainer { trait_ref }
1615 }
1616 ty::AssocContainer::TraitImpl(implemented_item_id) => {
1617 let implemented_item_id = implemented_item_id.unwrap();
1618 let item = translate_item_ref(s, container_id, container_args);
1619 let implemented_trait_ref = tcx
1620 .impl_trait_ref(container_id)
1621 .instantiate(tcx, container_args);
1622 let implemented_trait_ref = normalize(tcx, s.typing_env(), implemented_trait_ref);
1623 let implemented_trait_item = {
1624 let implemented_item_id = implemented_item_id.sinto(s);
1625 let generics =
1626 item_args.rebase_onto(tcx, container_id, implemented_trait_ref.args);
1627 ItemRef::translate_from_hax_def_id_maybe_resolve(
1629 s,
1630 implemented_item_id,
1631 generics,
1632 AssocItemResolution::None,
1633 )
1634 };
1635 AssocItemContainer::TraitImplContainer {
1636 impl_: item,
1637 implemented_trait_ref: implemented_trait_ref.sinto(s),
1638 implemented_trait_item,
1639 overrides_default: tcx.defaultness(implemented_item_id).has_value(),
1640 }
1641 }
1642 ty::AssocContainer::InherentImpl => AssocItemContainer::InherentImplContainer {
1643 impl_id: container_id.sinto(s),
1644 },
1645 };
1646 let name = match item.opt_name() {
1647 None if let ty::AssocKind::Type { data } = item.kind
1648 && let ty::AssocTypeData::Rpitit(rpitit) = data =>
1649 {
1650 let (ty::ImplTraitInTraitData::Trait { fn_def_id, .. }
1651 | ty::ImplTraitInTraitData::Impl { fn_def_id, .. }) = rpitit;
1652 let fn_name = tcx.item_name(fn_def_id);
1653 let name = Symbol::intern(&format!("{fn_name}_ty"));
1654 Some(name)
1655 }
1656 opt_name => opt_name,
1657 };
1658 AssocItem {
1659 def_id: item.def_id.sinto(s),
1660 name,
1661 kind: item.kind.sinto(s),
1662 container,
1663 has_value: item.defaultness(tcx).has_value(),
1664 }
1665 }
1666
1667 pub fn implemented_trait_item_id(&self) -> &DefId {
1669 match &self.container {
1670 AssocItemContainer::TraitImplContainer {
1671 implemented_trait_item,
1672 ..
1673 } => &implemented_trait_item.def_id,
1674 _ => &self.def_id,
1675 }
1676 }
1677}
1678
1679#[derive(AdtInto)]
1681#[args(<'tcx, S: BaseState<'tcx>>, from: ty::AssocKind, state: S as _tcx)]
1682#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1683pub enum AssocKind {
1684 Const { name: Symbol },
1685 Fn { name: Symbol, has_self: bool },
1686 Type { data: AssocTypeData },
1687}
1688
1689#[derive(AdtInto)]
1691#[args(<'tcx, S: BaseState<'tcx>>, from: ty::AssocTypeData, state: S as _tcx)]
1692#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1693pub enum AssocTypeData {
1694 Normal(Symbol),
1695 Rpitit(ImplTraitInTraitData),
1696}
1697
1698#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1699pub enum AssocItemContainer {
1700 TraitContainer {
1701 trait_ref: TraitRef,
1702 },
1703 TraitImplContainer {
1704 impl_: ItemRef,
1706 implemented_trait_ref: TraitRef,
1708 implemented_trait_item: ItemRef,
1710 overrides_default: bool,
1713 },
1714 InherentImplContainer {
1715 impl_id: DefId,
1716 },
1717}
1718
1719#[derive(AdtInto)]
1721#[args(<'tcx, S: BaseState<'tcx>>, from: ty::ImplTraitInTraitData, state: S as _s)]
1722#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1723pub enum ImplTraitInTraitData {
1724 Trait {
1725 fn_def_id: DefId,
1726 opaque_def_id: DefId,
1727 },
1728 Impl {
1729 fn_def_id: DefId,
1730 },
1731}