sway_core/language/ty/declaration/
const_generic.rs

1use crate::{
2    decl_engine::MaterializeConstGenerics,
3    engine_threading::HashWithEngines,
4    has_changes,
5    language::{parsed::ConstGenericDeclaration, ty::TyExpression, CallPath},
6    semantic_analysis::{TypeCheckAnalysis, TypeCheckAnalysisContext},
7    Engines, HasChanges, SubstTypes, TypeId,
8};
9use serde::{Deserialize, Serialize};
10use std::hash::{Hash as _, Hasher};
11use sway_error::handler::{ErrorEmitted, Handler};
12use sway_types::{Ident, Named, Span, Spanned};
13
14use super::TyDeclParsedType;
15
16#[derive(Clone, Debug, Serialize, Deserialize)]
17pub struct TyConstGenericDecl {
18    pub call_path: CallPath,
19    pub return_type: TypeId,
20    pub span: Span,
21    pub value: Option<TyExpression>,
22}
23
24impl HashWithEngines for TyConstGenericDecl {
25    fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
26        let type_engine = engines.te();
27        let TyConstGenericDecl {
28            call_path,
29            return_type,
30            span: _,
31            value: _,
32        } = self;
33        call_path.hash(state);
34        type_engine.get(*return_type).hash(state, engines);
35    }
36}
37
38impl SubstTypes for TyConstGenericDecl {
39    fn subst_inner(&mut self, ctx: &crate::SubstTypesContext) -> crate::HasChanges {
40        has_changes! {
41            self.return_type.subst(ctx);
42            if let Some(v) = ctx.get_renamed_const_generic(&self.call_path.suffix) {
43                self.call_path.suffix = v.clone();
44                HasChanges::Yes
45            } else {
46                HasChanges::No
47            };
48        }
49    }
50}
51
52impl MaterializeConstGenerics for TyConstGenericDecl {
53    fn materialize_const_generics(
54        &mut self,
55        _engines: &crate::Engines,
56        _handler: &Handler,
57        name: &str,
58        value: &TyExpression,
59    ) -> Result<(), ErrorEmitted> {
60        if self.call_path.suffix.as_str() == name {
61            match self.value.as_ref() {
62                Some(v) => {
63                    assert!(
64                        v.extract_literal_value()
65                            .unwrap()
66                            .cast_value_to_u64()
67                            .unwrap()
68                            == value
69                                .extract_literal_value()
70                                .unwrap()
71                                .cast_value_to_u64()
72                                .unwrap(),
73                        "{v:?} {value:?}",
74                    );
75                }
76                None => {
77                    self.value = Some(value.clone());
78                }
79            }
80        }
81        Ok(())
82    }
83}
84
85impl TypeCheckAnalysis for TyConstGenericDecl {
86    fn type_check_analyze(
87        &self,
88        _handler: &Handler,
89        _ctx: &mut TypeCheckAnalysisContext,
90    ) -> Result<(), ErrorEmitted> {
91        Ok(())
92    }
93}
94
95impl Named for TyConstGenericDecl {
96    fn name(&self) -> &Ident {
97        &self.call_path.suffix
98    }
99}
100
101impl Spanned for TyConstGenericDecl {
102    fn span(&self) -> Span {
103        self.span.clone()
104    }
105}
106
107impl TyDeclParsedType for TyConstGenericDecl {
108    type ParsedType = ConstGenericDeclaration;
109}