Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a new symbol resolving pass #5809

Merged
merged 9 commits into from
Aug 6, 2024
90 changes: 87 additions & 3 deletions sway-core/src/decl_engine/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ use crate::{
engine_threading::*,
language::{
parsed::{
AbiDeclaration, ConfigurableDeclaration, ConstantDeclaration, EnumDeclaration,
FunctionDeclaration, ImplSelfOrTrait, StorageDeclaration, StructDeclaration,
TraitDeclaration, TraitFn, TraitTypeDeclaration, TypeAliasDeclaration,
AbiDeclaration, ConfigurableDeclaration, ConstantDeclaration, Declaration,
EnumDeclaration, FunctionDeclaration, ImplSelfOrTrait, StorageDeclaration,
StructDeclaration, TraitDeclaration, TraitFn, TraitTypeDeclaration,
TypeAliasDeclaration,
},
ty::{
self, TyAbiDecl, TyConfigurableDecl, TyConstantDecl, TyDeclParsedType, TyEnumDecl,
Expand Down Expand Up @@ -122,6 +123,13 @@ where
fn get_parsed_decl_id(&self, decl_id: &DeclId<T>) -> Option<ParsedDeclId<T::ParsedType>>;
}

pub trait DeclEngineGetParsedDecl<T>
where
T: TyDeclParsedType,
{
fn get_parsed_decl(&self, decl_id: &DeclId<T>) -> Option<Declaration>;
}

pub trait DeclEngineInsert<T>
where
T: Named + Spanned + TyDeclParsedType,
Expand Down Expand Up @@ -288,6 +296,82 @@ decl_engine_parsed_decl_id!(configurable_parsed_decl_id_map, ty::TyConfigurableD
decl_engine_parsed_decl_id!(enum_parsed_decl_id_map, ty::TyEnumDecl);
decl_engine_parsed_decl_id!(type_alias_parsed_decl_id_map, ty::TyTypeAliasDecl);

macro_rules! decl_engine_parsed_decl {
($slab:ident, $decl:ty, $ctor:expr) => {
impl DeclEngineGetParsedDecl<$decl> for DeclEngine {
fn get_parsed_decl(&self, decl_id: &DeclId<$decl>) -> Option<Declaration> {
let parsed_decl_id_map = self.$slab.read();
if let Some(parsed_decl_id) = parsed_decl_id_map.get(&decl_id) {
return Some($ctor(parsed_decl_id.clone()));
} else {
None
}
}
}
};
}

decl_engine_parsed_decl!(
function_parsed_decl_id_map,
ty::TyFunctionDecl,
Declaration::FunctionDeclaration
);
decl_engine_parsed_decl!(
trait_parsed_decl_id_map,
ty::TyTraitDecl,
Declaration::TraitDeclaration
);
decl_engine_parsed_decl!(
trait_fn_parsed_decl_id_map,
ty::TyTraitFn,
Declaration::TraitFnDeclaration
);
decl_engine_parsed_decl!(
trait_type_parsed_decl_id_map,
ty::TyTraitType,
Declaration::TraitTypeDeclaration
);
decl_engine_parsed_decl!(
impl_self_or_trait_parsed_decl_id_map,
ty::TyImplSelfOrTrait,
Declaration::ImplSelfOrTrait
);
decl_engine_parsed_decl!(
struct_parsed_decl_id_map,
ty::TyStructDecl,
Declaration::StructDeclaration
);
decl_engine_parsed_decl!(
storage_parsed_decl_id_map,
ty::TyStorageDecl,
Declaration::StorageDeclaration
);
decl_engine_parsed_decl!(
abi_parsed_decl_id_map,
ty::TyAbiDecl,
Declaration::AbiDeclaration
);
decl_engine_parsed_decl!(
constant_parsed_decl_id_map,
ty::TyConstantDecl,
Declaration::ConstantDeclaration
);
decl_engine_parsed_decl!(
configurable_parsed_decl_id_map,
ty::TyConfigurableDecl,
Declaration::ConfigurableDeclaration
);
decl_engine_parsed_decl!(
enum_parsed_decl_id_map,
ty::TyEnumDecl,
Declaration::EnumDeclaration
);
decl_engine_parsed_decl!(
type_alias_parsed_decl_id_map,
ty::TyTypeAliasDecl,
Declaration::TypeAliasDeclaration
);

macro_rules! decl_engine_replace {
($slab:ident, $decl:ty) => {
impl DeclEngineReplace<$decl> for DeclEngine {
Expand Down
24 changes: 24 additions & 0 deletions sway-core/src/decl_engine/parsed_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,30 @@ decl_engine_insert!(enum_slab, EnumDeclaration);
decl_engine_insert!(enum_variant_slab, EnumVariant);
decl_engine_insert!(type_alias_slab, TypeAliasDeclaration);

macro_rules! decl_engine_replace {
($slab:ident, $decl:ty) => {
impl ParsedDeclEngineReplace<$decl> for ParsedDeclEngine {
fn replace(&self, index: ParsedDeclId<$decl>, decl: $decl) {
self.$slab.replace(index.inner(), decl);
}
}
};
}

decl_engine_replace!(variable_slab, VariableDeclaration);
decl_engine_replace!(function_slab, FunctionDeclaration);
decl_engine_replace!(trait_slab, TraitDeclaration);
decl_engine_replace!(trait_fn_slab, TraitFn);
decl_engine_replace!(trait_type_slab, TraitTypeDeclaration);
decl_engine_replace!(impl_self_or_trait_slab, ImplSelfOrTrait);
decl_engine_replace!(struct_slab, StructDeclaration);
decl_engine_replace!(storage_slab, StorageDeclaration);
decl_engine_replace!(abi_slab, AbiDeclaration);
decl_engine_replace!(configurable_slab, ConfigurableDeclaration);
decl_engine_replace!(constant_slab, ConstantDeclaration);
decl_engine_replace!(enum_slab, EnumDeclaration);
decl_engine_replace!(type_alias_slab, TypeAliasDeclaration);

macro_rules! decl_engine_clear {
($($slab:ident, $decl:ty);* $(;)?) => {
impl ParsedDeclEngine {
Expand Down
6 changes: 6 additions & 0 deletions sway-core/src/language/call_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ impl<T: OrdWithEngines> OrdWithEngines for CallPath<T> {
}
}

#[derive(Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct ResolvedCallPath<T, U = Ident> {
pub decl: T,
pub unresolved_call_path: CallPath<U>,
}

impl std::convert::From<Ident> for CallPath {
fn from(other: Ident) -> Self {
CallPath {
Expand Down
56 changes: 55 additions & 1 deletion sway-core/src/language/parsed/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ pub use r#enum::*;
pub use r#struct::*;
pub use r#trait::*;
pub use storage::*;
use sway_error::{
error::CompileError,
handler::{ErrorEmitted, Handler},
};
use sway_types::{Ident, Span, Spanned};
pub use type_alias::*;
pub use variable::*;
Expand All @@ -29,6 +33,7 @@ use crate::{
decl_engine::{
parsed_engine::{ParsedDeclEngine, ParsedDeclEngineGet},
parsed_id::ParsedDeclId,
DeclEngineGetParsedDeclId,
},
engine_threading::{
DebugWithEngines, DisplayWithEngines, EqWithEngines, PartialEqWithEngines,
Expand All @@ -53,6 +58,7 @@ pub enum Declaration {
StorageDeclaration(ParsedDeclId<StorageDeclaration>),
TypeAliasDeclaration(ParsedDeclId<TypeAliasDeclaration>),
TraitTypeDeclaration(ParsedDeclId<TraitTypeDeclaration>),
TraitFnDeclaration(ParsedDeclId<TraitFn>),
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -84,6 +90,7 @@ impl Declaration {
TraitTypeDeclaration(_) => "type",
FunctionDeclaration(_) => "function",
TraitDeclaration(_) => "trait",
TraitFnDeclaration(_) => "trait fn",
StructDeclaration(_) => "struct",
EnumDeclaration(_) => "enum",
EnumVariantDeclaration(_) => "enum variant",
Expand Down Expand Up @@ -111,9 +118,55 @@ impl Declaration {
StorageDeclaration(decl_id) => pe.get_storage(decl_id).span(),
TypeAliasDeclaration(decl_id) => pe.get_type_alias(decl_id).span(),
TraitTypeDeclaration(decl_id) => pe.get_trait_type(decl_id).span(),
TraitFnDeclaration(decl_id) => pe.get_trait_fn(decl_id).span(),
}
}

pub(crate) fn to_fn_ref(
&self,
handler: &Handler,
engines: &Engines,
) -> Result<ParsedDeclId<FunctionDeclaration>, ErrorEmitted> {
match self {
Declaration::FunctionDeclaration(decl_id) => Ok(*decl_id),
decl => Err(handler.emit_err(CompileError::DeclIsNotAFunction {
actually: decl.friendly_type_name().to_string(),
span: decl.span(engines),
})),
}
}

pub(crate) fn to_struct_decl(
&self,
handler: &Handler,
engines: &Engines,
) -> Result<ParsedDeclId<StructDeclaration>, ErrorEmitted> {
match self {
Declaration::StructDeclaration(decl_id) => Ok(*decl_id),
Declaration::TypeAliasDeclaration(decl_id) => {
let alias = engines.pe().get_type_alias(decl_id);
let struct_decl_id = engines.te().get(alias.ty.type_id).expect_struct(
handler,
engines,
&self.span(engines),
)?;

let parsed_decl_id = engines.de().get_parsed_decl_id(&struct_decl_id);
parsed_decl_id.ok_or_else(|| {
handler.emit_err(CompileError::InternalOwned(
"Cannot get parsed decl id from decl id".to_string(),
self.span(engines),
))
})
}
decl => Err(handler.emit_err(CompileError::DeclIsNotAStruct {
actually: decl.friendly_type_name().to_string(),
span: decl.span(engines),
})),
}
}

#[allow(unused)]
pub(crate) fn visibility(&self, decl_engine: &ParsedDeclEngine) -> Visibility {
match self {
Declaration::TraitDeclaration(decl_id) => decl_engine.get_trait(decl_id).visibility,
Expand All @@ -138,7 +191,8 @@ impl Declaration {
Declaration::ImplSelfOrTrait(_)
| Declaration::StorageDeclaration(_)
| Declaration::AbiDeclaration(_)
| Declaration::TraitTypeDeclaration(_) => Visibility::Public,
| Declaration::TraitTypeDeclaration(_)
| Declaration::TraitFnDeclaration(_) => Visibility::Public,
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions sway-core/src/language/parsed/declaration/function.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
engine_threading::*,
language::{parsed::*, *},
namespace::LexicalScopeId,
transform::{self, AttributeKind},
type_system::*,
};
Expand All @@ -27,6 +28,8 @@ pub struct FunctionDeclaration {
pub type_parameters: Vec<TypeParameter>,
pub where_clause: Vec<(Ident, Vec<TraitConstraint>)>,
pub kind: FunctionDeclarationKind,
pub implementing_type: Option<Declaration>,
pub lexical_scope: LexicalScopeId,
}

impl EqWithEngines for FunctionDeclaration {}
Expand Down
3 changes: 2 additions & 1 deletion sway-core/src/language/parsed/declaration/impl_trait.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{ConstantDeclaration, FunctionDeclaration, TraitTypeDeclaration};
use crate::{
decl_engine::parsed_id::ParsedDeclId,
decl_engine::{parsed_id::ParsedDeclId, ParsedInterfaceDeclId},
engine_threading::{
DebugWithEngines, EqWithEngines, PartialEqWithEngines, PartialEqWithEnginesContext,
},
Expand Down Expand Up @@ -69,6 +69,7 @@ pub struct ImplSelfOrTrait {
pub impl_type_parameters: Vec<TypeParameter>,
pub trait_name: CallPath,
pub trait_type_arguments: Vec<TypeArgument>,
pub trait_decl_ref: Option<ParsedInterfaceDeclId>,
pub implementing_for: TypeArgument,
pub items: Vec<ImplItem>,
// the span of the whole impl trait and block
Expand Down
6 changes: 6 additions & 0 deletions sway-core/src/language/parsed/declaration/trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ pub struct TraitFn {
pub return_type: TypeArgument,
}

impl Spanned for TraitFn {
fn span(&self) -> sway_types::Span {
self.span.clone()
}
}

#[derive(Debug, Clone)]
pub struct TraitTypeDeclaration {
pub name: Ident,
Expand Down
7 changes: 7 additions & 0 deletions sway-core/src/language/parsed/expression/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{cmp::Ordering, fmt, hash::Hasher};

use crate::{
decl_engine::parsed_id::ParsedDeclId,
engine_threading::{
DebugWithEngines, DisplayWithEngines, EqWithEngines, HashWithEngines, OrdWithEngines,
OrdWithEnginesContext, PartialEqWithEngines, PartialEqWithEnginesContext,
Expand All @@ -22,6 +23,8 @@ pub use method_name::MethodName;
pub use scrutinee::*;
use sway_ast::intrinsics::Intrinsic;

use super::{FunctionDeclaration, StructDeclaration};

/// Represents a parsed, but not yet type checked, [Expression](https://en.wikipedia.org/wiki/Expression_(computer_science)).
#[derive(Debug, Clone)]
pub struct Expression {
Expand All @@ -32,6 +35,8 @@ pub struct Expression {
#[derive(Debug, Clone)]
pub struct FunctionApplicationExpression {
pub call_path_binding: TypeBinding<CallPath>,
pub resolved_call_path_binding:
Option<TypeBinding<ResolvedCallPath<ParsedDeclId<FunctionDeclaration>>>>,
pub arguments: Vec<Expression>,
}

Expand Down Expand Up @@ -88,6 +93,8 @@ impl PartialEqWithEngines for ArrayExpression {

#[derive(Debug, Clone)]
pub struct StructExpression {
pub resolved_call_path_binding:
Option<TypeBinding<ResolvedCallPath<ParsedDeclId<StructDeclaration>>>>,
pub call_path_binding: TypeBinding<CallPath>,
pub fields: Vec<StructExpressionField>,
}
Expand Down
24 changes: 22 additions & 2 deletions sway-core/src/language/ty/declaration/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use sway_types::{Ident, Named, Span, Spanned};
use crate::{
decl_engine::*,
engine_threading::*,
language::{ty::*, Visibility},
language::{parsed::Declaration, ty::*, Visibility},
type_system::*,
types::*,
};
Expand Down Expand Up @@ -496,6 +496,26 @@ impl GetDeclIdent for TyDecl {
}

impl TyDecl {
pub(crate) fn get_parsed_decl(&self, decl_engine: &DeclEngine) -> Option<Declaration> {
match self {
TyDecl::VariableDecl(_decl) => None,
TyDecl::ConstantDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
TyDecl::ConfigurableDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
TyDecl::TraitTypeDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
TyDecl::FunctionDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
TyDecl::TraitDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
TyDecl::StructDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
TyDecl::EnumDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
TyDecl::EnumVariantDecl(decl) => decl_engine.get_parsed_decl(decl.enum_ref.id()),
TyDecl::ImplSelfOrTrait(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
TyDecl::AbiDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
TyDecl::GenericTypeForFunctionScope(_data) => None,
TyDecl::ErrorRecovery(_, _) => None,
TyDecl::StorageDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
TyDecl::TypeAliasDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
}
}

/// Retrieves the declaration as a `DeclId<TyEnumDecl>`.
///
/// Returns an error if `self` is not the [TyDecl][EnumDecl] variant.
Expand Down Expand Up @@ -535,7 +555,7 @@ impl TyDecl {
/// Retrieves the declaration as a `DeclRef<DeclId<TyStructDecl>>`.
///
/// Returns an error if `self` is not the [TyDecl][StructDecl] variant.
pub(crate) fn to_struct_id(
pub(crate) fn to_struct_decl(
&self,
handler: &Handler,
engines: &Engines,
Expand Down
Loading
Loading