sway_core/language/ty/declaration/
configurable.rs

1use crate::{
2    decl_engine::{DeclId, DeclMapping, DeclRef, ReplaceDecls},
3    engine_threading::*,
4    has_changes,
5    language::{parsed::ConfigurableDeclaration, ty::*, CallPath, Visibility},
6    semantic_analysis::TypeCheckContext,
7    transform,
8    type_system::*,
9};
10use serde::{Deserialize, Serialize};
11use std::{
12    fmt,
13    hash::{Hash, Hasher},
14};
15use sway_error::handler::{ErrorEmitted, Handler};
16use sway_types::{Ident, Named, Span, Spanned};
17
18#[derive(Clone, Debug, Serialize, Deserialize)]
19pub struct TyConfigurableDecl {
20    pub call_path: CallPath,
21    pub value: Option<TyExpression>,
22    pub visibility: Visibility,
23    pub attributes: transform::AttributesMap,
24    pub return_type: TypeId,
25    pub type_ascription: TypeArgument,
26    pub span: Span,
27    // Only encoding v1 has a decode_fn
28    pub decode_fn: Option<DeclRef<DeclId<TyFunctionDecl>>>,
29}
30
31impl TyDeclParsedType for TyConfigurableDecl {
32    type ParsedType = ConfigurableDeclaration;
33}
34
35impl DebugWithEngines for TyConfigurableDecl {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>, _engines: &Engines) -> fmt::Result {
37        write!(f, "{}", self.call_path)
38    }
39}
40
41impl EqWithEngines for TyConfigurableDecl {}
42impl PartialEqWithEngines for TyConfigurableDecl {
43    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
44        let type_engine = ctx.engines().te();
45        self.call_path == other.call_path
46            && self.value.eq(&other.value, ctx)
47            && self.visibility == other.visibility
48            && self.type_ascription.eq(&other.type_ascription, ctx)
49            && type_engine
50                .get(self.return_type)
51                .eq(&type_engine.get(other.return_type), ctx)
52    }
53}
54
55impl HashWithEngines for TyConfigurableDecl {
56    fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
57        let type_engine = engines.te();
58        let TyConfigurableDecl {
59            call_path,
60            value,
61            visibility,
62            return_type,
63            type_ascription,
64            // these fields are not hashed because they aren't relevant/a
65            // reliable source of obj v. obj distinction
66            attributes: _,
67            span: _,
68            decode_fn: _, // this is defined entirely by the type ascription
69        } = self;
70        call_path.hash(state);
71        value.hash(state, engines);
72        visibility.hash(state);
73        type_engine.get(*return_type).hash(state, engines);
74        type_ascription.hash(state, engines);
75    }
76}
77
78impl Named for TyConfigurableDecl {
79    fn name(&self) -> &Ident {
80        &self.call_path.suffix
81    }
82}
83
84impl Spanned for TyConfigurableDecl {
85    fn span(&self) -> Span {
86        self.span.clone()
87    }
88}
89
90impl SubstTypes for TyConfigurableDecl {
91    fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
92        has_changes! {
93            self.return_type.subst(ctx);
94            self.type_ascription.subst(ctx);
95            self.value.subst(ctx);
96        }
97    }
98}
99
100impl ReplaceDecls for TyConfigurableDecl {
101    fn replace_decls_inner(
102        &mut self,
103        decl_mapping: &DeclMapping,
104        handler: &Handler,
105        ctx: &mut TypeCheckContext,
106    ) -> Result<bool, ErrorEmitted> {
107        if let Some(expr) = &mut self.value {
108            expr.replace_decls(decl_mapping, handler, ctx)
109        } else {
110            Ok(false)
111        }
112    }
113}