Skip to main content

nwnrs_nwscript/
ir.rs

1use std::{collections::BTreeMap, error::Error, fmt};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6    AssignmentOp, BinaryOp, BuiltinType, BuiltinValue, HirBlock, HirCallTarget, HirExpr,
7    HirExprKind, HirFunction, HirModule, HirStmt, LangSpec, Literal, SemanticType, UnaryOp,
8    nwscript_string_hash,
9};
10
11/// One lowered IR module ready for code generation.
12#[derive(#[automatically_derived]
impl ::core::fmt::Debug for IrModule {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "IrModule",
            "globals", &self.globals, "functions", &&self.functions)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for IrModule {
    #[inline]
    fn clone(&self) -> IrModule {
        IrModule {
            globals: ::core::clone::Clone::clone(&self.globals),
            functions: ::core::clone::Clone::clone(&self.functions),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for IrModule {
    #[inline]
    fn eq(&self, other: &IrModule) -> bool {
        self.globals == other.globals && self.functions == other.functions
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for IrModule {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "IrModule", false as usize + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "globals", &self.globals)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "functions", &self.functions)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for IrModule {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "globals" => _serde::__private228::Ok(__Field::__field0),
                            "functions" => _serde::__private228::Ok(__Field::__field1),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"globals" => _serde::__private228::Ok(__Field::__field0),
                            b"functions" => _serde::__private228::Ok(__Field::__field1),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<IrModule>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = IrModule;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct IrModule")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<Vec<IrGlobal>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct IrModule with 2 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<Vec<IrFunction>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct IrModule with 2 elements")),
                            };
                        _serde::__private228::Ok(IrModule {
                                globals: __field0,
                                functions: __field1,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0:
                                _serde::__private228::Option<Vec<IrGlobal>> =
                            _serde::__private228::None;
                        let mut __field1:
                                _serde::__private228::Option<Vec<IrFunction>> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("globals"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<IrGlobal>>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("functions"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<IrFunction>>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("globals")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("functions")?,
                            };
                        _serde::__private228::Ok(IrModule {
                                globals: __field0,
                                functions: __field1,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["globals", "functions"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "IrModule", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<IrModule>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
13pub struct IrModule {
14    /// Globals lowered into the IR world.
15    pub globals:   Vec<IrGlobal>,
16    /// Functions lowered into stack-machine IR.
17    pub functions: Vec<IrFunction>,
18}
19
20/// One lowered global.
21#[derive(#[automatically_derived]
impl ::core::fmt::Debug for IrGlobal {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "IrGlobal",
            "name", &self.name, "ty", &&self.ty)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for IrGlobal {
    #[inline]
    fn clone(&self) -> IrGlobal {
        IrGlobal {
            name: ::core::clone::Clone::clone(&self.name),
            ty: ::core::clone::Clone::clone(&self.ty),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for IrGlobal {
    #[inline]
    fn eq(&self, other: &IrGlobal) -> bool {
        self.name == other.name && self.ty == other.ty
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for IrGlobal {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "IrGlobal", false as usize + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "name", &self.name)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "ty", &self.ty)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for IrGlobal {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "name" => _serde::__private228::Ok(__Field::__field0),
                            "ty" => _serde::__private228::Ok(__Field::__field1),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"name" => _serde::__private228::Ok(__Field::__field0),
                            b"ty" => _serde::__private228::Ok(__Field::__field1),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<IrGlobal>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = IrGlobal;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct IrGlobal")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct IrGlobal with 2 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<SemanticType>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct IrGlobal with 2 elements")),
                            };
                        _serde::__private228::Ok(IrGlobal {
                                name: __field0,
                                ty: __field1,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0: _serde::__private228::Option<String> =
                            _serde::__private228::None;
                        let mut __field1:
                                _serde::__private228::Option<SemanticType> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("name"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("ty"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<SemanticType>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("name")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("ty")?,
                            };
                        _serde::__private228::Ok(IrGlobal {
                                name: __field0,
                                ty: __field1,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] = &["name", "ty"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "IrGlobal", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<IrGlobal>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
22pub struct IrGlobal {
23    /// Global name.
24    pub name: String,
25    /// Global type.
26    pub ty:   SemanticType,
27}
28
29/// One lowered function.
30#[derive(#[automatically_derived]
impl ::core::fmt::Debug for IrFunction {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f, "IrFunction",
            "name", &self.name, "return_type", &self.return_type,
            "parameters", &self.parameters, "locals", &self.locals, "blocks",
            &&self.blocks)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for IrFunction {
    #[inline]
    fn clone(&self) -> IrFunction {
        IrFunction {
            name: ::core::clone::Clone::clone(&self.name),
            return_type: ::core::clone::Clone::clone(&self.return_type),
            parameters: ::core::clone::Clone::clone(&self.parameters),
            locals: ::core::clone::Clone::clone(&self.locals),
            blocks: ::core::clone::Clone::clone(&self.blocks),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for IrFunction {
    #[inline]
    fn eq(&self, other: &IrFunction) -> bool {
        self.name == other.name && self.return_type == other.return_type &&
                    self.parameters == other.parameters &&
                self.locals == other.locals && self.blocks == other.blocks
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for IrFunction {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "IrFunction", false as usize + 1 + 1 + 1 + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "name", &self.name)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "return_type", &self.return_type)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "parameters", &self.parameters)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "locals", &self.locals)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "blocks", &self.blocks)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for IrFunction {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field {
                    __field0,
                    __field1,
                    __field2,
                    __field3,
                    __field4,
                    __ignore,
                }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            3u64 => _serde::__private228::Ok(__Field::__field3),
                            4u64 => _serde::__private228::Ok(__Field::__field4),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "name" => _serde::__private228::Ok(__Field::__field0),
                            "return_type" =>
                                _serde::__private228::Ok(__Field::__field1),
                            "parameters" => _serde::__private228::Ok(__Field::__field2),
                            "locals" => _serde::__private228::Ok(__Field::__field3),
                            "blocks" => _serde::__private228::Ok(__Field::__field4),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"name" => _serde::__private228::Ok(__Field::__field0),
                            b"return_type" =>
                                _serde::__private228::Ok(__Field::__field1),
                            b"parameters" =>
                                _serde::__private228::Ok(__Field::__field2),
                            b"locals" => _serde::__private228::Ok(__Field::__field3),
                            b"blocks" => _serde::__private228::Ok(__Field::__field4),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<IrFunction>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = IrFunction;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct IrFunction")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct IrFunction with 5 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<SemanticType>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct IrFunction with 5 elements")),
                            };
                        let __field2 =
                            match _serde::de::SeqAccess::next_element::<Vec<SemanticType>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                &"struct IrFunction with 5 elements")),
                            };
                        let __field3 =
                            match _serde::de::SeqAccess::next_element::<Vec<SemanticType>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(3usize,
                                                &"struct IrFunction with 5 elements")),
                            };
                        let __field4 =
                            match _serde::de::SeqAccess::next_element::<Vec<IrBlock>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(4usize,
                                                &"struct IrFunction with 5 elements")),
                            };
                        _serde::__private228::Ok(IrFunction {
                                name: __field0,
                                return_type: __field1,
                                parameters: __field2,
                                locals: __field3,
                                blocks: __field4,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0: _serde::__private228::Option<String> =
                            _serde::__private228::None;
                        let mut __field1:
                                _serde::__private228::Option<SemanticType> =
                            _serde::__private228::None;
                        let mut __field2:
                                _serde::__private228::Option<Vec<SemanticType>> =
                            _serde::__private228::None;
                        let mut __field3:
                                _serde::__private228::Option<Vec<SemanticType>> =
                            _serde::__private228::None;
                        let mut __field4:
                                _serde::__private228::Option<Vec<IrBlock>> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("name"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("return_type"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<SemanticType>(&mut __map)?);
                                }
                                __Field::__field2 => {
                                    if _serde::__private228::Option::is_some(&__field2) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("parameters"));
                                    }
                                    __field2 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<SemanticType>>(&mut __map)?);
                                }
                                __Field::__field3 => {
                                    if _serde::__private228::Option::is_some(&__field3) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("locals"));
                                    }
                                    __field3 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<SemanticType>>(&mut __map)?);
                                }
                                __Field::__field4 => {
                                    if _serde::__private228::Option::is_some(&__field4) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("blocks"));
                                    }
                                    __field4 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<IrBlock>>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("name")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("return_type")?,
                            };
                        let __field2 =
                            match __field2 {
                                _serde::__private228::Some(__field2) => __field2,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("parameters")?,
                            };
                        let __field3 =
                            match __field3 {
                                _serde::__private228::Some(__field3) => __field3,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("locals")?,
                            };
                        let __field4 =
                            match __field4 {
                                _serde::__private228::Some(__field4) => __field4,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("blocks")?,
                            };
                        _serde::__private228::Ok(IrFunction {
                                name: __field0,
                                return_type: __field1,
                                parameters: __field2,
                                locals: __field3,
                                blocks: __field4,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["name", "return_type", "parameters", "locals", "blocks"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "IrFunction", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<IrFunction>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
31pub struct IrFunction {
32    /// Function name.
33    pub name:        String,
34    /// Return type.
35    pub return_type: SemanticType,
36    /// Parameter types in declaration order.
37    pub parameters:  Vec<SemanticType>,
38    /// Local types by slot.
39    pub locals:      Vec<SemanticType>,
40    /// Basic blocks in layout order.
41    pub blocks:      Vec<IrBlock>,
42}
43
44/// One basic block.
45#[derive(#[automatically_derived]
impl ::core::fmt::Debug for IrBlock {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "IrBlock", "id",
            &self.id, "instructions", &self.instructions, "terminator",
            &&self.terminator)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for IrBlock {
    #[inline]
    fn clone(&self) -> IrBlock {
        IrBlock {
            id: ::core::clone::Clone::clone(&self.id),
            instructions: ::core::clone::Clone::clone(&self.instructions),
            terminator: ::core::clone::Clone::clone(&self.terminator),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for IrBlock {
    #[inline]
    fn eq(&self, other: &IrBlock) -> bool {
        self.id == other.id && self.instructions == other.instructions &&
            self.terminator == other.terminator
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for IrBlock {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "IrBlock", false as usize + 1 + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "id", &self.id)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "instructions", &self.instructions)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "terminator", &self.terminator)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for IrBlock {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __field2, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "id" => _serde::__private228::Ok(__Field::__field0),
                            "instructions" =>
                                _serde::__private228::Ok(__Field::__field1),
                            "terminator" => _serde::__private228::Ok(__Field::__field2),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"id" => _serde::__private228::Ok(__Field::__field0),
                            b"instructions" =>
                                _serde::__private228::Ok(__Field::__field1),
                            b"terminator" =>
                                _serde::__private228::Ok(__Field::__field2),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<IrBlock>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = IrBlock;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct IrBlock")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<IrBlockId>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct IrBlock with 3 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<Vec<IrInstruction>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct IrBlock with 3 elements")),
                            };
                        let __field2 =
                            match _serde::de::SeqAccess::next_element::<IrTerminator>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                &"struct IrBlock with 3 elements")),
                            };
                        _serde::__private228::Ok(IrBlock {
                                id: __field0,
                                instructions: __field1,
                                terminator: __field2,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0: _serde::__private228::Option<IrBlockId> =
                            _serde::__private228::None;
                        let mut __field1:
                                _serde::__private228::Option<Vec<IrInstruction>> =
                            _serde::__private228::None;
                        let mut __field2:
                                _serde::__private228::Option<IrTerminator> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("id"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrBlockId>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("instructions"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<IrInstruction>>(&mut __map)?);
                                }
                                __Field::__field2 => {
                                    if _serde::__private228::Option::is_some(&__field2) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("terminator"));
                                    }
                                    __field2 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrTerminator>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("id")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("instructions")?,
                            };
                        let __field2 =
                            match __field2 {
                                _serde::__private228::Some(__field2) => __field2,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("terminator")?,
                            };
                        _serde::__private228::Ok(IrBlock {
                                id: __field0,
                                instructions: __field1,
                                terminator: __field2,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["id", "instructions", "terminator"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "IrBlock", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<IrBlock>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
46pub struct IrBlock {
47    /// Block id.
48    pub id:           IrBlockId,
49    /// Non-terminator instructions.
50    pub instructions: Vec<IrInstruction>,
51    /// Block terminator.
52    pub terminator:   IrTerminator,
53}
54
55/// One block id.
56#[derive(
57    #[automatically_derived]
impl ::core::fmt::Debug for IrBlockId {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "IrBlockId",
            &&self.0)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for IrBlockId {
    #[inline]
    fn clone(&self) -> IrBlockId {
        let _: ::core::clone::AssertParamIsClone<u32>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for IrBlockId { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for IrBlockId {
    #[inline]
    fn eq(&self, other: &IrBlockId) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for IrBlockId {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u32>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for IrBlockId {
    #[inline]
    fn partial_cmp(&self, other: &IrBlockId)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for IrBlockId {
    #[inline]
    fn cmp(&self, other: &IrBlockId) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.0, &other.0)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for IrBlockId {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for IrBlockId {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                _serde::Serializer::serialize_newtype_struct(__serializer,
                    "IrBlockId", &self.0)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for IrBlockId {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<IrBlockId>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = IrBlockId;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "tuple struct IrBlockId")
                    }
                    #[inline]
                    fn visit_newtype_struct<__E>(self, __e: __E)
                        -> _serde::__private228::Result<Self::Value, __E::Error>
                        where __E: _serde::Deserializer<'de> {
                        let __field0: u32 =
                            <u32 as _serde::Deserialize>::deserialize(__e)?;
                        _serde::__private228::Ok(IrBlockId(__field0))
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<u32>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"tuple struct IrBlockId with 1 element")),
                            };
                        _serde::__private228::Ok(IrBlockId(__field0))
                    }
                }
                _serde::Deserializer::deserialize_newtype_struct(__deserializer,
                    "IrBlockId",
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<IrBlockId>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize, #[automatically_derived]
impl ::core::default::Default for IrBlockId {
    #[inline]
    fn default() -> IrBlockId {
        IrBlockId(::core::default::Default::default())
    }
}Default,
58)]
59pub struct IrBlockId(pub u32);
60
61/// One SSA-like transient value id.
62#[derive(
63    #[automatically_derived]
impl ::core::fmt::Debug for IrValueId {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "IrValueId",
            &&self.0)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for IrValueId {
    #[inline]
    fn clone(&self) -> IrValueId {
        let _: ::core::clone::AssertParamIsClone<u32>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for IrValueId { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for IrValueId {
    #[inline]
    fn eq(&self, other: &IrValueId) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for IrValueId {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u32>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for IrValueId {
    #[inline]
    fn partial_cmp(&self, other: &IrValueId)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for IrValueId {
    #[inline]
    fn cmp(&self, other: &IrValueId) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.0, &other.0)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for IrValueId {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for IrValueId {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                _serde::Serializer::serialize_newtype_struct(__serializer,
                    "IrValueId", &self.0)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for IrValueId {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<IrValueId>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = IrValueId;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "tuple struct IrValueId")
                    }
                    #[inline]
                    fn visit_newtype_struct<__E>(self, __e: __E)
                        -> _serde::__private228::Result<Self::Value, __E::Error>
                        where __E: _serde::Deserializer<'de> {
                        let __field0: u32 =
                            <u32 as _serde::Deserialize>::deserialize(__e)?;
                        _serde::__private228::Ok(IrValueId(__field0))
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<u32>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"tuple struct IrValueId with 1 element")),
                            };
                        _serde::__private228::Ok(IrValueId(__field0))
                    }
                }
                _serde::Deserializer::deserialize_newtype_struct(__deserializer,
                    "IrValueId",
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<IrValueId>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize, #[automatically_derived]
impl ::core::default::Default for IrValueId {
    #[inline]
    fn default() -> IrValueId {
        IrValueId(::core::default::Default::default())
    }
}Default,
64)]
65pub struct IrValueId(pub u32);
66
67/// One local slot id.
68#[derive(
69    #[automatically_derived]
impl ::core::fmt::Debug for IrLocalId {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "IrLocalId",
            &&self.0)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for IrLocalId {
    #[inline]
    fn clone(&self) -> IrLocalId {
        let _: ::core::clone::AssertParamIsClone<u32>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for IrLocalId { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for IrLocalId {
    #[inline]
    fn eq(&self, other: &IrLocalId) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for IrLocalId {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u32>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for IrLocalId {
    #[inline]
    fn partial_cmp(&self, other: &IrLocalId)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for IrLocalId {
    #[inline]
    fn cmp(&self, other: &IrLocalId) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.0, &other.0)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for IrLocalId {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for IrLocalId {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                _serde::Serializer::serialize_newtype_struct(__serializer,
                    "IrLocalId", &self.0)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for IrLocalId {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<IrLocalId>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = IrLocalId;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "tuple struct IrLocalId")
                    }
                    #[inline]
                    fn visit_newtype_struct<__E>(self, __e: __E)
                        -> _serde::__private228::Result<Self::Value, __E::Error>
                        where __E: _serde::Deserializer<'de> {
                        let __field0: u32 =
                            <u32 as _serde::Deserialize>::deserialize(__e)?;
                        _serde::__private228::Ok(IrLocalId(__field0))
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<u32>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"tuple struct IrLocalId with 1 element")),
                            };
                        _serde::__private228::Ok(IrLocalId(__field0))
                    }
                }
                _serde::Deserializer::deserialize_newtype_struct(__deserializer,
                    "IrLocalId",
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<IrLocalId>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize, #[automatically_derived]
impl ::core::default::Default for IrLocalId {
    #[inline]
    fn default() -> IrLocalId {
        IrLocalId(::core::default::Default::default())
    }
}Default,
70)]
71pub struct IrLocalId(pub u32);
72
73/// One stack-oriented IR instruction.
74#[derive(#[automatically_derived]
impl ::core::fmt::Debug for IrInstruction {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            IrInstruction::Const { dst: __self_0, literal: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Const",
                    "dst", __self_0, "literal", &__self_1),
            IrInstruction::LoadLocal { dst: __self_0, local: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "LoadLocal", "dst", __self_0, "local", &__self_1),
            IrInstruction::StoreLocal { local: __self_0, value: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "StoreLocal", "local", __self_0, "value", &__self_1),
            IrInstruction::LoadGlobal { dst: __self_0, name: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "LoadGlobal", "dst", __self_0, "name", &__self_1),
            IrInstruction::StoreGlobal { name: __self_0, value: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "StoreGlobal", "name", __self_0, "value", &__self_1),
            IrInstruction::Unary {
                dst: __self_0, op: __self_1, operand: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "Unary",
                    "dst", __self_0, "op", __self_1, "operand", &__self_2),
            IrInstruction::Binary {
                dst: __self_0, op: __self_1, left: __self_2, right: __self_3 }
                =>
                ::core::fmt::Formatter::debug_struct_field4_finish(f,
                    "Binary", "dst", __self_0, "op", __self_1, "left", __self_2,
                    "right", &__self_3),
            IrInstruction::Assignment {
                dst: __self_0, op: __self_1, left: __self_2, right: __self_3 }
                =>
                ::core::fmt::Formatter::debug_struct_field4_finish(f,
                    "Assignment", "dst", __self_0, "op", __self_1, "left",
                    __self_2, "right", &__self_3),
            IrInstruction::Call {
                dst: __self_0, function: __self_1, arguments: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "Call",
                    "dst", __self_0, "function", __self_1, "arguments",
                    &__self_2),
            IrInstruction::FieldLoad {
                dst: __self_0, base: __self_1, field: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "FieldLoad", "dst", __self_0, "base", __self_1, "field",
                    &__self_2),
            IrInstruction::FieldStore {
                base: __self_0, field: __self_1, value: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "FieldStore", "base", __self_0, "field", __self_1, "value",
                    &__self_2),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for IrInstruction {
    #[inline]
    fn clone(&self) -> IrInstruction {
        match self {
            IrInstruction::Const { dst: __self_0, literal: __self_1 } =>
                IrInstruction::Const {
                    dst: ::core::clone::Clone::clone(__self_0),
                    literal: ::core::clone::Clone::clone(__self_1),
                },
            IrInstruction::LoadLocal { dst: __self_0, local: __self_1 } =>
                IrInstruction::LoadLocal {
                    dst: ::core::clone::Clone::clone(__self_0),
                    local: ::core::clone::Clone::clone(__self_1),
                },
            IrInstruction::StoreLocal { local: __self_0, value: __self_1 } =>
                IrInstruction::StoreLocal {
                    local: ::core::clone::Clone::clone(__self_0),
                    value: ::core::clone::Clone::clone(__self_1),
                },
            IrInstruction::LoadGlobal { dst: __self_0, name: __self_1 } =>
                IrInstruction::LoadGlobal {
                    dst: ::core::clone::Clone::clone(__self_0),
                    name: ::core::clone::Clone::clone(__self_1),
                },
            IrInstruction::StoreGlobal { name: __self_0, value: __self_1 } =>
                IrInstruction::StoreGlobal {
                    name: ::core::clone::Clone::clone(__self_0),
                    value: ::core::clone::Clone::clone(__self_1),
                },
            IrInstruction::Unary {
                dst: __self_0, op: __self_1, operand: __self_2 } =>
                IrInstruction::Unary {
                    dst: ::core::clone::Clone::clone(__self_0),
                    op: ::core::clone::Clone::clone(__self_1),
                    operand: ::core::clone::Clone::clone(__self_2),
                },
            IrInstruction::Binary {
                dst: __self_0, op: __self_1, left: __self_2, right: __self_3 }
                =>
                IrInstruction::Binary {
                    dst: ::core::clone::Clone::clone(__self_0),
                    op: ::core::clone::Clone::clone(__self_1),
                    left: ::core::clone::Clone::clone(__self_2),
                    right: ::core::clone::Clone::clone(__self_3),
                },
            IrInstruction::Assignment {
                dst: __self_0, op: __self_1, left: __self_2, right: __self_3 }
                =>
                IrInstruction::Assignment {
                    dst: ::core::clone::Clone::clone(__self_0),
                    op: ::core::clone::Clone::clone(__self_1),
                    left: ::core::clone::Clone::clone(__self_2),
                    right: ::core::clone::Clone::clone(__self_3),
                },
            IrInstruction::Call {
                dst: __self_0, function: __self_1, arguments: __self_2 } =>
                IrInstruction::Call {
                    dst: ::core::clone::Clone::clone(__self_0),
                    function: ::core::clone::Clone::clone(__self_1),
                    arguments: ::core::clone::Clone::clone(__self_2),
                },
            IrInstruction::FieldLoad {
                dst: __self_0, base: __self_1, field: __self_2 } =>
                IrInstruction::FieldLoad {
                    dst: ::core::clone::Clone::clone(__self_0),
                    base: ::core::clone::Clone::clone(__self_1),
                    field: ::core::clone::Clone::clone(__self_2),
                },
            IrInstruction::FieldStore {
                base: __self_0, field: __self_1, value: __self_2 } =>
                IrInstruction::FieldStore {
                    base: ::core::clone::Clone::clone(__self_0),
                    field: ::core::clone::Clone::clone(__self_1),
                    value: ::core::clone::Clone::clone(__self_2),
                },
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for IrInstruction {
    #[inline]
    fn eq(&self, other: &IrInstruction) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (IrInstruction::Const { dst: __self_0, literal: __self_1 },
                    IrInstruction::Const { dst: __arg1_0, literal: __arg1_1 })
                    => __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (IrInstruction::LoadLocal { dst: __self_0, local: __self_1 },
                    IrInstruction::LoadLocal { dst: __arg1_0, local: __arg1_1 })
                    => __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (IrInstruction::StoreLocal { local: __self_0, value: __self_1
                    }, IrInstruction::StoreLocal {
                    local: __arg1_0, value: __arg1_1 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (IrInstruction::LoadGlobal { dst: __self_0, name: __self_1 },
                    IrInstruction::LoadGlobal { dst: __arg1_0, name: __arg1_1 })
                    => __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (IrInstruction::StoreGlobal { name: __self_0, value: __self_1
                    }, IrInstruction::StoreGlobal {
                    name: __arg1_0, value: __arg1_1 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (IrInstruction::Unary {
                    dst: __self_0, op: __self_1, operand: __self_2 },
                    IrInstruction::Unary {
                    dst: __arg1_0, op: __arg1_1, operand: __arg1_2 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                        __self_2 == __arg1_2,
                (IrInstruction::Binary {
                    dst: __self_0, op: __self_1, left: __self_2, right: __self_3
                    }, IrInstruction::Binary {
                    dst: __arg1_0, op: __arg1_1, left: __arg1_2, right: __arg1_3
                    }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                            __self_2 == __arg1_2 && __self_3 == __arg1_3,
                (IrInstruction::Assignment {
                    dst: __self_0, op: __self_1, left: __self_2, right: __self_3
                    }, IrInstruction::Assignment {
                    dst: __arg1_0, op: __arg1_1, left: __arg1_2, right: __arg1_3
                    }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                            __self_2 == __arg1_2 && __self_3 == __arg1_3,
                (IrInstruction::Call {
                    dst: __self_0, function: __self_1, arguments: __self_2 },
                    IrInstruction::Call {
                    dst: __arg1_0, function: __arg1_1, arguments: __arg1_2 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                        __self_2 == __arg1_2,
                (IrInstruction::FieldLoad {
                    dst: __self_0, base: __self_1, field: __self_2 },
                    IrInstruction::FieldLoad {
                    dst: __arg1_0, base: __arg1_1, field: __arg1_2 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                        __self_2 == __arg1_2,
                (IrInstruction::FieldStore {
                    base: __self_0, field: __self_1, value: __self_2 },
                    IrInstruction::FieldStore {
                    base: __arg1_0, field: __arg1_1, value: __arg1_2 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                        __self_2 == __arg1_2,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for IrInstruction {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    IrInstruction::Const { ref dst, ref literal } => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrInstruction", 0u32, "Const", 0 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "dst", dst)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "literal", literal)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    IrInstruction::LoadLocal { ref dst, ref local } => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrInstruction", 1u32, "LoadLocal", 0 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "dst", dst)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "local", local)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    IrInstruction::StoreLocal { ref local, ref value } => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrInstruction", 2u32, "StoreLocal", 0 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "local", local)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "value", value)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    IrInstruction::LoadGlobal { ref dst, ref name } => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrInstruction", 3u32, "LoadGlobal", 0 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "dst", dst)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "name", name)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    IrInstruction::StoreGlobal { ref name, ref value } => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrInstruction", 4u32, "StoreGlobal", 0 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "name", name)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "value", value)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    IrInstruction::Unary { ref dst, ref op, ref operand } => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrInstruction", 5u32, "Unary", 0 + 1 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "dst", dst)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "op", op)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "operand", operand)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    IrInstruction::Binary { ref dst, ref op, ref left, ref right
                        } => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrInstruction", 6u32, "Binary", 0 + 1 + 1 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "dst", dst)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "op", op)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "left", left)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "right", right)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    IrInstruction::Assignment {
                        ref dst, ref op, ref left, ref right } => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrInstruction", 7u32, "Assignment", 0 + 1 + 1 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "dst", dst)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "op", op)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "left", left)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "right", right)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    IrInstruction::Call { ref dst, ref function, ref arguments }
                        => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrInstruction", 8u32, "Call", 0 + 1 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "dst", dst)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "function", function)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "arguments", arguments)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    IrInstruction::FieldLoad { ref dst, ref base, ref field } =>
                        {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrInstruction", 9u32, "FieldLoad", 0 + 1 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "dst", dst)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "base", base)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "field", field)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    IrInstruction::FieldStore { ref base, ref field, ref value }
                        => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrInstruction", 10u32, "FieldStore", 0 + 1 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "base", base)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "field", field)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "value", value)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                }
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for IrInstruction {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field {
                    __field0,
                    __field1,
                    __field2,
                    __field3,
                    __field4,
                    __field5,
                    __field6,
                    __field7,
                    __field8,
                    __field9,
                    __field10,
                }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "variant identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            3u64 => _serde::__private228::Ok(__Field::__field3),
                            4u64 => _serde::__private228::Ok(__Field::__field4),
                            5u64 => _serde::__private228::Ok(__Field::__field5),
                            6u64 => _serde::__private228::Ok(__Field::__field6),
                            7u64 => _serde::__private228::Ok(__Field::__field7),
                            8u64 => _serde::__private228::Ok(__Field::__field8),
                            9u64 => _serde::__private228::Ok(__Field::__field9),
                            10u64 => _serde::__private228::Ok(__Field::__field10),
                            _ =>
                                _serde::__private228::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value),
                                        &"variant index 0 <= i < 11")),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "Const" => _serde::__private228::Ok(__Field::__field0),
                            "LoadLocal" => _serde::__private228::Ok(__Field::__field1),
                            "StoreLocal" => _serde::__private228::Ok(__Field::__field2),
                            "LoadGlobal" => _serde::__private228::Ok(__Field::__field3),
                            "StoreGlobal" =>
                                _serde::__private228::Ok(__Field::__field4),
                            "Unary" => _serde::__private228::Ok(__Field::__field5),
                            "Binary" => _serde::__private228::Ok(__Field::__field6),
                            "Assignment" => _serde::__private228::Ok(__Field::__field7),
                            "Call" => _serde::__private228::Ok(__Field::__field8),
                            "FieldLoad" => _serde::__private228::Ok(__Field::__field9),
                            "FieldStore" =>
                                _serde::__private228::Ok(__Field::__field10),
                            _ => {
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"Const" => _serde::__private228::Ok(__Field::__field0),
                            b"LoadLocal" => _serde::__private228::Ok(__Field::__field1),
                            b"StoreLocal" =>
                                _serde::__private228::Ok(__Field::__field2),
                            b"LoadGlobal" =>
                                _serde::__private228::Ok(__Field::__field3),
                            b"StoreGlobal" =>
                                _serde::__private228::Ok(__Field::__field4),
                            b"Unary" => _serde::__private228::Ok(__Field::__field5),
                            b"Binary" => _serde::__private228::Ok(__Field::__field6),
                            b"Assignment" =>
                                _serde::__private228::Ok(__Field::__field7),
                            b"Call" => _serde::__private228::Ok(__Field::__field8),
                            b"FieldLoad" => _serde::__private228::Ok(__Field::__field9),
                            b"FieldStore" =>
                                _serde::__private228::Ok(__Field::__field10),
                            _ => {
                                let __value =
                                    &_serde::__private228::from_utf8_lossy(__value);
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<IrInstruction>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = IrInstruction;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "enum IrInstruction")
                    }
                    fn visit_enum<__A>(self, __data: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::EnumAccess<'de> {
                        match _serde::de::EnumAccess::variant(__data)? {
                            (__Field::__field0, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field { __field0, __field1, __ignore, }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "dst" => _serde::__private228::Ok(__Field::__field0),
                                            "literal" => _serde::__private228::Ok(__Field::__field1),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"dst" => _serde::__private228::Ok(__Field::__field0),
                                            b"literal" => _serde::__private228::Ok(__Field::__field1),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrInstruction>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrInstruction;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrInstruction::Const")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrInstruction::Const with 2 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<Literal>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrInstruction::Const with 2 elements")),
                                            };
                                        _serde::__private228::Ok(IrInstruction::Const {
                                                dst: __field0,
                                                literal: __field1,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field1: _serde::__private228::Option<Literal> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("dst"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("literal"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Literal>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("dst")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("literal")?,
                                            };
                                        _serde::__private228::Ok(IrInstruction::Const {
                                                dst: __field0,
                                                literal: __field1,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] = &["dst", "literal"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrInstruction>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                            (__Field::__field1, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field { __field0, __field1, __ignore, }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "dst" => _serde::__private228::Ok(__Field::__field0),
                                            "local" => _serde::__private228::Ok(__Field::__field1),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"dst" => _serde::__private228::Ok(__Field::__field0),
                                            b"local" => _serde::__private228::Ok(__Field::__field1),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrInstruction>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrInstruction;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrInstruction::LoadLocal")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrInstruction::LoadLocal with 2 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<IrLocalId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrInstruction::LoadLocal with 2 elements")),
                                            };
                                        _serde::__private228::Ok(IrInstruction::LoadLocal {
                                                dst: __field0,
                                                local: __field1,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field1: _serde::__private228::Option<IrLocalId> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("dst"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("local"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrLocalId>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("dst")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("local")?,
                                            };
                                        _serde::__private228::Ok(IrInstruction::LoadLocal {
                                                dst: __field0,
                                                local: __field1,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] = &["dst", "local"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrInstruction>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                            (__Field::__field2, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field { __field0, __field1, __ignore, }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "local" => _serde::__private228::Ok(__Field::__field0),
                                            "value" => _serde::__private228::Ok(__Field::__field1),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"local" => _serde::__private228::Ok(__Field::__field0),
                                            b"value" => _serde::__private228::Ok(__Field::__field1),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrInstruction>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrInstruction;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrInstruction::StoreLocal")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<IrLocalId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrInstruction::StoreLocal with 2 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrInstruction::StoreLocal with 2 elements")),
                                            };
                                        _serde::__private228::Ok(IrInstruction::StoreLocal {
                                                local: __field0,
                                                value: __field1,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0: _serde::__private228::Option<IrLocalId> =
                                            _serde::__private228::None;
                                        let mut __field1: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("local"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrLocalId>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("value"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("local")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("value")?,
                                            };
                                        _serde::__private228::Ok(IrInstruction::StoreLocal {
                                                local: __field0,
                                                value: __field1,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] = &["local", "value"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrInstruction>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                            (__Field::__field3, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field { __field0, __field1, __ignore, }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "dst" => _serde::__private228::Ok(__Field::__field0),
                                            "name" => _serde::__private228::Ok(__Field::__field1),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"dst" => _serde::__private228::Ok(__Field::__field0),
                                            b"name" => _serde::__private228::Ok(__Field::__field1),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrInstruction>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrInstruction;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrInstruction::LoadGlobal")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrInstruction::LoadGlobal with 2 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrInstruction::LoadGlobal with 2 elements")),
                                            };
                                        _serde::__private228::Ok(IrInstruction::LoadGlobal {
                                                dst: __field0,
                                                name: __field1,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field1: _serde::__private228::Option<String> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("dst"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("name"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("dst")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("name")?,
                                            };
                                        _serde::__private228::Ok(IrInstruction::LoadGlobal {
                                                dst: __field0,
                                                name: __field1,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] = &["dst", "name"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrInstruction>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                            (__Field::__field4, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field { __field0, __field1, __ignore, }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "name" => _serde::__private228::Ok(__Field::__field0),
                                            "value" => _serde::__private228::Ok(__Field::__field1),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"name" => _serde::__private228::Ok(__Field::__field0),
                                            b"value" => _serde::__private228::Ok(__Field::__field1),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrInstruction>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrInstruction;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrInstruction::StoreGlobal")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrInstruction::StoreGlobal with 2 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrInstruction::StoreGlobal with 2 elements")),
                                            };
                                        _serde::__private228::Ok(IrInstruction::StoreGlobal {
                                                name: __field0,
                                                value: __field1,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0: _serde::__private228::Option<String> =
                                            _serde::__private228::None;
                                        let mut __field1: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("name"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("value"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("name")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("value")?,
                                            };
                                        _serde::__private228::Ok(IrInstruction::StoreGlobal {
                                                name: __field0,
                                                value: __field1,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] = &["name", "value"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrInstruction>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                            (__Field::__field5, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field { __field0, __field1, __field2, __ignore, }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            2u64 => _serde::__private228::Ok(__Field::__field2),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "dst" => _serde::__private228::Ok(__Field::__field0),
                                            "op" => _serde::__private228::Ok(__Field::__field1),
                                            "operand" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"dst" => _serde::__private228::Ok(__Field::__field0),
                                            b"op" => _serde::__private228::Ok(__Field::__field1),
                                            b"operand" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrInstruction>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrInstruction;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrInstruction::Unary")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrInstruction::Unary with 3 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<UnaryOp>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrInstruction::Unary with 3 elements")),
                                            };
                                        let __field2 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                                &"struct variant IrInstruction::Unary with 3 elements")),
                                            };
                                        _serde::__private228::Ok(IrInstruction::Unary {
                                                dst: __field0,
                                                op: __field1,
                                                operand: __field2,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field1: _serde::__private228::Option<UnaryOp> =
                                            _serde::__private228::None;
                                        let mut __field2: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("dst"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("op"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<UnaryOp>(&mut __map)?);
                                                }
                                                __Field::__field2 => {
                                                    if _serde::__private228::Option::is_some(&__field2) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("operand"));
                                                    }
                                                    __field2 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("dst")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("op")?,
                                            };
                                        let __field2 =
                                            match __field2 {
                                                _serde::__private228::Some(__field2) => __field2,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("operand")?,
                                            };
                                        _serde::__private228::Ok(IrInstruction::Unary {
                                                dst: __field0,
                                                op: __field1,
                                                operand: __field2,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] =
                                    &["dst", "op", "operand"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrInstruction>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                            (__Field::__field6, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field {
                                    __field0,
                                    __field1,
                                    __field2,
                                    __field3,
                                    __ignore,
                                }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            2u64 => _serde::__private228::Ok(__Field::__field2),
                                            3u64 => _serde::__private228::Ok(__Field::__field3),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "dst" => _serde::__private228::Ok(__Field::__field0),
                                            "op" => _serde::__private228::Ok(__Field::__field1),
                                            "left" => _serde::__private228::Ok(__Field::__field2),
                                            "right" => _serde::__private228::Ok(__Field::__field3),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"dst" => _serde::__private228::Ok(__Field::__field0),
                                            b"op" => _serde::__private228::Ok(__Field::__field1),
                                            b"left" => _serde::__private228::Ok(__Field::__field2),
                                            b"right" => _serde::__private228::Ok(__Field::__field3),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrInstruction>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrInstruction;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrInstruction::Binary")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrInstruction::Binary with 4 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<BinaryOp>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrInstruction::Binary with 4 elements")),
                                            };
                                        let __field2 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                                &"struct variant IrInstruction::Binary with 4 elements")),
                                            };
                                        let __field3 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(3usize,
                                                                &"struct variant IrInstruction::Binary with 4 elements")),
                                            };
                                        _serde::__private228::Ok(IrInstruction::Binary {
                                                dst: __field0,
                                                op: __field1,
                                                left: __field2,
                                                right: __field3,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field1: _serde::__private228::Option<BinaryOp> =
                                            _serde::__private228::None;
                                        let mut __field2: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field3: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("dst"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("op"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<BinaryOp>(&mut __map)?);
                                                }
                                                __Field::__field2 => {
                                                    if _serde::__private228::Option::is_some(&__field2) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("left"));
                                                    }
                                                    __field2 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field3 => {
                                                    if _serde::__private228::Option::is_some(&__field3) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("right"));
                                                    }
                                                    __field3 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("dst")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("op")?,
                                            };
                                        let __field2 =
                                            match __field2 {
                                                _serde::__private228::Some(__field2) => __field2,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("left")?,
                                            };
                                        let __field3 =
                                            match __field3 {
                                                _serde::__private228::Some(__field3) => __field3,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("right")?,
                                            };
                                        _serde::__private228::Ok(IrInstruction::Binary {
                                                dst: __field0,
                                                op: __field1,
                                                left: __field2,
                                                right: __field3,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] =
                                    &["dst", "op", "left", "right"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrInstruction>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                            (__Field::__field7, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field {
                                    __field0,
                                    __field1,
                                    __field2,
                                    __field3,
                                    __ignore,
                                }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            2u64 => _serde::__private228::Ok(__Field::__field2),
                                            3u64 => _serde::__private228::Ok(__Field::__field3),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "dst" => _serde::__private228::Ok(__Field::__field0),
                                            "op" => _serde::__private228::Ok(__Field::__field1),
                                            "left" => _serde::__private228::Ok(__Field::__field2),
                                            "right" => _serde::__private228::Ok(__Field::__field3),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"dst" => _serde::__private228::Ok(__Field::__field0),
                                            b"op" => _serde::__private228::Ok(__Field::__field1),
                                            b"left" => _serde::__private228::Ok(__Field::__field2),
                                            b"right" => _serde::__private228::Ok(__Field::__field3),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrInstruction>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrInstruction;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrInstruction::Assignment")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrInstruction::Assignment with 4 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<AssignmentOp>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrInstruction::Assignment with 4 elements")),
                                            };
                                        let __field2 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                                &"struct variant IrInstruction::Assignment with 4 elements")),
                                            };
                                        let __field3 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(3usize,
                                                                &"struct variant IrInstruction::Assignment with 4 elements")),
                                            };
                                        _serde::__private228::Ok(IrInstruction::Assignment {
                                                dst: __field0,
                                                op: __field1,
                                                left: __field2,
                                                right: __field3,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field1:
                                                _serde::__private228::Option<AssignmentOp> =
                                            _serde::__private228::None;
                                        let mut __field2: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field3: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("dst"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("op"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<AssignmentOp>(&mut __map)?);
                                                }
                                                __Field::__field2 => {
                                                    if _serde::__private228::Option::is_some(&__field2) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("left"));
                                                    }
                                                    __field2 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field3 => {
                                                    if _serde::__private228::Option::is_some(&__field3) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("right"));
                                                    }
                                                    __field3 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("dst")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("op")?,
                                            };
                                        let __field2 =
                                            match __field2 {
                                                _serde::__private228::Some(__field2) => __field2,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("left")?,
                                            };
                                        let __field3 =
                                            match __field3 {
                                                _serde::__private228::Some(__field3) => __field3,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("right")?,
                                            };
                                        _serde::__private228::Ok(IrInstruction::Assignment {
                                                dst: __field0,
                                                op: __field1,
                                                left: __field2,
                                                right: __field3,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] =
                                    &["dst", "op", "left", "right"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrInstruction>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                            (__Field::__field8, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field { __field0, __field1, __field2, __ignore, }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            2u64 => _serde::__private228::Ok(__Field::__field2),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "dst" => _serde::__private228::Ok(__Field::__field0),
                                            "function" => _serde::__private228::Ok(__Field::__field1),
                                            "arguments" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"dst" => _serde::__private228::Ok(__Field::__field0),
                                            b"function" => _serde::__private228::Ok(__Field::__field1),
                                            b"arguments" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrInstruction>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrInstruction;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrInstruction::Call")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<Option<IrValueId>>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrInstruction::Call with 3 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrInstruction::Call with 3 elements")),
                                            };
                                        let __field2 =
                                            match _serde::de::SeqAccess::next_element::<Vec<IrCallArgument>>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                                &"struct variant IrInstruction::Call with 3 elements")),
                                            };
                                        _serde::__private228::Ok(IrInstruction::Call {
                                                dst: __field0,
                                                function: __field1,
                                                arguments: __field2,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0:
                                                _serde::__private228::Option<Option<IrValueId>> =
                                            _serde::__private228::None;
                                        let mut __field1: _serde::__private228::Option<String> =
                                            _serde::__private228::None;
                                        let mut __field2:
                                                _serde::__private228::Option<Vec<IrCallArgument>> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("dst"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Option<IrValueId>>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("function"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                                }
                                                __Field::__field2 => {
                                                    if _serde::__private228::Option::is_some(&__field2) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("arguments"));
                                                    }
                                                    __field2 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<IrCallArgument>>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("dst")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("function")?,
                                            };
                                        let __field2 =
                                            match __field2 {
                                                _serde::__private228::Some(__field2) => __field2,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("arguments")?,
                                            };
                                        _serde::__private228::Ok(IrInstruction::Call {
                                                dst: __field0,
                                                function: __field1,
                                                arguments: __field2,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] =
                                    &["dst", "function", "arguments"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrInstruction>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                            (__Field::__field9, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field { __field0, __field1, __field2, __ignore, }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            2u64 => _serde::__private228::Ok(__Field::__field2),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "dst" => _serde::__private228::Ok(__Field::__field0),
                                            "base" => _serde::__private228::Ok(__Field::__field1),
                                            "field" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"dst" => _serde::__private228::Ok(__Field::__field0),
                                            b"base" => _serde::__private228::Ok(__Field::__field1),
                                            b"field" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrInstruction>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrInstruction;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrInstruction::FieldLoad")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrInstruction::FieldLoad with 3 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrInstruction::FieldLoad with 3 elements")),
                                            };
                                        let __field2 =
                                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                                &"struct variant IrInstruction::FieldLoad with 3 elements")),
                                            };
                                        _serde::__private228::Ok(IrInstruction::FieldLoad {
                                                dst: __field0,
                                                base: __field1,
                                                field: __field2,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field1: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field2: _serde::__private228::Option<String> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("dst"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("base"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field2 => {
                                                    if _serde::__private228::Option::is_some(&__field2) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("field"));
                                                    }
                                                    __field2 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("dst")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("base")?,
                                            };
                                        let __field2 =
                                            match __field2 {
                                                _serde::__private228::Some(__field2) => __field2,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("field")?,
                                            };
                                        _serde::__private228::Ok(IrInstruction::FieldLoad {
                                                dst: __field0,
                                                base: __field1,
                                                field: __field2,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] =
                                    &["dst", "base", "field"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrInstruction>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                            (__Field::__field10, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field { __field0, __field1, __field2, __ignore, }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            2u64 => _serde::__private228::Ok(__Field::__field2),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "base" => _serde::__private228::Ok(__Field::__field0),
                                            "field" => _serde::__private228::Ok(__Field::__field1),
                                            "value" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"base" => _serde::__private228::Ok(__Field::__field0),
                                            b"field" => _serde::__private228::Ok(__Field::__field1),
                                            b"value" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrInstruction>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrInstruction;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrInstruction::FieldStore")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrInstruction::FieldStore with 3 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrInstruction::FieldStore with 3 elements")),
                                            };
                                        let __field2 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                                &"struct variant IrInstruction::FieldStore with 3 elements")),
                                            };
                                        _serde::__private228::Ok(IrInstruction::FieldStore {
                                                base: __field0,
                                                field: __field1,
                                                value: __field2,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field1: _serde::__private228::Option<String> =
                                            _serde::__private228::None;
                                        let mut __field2: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("base"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("field"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                                }
                                                __Field::__field2 => {
                                                    if _serde::__private228::Option::is_some(&__field2) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("value"));
                                                    }
                                                    __field2 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("base")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("field")?,
                                            };
                                        let __field2 =
                                            match __field2 {
                                                _serde::__private228::Some(__field2) => __field2,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("value")?,
                                            };
                                        _serde::__private228::Ok(IrInstruction::FieldStore {
                                                base: __field0,
                                                field: __field1,
                                                value: __field2,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] =
                                    &["base", "field", "value"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrInstruction>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                        }
                    }
                }
                #[doc(hidden)]
                const VARIANTS: &'static [&'static str] =
                    &["Const", "LoadLocal", "StoreLocal", "LoadGlobal",
                                "StoreGlobal", "Unary", "Binary", "Assignment", "Call",
                                "FieldLoad", "FieldStore"];
                _serde::Deserializer::deserialize_enum(__deserializer,
                    "IrInstruction", VARIANTS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<IrInstruction>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
75pub enum IrInstruction {
76    /// Materialize one literal.
77    Const {
78        /// Destination value.
79        dst:     IrValueId,
80        /// Literal payload.
81        literal: Literal,
82    },
83    /// Load one local.
84    LoadLocal {
85        /// Destination value.
86        dst:   IrValueId,
87        /// Local slot.
88        local: IrLocalId,
89    },
90    /// Store one local.
91    StoreLocal {
92        /// Local slot.
93        local: IrLocalId,
94        /// Stored value.
95        value: IrValueId,
96    },
97    /// Load one global.
98    LoadGlobal {
99        /// Destination value.
100        dst:  IrValueId,
101        /// Global name.
102        name: String,
103    },
104    /// Store one global.
105    StoreGlobal {
106        /// Global name.
107        name:  String,
108        /// Stored value.
109        value: IrValueId,
110    },
111    /// Apply one unary operator.
112    Unary {
113        /// Destination value.
114        dst:     IrValueId,
115        /// Operator.
116        op:      UnaryOp,
117        /// Operand.
118        operand: IrValueId,
119    },
120    /// Apply one binary operator.
121    Binary {
122        /// Destination value.
123        dst:   IrValueId,
124        /// Operator.
125        op:    BinaryOp,
126        /// Left operand.
127        left:  IrValueId,
128        /// Right operand.
129        right: IrValueId,
130    },
131    /// Apply one assignment operator in-place.
132    Assignment {
133        /// Destination value.
134        dst:   IrValueId,
135        /// Operator.
136        op:    AssignmentOp,
137        /// Left operand.
138        left:  IrValueId,
139        /// Right operand.
140        right: IrValueId,
141    },
142    /// Call one function or builtin by name.
143    Call {
144        /// Optional return destination.
145        dst:       Option<IrValueId>,
146        /// Function name.
147        function:  String,
148        /// Argument payloads in source order.
149        arguments: Vec<IrCallArgument>,
150    },
151    /// Load one structure field.
152    FieldLoad {
153        /// Destination value.
154        dst:   IrValueId,
155        /// Base value.
156        base:  IrValueId,
157        /// Field name.
158        field: String,
159    },
160    /// Store one structure field.
161    FieldStore {
162        /// Base value.
163        base:  IrValueId,
164        /// Field name.
165        field: String,
166        /// Stored value.
167        value: IrValueId,
168    },
169}
170
171/// One control-flow terminator.
172#[derive(#[automatically_derived]
impl ::core::fmt::Debug for IrTerminator {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            IrTerminator::Return(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Return",
                    &__self_0),
            IrTerminator::Jump(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Jump",
                    &__self_0),
            IrTerminator::Branch {
                condition: __self_0,
                then_block: __self_1,
                else_block: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "Branch", "condition", __self_0, "then_block", __self_1,
                    "else_block", &__self_2),
            IrTerminator::Switch {
                condition: __self_0, cases: __self_1, default: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "Switch", "condition", __self_0, "cases", __self_1,
                    "default", &__self_2),
            IrTerminator::Unreachable =>
                ::core::fmt::Formatter::write_str(f, "Unreachable"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for IrTerminator {
    #[inline]
    fn clone(&self) -> IrTerminator {
        match self {
            IrTerminator::Return(__self_0) =>
                IrTerminator::Return(::core::clone::Clone::clone(__self_0)),
            IrTerminator::Jump(__self_0) =>
                IrTerminator::Jump(::core::clone::Clone::clone(__self_0)),
            IrTerminator::Branch {
                condition: __self_0,
                then_block: __self_1,
                else_block: __self_2 } =>
                IrTerminator::Branch {
                    condition: ::core::clone::Clone::clone(__self_0),
                    then_block: ::core::clone::Clone::clone(__self_1),
                    else_block: ::core::clone::Clone::clone(__self_2),
                },
            IrTerminator::Switch {
                condition: __self_0, cases: __self_1, default: __self_2 } =>
                IrTerminator::Switch {
                    condition: ::core::clone::Clone::clone(__self_0),
                    cases: ::core::clone::Clone::clone(__self_1),
                    default: ::core::clone::Clone::clone(__self_2),
                },
            IrTerminator::Unreachable => IrTerminator::Unreachable,
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for IrTerminator {
    #[inline]
    fn eq(&self, other: &IrTerminator) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (IrTerminator::Return(__self_0),
                    IrTerminator::Return(__arg1_0)) => __self_0 == __arg1_0,
                (IrTerminator::Jump(__self_0), IrTerminator::Jump(__arg1_0))
                    => __self_0 == __arg1_0,
                (IrTerminator::Branch {
                    condition: __self_0,
                    then_block: __self_1,
                    else_block: __self_2 }, IrTerminator::Branch {
                    condition: __arg1_0,
                    then_block: __arg1_1,
                    else_block: __arg1_2 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                        __self_2 == __arg1_2,
                (IrTerminator::Switch {
                    condition: __self_0, cases: __self_1, default: __self_2 },
                    IrTerminator::Switch {
                    condition: __arg1_0, cases: __arg1_1, default: __arg1_2 })
                    =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                        __self_2 == __arg1_2,
                _ => true,
            }
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for IrTerminator {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    IrTerminator::Return(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "IrTerminator", 0u32, "Return", __field0),
                    IrTerminator::Jump(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "IrTerminator", 1u32, "Jump", __field0),
                    IrTerminator::Branch {
                        ref condition, ref then_block, ref else_block } => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrTerminator", 2u32, "Branch", 0 + 1 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "condition", condition)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "then_block", then_block)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "else_block", else_block)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    IrTerminator::Switch { ref condition, ref cases, ref default
                        } => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "IrTerminator", 3u32, "Switch", 0 + 1 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "condition", condition)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "cases", cases)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "default", default)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    IrTerminator::Unreachable =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "IrTerminator", 4u32, "Unreachable"),
                }
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for IrTerminator {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field {
                    __field0,
                    __field1,
                    __field2,
                    __field3,
                    __field4,
                }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "variant identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            3u64 => _serde::__private228::Ok(__Field::__field3),
                            4u64 => _serde::__private228::Ok(__Field::__field4),
                            _ =>
                                _serde::__private228::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value),
                                        &"variant index 0 <= i < 5")),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "Return" => _serde::__private228::Ok(__Field::__field0),
                            "Jump" => _serde::__private228::Ok(__Field::__field1),
                            "Branch" => _serde::__private228::Ok(__Field::__field2),
                            "Switch" => _serde::__private228::Ok(__Field::__field3),
                            "Unreachable" =>
                                _serde::__private228::Ok(__Field::__field4),
                            _ => {
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"Return" => _serde::__private228::Ok(__Field::__field0),
                            b"Jump" => _serde::__private228::Ok(__Field::__field1),
                            b"Branch" => _serde::__private228::Ok(__Field::__field2),
                            b"Switch" => _serde::__private228::Ok(__Field::__field3),
                            b"Unreachable" =>
                                _serde::__private228::Ok(__Field::__field4),
                            _ => {
                                let __value =
                                    &_serde::__private228::from_utf8_lossy(__value);
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<IrTerminator>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = IrTerminator;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "enum IrTerminator")
                    }
                    fn visit_enum<__A>(self, __data: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::EnumAccess<'de> {
                        match _serde::de::EnumAccess::variant(__data)? {
                            (__Field::__field0, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<Option<IrValueId>>(__variant),
                                    IrTerminator::Return),
                            (__Field::__field1, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<IrBlockId>(__variant),
                                    IrTerminator::Jump),
                            (__Field::__field2, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field { __field0, __field1, __field2, __ignore, }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            2u64 => _serde::__private228::Ok(__Field::__field2),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "condition" => _serde::__private228::Ok(__Field::__field0),
                                            "then_block" => _serde::__private228::Ok(__Field::__field1),
                                            "else_block" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"condition" => _serde::__private228::Ok(__Field::__field0),
                                            b"then_block" =>
                                                _serde::__private228::Ok(__Field::__field1),
                                            b"else_block" =>
                                                _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrTerminator>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrTerminator;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrTerminator::Branch")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrTerminator::Branch with 3 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<IrBlockId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrTerminator::Branch with 3 elements")),
                                            };
                                        let __field2 =
                                            match _serde::de::SeqAccess::next_element::<IrBlockId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                                &"struct variant IrTerminator::Branch with 3 elements")),
                                            };
                                        _serde::__private228::Ok(IrTerminator::Branch {
                                                condition: __field0,
                                                then_block: __field1,
                                                else_block: __field2,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field1: _serde::__private228::Option<IrBlockId> =
                                            _serde::__private228::None;
                                        let mut __field2: _serde::__private228::Option<IrBlockId> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("condition"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("then_block"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrBlockId>(&mut __map)?);
                                                }
                                                __Field::__field2 => {
                                                    if _serde::__private228::Option::is_some(&__field2) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("else_block"));
                                                    }
                                                    __field2 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrBlockId>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("condition")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("then_block")?,
                                            };
                                        let __field2 =
                                            match __field2 {
                                                _serde::__private228::Some(__field2) => __field2,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("else_block")?,
                                            };
                                        _serde::__private228::Ok(IrTerminator::Branch {
                                                condition: __field0,
                                                then_block: __field1,
                                                else_block: __field2,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] =
                                    &["condition", "then_block", "else_block"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrTerminator>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                            (__Field::__field3, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field { __field0, __field1, __field2, __ignore, }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            2u64 => _serde::__private228::Ok(__Field::__field2),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "condition" => _serde::__private228::Ok(__Field::__field0),
                                            "cases" => _serde::__private228::Ok(__Field::__field1),
                                            "default" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"condition" => _serde::__private228::Ok(__Field::__field0),
                                            b"cases" => _serde::__private228::Ok(__Field::__field1),
                                            b"default" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<IrTerminator>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = IrTerminator;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant IrTerminator::Switch")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<IrValueId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant IrTerminator::Switch with 3 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<Vec<(i32,
                                                            IrBlockId)>>(&mut __seq)? {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant IrTerminator::Switch with 3 elements")),
                                            };
                                        let __field2 =
                                            match _serde::de::SeqAccess::next_element::<IrBlockId>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                                &"struct variant IrTerminator::Switch with 3 elements")),
                                            };
                                        _serde::__private228::Ok(IrTerminator::Switch {
                                                condition: __field0,
                                                cases: __field1,
                                                default: __field2,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0: _serde::__private228::Option<IrValueId> =
                                            _serde::__private228::None;
                                        let mut __field1:
                                                _serde::__private228::Option<Vec<(i32, IrBlockId)>> =
                                            _serde::__private228::None;
                                        let mut __field2: _serde::__private228::Option<IrBlockId> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("condition"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrValueId>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("cases"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<(i32,
                                                                        IrBlockId)>>(&mut __map)?);
                                                }
                                                __Field::__field2 => {
                                                    if _serde::__private228::Option::is_some(&__field2) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("default"));
                                                    }
                                                    __field2 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<IrBlockId>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("condition")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("cases")?,
                                            };
                                        let __field2 =
                                            match __field2 {
                                                _serde::__private228::Some(__field2) => __field2,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("default")?,
                                            };
                                        _serde::__private228::Ok(IrTerminator::Switch {
                                                condition: __field0,
                                                cases: __field1,
                                                default: __field2,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] =
                                    &["condition", "cases", "default"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<IrTerminator>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                            (__Field::__field4, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(IrTerminator::Unreachable)
                            }
                        }
                    }
                }
                #[doc(hidden)]
                const VARIANTS: &'static [&'static str] =
                    &["Return", "Jump", "Branch", "Switch", "Unreachable"];
                _serde::Deserializer::deserialize_enum(__deserializer,
                    "IrTerminator", VARIANTS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<IrTerminator>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
173pub enum IrTerminator {
174    /// Return from the current function.
175    Return(Option<IrValueId>),
176    /// Unconditional branch.
177    Jump(IrBlockId),
178    /// Conditional branch.
179    Branch {
180        /// Condition value.
181        condition:  IrValueId,
182        /// True target.
183        then_block: IrBlockId,
184        /// False target.
185        else_block: IrBlockId,
186    },
187    /// Multi-way integer branch.
188    Switch {
189        /// Condition value.
190        condition: IrValueId,
191        /// Cases in source order.
192        cases:     Vec<(i32, IrBlockId)>,
193        /// Default target.
194        default:   IrBlockId,
195    },
196    /// Unreachable control flow.
197    Unreachable,
198}
199
200/// One lowered call argument.
201#[derive(#[automatically_derived]
impl ::core::fmt::Debug for IrCallArgument {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            IrCallArgument::Value(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Value",
                    &__self_0),
            IrCallArgument::Action(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Action",
                    &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for IrCallArgument {
    #[inline]
    fn clone(&self) -> IrCallArgument {
        match self {
            IrCallArgument::Value(__self_0) =>
                IrCallArgument::Value(::core::clone::Clone::clone(__self_0)),
            IrCallArgument::Action(__self_0) =>
                IrCallArgument::Action(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for IrCallArgument {
    #[inline]
    fn eq(&self, other: &IrCallArgument) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (IrCallArgument::Value(__self_0),
                    IrCallArgument::Value(__arg1_0)) => __self_0 == __arg1_0,
                (IrCallArgument::Action(__self_0),
                    IrCallArgument::Action(__arg1_0)) => __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for IrCallArgument {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    IrCallArgument::Value(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "IrCallArgument", 0u32, "Value", __field0),
                    IrCallArgument::Action(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "IrCallArgument", 1u32, "Action", __field0),
                }
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for IrCallArgument {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "variant identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            _ =>
                                _serde::__private228::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value),
                                        &"variant index 0 <= i < 2")),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "Value" => _serde::__private228::Ok(__Field::__field0),
                            "Action" => _serde::__private228::Ok(__Field::__field1),
                            _ => {
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"Value" => _serde::__private228::Ok(__Field::__field0),
                            b"Action" => _serde::__private228::Ok(__Field::__field1),
                            _ => {
                                let __value =
                                    &_serde::__private228::from_utf8_lossy(__value);
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<IrCallArgument>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = IrCallArgument;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "enum IrCallArgument")
                    }
                    fn visit_enum<__A>(self, __data: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::EnumAccess<'de> {
                        match _serde::de::EnumAccess::variant(__data)? {
                            (__Field::__field0, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<IrValueId>(__variant),
                                    IrCallArgument::Value),
                            (__Field::__field1, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<Box<HirExpr>>(__variant),
                                    IrCallArgument::Action),
                        }
                    }
                }
                #[doc(hidden)]
                const VARIANTS: &'static [&'static str] =
                    &["Value", "Action"];
                _serde::Deserializer::deserialize_enum(__deserializer,
                    "IrCallArgument", VARIANTS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<IrCallArgument>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
202pub enum IrCallArgument {
203    /// One eagerly-evaluated value argument.
204    Value(IrValueId),
205    /// One deferred action body preserved as HIR because it executes later.
206    Action(Box<HirExpr>),
207}
208
209/// One HIR-to-IR lowering failure.
210#[derive(#[automatically_derived]
impl ::core::fmt::Debug for IrLowerError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "IrLowerError",
            "span", &self.span, "message", &&self.message)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for IrLowerError {
    #[inline]
    fn clone(&self) -> IrLowerError {
        IrLowerError {
            span: ::core::clone::Clone::clone(&self.span),
            message: ::core::clone::Clone::clone(&self.message),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for IrLowerError {
    #[inline]
    fn eq(&self, other: &IrLowerError) -> bool {
        self.span == other.span && self.message == other.message
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for IrLowerError {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Option<crate::Span>>;
        let _: ::core::cmp::AssertParamIsEq<String>;
    }
}Eq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for IrLowerError {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "IrLowerError", false as usize + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "span", &self.span)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "message", &self.message)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for IrLowerError {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "span" => _serde::__private228::Ok(__Field::__field0),
                            "message" => _serde::__private228::Ok(__Field::__field1),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"span" => _serde::__private228::Ok(__Field::__field0),
                            b"message" => _serde::__private228::Ok(__Field::__field1),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<IrLowerError>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = IrLowerError;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct IrLowerError")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<Option<crate::Span>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct IrLowerError with 2 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct IrLowerError with 2 elements")),
                            };
                        _serde::__private228::Ok(IrLowerError {
                                span: __field0,
                                message: __field1,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0:
                                _serde::__private228::Option<Option<crate::Span>> =
                            _serde::__private228::None;
                        let mut __field1: _serde::__private228::Option<String> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("span"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Option<crate::Span>>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("message"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("span")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("message")?,
                            };
                        _serde::__private228::Ok(IrLowerError {
                                span: __field0,
                                message: __field1,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] = &["span", "message"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "IrLowerError", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<IrLowerError>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
211pub struct IrLowerError {
212    /// Optional source span tied to the failure.
213    pub span:    Option<crate::Span>,
214    /// Human-readable error text.
215    pub message: String,
216}
217
218impl IrLowerError {
219    fn new(span: Option<crate::Span>, message: impl Into<String>) -> Self {
220        Self {
221            span,
222            message: message.into(),
223        }
224    }
225}
226
227impl fmt::Display for IrLowerError {
228    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
229        f.write_str(&self.message)
230    }
231}
232
233impl Error for IrLowerError {}
234
235/// Lowers HIR into the compiler IR used by later codegen work.
236///
237/// # Errors
238///
239/// Returns [`IrLowerError`] if the HIR cannot be lowered.
240pub fn lower_hir_to_ir(
241    hir: &HirModule,
242    langspec: Option<&LangSpec>,
243) -> Result<IrModule, IrLowerError> {
244    IrLowerer::new(hir, langspec).lower()
245}
246
247struct IrLowerer<'a> {
248    hir:                     &'a HirModule,
249    builtin_constants:       BTreeMap<String, Literal>,
250    builtin_parameter_types: BTreeMap<String, Vec<SemanticType>>,
251    functions:               BTreeMap<String, &'a HirFunction>,
252}
253
254impl<'a> IrLowerer<'a> {
255    fn new(hir: &'a HirModule, langspec: Option<&LangSpec>) -> Self {
256        let mut builtin_constants = BTreeMap::new();
257        let mut builtin_parameter_types = BTreeMap::new();
258        if let Some(langspec) = langspec {
259            for constant in &langspec.constants {
260                if let Some(literal) = literal_from_builtin_value(&constant.value) {
261                    builtin_constants.insert(constant.name.clone(), literal);
262                }
263            }
264            for function in &langspec.functions {
265                builtin_parameter_types.insert(
266                    function.name.clone(),
267                    function
268                        .parameters
269                        .iter()
270                        .map(|parameter| semantic_type_from_builtin_type(&parameter.ty))
271                        .collect(),
272                );
273            }
274        }
275        let functions = hir
276            .functions
277            .iter()
278            .map(|function| (function.name.clone(), function))
279            .collect::<BTreeMap<_, _>>();
280        Self {
281            hir,
282            builtin_constants,
283            builtin_parameter_types,
284            functions,
285        }
286    }
287
288    fn lower(self) -> Result<IrModule, IrLowerError> {
289        let globals = self
290            .hir
291            .globals
292            .iter()
293            .map(|global| IrGlobal {
294                name: global.name.clone(),
295                ty:   global.ty.clone(),
296            })
297            .collect();
298        let mut functions = Vec::new();
299        for function in &self.hir.functions {
300            if function.is_builtin {
301                continue;
302            }
303            functions.push(FunctionLowerer::new(&self, function).lower()?);
304        }
305        Ok(IrModule {
306            globals,
307            functions,
308        })
309    }
310}
311
312struct BlockBuilder {
313    id:           IrBlockId,
314    instructions: Vec<IrInstruction>,
315    terminator:   Option<IrTerminator>,
316}
317
318struct FunctionLowerer<'a, 'b> {
319    lowerer:          &'b IrLowerer<'a>,
320    function:         &'a HirFunction,
321    locals:           Vec<SemanticType>,
322    blocks:           Vec<BlockBuilder>,
323    next_value:       u32,
324    break_targets:    Vec<IrBlockId>,
325    continue_targets: Vec<IrBlockId>,
326}
327
328impl<'a, 'b> FunctionLowerer<'a, 'b> {
329    fn new(lowerer: &'b IrLowerer<'a>, function: &'a HirFunction) -> Self {
330        Self {
331            lowerer,
332            function,
333            locals: function
334                .locals
335                .iter()
336                .map(|local| local.ty.clone())
337                .collect(),
338            blocks: Vec::new(),
339            next_value: 0,
340            break_targets: Vec::new(),
341            continue_targets: Vec::new(),
342        }
343    }
344
345    fn lower(mut self) -> Result<IrFunction, IrLowerError> {
346        if let Some(body) = &self.function.body {
347            let entry = self.new_block();
348            let tail = self.lower_block(body, Some(entry))?;
349            if let Some(tail) = tail {
350                let terminator = if self.function.return_type == SemanticType::Void {
351                    IrTerminator::Return(None)
352                } else {
353                    IrTerminator::Unreachable
354                };
355                self.set_terminator(tail, terminator)?;
356            }
357        }
358
359        Ok(IrFunction {
360            name:        self.function.name.clone(),
361            return_type: self.function.return_type.clone(),
362            parameters:  self
363                .function
364                .parameters
365                .iter()
366                .map(|parameter| parameter.ty.clone())
367                .collect(),
368            locals:      self.locals,
369            blocks:      self
370                .blocks
371                .into_iter()
372                .map(|block| IrBlock {
373                    id:           block.id,
374                    instructions: block.instructions,
375                    terminator:   block.terminator.unwrap_or(IrTerminator::Unreachable),
376                })
377                .collect(),
378        })
379    }
380
381    fn new_block(&mut self) -> IrBlockId {
382        let id = IrBlockId(u32::try_from(self.blocks.len()).ok().unwrap_or(u32::MAX));
383        self.blocks.push(BlockBuilder {
384            id,
385            instructions: Vec::new(),
386            terminator: None,
387        });
388        id
389    }
390
391    fn block_mut(&mut self, id: IrBlockId) -> Result<&mut BlockBuilder, IrLowerError> {
392        self.blocks
393            .get_mut(id.0 as usize)
394            .ok_or_else(|| IrLowerError::new(None, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown IR block {0:?}", id))
    })format!("unknown IR block {id:?}")))
395    }
396
397    fn push_instruction(
398        &mut self,
399        block: IrBlockId,
400        instruction: IrInstruction,
401    ) -> Result<(), IrLowerError> {
402        self.block_mut(block)?.instructions.push(instruction);
403        Ok(())
404    }
405
406    fn set_terminator(
407        &mut self,
408        block: IrBlockId,
409        terminator: IrTerminator,
410    ) -> Result<(), IrLowerError> {
411        self.block_mut(block)?.terminator = Some(terminator);
412        Ok(())
413    }
414
415    fn new_value(&mut self) -> IrValueId {
416        let id = IrValueId(self.next_value);
417        self.next_value += 1;
418        id
419    }
420
421    fn new_temp_local(&mut self, ty: SemanticType) -> IrLocalId {
422        let local = IrLocalId(u32::try_from(self.locals.len()).ok().unwrap_or(u32::MAX));
423        self.locals.push(ty);
424        local
425    }
426
427    fn lower_block(
428        &mut self,
429        block: &HirBlock,
430        mut current: Option<IrBlockId>,
431    ) -> Result<Option<IrBlockId>, IrLowerError> {
432        for statement in &block.statements {
433            current = self.lower_stmt(statement, current)?;
434        }
435        Ok(current)
436    }
437
438    fn lower_stmt(
439        &mut self,
440        statement: &HirStmt,
441        current: Option<IrBlockId>,
442    ) -> Result<Option<IrBlockId>, IrLowerError> {
443        let Some(current) = current else {
444            return Ok(None);
445        };
446
447        match statement {
448            HirStmt::Block(block) => self.lower_block(block, Some(current)),
449            HirStmt::Declare(statement) => {
450                let mut current = current;
451                for declarator in &statement.declarators {
452                    if let Some(initializer) = &declarator.initializer {
453                        let (value, next_block) = self.lower_expr(initializer, current)?;
454                        current = next_block;
455                        let value = value.ok_or_else(|| {
456                            IrLowerError::new(
457                                Some(initializer.span),
458                                "void initializer is not supported in IR",
459                            )
460                        })?;
461                        self.push_instruction(
462                            current,
463                            IrInstruction::StoreLocal {
464                                local: IrLocalId(declarator.local.0),
465                                value,
466                            },
467                        )?;
468                    }
469                }
470                Ok(Some(current))
471            }
472            HirStmt::Expr(expr) => {
473                let (_value, current) = self.lower_expr(expr, current)?;
474                Ok(Some(current))
475            }
476            HirStmt::If(statement) => self.lower_if(statement, current),
477            HirStmt::Switch(statement) => self.lower_switch(statement, current),
478            HirStmt::Return(statement) => {
479                let value = statement
480                    .value
481                    .as_ref()
482                    .map(|expr| self.lower_expr(expr, current))
483                    .transpose()?;
484                let (value, current) = value.unwrap_or((None, current));
485                self.set_terminator(current, IrTerminator::Return(value))?;
486                Ok(None)
487            }
488            HirStmt::While(statement) => self.lower_while(statement, current),
489            HirStmt::DoWhile(statement) => self.lower_do_while(statement, current),
490            HirStmt::For(statement) => self.lower_for(statement, current),
491            HirStmt::Case(_) | HirStmt::Default(_) => Err(IrLowerError::new(
492                None,
493                "case/default labels must be lowered through lower_switch",
494            )),
495            HirStmt::Break(span) => {
496                let target = self.break_targets.last().copied().ok_or_else(|| {
497                    IrLowerError::new(Some(*span), "break used outside loop or switch")
498                })?;
499                self.set_terminator(current, IrTerminator::Jump(target))?;
500                Ok(None)
501            }
502            HirStmt::Continue(span) => {
503                let target =
504                    self.continue_targets.last().copied().ok_or_else(|| {
505                        IrLowerError::new(Some(*span), "continue used outside loop")
506                    })?;
507                self.set_terminator(current, IrTerminator::Jump(target))?;
508                Ok(None)
509            }
510            HirStmt::Empty(_) => Ok(Some(current)),
511        }
512    }
513
514    fn lower_if(
515        &mut self,
516        statement: &crate::HirIfStmt,
517        current: IrBlockId,
518    ) -> Result<Option<IrBlockId>, IrLowerError> {
519        let (condition, current) = self.lower_expr(&statement.condition, current)?;
520        let condition = condition.ok_or_else(|| {
521            IrLowerError::new(
522                Some(statement.condition.span),
523                "if condition must produce a value",
524            )
525        })?;
526        let then_block = self.new_block();
527        let else_block = self.new_block();
528        self.set_terminator(
529            current,
530            IrTerminator::Branch {
531                condition,
532                then_block,
533                else_block,
534            },
535        )?;
536
537        let then_tail = self.lower_stmt(&statement.then_branch, Some(then_block))?;
538        let else_tail = if let Some(else_branch) = &statement.else_branch {
539            self.lower_stmt(else_branch, Some(else_block))?
540        } else {
541            Some(else_block)
542        };
543
544        let join = self.new_block();
545        let mut falls_through = false;
546        if let Some(then_tail) = then_tail {
547            self.set_terminator(then_tail, IrTerminator::Jump(join))?;
548            falls_through = true;
549        }
550        if let Some(else_tail) = else_tail {
551            self.set_terminator(else_tail, IrTerminator::Jump(join))?;
552            falls_through = true;
553        }
554
555        Ok(falls_through.then_some(join))
556    }
557
558    fn lower_while(
559        &mut self,
560        statement: &crate::HirWhileStmt,
561        current: IrBlockId,
562    ) -> Result<Option<IrBlockId>, IrLowerError> {
563        let cond_block = self.new_block();
564        let body_block = self.new_block();
565        let end_block = self.new_block();
566        self.set_terminator(current, IrTerminator::Jump(cond_block))?;
567
568        let (condition, cond_block) = self.lower_expr(&statement.condition, cond_block)?;
569        let condition = condition.ok_or_else(|| {
570            IrLowerError::new(
571                Some(statement.condition.span),
572                "while condition must produce a value",
573            )
574        })?;
575        self.set_terminator(
576            cond_block,
577            IrTerminator::Branch {
578                condition,
579                then_block: body_block,
580                else_block: end_block,
581            },
582        )?;
583
584        self.break_targets.push(end_block);
585        self.continue_targets.push(cond_block);
586        let body_tail = self.lower_stmt(&statement.body, Some(body_block))?;
587        self.continue_targets.pop();
588        self.break_targets.pop();
589        if let Some(body_tail) = body_tail {
590            self.set_terminator(body_tail, IrTerminator::Jump(cond_block))?;
591        }
592
593        Ok(Some(end_block))
594    }
595
596    fn lower_do_while(
597        &mut self,
598        statement: &crate::HirDoWhileStmt,
599        current: IrBlockId,
600    ) -> Result<Option<IrBlockId>, IrLowerError> {
601        let body_block = self.new_block();
602        let cond_block = self.new_block();
603        let end_block = self.new_block();
604        self.set_terminator(current, IrTerminator::Jump(body_block))?;
605
606        self.break_targets.push(end_block);
607        self.continue_targets.push(cond_block);
608        let body_tail = self.lower_stmt(&statement.body, Some(body_block))?;
609        self.continue_targets.pop();
610        self.break_targets.pop();
611        if let Some(body_tail) = body_tail {
612            self.set_terminator(body_tail, IrTerminator::Jump(cond_block))?;
613        }
614
615        let (condition, cond_block) = self.lower_expr(&statement.condition, cond_block)?;
616        let condition = condition.ok_or_else(|| {
617            IrLowerError::new(
618                Some(statement.condition.span),
619                "do/while condition must produce a value",
620            )
621        })?;
622        self.set_terminator(
623            cond_block,
624            IrTerminator::Branch {
625                condition,
626                then_block: body_block,
627                else_block: end_block,
628            },
629        )?;
630
631        Ok(Some(end_block))
632    }
633
634    fn lower_for(
635        &mut self,
636        statement: &crate::HirForStmt,
637        current: IrBlockId,
638    ) -> Result<Option<IrBlockId>, IrLowerError> {
639        let mut current = current;
640        if let Some(initializer) = &statement.initializer {
641            let (_value, next_block) = self.lower_expr(initializer, current)?;
642            current = next_block;
643        }
644
645        let cond_block = self.new_block();
646        let body_block = self.new_block();
647        let update_block = self.new_block();
648        let end_block = self.new_block();
649        self.set_terminator(current, IrTerminator::Jump(cond_block))?;
650
651        if let Some(condition_expr) = &statement.condition {
652            let (condition, cond_block) = self.lower_expr(condition_expr, cond_block)?;
653            let condition = condition.ok_or_else(|| {
654                IrLowerError::new(
655                    Some(condition_expr.span),
656                    "for condition must produce a value",
657                )
658            })?;
659            self.set_terminator(
660                cond_block,
661                IrTerminator::Branch {
662                    condition,
663                    then_block: body_block,
664                    else_block: end_block,
665                },
666            )?;
667        } else {
668            self.set_terminator(cond_block, IrTerminator::Jump(body_block))?;
669        }
670
671        self.break_targets.push(end_block);
672        self.continue_targets.push(update_block);
673        let body_tail = self.lower_stmt(&statement.body, Some(body_block))?;
674        self.continue_targets.pop();
675        self.break_targets.pop();
676        if let Some(body_tail) = body_tail {
677            self.set_terminator(body_tail, IrTerminator::Jump(update_block))?;
678        }
679
680        if let Some(update) = &statement.update {
681            let (_value, update_block) = self.lower_expr(update, update_block)?;
682            self.set_terminator(update_block, IrTerminator::Jump(cond_block))?;
683            return Ok(Some(end_block));
684        }
685        self.set_terminator(update_block, IrTerminator::Jump(cond_block))?;
686
687        Ok(Some(end_block))
688    }
689
690    fn lower_switch(
691        &mut self,
692        statement: &crate::HirSwitchStmt,
693        current: IrBlockId,
694    ) -> Result<Option<IrBlockId>, IrLowerError> {
695        let HirStmt::Block(block) = statement.body.as_ref() else {
696            return Err(IrLowerError::new(
697                Some(statement.span),
698                "switch lowering requires a block body",
699            ));
700        };
701        let (condition, current) = self.lower_expr(&statement.condition, current)?;
702        let condition = condition.ok_or_else(|| {
703            IrLowerError::new(
704                Some(statement.condition.span),
705                "switch condition must produce a value",
706            )
707        })?;
708        let end_block = self.new_block();
709
710        let mut case_targets = Vec::new();
711        let mut default_target = end_block;
712        for stmt in &block.statements {
713            match stmt {
714                HirStmt::Case(expr) => case_targets.push((
715                    evaluate_case_value(expr, &self.lowerer.builtin_constants)?,
716                    self.new_block(),
717                )),
718                HirStmt::Default(_) => {
719                    default_target = self.new_block();
720                }
721                _ => {}
722            }
723        }
724        self.set_terminator(
725            current,
726            IrTerminator::Switch {
727                condition,
728                cases: case_targets.clone(),
729                default: default_target,
730            },
731        )?;
732
733        self.break_targets.push(end_block);
734        let mut active: Option<IrBlockId> = None;
735        let mut next_case = 0usize;
736        for stmt in &block.statements {
737            match stmt {
738                HirStmt::Case(_) => {
739                    let Some((_, target)) = case_targets.get(next_case).copied() else {
740                        return Err(IrLowerError::new(
741                            Some(statement.span),
742                            "case label index out of bounds during IR lowering",
743                        ));
744                    };
745                    next_case += 1;
746                    if let Some(active_block) = active {
747                        self.set_terminator(active_block, IrTerminator::Jump(target))?;
748                    }
749                    active = Some(target);
750                }
751                HirStmt::Default(_) => {
752                    if let Some(active_block) = active {
753                        self.set_terminator(active_block, IrTerminator::Jump(default_target))?;
754                    }
755                    active = Some(default_target);
756                }
757                other => {
758                    let current = active.ok_or_else(|| {
759                        IrLowerError::new(
760                            Some(statement.span),
761                            "switch body contained statements before any case/default label",
762                        )
763                    })?;
764                    active = self.lower_stmt(other, Some(current))?;
765                }
766            }
767        }
768        self.break_targets.pop();
769
770        if let Some(active) = active {
771            self.set_terminator(active, IrTerminator::Jump(end_block))?;
772        }
773
774        Ok(Some(end_block))
775    }
776
777    #[allow(clippy::too_many_lines)]
778    fn lower_expr(
779        &mut self,
780        expr: &HirExpr,
781        block: IrBlockId,
782    ) -> Result<(Option<IrValueId>, IrBlockId), IrLowerError> {
783        match &expr.kind {
784            HirExprKind::Literal(literal) => {
785                let dst = self.new_value();
786                self.push_instruction(
787                    block,
788                    IrInstruction::Const {
789                        dst,
790                        literal: literal.clone(),
791                    },
792                )?;
793                Ok((Some(dst), block))
794            }
795            HirExprKind::Value(crate::HirValueRef::Local(local)) => {
796                let dst = self.new_value();
797                self.push_instruction(
798                    block,
799                    IrInstruction::LoadLocal {
800                        dst,
801                        local: IrLocalId(local.0),
802                    },
803                )?;
804                Ok((Some(dst), block))
805            }
806            HirExprKind::Value(
807                crate::HirValueRef::Global(name) | crate::HirValueRef::ConstGlobal(name),
808            ) => {
809                let dst = self.new_value();
810                self.push_instruction(
811                    block,
812                    IrInstruction::LoadGlobal {
813                        dst,
814                        name: name.clone(),
815                    },
816                )?;
817                Ok((Some(dst), block))
818            }
819            HirExprKind::Value(crate::HirValueRef::BuiltinConstant(name)) => {
820                let literal = self.lowerer.builtin_constants.get(name).ok_or_else(|| {
821                    IrLowerError::new(
822                        Some(expr.span),
823                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown builtin constant {0:?}",
                name))
    })format!("unknown builtin constant {name:?}"),
824                    )
825                })?;
826                let dst = self.new_value();
827                self.push_instruction(
828                    block,
829                    IrInstruction::Const {
830                        dst,
831                        literal: literal.clone(),
832                    },
833                )?;
834                Ok((Some(dst), block))
835            }
836            HirExprKind::Call {
837                target,
838                arguments,
839            } => {
840                let function_name = match target {
841                    HirCallTarget::Builtin(name) | HirCallTarget::Function(name) => name.clone(),
842                };
843                let mut current = block;
844                let mut lowered_arguments = Vec::new();
845                match target {
846                    HirCallTarget::Builtin(_) => {
847                        let parameter_types = self
848                            .lowerer
849                            .builtin_parameter_types
850                            .get(&function_name)
851                            .ok_or_else(|| {
852                                IrLowerError::new(
853                                    Some(expr.span),
854                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown builtin {0:?}",
                function_name))
    })format!("unknown builtin {function_name:?}"),
855                                )
856                            })?;
857                        for (index, argument) in arguments.iter().enumerate() {
858                            if parameter_types
859                                .get(index)
860                                .is_some_and(|ty| *ty == SemanticType::Action)
861                            {
862                                lowered_arguments
863                                    .push(IrCallArgument::Action(Box::new(argument.clone())));
864                                continue;
865                            }
866
867                            let (value, next_block) = self.lower_expr(argument, current)?;
868                            current = next_block;
869                            let value = value.ok_or_else(|| {
870                                IrLowerError::new(
871                                    Some(argument.span),
872                                    "void-valued call arguments are not represented in IR yet",
873                                )
874                            })?;
875                            lowered_arguments.push(IrCallArgument::Value(value));
876                        }
877                    }
878                    HirCallTarget::Function(name) => {
879                        let callee = self.lowerer.functions.get(name).ok_or_else(|| {
880                            IrLowerError::new(Some(expr.span), ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown function {0:?}", name))
    })format!("unknown function {name:?}"))
881                        })?;
882                        for (argument, parameter) in arguments.iter().zip(&callee.parameters) {
883                            if parameter.ty == SemanticType::Action {
884                                lowered_arguments
885                                    .push(IrCallArgument::Action(Box::new(argument.clone())));
886                                continue;
887                            }
888
889                            let (value, next_block) = self.lower_expr(argument, current)?;
890                            current = next_block;
891                            let value = value.ok_or_else(|| {
892                                IrLowerError::new(
893                                    Some(argument.span),
894                                    "void-valued call arguments are not represented in IR yet",
895                                )
896                            })?;
897                            lowered_arguments.push(IrCallArgument::Value(value));
898                        }
899
900                        if arguments.len() < callee.parameters.len() {
901                            for parameter in callee.parameters.iter().skip(arguments.len()) {
902                                let default = parameter.default.as_ref().ok_or_else(|| {
903                                    IrLowerError::new(
904                                        Some(expr.span),
905                                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("missing required parameter for function {0:?}",
                name))
    })format!("missing required parameter for function {name:?}"),
906                                    )
907                                })?;
908                                if parameter.ty == SemanticType::Action {
909                                    lowered_arguments
910                                        .push(IrCallArgument::Action(Box::new(default.clone())));
911                                    continue;
912                                }
913
914                                let (value, next_block) = self.lower_expr(default, current)?;
915                                current = next_block;
916                                let value = value.ok_or_else(|| {
917                                    IrLowerError::new(
918                                        Some(default.span),
919                                        "void-valued default argument is not supported in IR",
920                                    )
921                                })?;
922                                lowered_arguments.push(IrCallArgument::Value(value));
923                            }
924                        }
925                    }
926                }
927
928                let dst = if expr.ty == SemanticType::Void {
929                    None
930                } else {
931                    Some(self.new_value())
932                };
933                self.push_instruction(
934                    current,
935                    IrInstruction::Call {
936                        dst,
937                        function: function_name,
938                        arguments: lowered_arguments,
939                    },
940                )?;
941                Ok((dst, current))
942            }
943            HirExprKind::FieldAccess {
944                base,
945                field,
946            } => {
947                let (base, block) = self.lower_expr(base, block)?;
948                let base = base.ok_or_else(|| {
949                    IrLowerError::new(
950                        Some(expr.span),
951                        "field access requires a value-producing base",
952                    )
953                })?;
954                let dst = self.new_value();
955                self.push_instruction(
956                    block,
957                    IrInstruction::FieldLoad {
958                        dst,
959                        base,
960                        field: field.clone(),
961                    },
962                )?;
963                Ok((Some(dst), block))
964            }
965            HirExprKind::Unary {
966                op,
967                expr: inner,
968            } => match op {
969                UnaryOp::PreIncrement
970                | UnaryOp::PreDecrement
971                | UnaryOp::PostIncrement
972                | UnaryOp::PostDecrement => {
973                    let (old, block) = self.lower_expr(inner, block)?;
974                    let old = old.ok_or_else(|| {
975                        IrLowerError::new(Some(inner.span), "increment requires an int lvalue")
976                    })?;
977                    let one = self.new_value();
978                    self.push_instruction(
979                        block,
980                        IrInstruction::Const {
981                            dst:     one,
982                            literal: Literal::Integer(1),
983                        },
984                    )?;
985                    let next = self.new_value();
986                    self.push_instruction(
987                        block,
988                        IrInstruction::Binary {
989                            dst:   next,
990                            op:    match op {
991                                UnaryOp::PreIncrement | UnaryOp::PostIncrement => BinaryOp::Add,
992                                UnaryOp::PreDecrement | UnaryOp::PostDecrement => {
993                                    BinaryOp::Subtract
994                                }
995                                _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
996                            },
997                            left:  old,
998                            right: one,
999                        },
1000                    )?;
1001                    self.lower_store_target(inner, block, next)?;
1002                    Ok((
1003                        if #[allow(non_exhaustive_omitted_patterns)] match op {
    UnaryOp::PostIncrement | UnaryOp::PostDecrement => true,
    _ => false,
}matches!(op, UnaryOp::PostIncrement | UnaryOp::PostDecrement) {
1004                            Some(old)
1005                        } else {
1006                            Some(next)
1007                        },
1008                        block,
1009                    ))
1010                }
1011                _ => {
1012                    let (operand, block) = self.lower_expr(inner, block)?;
1013                    let operand = operand.ok_or_else(|| {
1014                        IrLowerError::new(Some(inner.span), "unary operator requires a value")
1015                    })?;
1016                    let dst = self.new_value();
1017                    self.push_instruction(
1018                        block,
1019                        IrInstruction::Unary {
1020                            dst,
1021                            op: *op,
1022                            operand,
1023                        },
1024                    )?;
1025                    Ok((Some(dst), block))
1026                }
1027            },
1028            HirExprKind::Binary {
1029                op,
1030                left,
1031                right,
1032            } => {
1033                let (left_value, block) = self.lower_expr(left, block)?;
1034                let left_value = left_value.ok_or_else(|| {
1035                    IrLowerError::new(Some(left.span), "left operand must produce a value")
1036                })?;
1037                let (right_value, block) = self.lower_expr(right, block)?;
1038                let right_value = right_value.ok_or_else(|| {
1039                    IrLowerError::new(Some(right.span), "right operand must produce a value")
1040                })?;
1041                let dst = self.new_value();
1042                self.push_instruction(
1043                    block,
1044                    IrInstruction::Binary {
1045                        dst,
1046                        op: *op,
1047                        left: left_value,
1048                        right: right_value,
1049                    },
1050                )?;
1051                Ok((Some(dst), block))
1052            }
1053            HirExprKind::Conditional {
1054                condition,
1055                when_true,
1056                when_false,
1057            } => {
1058                let (condition_value, block) = self.lower_expr(condition, block)?;
1059                let condition_value = condition_value.ok_or_else(|| {
1060                    IrLowerError::new(
1061                        Some(condition.span),
1062                        "conditional expression condition must produce a value",
1063                    )
1064                })?;
1065                let then_block = self.new_block();
1066                let else_block = self.new_block();
1067                let join_block = self.new_block();
1068                self.set_terminator(
1069                    block,
1070                    IrTerminator::Branch {
1071                        condition: condition_value,
1072                        then_block,
1073                        else_block,
1074                    },
1075                )?;
1076
1077                let result_local =
1078                    (expr.ty != SemanticType::Void).then(|| self.new_temp_local(expr.ty.clone()));
1079
1080                let (then_value, then_tail) = self.lower_expr(when_true, then_block)?;
1081                if let Some(local) = result_local {
1082                    let then_value = then_value.ok_or_else(|| {
1083                        IrLowerError::new(
1084                            Some(when_true.span),
1085                            "conditional true branch must produce a value",
1086                        )
1087                    })?;
1088                    self.push_instruction(
1089                        then_tail,
1090                        IrInstruction::StoreLocal {
1091                            local,
1092                            value: then_value,
1093                        },
1094                    )?;
1095                }
1096                self.set_terminator(then_tail, IrTerminator::Jump(join_block))?;
1097
1098                let (else_value, else_tail) = self.lower_expr(when_false, else_block)?;
1099                if let Some(local) = result_local {
1100                    let else_value = else_value.ok_or_else(|| {
1101                        IrLowerError::new(
1102                            Some(when_false.span),
1103                            "conditional false branch must produce a value",
1104                        )
1105                    })?;
1106                    self.push_instruction(
1107                        else_tail,
1108                        IrInstruction::StoreLocal {
1109                            local,
1110                            value: else_value,
1111                        },
1112                    )?;
1113                }
1114                self.set_terminator(else_tail, IrTerminator::Jump(join_block))?;
1115
1116                if let Some(local) = result_local {
1117                    let dst = self.new_value();
1118                    self.push_instruction(
1119                        join_block,
1120                        IrInstruction::LoadLocal {
1121                            dst,
1122                            local,
1123                        },
1124                    )?;
1125                    Ok((Some(dst), join_block))
1126                } else {
1127                    Ok((None, join_block))
1128                }
1129            }
1130            HirExprKind::Assignment {
1131                op,
1132                left,
1133                right,
1134            } => {
1135                if *op == AssignmentOp::Assign {
1136                    let (value, block) = self.lower_expr(right, block)?;
1137                    let value = value.ok_or_else(|| {
1138                        IrLowerError::new(Some(right.span), "assignment requires a value")
1139                    })?;
1140                    self.lower_store_target(left, block, value)?;
1141                    return Ok((Some(value), block));
1142                }
1143
1144                let (left_value, block) = self.lower_expr(left, block)?;
1145                let left_value = left_value.ok_or_else(|| {
1146                    IrLowerError::new(Some(left.span), "assignment target must produce a value")
1147                })?;
1148                let (right_value, block) = self.lower_expr(right, block)?;
1149                let right_value = right_value.ok_or_else(|| {
1150                    IrLowerError::new(Some(right.span), "assignment requires a value")
1151                })?;
1152                let dst = self.new_value();
1153                self.push_instruction(
1154                    block,
1155                    IrInstruction::Assignment {
1156                        dst,
1157                        op: *op,
1158                        left: left_value,
1159                        right: right_value,
1160                    },
1161                )?;
1162                self.lower_store_target(left, block, dst)?;
1163                Ok((Some(dst), block))
1164            }
1165        }
1166    }
1167
1168    fn lower_store_target(
1169        &mut self,
1170        target: &HirExpr,
1171        block: IrBlockId,
1172        value: IrValueId,
1173    ) -> Result<(), IrLowerError> {
1174        match &target.kind {
1175            HirExprKind::Value(crate::HirValueRef::Local(local)) => self.push_instruction(
1176                block,
1177                IrInstruction::StoreLocal {
1178                    local: IrLocalId(local.0),
1179                    value,
1180                },
1181            ),
1182            HirExprKind::Value(
1183                crate::HirValueRef::Global(name) | crate::HirValueRef::ConstGlobal(name),
1184            ) => self.push_instruction(
1185                block,
1186                IrInstruction::StoreGlobal {
1187                    name: name.clone(),
1188                    value,
1189                },
1190            ),
1191            _ => Err(IrLowerError::new(
1192                Some(target.span),
1193                "IR lowering only supports local/global assignment targets",
1194            )),
1195        }
1196    }
1197}
1198
1199fn evaluate_case_value(
1200    expr: &HirExpr,
1201    builtin_constants: &BTreeMap<String, Literal>,
1202) -> Result<i32, IrLowerError> {
1203    match &expr.kind {
1204        HirExprKind::Literal(Literal::Integer(value)) => Ok(*value),
1205        HirExprKind::Literal(Literal::String(value)) => Ok(nwscript_string_hash(value)),
1206        HirExprKind::Value(crate::HirValueRef::BuiltinConstant(name)) => {
1207            let literal = builtin_constants.get(name).ok_or_else(|| {
1208                IrLowerError::new(
1209                    Some(expr.span),
1210                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown builtin constant {0:?}",
                name))
    })format!("unknown builtin constant {name:?}"),
1211                )
1212            })?;
1213            match literal {
1214                Literal::Integer(value) => Ok(*value),
1215                Literal::String(value) => Ok(nwscript_string_hash(value)),
1216                _ => Err(IrLowerError::new(
1217                    Some(expr.span),
1218                    "switch case requires an int or string constant",
1219                )),
1220            }
1221        }
1222        _ => Err(IrLowerError::new(
1223            Some(expr.span),
1224            "switch case requires a constant int or string",
1225        )),
1226    }
1227}
1228
1229fn literal_from_builtin_value(value: &BuiltinValue) -> Option<Literal> {
1230    match value {
1231        BuiltinValue::Int(value) | BuiltinValue::ObjectId(value) => Some(Literal::Integer(*value)),
1232        BuiltinValue::Float(value) => Some(Literal::Float(*value)),
1233        BuiltinValue::String(value) => Some(Literal::String(value.clone())),
1234        BuiltinValue::ObjectSelf => Some(Literal::ObjectSelf),
1235        BuiltinValue::ObjectInvalid => Some(Literal::ObjectInvalid),
1236        BuiltinValue::LocationInvalid => Some(Literal::LocationInvalid),
1237        BuiltinValue::Json(value) => Some(Literal::Json(value.clone())),
1238        BuiltinValue::Vector(value) => Some(Literal::Vector(*value)),
1239        BuiltinValue::Raw(_) => None,
1240    }
1241}
1242
1243fn semantic_type_from_builtin_type(ty: &BuiltinType) -> SemanticType {
1244    match ty {
1245        BuiltinType::Void => SemanticType::Void,
1246        BuiltinType::Int => SemanticType::Int,
1247        BuiltinType::Float => SemanticType::Float,
1248        BuiltinType::String => SemanticType::String,
1249        BuiltinType::Object => SemanticType::Object,
1250        BuiltinType::Action => SemanticType::Action,
1251        BuiltinType::Vector => SemanticType::Vector,
1252        BuiltinType::EngineStructure(name) => SemanticType::EngineStructure(name.clone()),
1253    }
1254}
1255
1256#[cfg(test)]
1257mod tests {
1258    use super::{IrCallArgument, IrInstruction, IrTerminator, lower_hir_to_ir};
1259    use crate::{
1260        BuiltinConstant, BuiltinFunction, BuiltinParameter, BuiltinType, BuiltinValue,
1261        HirCallTarget, HirExprKind, LangSpec, SourceId, analyze_script, lower_to_hir, parse_text,
1262    };
1263
1264    fn test_langspec() -> LangSpec {
1265        LangSpec {
1266            engine_num_structures: 3,
1267            engine_structures:     vec![
1268                "effect".to_string(),
1269                "location".to_string(),
1270                "json".to_string(),
1271            ],
1272            constants:             vec![
1273                BuiltinConstant {
1274                    name:  "TRUE".to_string(),
1275                    ty:    BuiltinType::Int,
1276                    value: BuiltinValue::Int(1),
1277                },
1278                BuiltinConstant {
1279                    name:  "FALSE".to_string(),
1280                    ty:    BuiltinType::Int,
1281                    value: BuiltinValue::Int(0),
1282                },
1283            ],
1284            functions:             vec![
1285                BuiltinFunction {
1286                    name:        "GetCurrentHitPoints".to_string(),
1287                    return_type: BuiltinType::Int,
1288                    parameters:  vec![],
1289                },
1290                BuiltinFunction {
1291                    name:        "DelayCommand".to_string(),
1292                    return_type: BuiltinType::Void,
1293                    parameters:  vec![
1294                        BuiltinParameter {
1295                            name:    "fSeconds".to_string(),
1296                            ty:      BuiltinType::Float,
1297                            default: None,
1298                        },
1299                        BuiltinParameter {
1300                            name:    "aAction".to_string(),
1301                            ty:      BuiltinType::Action,
1302                            default: None,
1303                        },
1304                    ],
1305                },
1306            ],
1307        }
1308    }
1309
1310    #[test]
1311    fn lowers_simple_control_flow_to_basic_blocks() {
1312        let script = parse_text(
1313            SourceId::new(90),
1314            r#"
1315                int StartingConditional() {
1316                    int nCurHP = GetCurrentHitPoints();
1317                    if (nCurHP > 0) {
1318                        return TRUE;
1319                    }
1320                    return FALSE;
1321                }
1322            "#,
1323            Some(&test_langspec()),
1324        )
1325        .expect("script should parse");
1326        let semantic =
1327            analyze_script(&script, Some(&test_langspec())).expect("script should analyze");
1328        let hir =
1329            lower_to_hir(&script, &semantic, Some(&test_langspec())).expect("HIR should lower");
1330        let ir = lower_hir_to_ir(&hir, Some(&test_langspec())).expect("IR should lower");
1331
1332        let function = ir
1333            .functions
1334            .iter()
1335            .find(|function| function.name == "StartingConditional")
1336            .expect("function should exist");
1337
1338        assert!(function.blocks.len() >= 4);
1339        assert!(function.blocks.iter().any(|block| {
1340            block.instructions.iter().any(|instruction| {
1341                matches!(instruction, IrInstruction::Call { function, .. } if function == "GetCurrentHitPoints")
1342            })
1343        }));
1344        assert!(
1345            function
1346                .blocks
1347                .iter()
1348                .any(|block| matches!(block.terminator, IrTerminator::Branch { .. }))
1349        );
1350    }
1351
1352    #[test]
1353    fn lowers_user_optional_parameter_defaults_into_call_arguments() {
1354        let script = parse_text(
1355            SourceId::new(91),
1356            r#"
1357                int AddOne(int nBase = TRUE) {
1358                    return nBase + 1;
1359                }
1360                int StartingConditional() {
1361                    return AddOne();
1362                }
1363            "#,
1364            Some(&test_langspec()),
1365        )
1366        .expect("script should parse");
1367        let semantic =
1368            analyze_script(&script, Some(&test_langspec())).expect("script should analyze");
1369        let hir =
1370            lower_to_hir(&script, &semantic, Some(&test_langspec())).expect("HIR should lower");
1371        let ir = lower_hir_to_ir(&hir, Some(&test_langspec())).expect("IR should lower");
1372
1373        let caller = ir
1374            .functions
1375            .iter()
1376            .find(|function| function.name == "StartingConditional")
1377            .expect("caller should exist");
1378        assert!(caller.blocks.iter().any(|block| {
1379            block.instructions.iter().any(|instruction| {
1380                matches!(instruction, IrInstruction::Call { function, arguments, .. } if function == "AddOne" && arguments.len() == 1)
1381            })
1382        }));
1383    }
1384
1385    #[test]
1386    fn lowers_conditional_expressions_into_branching_ir() {
1387        let script = parse_text(
1388            SourceId::new(92),
1389            r#"
1390                int StartingConditional() {
1391                    int nCurHP = GetCurrentHitPoints();
1392                    return nCurHP > 0 ? TRUE : FALSE;
1393                }
1394            "#,
1395            Some(&test_langspec()),
1396        )
1397        .expect("script should parse");
1398        let semantic =
1399            analyze_script(&script, Some(&test_langspec())).expect("script should analyze");
1400        let hir =
1401            lower_to_hir(&script, &semantic, Some(&test_langspec())).expect("HIR should lower");
1402        let ir = lower_hir_to_ir(&hir, Some(&test_langspec())).expect("IR should lower");
1403
1404        let function = ir
1405            .functions
1406            .iter()
1407            .find(|function| function.name == "StartingConditional")
1408            .expect("function should exist");
1409
1410        assert!(
1411            function
1412                .blocks
1413                .iter()
1414                .any(|block| matches!(block.terminator, IrTerminator::Branch { .. })),
1415            "conditional expression should lower into a branch",
1416        );
1417        assert!(
1418            function.blocks.iter().any(|block| {
1419                block
1420                    .instructions
1421                    .iter()
1422                    .any(|instruction| matches!(instruction, IrInstruction::StoreLocal { .. }))
1423            }),
1424            "conditional expression should store branch results into a merge slot",
1425        );
1426        assert!(
1427            function.blocks.iter().any(|block| {
1428                block
1429                    .instructions
1430                    .iter()
1431                    .any(|instruction| matches!(instruction, IrInstruction::LoadLocal { .. }))
1432            }),
1433            "conditional expression should reload the merged branch result",
1434        );
1435    }
1436
1437    #[test]
1438    fn preserves_deferred_action_arguments_in_ir_calls() {
1439        let script = parse_text(
1440            SourceId::new(93),
1441            r#"
1442                void helper() {}
1443                void main() {
1444                    DelayCommand(1.0, helper());
1445                }
1446            "#,
1447            Some(&test_langspec()),
1448        )
1449        .expect("script should parse");
1450        let semantic =
1451            analyze_script(&script, Some(&test_langspec())).expect("script should analyze");
1452        let hir =
1453            lower_to_hir(&script, &semantic, Some(&test_langspec())).expect("HIR should lower");
1454        let ir = lower_hir_to_ir(&hir, Some(&test_langspec())).expect("IR should lower");
1455
1456        let main = ir
1457            .functions
1458            .iter()
1459            .find(|function| function.name == "main")
1460            .expect("main should exist");
1461        let call = main
1462            .blocks
1463            .iter()
1464            .flat_map(|block| block.instructions.iter())
1465            .find_map(|instruction| match instruction {
1466                IrInstruction::Call {
1467                    function,
1468                    arguments,
1469                    ..
1470                } if function == "DelayCommand" => Some(arguments),
1471                _ => None,
1472            })
1473            .expect("DelayCommand call should be present");
1474
1475        assert_eq!(call.len(), 2);
1476        assert!(matches!(call.first(), Some(IrCallArgument::Value(_))));
1477        assert!(matches!(call.get(1), Some(IrCallArgument::Action(_))));
1478        let action = match call.get(1) {
1479            Some(IrCallArgument::Action(action)) => action,
1480            _ => return,
1481        };
1482        assert!(matches!(&action.kind, HirExprKind::Call { .. }));
1483        let (target, arguments) = match &action.kind {
1484            HirExprKind::Call {
1485                target,
1486                arguments,
1487            } => (target, arguments),
1488            _ => return,
1489        };
1490        assert_eq!(target, &HirCallTarget::Function("helper".to_string()));
1491        assert!(arguments.is_empty());
1492    }
1493}