sway_core/language/parsed/declaration/
impl_trait.rs

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