sway_core/language/ty/declaration/
trait_fn.rs

1use std::{
2    fmt,
3    hash::{Hash, Hasher},
4};
5
6use monomorphization::MonomorphizeHelper;
7use sway_types::{Ident, Named, Span, Spanned};
8
9use crate::{
10    ast_elements::type_argument::GenericTypeArgument,
11    engine_threading::*,
12    has_changes,
13    language::{parsed::TraitFn, ty::*, Purity},
14    transform,
15    type_system::*,
16};
17
18#[derive(Clone, Debug)]
19pub struct TyTraitFn {
20    pub name: Ident,
21    pub(crate) span: Span,
22    pub(crate) purity: Purity,
23    pub parameters: Vec<TyFunctionParameter>,
24    pub return_type: GenericTypeArgument,
25    pub attributes: transform::Attributes,
26}
27
28impl TyDeclParsedType for TyTraitFn {
29    type ParsedType = TraitFn;
30}
31
32impl DebugWithEngines for TyTraitFn {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result {
34        write!(
35            f,
36            "{:?}({}):{}",
37            self.name,
38            self.parameters
39                .iter()
40                .map(|p| format!(
41                    "{}:{}",
42                    p.name.as_str(),
43                    engines.help_out(p.type_argument.initial_type_id)
44                ))
45                .collect::<Vec<_>>()
46                .join(", "),
47            engines.help_out(self.return_type.initial_type_id),
48        )
49    }
50}
51
52impl Named for TyTraitFn {
53    fn name(&self) -> &Ident {
54        &self.name
55    }
56}
57
58impl Spanned for TyTraitFn {
59    fn span(&self) -> Span {
60        self.span.clone()
61    }
62}
63
64impl IsConcrete for TyTraitFn {
65    fn is_concrete(&self, engines: &Engines) -> bool {
66        self.type_parameters()
67            .iter()
68            .all(|tp| tp.is_concrete(engines))
69            && self
70                .return_type
71                .type_id
72                .is_concrete(engines, TreatNumericAs::Concrete)
73            && self.parameters().iter().all(|t| {
74                t.type_argument
75                    .type_id
76                    .is_concrete(engines, TreatNumericAs::Concrete)
77            })
78    }
79}
80
81impl declaration::FunctionSignature for TyTraitFn {
82    fn parameters(&self) -> &Vec<TyFunctionParameter> {
83        &self.parameters
84    }
85
86    fn return_type(&self) -> &GenericTypeArgument {
87        &self.return_type
88    }
89}
90
91impl EqWithEngines for TyTraitFn {}
92impl PartialEqWithEngines for TyTraitFn {
93    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
94        let type_engine = ctx.engines().te();
95        self.name == other.name
96            && self.purity == other.purity
97            && self.parameters.eq(&other.parameters, ctx)
98            && type_engine
99                .get(self.return_type.type_id)
100                .eq(&type_engine.get(other.return_type.type_id), ctx)
101            && self.attributes == other.attributes
102    }
103}
104
105impl HashWithEngines for TyTraitFn {
106    fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
107        let TyTraitFn {
108            name,
109            purity,
110            parameters,
111            return_type,
112            // these fields are not hashed because they aren't relevant/a
113            // reliable source of obj v. obj distinction
114            span: _,
115            attributes: _,
116        } = self;
117        let type_engine = engines.te();
118        name.hash(state);
119        parameters.hash(state, engines);
120        type_engine.get(return_type.type_id).hash(state, engines);
121        purity.hash(state);
122    }
123}
124
125impl SubstTypes for TyTraitFn {
126    fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
127        has_changes! {
128            self.parameters.subst(ctx);
129            self.return_type.subst(ctx);
130        }
131    }
132}
133
134impl MonomorphizeHelper for TyTraitFn {
135    fn name(&self) -> &Ident {
136        &self.name
137    }
138
139    fn type_parameters(&self) -> &[TypeParameter] {
140        &[]
141    }
142
143    fn has_self_type_param(&self) -> bool {
144        false
145    }
146}