sway_core/language/parsed/declaration/
trait.rs

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