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