1use std::marker::PhantomData;
2
3use derive_where::derive_where;
4#[cfg(feature = "nightly")]
5use rustc_macros::StableHash_NoContext;
6use rustc_type_ir_macros::TypeVisitable_Generic;
7
8use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder};
9use crate::inherent::*;
10use crate::upcast::Upcast;
11use crate::{
12 Binder, BoundConstness, ClauseKind, HostEffectPredicate, Interner, PredicatePolarity,
13 TraitPredicate, TraitRef,
14};
15
16#[automatically_derived]
impl<I: Interner, T> ::core::fmt::Debug for Unnormalized<I, T> where
T: ::core::fmt::Debug {
fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
-> ::core::fmt::Result {
match self {
Unnormalized { value: ref __field_value, _tcx: ref __field__tcx }
=> {
let mut __builder =
::core::fmt::Formatter::debug_struct(__f, "Unnormalized");
::core::fmt::DebugStruct::field(&mut __builder, "value",
__field_value);
::core::fmt::DebugStruct::finish_non_exhaustive(&mut __builder)
}
}
}
}#[derive_where(Clone, Copy, PartialOrd, PartialEq, Eq, Hash, Debug; T)]
32#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<I: Interner, T> ::rustc_data_structures::stable_hash::StableHash
for Unnormalized<I, T> where
T: ::rustc_data_structures::stable_hash::StableHash,
PhantomData<fn()
-> I>: ::rustc_data_structures::stable_hash::StableHash {
#[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 {
Unnormalized { value: ref __binding_0, _tcx: ref __binding_1
} => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash_NoContext))]
33#[derive(const _: () =
{
impl<I: Interner, T> ::rustc_type_ir::TypeVisitable<I> for
Unnormalized<I, T> where I: Interner,
T: ::rustc_type_ir::TypeVisitable<I> {
fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
__visitor: &mut __V) -> __V::Result {
match *self {
Unnormalized { value: ref __binding_0, .. } => {
{
match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_type_ir::VisitorResult::from_residual(r);
}
}
}
}
}
<__V::Result as ::rustc_type_ir::VisitorResult>::output()
}
}
};TypeVisitable_Generic)]
34pub struct Unnormalized<I: Interner, T> {
35 value: T,
36 #[type_visitable(ignore)]
37 #[derive_where(skip(Debug))]
38 _tcx: PhantomData<fn() -> I>,
39}
40
41impl<I: Interner, T> Unnormalized<I, T> {
42 pub fn new(value: T) -> Unnormalized<I, T> {
45 Unnormalized { value, _tcx: PhantomData }
46 }
47
48 pub fn dummy(value: T) -> Unnormalized<I, T> {
52 Unnormalized { value, _tcx: PhantomData }
53 }
54
55 pub fn new_wip(value: T) -> Unnormalized<I, T> {
58 Unnormalized { value, _tcx: PhantomData }
59 }
60
61 pub fn skip_normalization(self) -> T {
64 self.value
65 }
66
67 pub fn skip_norm_wip(self) -> T {
72 self.value
73 }
74
75 pub fn map<F, U>(self, f: F) -> Unnormalized<I, U>
76 where
77 F: FnOnce(T) -> U,
78 {
79 Unnormalized { value: f(self.value), _tcx: PhantomData }
80 }
81
82 pub fn as_ref(&self) -> Unnormalized<I, &T> {
83 Unnormalized { value: &self.value, _tcx: PhantomData }
84 }
85
86 pub fn map_ref<U, F>(&self, f: F) -> Unnormalized<I, U>
87 where
88 F: FnOnce(&T) -> U,
89 {
90 Unnormalized { value: f(&self.value), _tcx: PhantomData }
91 }
92}
93
94impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Unnormalized<I, T> {
95 fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
96 Ok(Unnormalized::new(self.value.try_fold_with(folder)?))
97 }
98
99 fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
100 Unnormalized::new(self.value.fold_with(folder))
101 }
102}
103
104impl<I: Interner, T, U> Unnormalized<I, (T, U)> {
105 pub fn unzip(self) -> (Unnormalized<I, T>, Unnormalized<I, U>) {
106 (Unnormalized::new(self.value.0), Unnormalized::new(self.value.1))
107 }
108}
109
110impl<I: Interner, T> Unnormalized<I, Binder<I, T>> {
111 pub fn skip_binder(self) -> T {
112 self.value.skip_binder()
113 }
114}
115
116impl<I: Interner> Unnormalized<I, I::Clause> {
117 pub fn as_trait_clause(self) -> Option<Unnormalized<I, Binder<I, TraitPredicate<I>>>> {
118 self.value.as_trait_clause().map(|v| Unnormalized::new(v))
119 }
120
121 pub fn kind(self) -> Unnormalized<I, Binder<I, ClauseKind<I>>> {
122 self.map(|v| v.kind())
123 }
124}
125
126impl<I: Interner> Unnormalized<I, Binder<I, TraitPredicate<I>>> {
127 pub fn self_ty(self) -> Unnormalized<I, Binder<I, I::Ty>> {
128 self.map(|pred| pred.self_ty())
129 }
130
131 pub fn def_id(self) -> I::TraitId {
132 self.value.skip_binder().def_id()
133 }
134
135 #[inline]
136 pub fn polarity(self) -> PredicatePolarity {
137 self.value.skip_binder().polarity
138 }
139}
140
141impl<I: Interner> Unnormalized<I, Binder<I, TraitRef<I>>> {
142 pub fn self_ty(&self) -> Unnormalized<I, Binder<I, I::Ty>> {
143 self.map_ref(|tr| tr.self_ty())
144 }
145
146 pub fn def_id(&self) -> I::TraitId {
147 self.value.skip_binder().def_id
148 }
149
150 pub fn to_host_effect_clause(
151 self,
152 cx: I,
153 constness: BoundConstness,
154 ) -> Unnormalized<I, I::Clause> {
155 let inner = self
156 .value
157 .map_bound(|trait_ref| {
158 ClauseKind::HostEffect(HostEffectPredicate { trait_ref, constness })
159 })
160 .upcast(cx);
161 Unnormalized::new(inner)
162 }
163}