1use std::assert_matches::assert_matches;
2
3use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
4
5use super::Const;
6use crate::mir;
7use crate::ty::abstract_const::CastKind;
8use crate::ty::{self, Ty, TyCtxt};
9
10#[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)]
11#[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)]
12pub enum ExprKind {
13 Binop(mir::BinOp),
14 UnOp(mir::UnOp),
15 FunctionCall,
16 Cast(CastKind),
17}
18#[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)]
19#[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)]
20pub struct Expr<'tcx> {
21 pub kind: ExprKind,
22 args: ty::GenericArgsRef<'tcx>,
23}
24
25impl<'tcx> rustc_type_ir::inherent::ExprConst<TyCtxt<'tcx>> for Expr<'tcx> {
26 fn args(self) -> ty::GenericArgsRef<'tcx> {
27 self.args
28 }
29}
30
31impl<'tcx> Expr<'tcx> {
32 pub fn new_binop(
33 tcx: TyCtxt<'tcx>,
34 binop: mir::BinOp,
35 lhs_ty: Ty<'tcx>,
36 rhs_ty: Ty<'tcx>,
37 lhs_ct: Const<'tcx>,
38 rhs_ct: Const<'tcx>,
39 ) -> Self {
40 let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
41 [lhs_ty.into(), rhs_ty.into(), lhs_ct.into(), rhs_ct.into()].into_iter(),
42 );
43
44 Self { kind: ExprKind::Binop(binop), args }
45 }
46
47 pub fn binop_args(self) -> (Ty<'tcx>, Ty<'tcx>, Const<'tcx>, Const<'tcx>) {
48 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(_));
49
50 match self.args().as_slice() {
51 [lhs_ty, rhs_ty, lhs_ct, rhs_ct] => (
52 lhs_ty.expect_ty(),
53 rhs_ty.expect_ty(),
54 lhs_ct.expect_const(),
55 rhs_ct.expect_const(),
56 ),
57 _ => crate::util::bug::bug_fmt(format_args!("Invalid args for `Binop` expr {0:?}",
self))bug!("Invalid args for `Binop` expr {self:?}"),
58 }
59 }
60
61 pub fn new_unop(tcx: TyCtxt<'tcx>, unop: mir::UnOp, ty: Ty<'tcx>, ct: Const<'tcx>) -> Self {
62 let args =
63 tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>([ty.into(), ct.into()].into_iter());
64
65 Self { kind: ExprKind::UnOp(unop), args }
66 }
67
68 pub fn unop_args(self) -> (Ty<'tcx>, Const<'tcx>) {
69 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(_));
70
71 match self.args().as_slice() {
72 [ty, ct] => (ty.expect_ty(), ct.expect_const()),
73 _ => crate::util::bug::bug_fmt(format_args!("Invalid args for `UnOp` expr {0:?}",
self))bug!("Invalid args for `UnOp` expr {self:?}"),
74 }
75 }
76
77 pub fn new_call(
78 tcx: TyCtxt<'tcx>,
79 func_ty: Ty<'tcx>,
80 func_expr: Const<'tcx>,
81 arguments: impl IntoIterator<Item = Const<'tcx>>,
82 ) -> Self {
83 let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
84 [func_ty.into(), func_expr.into()]
85 .into_iter()
86 .chain(arguments.into_iter().map(|ct| ct.into())),
87 );
88
89 Self { kind: ExprKind::FunctionCall, args }
90 }
91
92 pub fn call_args(self) -> (Ty<'tcx>, Const<'tcx>, impl Iterator<Item = Const<'tcx>>) {
93 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);
94
95 match self.args().as_slice() {
96 [func_ty, func, rest @ ..] => (
97 func_ty.expect_ty(),
98 func.expect_const(),
99 rest.iter().map(|arg| arg.expect_const()),
100 ),
101 _ => crate::util::bug::bug_fmt(format_args!("Invalid args for `Call` expr {0:?}",
self))bug!("Invalid args for `Call` expr {self:?}"),
102 }
103 }
104
105 pub fn new_cast(
106 tcx: TyCtxt<'tcx>,
107 cast: CastKind,
108 value_ty: Ty<'tcx>,
109 value: Const<'tcx>,
110 to_ty: Ty<'tcx>,
111 ) -> Self {
112 let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
113 [value_ty.into(), value.into(), to_ty.into()].into_iter(),
114 );
115
116 Self { kind: ExprKind::Cast(cast), args }
117 }
118
119 pub fn cast_args(self) -> (Ty<'tcx>, Const<'tcx>, Ty<'tcx>) {
120 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(_));
121
122 match self.args().as_slice() {
123 [value_ty, value, to_ty] => {
124 (value_ty.expect_ty(), value.expect_const(), to_ty.expect_ty())
125 }
126 _ => crate::util::bug::bug_fmt(format_args!("Invalid args for `Cast` expr {0:?}",
self))bug!("Invalid args for `Cast` expr {self:?}"),
127 }
128 }
129
130 pub fn new(kind: ExprKind, args: ty::GenericArgsRef<'tcx>) -> Self {
131 Self { kind, args }
132 }
133
134 pub fn args(self) -> ty::GenericArgsRef<'tcx> {
135 self.args
136 }
137}
138
139#[cfg(target_pointer_width = "64")]
140const _: [(); 16] = [(); ::std::mem::size_of::<Expr<'_>>()];rustc_data_structures::static_assert_size!(Expr<'_>, 16);