sway_core/language/ty/expression/
intrinsic_function.rs1use crate::{engine_threading::*, has_changes, language::ty::*, type_system::*, types::*};
2use itertools::Itertools;
3use serde::{Deserialize, Serialize};
4use std::{
5 fmt,
6 hash::{Hash, Hasher},
7};
8use sway_ast::Intrinsic;
9use sway_error::handler::{ErrorEmitted, Handler};
10use sway_types::Span;
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct TyIntrinsicFunctionKind {
14 pub kind: Intrinsic,
15 pub arguments: Vec<TyExpression>,
16 pub type_arguments: Vec<GenericArgument>,
17 pub span: Span,
18}
19
20impl EqWithEngines for TyIntrinsicFunctionKind {}
21impl PartialEqWithEngines for TyIntrinsicFunctionKind {
22 fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
23 self.kind == other.kind
24 && self.arguments.eq(&other.arguments, ctx)
25 && self.type_arguments.eq(&other.type_arguments, ctx)
26 }
27}
28
29impl HashWithEngines for TyIntrinsicFunctionKind {
30 fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
31 let TyIntrinsicFunctionKind {
32 kind,
33 arguments,
34 type_arguments,
35 span: _,
38 } = self;
39 kind.hash(state);
40 arguments.hash(state, engines);
41 type_arguments.hash(state, engines);
42 }
43}
44
45impl SubstTypes for TyIntrinsicFunctionKind {
46 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
47 has_changes! {
48 self.arguments.subst(ctx);
49 self.type_arguments.subst(ctx);
50 }
51 }
52}
53
54impl DebugWithEngines for TyIntrinsicFunctionKind {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result {
56 let targs = self
57 .type_arguments
58 .iter()
59 .map(|targ| format!("{:?}", engines.help_out(targ.type_id())))
60 .join(", ");
61 let args = self
62 .arguments
63 .iter()
64 .map(|e| format!("{:?}", engines.help_out(e)))
65 .join(", ");
66
67 write!(f, "{}::<{}>::({})", self.kind, targs, args)
68 }
69}
70
71impl CollectTypesMetadata for TyIntrinsicFunctionKind {
72 fn collect_types_metadata(
73 &self,
74 handler: &Handler,
75 ctx: &mut CollectTypesMetadataContext,
76 ) -> Result<Vec<TypeMetadata>, ErrorEmitted> {
77 let mut types_metadata = vec![];
78 for type_arg in self.type_arguments.iter() {
79 types_metadata.append(&mut type_arg.type_id().collect_types_metadata(handler, ctx)?);
80 }
81 for arg in self.arguments.iter() {
82 types_metadata.append(&mut arg.collect_types_metadata(handler, ctx)?);
83 }
84
85 match self.kind {
86 Intrinsic::Log => {
87 let logged_type_id = TypeMetadata::get_logged_type_id(
88 &self.arguments[0],
89 ctx.experimental.new_encoding,
90 )
91 .map_err(|err| handler.emit_err(err))?;
92 let logged_type = TypeMetadata::new_logged_type(
93 ctx.engines,
94 logged_type_id,
95 ctx.program_name.clone(),
96 );
97 types_metadata.push(logged_type);
98 }
99 Intrinsic::Smo => {
100 types_metadata.push(TypeMetadata::MessageType(
101 MessageId::new(ctx.message_id_counter()),
102 self.arguments[1].return_type,
103 ));
104 *ctx.message_id_counter_mut() += 1;
105 }
106 _ => {}
107 }
108
109 Ok(types_metadata)
110 }
111}