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.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, 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
627impl Alias {
628 #[tracing::instrument(level = "trace", skip(s))]
629 fn from<'tcx, S: UnderOwnerState<'tcx>>(s: &S, alias_ty: &ty::AliasTy<'tcx>) -> TyKind {
630 let tcx = s.base().tcx;
631 let typing_env = s.typing_env();
632 use rustc_type_ir::AliasTyKind as RustAliasKind;
633
634 let ty = ty::Ty::new_alias(tcx, *alias_ty);
636 let ty = normalize(tcx, typing_env, ty::Unnormalized::new(ty));
637 let ty::Alias(alias_ty) = ty.kind() else {
638 let ty: Ty = ty.sinto(s);
639 return ty.kind().clone();
640 };
641
642 let kind = match alias_ty.kind {
643 RustAliasKind::Projection { def_id } => {
644 AliasKind::Projection(ItemRef::translate_projection(s, def_id, alias_ty.args))
645 }
646 RustAliasKind::Inherent { .. } => AliasKind::Inherent,
647 RustAliasKind::Opaque { def_id } => {
648 let ty = tcx.type_of(def_id).instantiate(tcx, alias_ty.args);
650 let ty = normalize(tcx, s.typing_env(), ty);
651 AliasKind::Opaque {
652 hidden_ty: ty.sinto(s),
653 }
654 }
655 RustAliasKind::Free { .. } => AliasKind::Free,
656 };
657 TyKind::Alias(Alias {
658 kind,
659 args: alias_ty.args.sinto(s),
660 def_id: alias_ty.kind.def_id().sinto(s),
661 })
662 }
663}
664
665impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Box<Ty>> for ty::Ty<'tcx> {
666 fn sinto(&self, s: &S) -> Box<Ty> {
667 Box::new(self.sinto(s))
668 }
669}
670
671#[derive(Clone, Debug, Hash, PartialEq, Eq)]
674pub struct Ty {
675 pub(crate) kind: HashConsed<TyKind>,
676}
677
678impl Ty {
679 pub fn new<'tcx, S: BaseState<'tcx>>(_s: &S, kind: TyKind) -> Self {
680 let kind = HashConsed::new(kind);
681 Ty { kind }
682 }
683
684 pub fn kind(&self) -> &TyKind {
685 self.kind.inner()
686 }
687}
688
689impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Ty> for rustc_middle::ty::Ty<'tcx> {
690 fn sinto(&self, s: &S) -> Ty {
691 if let Some(ty) = s.with_cache(|cache| cache.tys.get(self).cloned()) {
692 return ty;
693 }
694 let kind: TyKind = self.kind().sinto(s);
695 let ty = Ty::new(s, kind);
696 s.with_cache(|cache| {
697 cache.tys.insert(*self, ty.clone());
698 });
699 ty
700 }
701}
702
703#[derive(AdtInto)]
705#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::TyKind<'tcx>, state: S as s)]
706#[derive(Clone, Debug, Hash, PartialEq, Eq)]
707pub enum TyKind {
708 Bool,
709 Char,
710 Int(IntTy),
711 Uint(UintTy),
712 Float(FloatTy),
713
714 #[custom_arm(
715 ty::TyKind::FnDef(fun_id, generics) => {
716 let item = translate_item_ref(s, *fun_id, generics);
717 let tcx = s.base().tcx;
718 let fn_sig = tcx.fn_sig(*fun_id).instantiate(tcx, generics);
719 let fn_sig = Box::new(normalize(tcx, s.typing_env(), fn_sig).sinto(s));
720 TyKind::FnDef { item, fn_sig }
721 },
722 )]
723 FnDef {
725 item: ItemRef,
726 fn_sig: Box<PolyFnSig>,
727 },
728
729 #[custom_arm(
730 ty::TyKind::FnPtr(tys, header) => {
731 let fn_sig_kind = ty::FnSigKind::new(header.abi(), header.safety(), header.c_variadic());
732 let sig = tys.map_bound(|tys| ty::FnSig {
733 inputs_and_output: tys.inputs_and_output,
734 fn_sig_kind,
735 });
736 TyKind::Arrow(Box::new(sig.sinto(s)))
737 },
738 )]
739 Arrow(Box<PolyFnSig>),
741
742 #[custom_arm(
743 ty::TyKind::Closure (def_id, generics) => {
744 TyKind::Closure(ClosureArgs::sfrom(s, *def_id, generics))
745 },
746 )]
747 Closure(ClosureArgs),
748
749 #[custom_arm(FROM_TYPE::Adt(adt_def, generics) => TO_TYPE::Adt(translate_item_ref(s, adt_def.did(), generics)),)]
750 Adt(ItemRef),
751 #[custom_arm(FROM_TYPE::Foreign(def_id) => TO_TYPE::Foreign(translate_item_ref(s, *def_id, Default::default())),)]
752 Foreign(ItemRef),
753 #[custom_arm(FROM_TYPE::Array(ty, len) => TO_TYPE::Array({
755 let args = s.base().tcx.mk_args(&[(*ty).into(), (*len).into()]);
756 ItemRef::translate_synthetic(s, SyntheticItem::Array, args)
757 }),)]
758 Array(ItemRef),
759 Pat(Ty, Pattern),
760 #[custom_arm(FROM_TYPE::Slice(ty) => TO_TYPE::Slice({
762 let args = s.base().tcx.mk_args(&[(*ty).into()]);
763 ItemRef::translate_synthetic(s, SyntheticItem::Slice, args)
764 }),)]
765 Slice(ItemRef),
766 #[custom_arm(FROM_TYPE::Tuple(tys) => TO_TYPE::Tuple({
768 let args = s.base().tcx.mk_args_from_iter(tys.into_iter().map(ty::GenericArg::from));
769 ItemRef::translate_synthetic(s, SyntheticItem::Tuple(tys.len()), args)
770 }),)]
771 Tuple(ItemRef),
772 Str,
773 RawPtr(Box<Ty>, Mutability),
774 Ref(Region, Box<Ty>, Mutability),
775 #[custom_arm(FROM_TYPE::Dynamic(preds, region) => TyKind::Dynamic(resolve_for_dyn(s, preds, |_, _| ()), region.sinto(s)),)]
776 Dynamic(DynBinder<()>, Region),
777 #[custom_arm(FROM_TYPE::Coroutine(def_id, generics) => TO_TYPE::Coroutine(translate_item_ref(s, *def_id, generics)),)]
778 Coroutine(ItemRef),
779 Never,
780 #[custom_arm(FROM_TYPE::Alias(alias_ty) => Alias::from(s, alias_ty),)]
781 Alias(Alias),
782 Param(ParamTy),
783 Bound(BoundVarIndexKind, BoundTy),
784 Placeholder(PlaceholderType),
785 Infer(InferTy),
786 #[custom_arm(FROM_TYPE::Error(..) => TO_TYPE::Error,)]
787 Error,
788 #[todo]
789 Todo(String),
790}
791
792#[derive(Clone, Debug, Hash, PartialEq, Eq)]
797pub struct DynBinder<T> {
798 pub existential_ty: ParamTy,
800 pub predicates: GenericPredicates,
803 pub val: T,
805}
806
807fn resolve_for_dyn<'tcx, S: UnderOwnerState<'tcx>, R>(
809 s: &S,
810 epreds: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
812 f: impl FnOnce(&mut PredicateSearcher<'tcx>, ty::Ty<'tcx>) -> R,
813) -> DynBinder<R> {
814 fn searcher_for_traits<'tcx, S: UnderOwnerState<'tcx>>(
815 s: &S,
816 preds: &ItemPredicates<'tcx, DefId>,
817 ) -> PredicateSearcher<'tcx> {
818 let tcx = s.base().tcx;
819 let mut predicate_searcher = s.with_predicate_searcher(|ps, _| ps.clone());
821 predicate_searcher.insert_bound_predicates(&s.base_state(), preds.iter());
822 predicate_searcher.set_param_env(param_env_from_clauses(
823 tcx,
824 s.param_env()
825 .caller_bounds()
826 .iter()
827 .chain(preds.iter().map(|pred| pred.clause)),
828 ));
829 predicate_searcher
830 }
831
832 fn fresh_param_ty<'tcx, S: UnderOwnerState<'tcx>>(s: &S) -> ty::ParamTy {
833 let generics = s.owner().generics_of(s);
834 let param_count = generics.count();
835 ty::ParamTy::new(param_count as u32 + 1, rustc_span::Symbol::intern("_dyn"))
836 }
837
838 let tcx = s.base().tcx;
839 let span = rustc_span::DUMMY_SP.sinto(s);
840
841 let new_param_ty = fresh_param_ty(s);
843 let new_ty = new_param_ty.to_ty(tcx);
844
845 let predicates = epreds.iter().map(|epred| epred.with_self_ty(tcx, new_ty));
847 let predicates: ItemPredicates<'_, DefId> = ItemPredicates::new_unmapped(span, predicates);
848
849 let mut predicate_searcher = searcher_for_traits(s, &predicates);
851 let val = f(&mut predicate_searcher, new_ty);
852
853 let predicates = predicates
856 .iter()
857 .map(|pred| {
858 match pred.clause.as_projection_clause() {
859 None => pred.sinto(s),
861 Some(proj) => {
865 let bound_vars = proj.bound_vars().sinto(s);
866 let proj = {
867 let alias_ty = &proj.skip_binder().projection_term.expect_ty(tcx);
868 let trait_proof = {
869 let poly_trait_ref = proj.rebind(alias_ty.trait_ref(tcx));
870 predicate_searcher
871 .resolve(&s.base_state(), &poly_trait_ref)
872 .sinto(s)
873 };
874 let Term::Ty(ty) = proj.skip_binder().term.sinto(s) else {
875 unreachable!()
876 };
877 let item = tcx.associated_item(alias_ty.kind.def_id());
878 ProjectionPredicate {
879 trait_proof,
880 assoc_item: AssocItem::sfrom(s, &item),
881 ty,
882 }
883 };
884 let kind = Binder {
885 value: ClauseKind::Projection(proj),
886 bound_vars,
887 };
888 let clause = Clause { kind };
889 GenericPredicate {
890 id: pred.id.sinto(s),
891 clause,
892 span,
893 }
894 }
895 }
896 })
897 .collect();
898
899 let predicates = GenericPredicates { predicates };
900 DynBinder {
901 existential_ty: new_param_ty.sinto(s),
902 predicates,
903 val,
904 }
905}
906
907#[derive(AdtInto)]
908#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::pattern::PatternKind<'tcx>, state: S as gstate)]
909#[derive(Clone, Debug, Hash, PartialEq, Eq)]
910pub enum Pattern {
911 Range {
912 start: ConstantExpr,
913 end: ConstantExpr,
914 },
915 Or(Vec<Pattern>),
916 NotNull,
917}
918
919impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Pattern> for ty::Pattern<'tcx> {
920 fn sinto(&self, s: &S) -> Pattern {
921 self.kind().sinto(s)
922 }
923}
924#[derive(AdtInto)]
926#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::CanonicalUserTypeAnnotation<'tcx>, state: S as gstate)]
927#[derive(Clone, Debug)]
928pub struct CanonicalUserTypeAnnotation {
929 pub user_ty: CanonicalUserType,
930 pub span: Span,
931 pub inferred_ty: Ty,
932}
933
934#[derive(Copy, Clone, Debug)]
937pub enum AdtKind {
938 Struct,
939 Union,
940 Enum,
941 Array,
943 Slice,
945 Tuple,
947}
948
949impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, AdtKind> for ty::AdtKind {
950 fn sinto(&self, _s: &S) -> AdtKind {
951 match self {
952 ty::AdtKind::Struct => AdtKind::Struct,
953 ty::AdtKind::Union => AdtKind::Union,
954 ty::AdtKind::Enum => AdtKind::Enum,
955 }
956 }
957}
958
959sinto_todo!(rustc_middle::ty, AdtFlags);
960
961#[derive(AdtInto, Clone, Debug)]
964#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: rustc_abi::ReprOptions, state: S as s)]
965pub struct ReprOptions {
966 #[value(self.int.is_some())]
968 pub int_specified: bool,
969 #[value({
971 use rustc_middle::ty::util::IntTypeExt;
972 self.discr_type().to_ty(s.base().tcx).sinto(s)
973 })]
974 pub typ: Ty,
975 pub align: Option<Align>,
976 pub pack: Option<Align>,
977 #[value(ReprFlags { is_c: self.c(), is_transparent: self.transparent(), is_simd: self.simd() })]
978 pub flags: ReprFlags,
979}
980
981#[derive(Default, Clone, Debug)]
984pub struct ReprFlags {
985 pub is_c: bool,
986 pub is_transparent: bool,
987 pub is_simd: bool,
988}
989
990#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
993#[args(<'tcx, S: BaseState<'tcx>>, from: rustc_abi::Align, state: S as _s)]
994pub struct Align {
995 #[value({
996 self.bytes()
997 })]
998 pub bytes: u64,
999}
1000
1001#[derive(Clone, Debug)]
1003pub enum UnsizingMetadata {
1004 Length(ConstantExpr),
1006 DirectVTable(TraitProof),
1008 NestedVTable(DynBinder<TraitProof>),
1010 Unknown,
1012}
1013
1014pub fn compute_unsizing_metadata<'tcx, S: UnderOwnerState<'tcx>>(
1015 s: &S,
1016 src_ty: ty::Ty<'tcx>,
1017 tgt_ty: ty::Ty<'tcx>,
1018) -> UnsizingMetadata {
1019 let (Some(src_ty), Some(tgt_ty)) = (src_ty.builtin_deref(true), tgt_ty.builtin_deref(true))
1025 else {
1026 return UnsizingMetadata::Unknown;
1027 };
1028
1029 let tcx = s.base().tcx;
1030 let typing_env = s.typing_env();
1031 let (src_ty, tgt_ty) =
1032 tcx.struct_lockstep_tails_raw(src_ty, tgt_ty, |ty| normalize(tcx, typing_env, ty));
1033
1034 match (&src_ty.kind(), &tgt_ty.kind()) {
1035 (ty::Array(_, len), ty::Slice(_)) => {
1036 let len = len.sinto(s);
1037 UnsizingMetadata::Length(len)
1038 }
1039 (ty::Dynamic(from_preds, _), ty::Dynamic(to_preds, ..)) => {
1040 let trait_proof = resolve_for_dyn(s, from_preds, |searcher, fresh_ty| {
1041 let to_pred = if let Some(to_principal) = to_preds.principal() {
1042 to_principal.with_self_ty(tcx, fresh_ty)
1043 } else {
1044 let def_id = to_preds
1045 .iter()
1046 .find_map(|pred| match pred.skip_binder() {
1047 ty::ExistentialPredicate::AutoTrait(def_id) => Some(def_id),
1048 _ => None,
1049 })
1050 .expect("expected a trait predicate in dyn upcast target");
1051 ty::Binder::dummy(ty::TraitRef::new(tcx, def_id, [fresh_ty]))
1052 };
1053 searcher.resolve(&s.base_state(), &to_pred).sinto(s)
1054 });
1055 UnsizingMetadata::NestedVTable(trait_proof)
1056 }
1057 (_, ty::Dynamic(preds, ..)) => {
1058 let pred = preds[0].with_self_ty(tcx, src_ty);
1059 let clause = pred.as_trait_clause().expect(
1060 "the first `ExistentialPredicate` of `TyKind::Dynamic` \\
1061 should be a trait clause",
1062 );
1063 let tref = clause.rebind(clause.skip_binder().trait_ref);
1064 let trait_proof = solve_trait(s, tref);
1065
1066 UnsizingMetadata::DirectVTable(trait_proof)
1067 }
1068 _ => UnsizingMetadata::Unknown,
1069 }
1070}
1071
1072#[derive(AdtInto, Clone, Debug, Hash, PartialEq, Eq)]
1074#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::FnSig<'tcx>, state: S as s)]
1075pub struct TyFnSig {
1076 #[value(self.inputs().sinto(s))]
1077 pub inputs: Vec<Ty>,
1078 #[value(self.output().sinto(s))]
1079 pub output: Ty,
1080 #[value(self.c_variadic())]
1081 pub c_variadic: bool,
1082 #[value(self.safety())]
1083 pub safety: Safety,
1084 #[value(self.abi())]
1085 pub abi: ExternAbi,
1086}
1087
1088pub type PolyFnSig = Binder<TyFnSig>;
1090
1091pub type TraitRef = ItemRef;
1097
1098impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, TraitRef> for ty::TraitRef<'tcx> {
1099 fn sinto(&self, s: &S) -> TraitRef {
1100 translate_item_ref(s, self.def_id, self.args)
1101 }
1102}
1103
1104#[derive(AdtInto)]
1106#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::TraitPredicate<'tcx>, state: S as tcx)]
1107#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1108pub struct TraitPredicate {
1109 pub trait_ref: TraitRef,
1110 #[map(*x == ty::PredicatePolarity::Positive)]
1111 #[from(polarity)]
1112 pub is_positive: bool,
1113}
1114
1115#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1121pub struct OutlivesPredicate<T> {
1122 pub lhs: T,
1123 pub rhs: Region,
1124}
1125
1126impl<'tcx, S: UnderOwnerState<'tcx>, T, U> SInto<S, OutlivesPredicate<U>>
1127 for ty::OutlivesPredicate<'tcx, T>
1128where
1129 T: SInto<S, U>,
1130{
1131 fn sinto(&self, s: &S) -> OutlivesPredicate<U> where {
1132 OutlivesPredicate {
1133 lhs: self.0.sinto(s),
1134 rhs: self.1.sinto(s),
1135 }
1136 }
1137}
1138
1139pub type RegionOutlivesPredicate = OutlivesPredicate<Region>;
1141pub type TypeOutlivesPredicate = OutlivesPredicate<Ty>;
1143
1144#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1147pub enum Term {
1148 Ty(Ty),
1149 Const(ConstantExpr),
1150}
1151
1152impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Term> for ty::Term<'tcx> {
1153 fn sinto(&self, s: &S) -> Term {
1154 use ty::TermKind;
1155 match self.kind() {
1156 TermKind::Ty(ty) => Term::Ty(ty.sinto(s)),
1157 TermKind::Const(c) => Term::Const(c.sinto(s)),
1158 }
1159 }
1160}
1161
1162#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1172pub struct ProjectionPredicate {
1173 pub trait_proof: TraitProof,
1175 pub assoc_item: AssocItem,
1177 pub ty: Ty,
1179}
1180
1181impl<'tcx, S: UnderBinderState<'tcx>> SInto<S, ProjectionPredicate>
1182 for ty::ProjectionPredicate<'tcx>
1183{
1184 fn sinto(&self, s: &S) -> ProjectionPredicate {
1185 let tcx = s.base().tcx;
1186 let alias_ty = &self.projection_term.expect_ty(tcx);
1187 let poly_trait_ref = s.binder().rebind(alias_ty.trait_ref(tcx));
1188 let Term::Ty(ty) = self.term.sinto(s) else {
1189 unreachable!()
1190 };
1191 let item = tcx.associated_item(alias_ty.kind.def_id());
1192 ProjectionPredicate {
1193 trait_proof: solve_trait(s, poly_trait_ref),
1194 assoc_item: AssocItem::sfrom(s, &item),
1195 ty,
1196 }
1197 }
1198}
1199
1200#[derive(AdtInto)]
1202#[args(<'tcx, S: UnderBinderState<'tcx>>, from: ty::ClauseKind<'tcx>, state: S as tcx)]
1203#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1204pub enum ClauseKind {
1205 Trait(TraitPredicate),
1206 RegionOutlives(RegionOutlivesPredicate),
1207 TypeOutlives(TypeOutlivesPredicate),
1208 Projection(ProjectionPredicate),
1209 ConstArgHasType(ConstantExpr, Ty),
1210 WellFormed(Term),
1211 ConstEvaluatable(ConstantExpr),
1212 HostEffect(HostEffectPredicate),
1213 UnstableFeature(Symbol),
1214}
1215
1216sinto_todo!(rustc_middle::ty, HostEffectPredicate<'tcx>);
1217
1218#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1221pub struct Clause {
1222 pub kind: Binder<ClauseKind>,
1223}
1224
1225impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Clause> for ty::Clause<'tcx> {
1226 fn sinto(&self, s: &S) -> Clause {
1227 let kind = self.kind().sinto(s);
1228 Clause { kind }
1229 }
1230}
1231
1232impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Clause> for ty::PolyTraitPredicate<'tcx> {
1233 fn sinto(&self, s: &S) -> Clause {
1234 let kind: Binder<_> = self.sinto(s);
1235 let kind: Binder<ClauseKind> = kind.map(ClauseKind::Trait);
1236 Clause { kind }
1237 }
1238}
1239
1240#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1243pub struct Predicate {
1244 pub kind: Binder<PredicateKind>,
1245}
1246
1247impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Predicate> for ty::Predicate<'tcx> {
1248 fn sinto(&self, s: &S) -> Predicate {
1249 let kind = self.kind().sinto(s);
1250 Predicate { kind }
1251 }
1252}
1253
1254#[derive(AdtInto)]
1256#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::BoundVariableKind<'tcx>, state: S as tcx)]
1257#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1258pub enum BoundVariableKind {
1259 Ty(BoundTyKind),
1260 #[custom_arm(
1261 &FROM_TYPE::Region(region) => TO_TYPE::Region(region.sinto(tcx), None),
1262 )]
1263 Region(BoundRegionKind, Option<Variance>),
1264 Const,
1265}
1266
1267#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1270pub struct Binder<T> {
1271 pub value: T,
1272 pub bound_vars: Vec<BoundVariableKind>,
1273}
1274
1275impl Binder<()> {
1276 pub fn empty() -> Self {
1277 Binder {
1278 value: (),
1279 bound_vars: vec![],
1280 }
1281 }
1282}
1283
1284impl<T> Binder<T> {
1285 pub fn as_ref(&self) -> Binder<&T> {
1286 Binder {
1287 value: &self.value,
1288 bound_vars: self.bound_vars.clone(),
1289 }
1290 }
1291
1292 pub fn hax_skip_binder(self) -> T {
1293 self.value
1294 }
1295
1296 pub fn hax_skip_binder_ref(&self) -> &T {
1297 &self.value
1298 }
1299
1300 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binder<U> {
1301 Binder {
1302 value: f(self.value),
1303 bound_vars: self.bound_vars,
1304 }
1305 }
1306
1307 pub fn inner_mut(&mut self) -> &mut T {
1308 &mut self.value
1309 }
1310
1311 pub fn rebind<U>(&self, value: U) -> Binder<U> {
1312 self.as_ref().map(|_| value)
1313 }
1314}
1315
1316#[derive(AdtInto)]
1318#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: traits::ItemPredicateId<DefId>, state: S as s)]
1319#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1320pub enum GenericPredicateId {
1321 Required(DefId, u32),
1324 Implied(DefId, u32),
1328 Unmapped(u32),
1331 TraitSelf,
1333}
1334
1335#[derive(AdtInto)]
1336#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: traits::ItemPredicate<'tcx, DefId>, state: S as s)]
1337#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1338pub struct GenericPredicate {
1339 pub id: GenericPredicateId,
1340 pub clause: Clause,
1341 pub span: Span,
1342}
1343
1344#[derive(AdtInto)]
1346#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: traits::ItemPredicates<'tcx, DefId>, state: S as s)]
1347#[derive(Clone, Debug, Default, Hash, PartialEq, Eq)]
1348pub struct GenericPredicates {
1349 pub predicates: Vec<GenericPredicate>,
1350}
1351
1352impl GenericPredicates {
1353 pub fn iter(&self) -> impl Iterator<Item = &GenericPredicate> {
1354 self.predicates.iter()
1355 }
1356 pub fn iter_trait_clauses(&self) -> impl Iterator<Item = &GenericPredicate> {
1358 self.iter()
1359 .filter(|pred| matches!(pred.clause.kind.hax_skip_binder_ref(), ClauseKind::Trait(_)))
1360 }
1361}
1362
1363trait BinderVariances<'tcx>: Sized {
1365 fn variances(
1366 _tcx: ty::TyCtxt<'tcx>,
1367 _binder: &ty::Binder<'tcx, Self>,
1368 ) -> HashMap<ty::BoundVar, ty::Variance> {
1369 HashMap::new()
1370 }
1371}
1372
1373impl<'tcx> BinderVariances<'tcx> for ty::FnSig<'tcx> {
1374 fn variances(
1375 tcx: ty::TyCtxt<'tcx>,
1376 binder: &ty::Binder<'tcx, Self>,
1377 ) -> HashMap<ty::BoundVar, ty::Variance> {
1378 fn_sig_bound_region_variances(tcx, *binder)
1379 }
1380}
1381
1382impl<'tcx> BinderVariances<'tcx> for ty::ClauseKind<'tcx> {}
1383impl<'tcx> BinderVariances<'tcx> for ty::PredicateKind<'tcx> {}
1384impl<'tcx> BinderVariances<'tcx> for ty::TraitRef<'tcx> {}
1385impl<'tcx> BinderVariances<'tcx> for ty::TraitPredicate<'tcx> {}
1386
1387impl<'tcx, S: UnderOwnerState<'tcx>, T1, T2> SInto<S, Binder<T2>> for ty::Binder<'tcx, T1>
1388where
1389 T1: SInto<StateWithBinder<'tcx>, T2> + BinderVariances<'tcx>,
1390{
1391 fn sinto(&self, s: &S) -> Binder<T2> {
1392 let variances = T1::variances(s.base().tcx, self);
1393 let mut bound_vars = self.bound_vars().sinto(s);
1394 for (index, var) in bound_vars.iter_mut().enumerate() {
1395 if let BoundVariableKind::Region(_, variance) = var {
1396 *variance = variances
1397 .get(&ty::BoundVar::from_usize(index))
1398 .copied()
1399 .sinto(s);
1400 }
1401 }
1402 let value = {
1403 let under_binder_s = &s.with_binder(self.as_ref().map_bound(|_| ()));
1404 self.as_ref().skip_binder().sinto(under_binder_s)
1405 };
1406 Binder { value, bound_vars }
1407 }
1408}
1409
1410#[derive(AdtInto)]
1412#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::SubtypePredicate<'tcx>, state: S as tcx)]
1413#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1414pub struct SubtypePredicate {
1415 pub a_is_expected: bool,
1416 pub a: Ty,
1417 pub b: Ty,
1418}
1419
1420#[derive(AdtInto)]
1422#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::CoercePredicate<'tcx>, state: S as tcx)]
1423#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1424pub struct CoercePredicate {
1425 pub a: Ty,
1426 pub b: Ty,
1427}
1428
1429#[derive(AdtInto)]
1431#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::AliasRelationDirection, state: S as _tcx)]
1432#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1433pub enum AliasRelationDirection {
1434 Equate,
1435 Subtype,
1436}
1437
1438#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1440
1441pub struct ClosureArgs {
1442 pub item: ItemRef,
1443 pub kind: ClosureKind,
1446 pub fn_sig: PolyFnSig,
1448 pub upvar_tys: Vec<Ty>,
1450}
1451
1452impl ClosureArgs {
1453 pub fn iter_upvar_borrows(&self) -> impl Iterator<Item = &Ty> {
1456 self.upvar_tys.iter().filter(|ty| {
1457 matches!(
1458 ty.kind(),
1459 TyKind::Ref(
1460 Region {
1461 kind: RegionKind::ReErased
1462 },
1463 ..
1464 )
1465 )
1466 })
1467 }
1468}
1469
1470impl ClosureArgs {
1471 pub fn sfrom<'tcx, S>(s: &S, def_id: RDefId, from: ty::GenericArgsRef<'tcx>) -> Self
1473 where
1474 S: UnderOwnerState<'tcx>,
1475 {
1476 use rustc_middle::ty;
1477 use rustc_type_ir::TypeFoldable;
1478 use rustc_type_ir::TypeSuperFoldable;
1479
1480 struct RegionUnEraserVisitor<'tcx> {
1481 tcx: ty::TyCtxt<'tcx>,
1482 depth: u32,
1483 bound_vars: Vec<ty::BoundVariableKind<'tcx>>,
1484 }
1485
1486 impl<'tcx> ty::TypeFolder<ty::TyCtxt<'tcx>> for RegionUnEraserVisitor<'tcx> {
1487 fn cx(&self) -> ty::TyCtxt<'tcx> {
1488 self.tcx
1489 }
1490
1491 fn fold_ty(&mut self, ty: ty::Ty<'tcx>) -> ty::Ty<'tcx> {
1492 ty.super_fold_with(self)
1493 }
1494
1495 fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
1496 where
1497 T: ty::TypeFoldable<ty::TyCtxt<'tcx>>,
1498 {
1499 self.depth += 1;
1500 let t = t.super_fold_with(self);
1501 self.depth -= 1;
1502 t
1503 }
1504
1505 fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
1506 if r.is_erased() {
1508 let bound_region = ty::BoundRegion {
1509 var: ty::BoundVar::from_usize(self.bound_vars.len()),
1510 kind: ty::BoundRegionKind::Anon,
1511 };
1512 self.bound_vars
1513 .push(ty::BoundVariableKind::Region(bound_region.kind));
1514 ty::Region::new_bound(
1515 self.tcx,
1516 ty::DebruijnIndex::from(self.depth),
1517 bound_region,
1518 )
1519 } else {
1520 r
1521 }
1522 }
1523 }
1524
1525 let tcx = s.base().tcx;
1526 let closure = from.as_closure();
1527 let item = {
1528 let parent_args = tcx.mk_args(closure.parent_args());
1531 translate_item_ref(s, def_id, parent_args)
1532 };
1533 let sig = closure.sig();
1534 let sig = tcx.signature_unclosure(sig, rustc_hir::Safety::Safe);
1535 let sig = {
1537 let mut visitor = RegionUnEraserVisitor {
1538 tcx,
1539 depth: 0,
1540 bound_vars: sig.bound_vars().iter().collect(),
1541 };
1542 let unbound_sig = sig.skip_binder().fold_with(&mut visitor);
1543 let bound_vars = tcx.mk_bound_variable_kinds(&visitor.bound_vars);
1544 ty::Binder::bind_with_vars(unbound_sig, bound_vars)
1545 };
1546 ClosureArgs {
1547 item,
1548 kind: closure.kind().sinto(s),
1549 fn_sig: sig.sinto(s),
1550 upvar_tys: closure.upvar_tys().sinto(s),
1551 }
1552 }
1553}
1554
1555#[derive(AdtInto)]
1557#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: ty::ClosureKind, state: S as _tcx)]
1558#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1559pub enum ClosureKind {
1560 Fn,
1561 FnMut,
1562 FnOnce,
1563}
1564
1565sinto_todo!(rustc_middle::ty, NormalizesTo<'tcx>);
1566
1567#[derive(AdtInto)]
1569#[args(<'tcx, S: UnderBinderState<'tcx>>, from: ty::PredicateKind<'tcx>, state: S as tcx)]
1570#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1571pub enum PredicateKind {
1572 Clause(ClauseKind),
1573 DynCompatible(DefId),
1574 Subtype(SubtypePredicate),
1575 Coerce(CoercePredicate),
1576 ConstEquate(ConstantExpr, ConstantExpr),
1577 Ambiguous,
1578 AliasRelate(Term, Term, AliasRelationDirection),
1579 NormalizesTo(NormalizesTo),
1580}
1581
1582#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1585pub struct AssocItem {
1586 pub def_id: DefId,
1587 pub name: Option<Symbol>,
1589 pub kind: AssocKind,
1590 pub container: AssocItemContainer,
1591 pub has_value: bool,
1594}
1595
1596impl AssocItem {
1597 pub fn sfrom<'tcx, S: BaseState<'tcx>>(s: &S, item: &ty::AssocItem) -> AssocItem {
1598 Self::sfrom_instantiated(s, item, None)
1599 }
1600
1601 pub fn sfrom_instantiated<'tcx, S: BaseState<'tcx>>(
1603 s: &S,
1604 item: &ty::AssocItem,
1605 item_args: Option<ty::GenericArgsRef<'tcx>>,
1606 ) -> AssocItem {
1607 let tcx = s.base().tcx;
1608 let item_def_id = item.def_id.sinto(s);
1610 let s = &s.with_hax_owner(&item_def_id);
1611 let item_args = item_args.unwrap_or_else(|| item_def_id.identity_args(s));
1612 let container_id = item.container_id(tcx);
1613 let container_args = item_args.truncate_to(tcx, tcx.generics_of(container_id));
1614 let container = match item.container {
1615 ty::AssocContainer::Trait => {
1616 let trait_ref =
1617 ty::TraitRef::new_from_args(tcx, container_id, container_args).sinto(s);
1618 AssocItemContainer::TraitContainer { trait_ref }
1619 }
1620 ty::AssocContainer::TraitImpl(implemented_item_id) => {
1621 let implemented_item_id = implemented_item_id.unwrap();
1622 let item = translate_item_ref(s, container_id, container_args);
1623 let implemented_trait_ref = tcx
1624 .impl_trait_ref(container_id)
1625 .instantiate(tcx, container_args);
1626 let implemented_trait_ref = normalize(tcx, s.typing_env(), implemented_trait_ref);
1627 let implemented_trait_item = {
1628 let implemented_item_id = implemented_item_id.sinto(s);
1629 let generics =
1630 item_args.rebase_onto(tcx, container_id, implemented_trait_ref.args);
1631 ItemRef::translate_from_hax_def_id_maybe_resolve(
1633 s,
1634 implemented_item_id,
1635 generics,
1636 AssocItemResolution::None,
1637 )
1638 };
1639 AssocItemContainer::TraitImplContainer {
1640 impl_: item,
1641 implemented_trait_ref: implemented_trait_ref.sinto(s),
1642 implemented_trait_item,
1643 overrides_default: tcx.defaultness(implemented_item_id).has_value(),
1644 }
1645 }
1646 ty::AssocContainer::InherentImpl => AssocItemContainer::InherentImplContainer {
1647 impl_id: container_id.sinto(s),
1648 },
1649 };
1650 let name = match item.opt_name() {
1651 None if let ty::AssocKind::Type { data } = item.kind
1652 && let ty::AssocTypeData::Rpitit(rpitit) = data =>
1653 {
1654 let (ty::ImplTraitInTraitData::Trait { fn_def_id, .. }
1655 | ty::ImplTraitInTraitData::Impl { fn_def_id, .. }) = rpitit;
1656 let fn_name = tcx.item_name(fn_def_id);
1657 let name = Symbol::intern(&format!("{fn_name}_ty"));
1658 Some(name)
1659 }
1660 opt_name => opt_name,
1661 };
1662 AssocItem {
1663 def_id: item.def_id.sinto(s),
1664 name,
1665 kind: item.kind.sinto(s),
1666 container,
1667 has_value: item.defaultness(tcx).has_value(),
1668 }
1669 }
1670
1671 pub fn implemented_trait_item_id(&self) -> &DefId {
1673 match &self.container {
1674 AssocItemContainer::TraitImplContainer {
1675 implemented_trait_item,
1676 ..
1677 } => &implemented_trait_item.def_id,
1678 _ => &self.def_id,
1679 }
1680 }
1681}
1682
1683#[derive(AdtInto)]
1685#[args(<'tcx, S: BaseState<'tcx>>, from: ty::AssocKind, state: S as _tcx)]
1686#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1687pub enum AssocKind {
1688 Const { name: Symbol },
1689 Fn { name: Symbol, has_self: bool },
1690 Type { data: AssocTypeData },
1691}
1692
1693#[derive(AdtInto)]
1695#[args(<'tcx, S: BaseState<'tcx>>, from: ty::AssocTypeData, state: S as _tcx)]
1696#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1697pub enum AssocTypeData {
1698 Normal(Symbol),
1699 Rpitit(ImplTraitInTraitData),
1700}
1701
1702#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1703pub enum AssocItemContainer {
1704 TraitContainer {
1705 trait_ref: TraitRef,
1706 },
1707 TraitImplContainer {
1708 impl_: ItemRef,
1710 implemented_trait_ref: TraitRef,
1712 implemented_trait_item: ItemRef,
1714 overrides_default: bool,
1717 },
1718 InherentImplContainer {
1719 impl_id: DefId,
1720 },
1721}
1722
1723#[derive(AdtInto)]
1725#[args(<'tcx, S: BaseState<'tcx>>, from: ty::ImplTraitInTraitData, state: S as _s)]
1726#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1727pub enum ImplTraitInTraitData {
1728 Trait {
1729 fn_def_id: DefId,
1730 opaque_def_id: DefId,
1731 },
1732 Impl {
1733 fn_def_id: DefId,
1734 },
1735}