sway_core/language/parsed/declaration/
impl_trait.rs

1use super::{ConstantDeclaration, FunctionDeclaration, TraitTypeDeclaration};
2use crate::{
3    decl_engine::{parsed_id::ParsedDeclId, ParsedInterfaceDeclId},
4    engine_threading::{
5        DebugWithEngines, EqWithEngines, PartialEqWithEngines, PartialEqWithEnginesContext,
6    },
7    language::CallPath,
8    type_system::GenericArgument,
9    Engines, TypeParameter,
10};
11
12use sway_types::{span::Span, Named, Spanned};
13
14#[derive(Debug, Clone)]
15pub enum ImplItem {
16    Fn(ParsedDeclId<FunctionDeclaration>),
17    Constant(ParsedDeclId<ConstantDeclaration>),
18    Type(ParsedDeclId<TraitTypeDeclaration>),
19}
20
21impl ImplItem {
22    pub fn span(&self, engines: &Engines) -> Span {
23        match self {
24            ImplItem::Fn(id) => engines.pe().get_function(id).span(),
25            ImplItem::Constant(id) => engines.pe().get_constant(id).span(),
26            ImplItem::Type(id) => engines.pe().get_trait_type(id).span(),
27        }
28    }
29}
30
31impl EqWithEngines for ImplItem {}
32impl PartialEqWithEngines for ImplItem {
33    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
34        match (self, other) {
35            (ImplItem::Fn(lhs), ImplItem::Fn(rhs)) => PartialEqWithEngines::eq(lhs, rhs, ctx),
36            (ImplItem::Constant(lhs), ImplItem::Constant(rhs)) => {
37                PartialEqWithEngines::eq(lhs, rhs, ctx)
38            }
39            (ImplItem::Type(lhs), ImplItem::Type(rhs)) => PartialEqWithEngines::eq(lhs, rhs, ctx),
40            _ => false,
41        }
42    }
43}
44
45impl DebugWithEngines for ImplItem {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>, engines: &Engines) -> std::fmt::Result {
47        match self {
48            ImplItem::Fn(decl_id) => {
49                let decl = engines.pe().get_function(decl_id);
50                f.write_fmt(format_args!("{:?}", engines.help_out(decl)))
51            }
52            ImplItem::Constant(decl_id) => {
53                let decl = engines.pe().get_constant(decl_id);
54                f.write_fmt(format_args!("{:?}", engines.help_out(decl)))
55            }
56            ImplItem::Type(decl_id) => {
57                let decl = engines.pe().get_trait_type(decl_id);
58                f.write_fmt(format_args!("{:?}", engines.help_out(decl)))
59            }
60        }
61    }
62}
63
64/// An impl trait, or impl self of methods without a trait.
65/// like `impl MyType { fn foo { .. } }`
66#[derive(Debug, Clone)]
67pub struct ImplSelfOrTrait {
68    pub is_self: bool,
69    pub impl_type_parameters: Vec<TypeParameter>,
70    pub trait_name: CallPath,
71    pub trait_type_arguments: Vec<GenericArgument>,
72    pub trait_decl_ref: Option<ParsedInterfaceDeclId>,
73    pub implementing_for: GenericArgument,
74    pub items: Vec<ImplItem>,
75    /// The [Span] of the whole impl trait and block.
76    pub(crate) block_span: Span,
77}
78
79impl EqWithEngines for ImplSelfOrTrait {}
80impl PartialEqWithEngines for ImplSelfOrTrait {
81    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
82        self.impl_type_parameters
83            .eq(&other.impl_type_parameters, ctx)
84            && self.trait_name == other.trait_name
85            && self
86                .trait_type_arguments
87                .eq(&other.trait_type_arguments, ctx)
88            && self.implementing_for.eq(&other.implementing_for, ctx)
89            && self.items.eq(&other.items, ctx)
90            && self.block_span == other.block_span
91    }
92}
93
94impl Named for ImplSelfOrTrait {
95    fn name(&self) -> &sway_types::BaseIdent {
96        &self.trait_name.suffix
97    }
98}
99
100impl Spanned for ImplSelfOrTrait {
101    fn span(&self) -> sway_types::Span {
102        self.block_span.clone()
103    }
104}
105
106impl DebugWithEngines for ImplSelfOrTrait {
107    fn fmt(&self, f: &mut std::fmt::Formatter<'_>, engines: &Engines) -> std::fmt::Result {
108        if self.is_self {
109            f.write_fmt(format_args!(
110                "impl {}",
111                engines.help_out(self.implementing_for.clone())
112            ))
113        } else {
114            f.write_fmt(format_args!(
115                "impl {} for {:?}",
116                self.trait_name,
117                engines.help_out(self.implementing_for.clone())
118            ))
119        }
120    }
121}