1use rustc_data_structures::assert_matches;
2use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
3
4use super::Const;
5use crate::mir;
6use crate::ty::abstract_const::CastKind;
7use crate::ty::{self, Ty, TyCtxt};
8
9#[derive(#[automatically_derived]
impl ::core::marker::Copy for ExprKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ExprKind {
#[inline]
fn clone(&self) -> ExprKind {
let _: ::core::clone::AssertParamIsClone<mir::BinOp>;
let _: ::core::clone::AssertParamIsClone<mir::UnOp>;
let _: ::core::clone::AssertParamIsClone<CastKind>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for ExprKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<mir::BinOp>;
let _: ::core::cmp::AssertParamIsEq<mir::UnOp>;
let _: ::core::cmp::AssertParamIsEq<CastKind>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for ExprKind {
#[inline]
fn eq(&self, other: &ExprKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(ExprKind::Binop(__self_0), ExprKind::Binop(__arg1_0)) =>
__self_0 == __arg1_0,
(ExprKind::UnOp(__self_0), ExprKind::UnOp(__arg1_0)) =>
__self_0 == __arg1_0,
(ExprKind::Cast(__self_0), ExprKind::Cast(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for ExprKind {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
ExprKind::Binop(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
ExprKind::UnOp(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
ExprKind::Cast(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for ExprKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ExprKind::Binop(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Binop",
&__self_0),
ExprKind::UnOp(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "UnOp",
&__self_0),
ExprKind::FunctionCall =>
::core::fmt::Formatter::write_str(f, "FunctionCall"),
ExprKind::Cast(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Cast",
&__self_0),
}
}
}Debug)]
10#[derive(const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
for ExprKind {
#[inline]
fn hash_stable(&self,
__hcx:
&mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
ExprKind::Binop(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
ExprKind::UnOp(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
ExprKind::FunctionCall => {}
ExprKind::Cast(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for ExprKind {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
ExprKind::Binop(ref __binding_0) => { 0usize }
ExprKind::UnOp(ref __binding_0) => { 1usize }
ExprKind::FunctionCall => { 2usize }
ExprKind::Cast(ref __binding_0) => { 3usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
ExprKind::Binop(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
ExprKind::UnOp(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
ExprKind::FunctionCall => {}
ExprKind::Cast(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};TyEncodable, const _: () =
{
impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
::rustc_serialize::Decodable<__D> for ExprKind {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
ExprKind::Binop(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => {
ExprKind::UnOp(::rustc_serialize::Decodable::decode(__decoder))
}
2usize => { ExprKind::FunctionCall }
3usize => {
ExprKind::Cast(::rustc_serialize::Decodable::decode(__decoder))
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `ExprKind`, expected 0..4, actual {0}",
n));
}
}
}
}
};TyDecodable, const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
for ExprKind {
fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
__visitor: &mut __V) -> __V::Result {
match *self {
ExprKind::Binop(ref __binding_0) => {
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
}
ExprKind::UnOp(ref __binding_0) => {
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
}
ExprKind::FunctionCall => {}
ExprKind::Cast(ref __binding_0) => {
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
}
}
<__V::Result as ::rustc_middle::ty::VisitorResult>::output()
}
}
};TypeVisitable, const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
for ExprKind {
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 {
ExprKind::Binop(__binding_0) => {
ExprKind::Binop(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
__folder)?)
}
ExprKind::UnOp(__binding_0) => {
ExprKind::UnOp(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
__folder)?)
}
ExprKind::FunctionCall => { ExprKind::FunctionCall }
ExprKind::Cast(__binding_0) => {
ExprKind::Cast(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
__folder)?)
}
})
}
fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Self {
match self {
ExprKind::Binop(__binding_0) => {
ExprKind::Binop(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
__folder))
}
ExprKind::UnOp(__binding_0) => {
ExprKind::UnOp(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
__folder))
}
ExprKind::FunctionCall => { ExprKind::FunctionCall }
ExprKind::Cast(__binding_0) => {
ExprKind::Cast(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
__folder))
}
}
}
}
};TypeFoldable)]
11pub enum ExprKind {
12 Binop(mir::BinOp),
13 UnOp(mir::UnOp),
14 FunctionCall,
15 Cast(CastKind),
16}
17#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for Expr<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for Expr<'tcx> {
#[inline]
fn clone(&self) -> Expr<'tcx> {
let _: ::core::clone::AssertParamIsClone<ExprKind>;
let _: ::core::clone::AssertParamIsClone<ty::GenericArgsRef<'tcx>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for Expr<'tcx> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<ExprKind>;
let _: ::core::cmp::AssertParamIsEq<ty::GenericArgsRef<'tcx>>;
}
}Eq, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for Expr<'tcx> {
#[inline]
fn eq(&self, other: &Expr<'tcx>) -> bool {
self.kind == other.kind && self.args == other.args
}
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for Expr<'tcx> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.kind, state);
::core::hash::Hash::hash(&self.args, state)
}
}Hash)]
18#[derive(const _: () =
{
impl<'tcx, '__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
for Expr<'tcx> {
#[inline]
fn hash_stable(&self,
__hcx:
&mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
Expr { kind: ref __binding_0, args: ref __binding_1 } => {
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for Expr<'tcx> {
fn encode(&self, __encoder: &mut __E) {
match *self {
Expr { kind: ref __binding_0, args: ref __binding_1 } => {
::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 Expr<'tcx> {
fn decode(__decoder: &mut __D) -> Self {
Expr {
kind: ::rustc_serialize::Decodable::decode(__decoder),
args: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};TyDecodable, const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
for Expr<'tcx> {
fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
__visitor: &mut __V) -> __V::Result {
match *self {
Expr { kind: ref __binding_0, args: 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>
::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
for Expr<'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 {
Expr { kind: __binding_0, args: __binding_1 } => {
Expr {
kind: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
__folder)?,
args: ::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 {
Expr { kind: __binding_0, args: __binding_1 } => {
Expr {
kind: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
__folder),
args: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
__folder),
}
}
}
}
}
};TypeFoldable)]
19pub struct Expr<'tcx> {
20 pub kind: ExprKind,
21 args: ty::GenericArgsRef<'tcx>,
22}
23
24impl<'tcx> rustc_type_ir::inherent::ExprConst<TyCtxt<'tcx>> for Expr<'tcx> {
25 fn args(self) -> ty::GenericArgsRef<'tcx> {
26 self.args
27 }
28}
29
30impl<'tcx> Expr<'tcx> {
31 pub fn new_binop(
32 tcx: TyCtxt<'tcx>,
33 binop: mir::BinOp,
34 lhs_ty: Ty<'tcx>,
35 rhs_ty: Ty<'tcx>,
36 lhs_ct: Const<'tcx>,
37 rhs_ct: Const<'tcx>,
38 ) -> Self {
39 let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
40 [lhs_ty.into(), rhs_ty.into(), lhs_ct.into(), rhs_ct.into()].into_iter(),
41 );
42
43 Self { kind: ExprKind::Binop(binop), args }
44 }
45
46 pub fn binop_args(self) -> (Ty<'tcx>, Ty<'tcx>, Const<'tcx>, Const<'tcx>) {
47 match self.kind {
ExprKind::Binop(_) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"ExprKind::Binop(_)", ::core::option::Option::None);
}
};assert_matches!(self.kind, ExprKind::Binop(_));
48
49 match self.args().as_slice() {
50 [lhs_ty, rhs_ty, lhs_ct, rhs_ct] => (
51 lhs_ty.expect_ty(),
52 rhs_ty.expect_ty(),
53 lhs_ct.expect_const(),
54 rhs_ct.expect_const(),
55 ),
56 _ => crate::util::bug::bug_fmt(format_args!("Invalid args for `Binop` expr {0:?}",
self))bug!("Invalid args for `Binop` expr {self:?}"),
57 }
58 }
59
60 pub fn new_unop(tcx: TyCtxt<'tcx>, unop: mir::UnOp, ty: Ty<'tcx>, ct: Const<'tcx>) -> Self {
61 let args =
62 tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>([ty.into(), ct.into()].into_iter());
63
64 Self { kind: ExprKind::UnOp(unop), args }
65 }
66
67 pub fn unop_args(self) -> (Ty<'tcx>, Const<'tcx>) {
68 match self.kind {
ExprKind::UnOp(_) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"ExprKind::UnOp(_)", ::core::option::Option::None);
}
};assert_matches!(self.kind, ExprKind::UnOp(_));
69
70 match self.args().as_slice() {
71 [ty, ct] => (ty.expect_ty(), ct.expect_const()),
72 _ => crate::util::bug::bug_fmt(format_args!("Invalid args for `UnOp` expr {0:?}",
self))bug!("Invalid args for `UnOp` expr {self:?}"),
73 }
74 }
75
76 pub fn new_call(
77 tcx: TyCtxt<'tcx>,
78 func_ty: Ty<'tcx>,
79 func_expr: Const<'tcx>,
80 arguments: impl IntoIterator<Item = Const<'tcx>>,
81 ) -> Self {
82 let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
83 [func_ty.into(), func_expr.into()]
84 .into_iter()
85 .chain(arguments.into_iter().map(|ct| ct.into())),
86 );
87
88 Self { kind: ExprKind::FunctionCall, args }
89 }
90
91 pub fn call_args(self) -> (Ty<'tcx>, Const<'tcx>, impl Iterator<Item = Const<'tcx>>) {
92 match self.kind {
ExprKind::FunctionCall => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"ExprKind::FunctionCall", ::core::option::Option::None);
}
};assert_matches!(self.kind, ExprKind::FunctionCall);
93
94 match self.args().as_slice() {
95 [func_ty, func, rest @ ..] => (
96 func_ty.expect_ty(),
97 func.expect_const(),
98 rest.iter().map(|arg| arg.expect_const()),
99 ),
100 _ => crate::util::bug::bug_fmt(format_args!("Invalid args for `Call` expr {0:?}",
self))bug!("Invalid args for `Call` expr {self:?}"),
101 }
102 }
103
104 pub fn new_cast(
105 tcx: TyCtxt<'tcx>,
106 cast: CastKind,
107 value_ty: Ty<'tcx>,
108 value: Const<'tcx>,
109 to_ty: Ty<'tcx>,
110 ) -> Self {
111 let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
112 [value_ty.into(), value.into(), to_ty.into()].into_iter(),
113 );
114
115 Self { kind: ExprKind::Cast(cast), args }
116 }
117
118 pub fn cast_args(self) -> (Ty<'tcx>, Const<'tcx>, Ty<'tcx>) {
119 match self.kind {
ExprKind::Cast(_) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"ExprKind::Cast(_)", ::core::option::Option::None);
}
};assert_matches!(self.kind, ExprKind::Cast(_));
120
121 match self.args().as_slice() {
122 [value_ty, value, to_ty] => {
123 (value_ty.expect_ty(), value.expect_const(), to_ty.expect_ty())
124 }
125 _ => crate::util::bug::bug_fmt(format_args!("Invalid args for `Cast` expr {0:?}",
self))bug!("Invalid args for `Cast` expr {self:?}"),
126 }
127 }
128
129 pub fn new(kind: ExprKind, args: ty::GenericArgsRef<'tcx>) -> Self {
130 Self { kind, args }
131 }
132
133 pub fn args(self) -> ty::GenericArgsRef<'tcx> {
134 self.args
135 }
136}
137
138#[cfg(target_pointer_width = "64")]
139const _: [(); 16] = [(); ::std::mem::size_of::<Expr<'_>>()];rustc_data_structures::static_assert_size!(Expr<'_>, 16);