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