sway_core/language/ty/declaration/
constant.rs1use crate::{
2 decl_engine::{DeclMapping, MaterializeConstGenerics, ReplaceDecls},
3 engine_threading::*,
4 has_changes,
5 language::{parsed::ConstantDeclaration, ty::*, CallPath, Visibility},
6 semantic_analysis::TypeCheckContext,
7 transform,
8 type_system::*,
9 HasChanges,
10};
11use serde::{Deserialize, Serialize};
12use std::{
13 fmt,
14 hash::{Hash, Hasher},
15};
16use sway_error::handler::{ErrorEmitted, Handler};
17use sway_types::{Ident, Named, Span, Spanned};
18
19#[derive(Clone, Debug, Serialize, Deserialize)]
20pub struct TyConstantDecl {
21 pub call_path: CallPath,
22 pub value: Option<TyExpression>,
23 pub visibility: Visibility,
24 pub attributes: transform::Attributes,
25 pub return_type: TypeId,
26 pub type_ascription: GenericTypeArgument,
27 pub span: Span,
28}
29
30impl TyDeclParsedType for TyConstantDecl {
31 type ParsedType = ConstantDeclaration;
32}
33
34impl DebugWithEngines for TyConstantDecl {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>, _engines: &Engines) -> fmt::Result {
36 write!(f, "{}", self.call_path)
37 }
38}
39
40impl EqWithEngines for TyConstantDecl {}
41impl PartialEqWithEngines for TyConstantDecl {
42 fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
43 let type_engine = ctx.engines().te();
44 self.call_path == other.call_path
45 && self.value.eq(&other.value, ctx)
46 && self.visibility == other.visibility
47 && self.type_ascription.eq(&other.type_ascription, ctx)
48 && type_engine
49 .get(self.return_type)
50 .eq(&type_engine.get(other.return_type), ctx)
51 }
52}
53
54impl HashWithEngines for TyConstantDecl {
55 fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
56 let type_engine = engines.te();
57 let TyConstantDecl {
58 call_path,
59 value,
60 visibility,
61 return_type,
62 type_ascription,
63 attributes: _,
66 span: _,
67 } = self;
68 call_path.hash(state);
69 value.hash(state, engines);
70 visibility.hash(state);
71 type_engine.get(*return_type).hash(state, engines);
72 type_ascription.hash(state, engines);
73 }
74}
75
76impl Named for TyConstantDecl {
77 fn name(&self) -> &Ident {
78 &self.call_path.suffix
79 }
80}
81
82impl Spanned for TyConstantDecl {
83 fn span(&self) -> Span {
84 self.span.clone()
85 }
86}
87
88impl IsConcrete for TyConstantDecl {
89 fn is_concrete(&self, _: &Handler, engines: &Engines) -> bool {
90 self.return_type
91 .is_concrete(engines, TreatNumericAs::Concrete)
92 }
93}
94
95impl SubstTypes for TyConstantDecl {
96 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
97 has_changes! {
98 self.return_type.subst(ctx);
99 self.type_ascription.subst(ctx);
100 self.value.subst(ctx);
101 }
102 }
103}
104
105impl ReplaceDecls for TyConstantDecl {
106 fn replace_decls_inner(
107 &mut self,
108 decl_mapping: &DeclMapping,
109 handler: &Handler,
110 ctx: &mut TypeCheckContext,
111 ) -> Result<HasChanges, ErrorEmitted> {
112 if let Some(expr) = &mut self.value {
113 expr.replace_decls(decl_mapping, handler, ctx)
114 } else {
115 Ok(HasChanges::No)
116 }
117 }
118}
119
120impl MaterializeConstGenerics for TyConstantDecl {
121 fn materialize_const_generics(
122 &mut self,
123 engines: &Engines,
124 handler: &Handler,
125 name: &str,
126 value: &TyExpression,
127 ) -> Result<HasChanges, ErrorEmitted> {
128 let mut has_changes = HasChanges::No;
129 if let Some(v) = self.value.as_mut() {
130 has_changes |= v.materialize_const_generics(engines, handler, name, value)?;
131 }
132 has_changes |= self
133 .return_type
134 .materialize_const_generics(engines, handler, name, value)?;
135 has_changes |= self
136 .type_ascription
137 .type_id
138 .materialize_const_generics(engines, handler, name, value)?;
139 Ok(has_changes)
140 }
141}