sway_core/semantic_analysis/namespace/
resolved_declaration.rs

1use std::fmt;
2
3use crate::{
4    decl_engine::DeclEngine,
5    engine_threading::*,
6    language::{
7        parsed::*,
8        ty::{self, StructDecl, TyDecl},
9        Visibility,
10    },
11    TypeId,
12};
13use sway_error::handler::{ErrorEmitted, Handler};
14
15#[derive(Clone, Debug)]
16pub enum ResolvedDeclaration {
17    Parsed(Declaration),
18    Typed(ty::TyDecl),
19}
20
21impl DisplayWithEngines for ResolvedDeclaration {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result {
23        match self {
24            ResolvedDeclaration::Parsed(decl) => DisplayWithEngines::fmt(decl, f, engines),
25            ResolvedDeclaration::Typed(decl) => DisplayWithEngines::fmt(decl, f, engines),
26        }
27    }
28}
29
30impl DebugWithEngines for ResolvedDeclaration {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result {
32        match self {
33            ResolvedDeclaration::Parsed(decl) => DebugWithEngines::fmt(decl, f, engines),
34            ResolvedDeclaration::Typed(decl) => DebugWithEngines::fmt(decl, f, engines),
35        }
36    }
37}
38
39impl PartialEqWithEngines for ResolvedDeclaration {
40    fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
41        match (self, other) {
42            (ResolvedDeclaration::Parsed(lhs), ResolvedDeclaration::Parsed(rhs)) => {
43                lhs.eq(rhs, ctx)
44            }
45            (ResolvedDeclaration::Typed(lhs), ResolvedDeclaration::Typed(rhs)) => lhs.eq(rhs, ctx),
46            // TODO: Right now we consider differently represented resolved declarations to not be
47            // equal. This is only used for comparing paths when doing imports, and we will be able
48            // to safely remove it once we introduce normalized paths.
49            (ResolvedDeclaration::Parsed(_lhs), ResolvedDeclaration::Typed(_rhs)) => false,
50            (ResolvedDeclaration::Typed(_lhs), ResolvedDeclaration::Parsed(_rhs)) => false,
51        }
52    }
53}
54
55impl ResolvedDeclaration {
56    pub fn is_typed(&self) -> bool {
57        match self {
58            ResolvedDeclaration::Parsed(_) => false,
59            ResolvedDeclaration::Typed(_) => true,
60        }
61    }
62
63    pub fn resolve_parsed(self, decl_engine: &DeclEngine) -> Declaration {
64        match self {
65            ResolvedDeclaration::Parsed(decl) => decl,
66            ResolvedDeclaration::Typed(ty_decl) => ty_decl
67                .get_parsed_decl(decl_engine)
68                .expect("expecting valid parsed declaration"),
69        }
70    }
71
72    pub fn expect_parsed(self) -> Declaration {
73        match self {
74            ResolvedDeclaration::Parsed(decl) => decl,
75            ResolvedDeclaration::Typed(_ty_decl) => panic!(),
76        }
77    }
78
79    pub fn expect_typed(self) -> ty::TyDecl {
80        match self {
81            ResolvedDeclaration::Parsed(_) => panic!(),
82            ResolvedDeclaration::Typed(ty_decl) => ty_decl,
83        }
84    }
85
86    pub fn expect_typed_ref(&self) -> &ty::TyDecl {
87        match self {
88            ResolvedDeclaration::Parsed(_) => panic!(),
89            ResolvedDeclaration::Typed(ty_decl) => ty_decl,
90        }
91    }
92
93    pub(crate) fn to_struct_decl(
94        &self,
95        handler: &Handler,
96        engines: &Engines,
97    ) -> Result<ResolvedDeclaration, ErrorEmitted> {
98        match self {
99            ResolvedDeclaration::Parsed(decl) => decl
100                .to_struct_decl(handler, engines)
101                .map(|id| ResolvedDeclaration::Parsed(Declaration::StructDeclaration(id))),
102            ResolvedDeclaration::Typed(decl) => decl.to_struct_decl(handler, engines).map(|id| {
103                ResolvedDeclaration::Typed(TyDecl::StructDecl(StructDecl { decl_id: id }))
104            }),
105        }
106    }
107
108    pub(crate) fn visibility(&self, engines: &Engines) -> Visibility {
109        match self {
110            ResolvedDeclaration::Parsed(decl) => decl.visibility(engines.pe()),
111            ResolvedDeclaration::Typed(decl) => decl.visibility(engines.de()),
112        }
113    }
114
115    pub(crate) fn span(&self, engines: &Engines) -> sway_types::Span {
116        match self {
117            ResolvedDeclaration::Parsed(decl) => decl.span(engines),
118            ResolvedDeclaration::Typed(decl) => decl.span(engines),
119        }
120    }
121
122    pub(crate) fn return_type(
123        &self,
124        handler: &Handler,
125        engines: &Engines,
126    ) -> Result<TypeId, ErrorEmitted> {
127        match self {
128            ResolvedDeclaration::Parsed(_decl) => unreachable!(),
129            ResolvedDeclaration::Typed(decl) => decl.return_type(handler, engines),
130        }
131    }
132
133    pub(crate) fn is_trait(&self) -> bool {
134        match self {
135            ResolvedDeclaration::Parsed(decl) => {
136                matches!(decl, Declaration::TraitDeclaration(_))
137            }
138            ResolvedDeclaration::Typed(decl) => {
139                matches!(decl, TyDecl::TraitDecl(_))
140            }
141        }
142    }
143}