sway_core/language/parsed/declaration/
trait.rs

1use super::{ConstantDeclaration, FunctionDeclaration, FunctionParameter};
2use crate::{
3    decl_engine::{parsed_id::ParsedDeclId, DeclRefTrait},
4    engine_threading::*,
5    language::*,
6    transform,
7    type_system::*,
8};
9use serde::{Deserialize, Serialize};
10use std::hash::{Hash, Hasher};
11use sway_error::handler::ErrorEmitted;
12use sway_types::{ident::Ident, span::Span, Named, Spanned};
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub enum TraitItem {
16    TraitFn(ParsedDeclId<TraitFn>),
17    Constant(ParsedDeclId<ConstantDeclaration>),
18    Type(ParsedDeclId<TraitTypeDeclaration>),
19    // to handle parser recovery: Error represents an incomplete trait item
20    Error(Box<[Span]>, #[serde(skip)] ErrorEmitted),
21}
22
23impl EqWithEngines for TraitItem {}
24impl PartialEqWithEngines for TraitItem {
25    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
26        match (self, other) {
27            (TraitItem::TraitFn(lhs), TraitItem::TraitFn(rhs)) => {
28                PartialEqWithEngines::eq(lhs, rhs, ctx)
29            }
30            (TraitItem::Constant(lhs), TraitItem::Constant(rhs)) => {
31                PartialEqWithEngines::eq(lhs, rhs, ctx)
32            }
33            (TraitItem::Type(lhs), TraitItem::Type(rhs)) => PartialEqWithEngines::eq(lhs, rhs, ctx),
34            (TraitItem::Error(lhs, _), TraitItem::Error(rhs, _)) => lhs.eq(rhs),
35            _ => false,
36        }
37    }
38}
39
40#[derive(Debug, Clone)]
41pub struct TraitDeclaration {
42    pub name: Ident,
43    pub(crate) type_parameters: Vec<TypeParameter>,
44    pub attributes: transform::AttributesMap,
45    pub interface_surface: Vec<TraitItem>,
46    pub methods: Vec<ParsedDeclId<FunctionDeclaration>>,
47    pub supertraits: Vec<Supertrait>,
48    pub visibility: Visibility,
49    pub span: Span,
50}
51
52impl EqWithEngines for TraitDeclaration {}
53impl PartialEqWithEngines for TraitDeclaration {
54    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
55        self.name.eq(&other.name)
56            && self.type_parameters.eq(&other.type_parameters, ctx)
57            && self.attributes.eq(&other.attributes)
58            && self.interface_surface.eq(&other.interface_surface, ctx)
59            && PartialEqWithEngines::eq(&self.methods, &other.methods, ctx)
60            && self.supertraits.eq(&other.supertraits, ctx)
61            && self.visibility.eq(&other.visibility)
62    }
63}
64
65impl Named for TraitDeclaration {
66    fn name(&self) -> &sway_types::BaseIdent {
67        &self.name
68    }
69}
70
71impl Spanned for TraitDeclaration {
72    fn span(&self) -> sway_types::Span {
73        self.span.clone()
74    }
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct Supertrait {
79    pub name: CallPath,
80    pub decl_ref: Option<DeclRefTrait>,
81}
82
83impl Spanned for Supertrait {
84    fn span(&self) -> Span {
85        self.name.span()
86    }
87}
88
89impl EqWithEngines for Supertrait {}
90impl PartialEqWithEngines for Supertrait {
91    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
92        let Supertrait {
93            name: ln,
94            decl_ref: ldr,
95        } = self;
96        let Supertrait {
97            name: rn,
98            decl_ref: rdr,
99        } = other;
100        ln == rn && ldr.eq(rdr, ctx)
101    }
102}
103
104impl HashWithEngines for Supertrait {
105    fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
106        let Supertrait { name, decl_ref } = self;
107        name.hash(state);
108        decl_ref.hash(state, engines);
109    }
110}
111
112#[derive(Debug, Clone)]
113pub struct TraitFn {
114    pub name: Ident,
115    pub span: Span,
116    pub attributes: transform::AttributesMap,
117    pub purity: Purity,
118    pub parameters: Vec<FunctionParameter>,
119    pub return_type: TypeArgument,
120}
121
122impl Spanned for TraitFn {
123    fn span(&self) -> sway_types::Span {
124        self.span.clone()
125    }
126}
127
128#[derive(Debug, Clone)]
129pub struct TraitTypeDeclaration {
130    pub name: Ident,
131    pub attributes: transform::AttributesMap,
132    pub ty_opt: Option<TypeArgument>,
133    pub span: Span,
134}
135
136impl EqWithEngines for TraitTypeDeclaration {}
137impl PartialEqWithEngines for TraitTypeDeclaration {
138    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
139        self.name == other.name
140            && self.attributes == other.attributes
141            && self.ty_opt.eq(&other.ty_opt, ctx)
142    }
143}
144
145impl Named for TraitTypeDeclaration {
146    fn name(&self) -> &sway_types::BaseIdent {
147        &self.name
148    }
149}
150
151impl Spanned for TraitTypeDeclaration {
152    fn span(&self) -> sway_types::Span {
153        self.span.clone()
154    }
155}
156
157impl DebugWithEngines for TraitTypeDeclaration {
158    fn fmt(&self, f: &mut std::fmt::Formatter<'_>, _engines: &Engines) -> std::fmt::Result {
159        f.write_fmt(format_args!("{}", self.name))
160    }
161}