Skip to content

Commit

Permalink
Implements associated types.
Browse files Browse the repository at this point in the history
Implements associated types parsing.

Adds associated types to trait map.

Modifies resolve_symbol to handle associated types.
  • Loading branch information
esdrubal committed Sep 11, 2023
1 parent 4910dbc commit cbe2832
Show file tree
Hide file tree
Showing 112 changed files with 1,910 additions and 184 deletions.
1 change: 1 addition & 0 deletions forc-plugins/forc-doc/src/render/item/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ impl Renderable for TyTraitItem {
let item = match self {
TyTraitItem::Fn(item_fn) => item_fn,
TyTraitItem::Constant(_) => unimplemented!("Constant Trait items not yet implemented"),
TyTraitItem::Type(_) => unimplemented!("Type Trait items not yet implemented"),
};
let method = render_plan.engines.de().get_function(item.id());
let attributes = method.attributes.to_html_string();
Expand Down
2 changes: 2 additions & 0 deletions sway-ast/src/item/item_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::priv_prelude::*;
pub enum ItemImplItem {
Fn(ItemFn),
Const(ItemConst),
Type(TraitType),
}

#[derive(Clone, Debug, Serialize)]
Expand All @@ -27,6 +28,7 @@ impl Spanned for ItemImplItem {
match self {
ItemImplItem::Fn(fn_decl) => fn_decl.span(),
ItemImplItem::Const(const_decl) => const_decl.span(),
ItemImplItem::Type(type_decl) => type_decl.span(),
}
}
}
7 changes: 7 additions & 0 deletions sway-ast/src/item/item_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::priv_prelude::*;
pub enum ItemTraitItem {
Fn(FnSignature, Option<SemicolonToken>),
Const(ItemConst, Option<SemicolonToken>),
Type(TraitType, Option<SemicolonToken>),
// to handle parser recovery: Error represents an incomplete trait item
Error(Box<[Span]>, #[serde(skip_serializing)] ErrorEmitted),
}
Expand Down Expand Up @@ -49,6 +50,12 @@ impl Spanned for ItemTraitItem {
None => const_decl.span(),
}
}
ItemTraitItem::Type(type_decl, semicolon) => {
match semicolon.as_ref().map(|x| x.span()) {
Some(semicolon) => Span::join(type_decl.span(), semicolon),
None => type_decl.span(),
}
}
ItemTraitItem::Error(spans, _) => Span::join_all(spans.iter().cloned()),
}
}
Expand Down
20 changes: 20 additions & 0 deletions sway-ast/src/item/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,23 @@ impl Spanned for FnSignature {
Span::join(start, end)
}
}

#[derive(Clone, Debug, Serialize)]
pub struct TraitType {
pub name: Ident,
pub type_token: TypeToken,
pub eq_token_opt: Option<EqToken>,
pub ty_opt: Option<Ty>,
pub semicolon_token: SemicolonToken,
}

impl Spanned for TraitType {
fn span(&self) -> Span {
let start = self.type_token.span();
let end = match &self.ty_opt {
Some(ty_opt) => ty_opt.span(),
None => self.name.span(),
};
Span::join(start, end)
}
}
2 changes: 1 addition & 1 deletion sway-ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub use crate::{
item_trait::{ItemTrait, ItemTraitItem, Traits},
item_type_alias::ItemTypeAlias,
item_use::{ItemUse, UseTree},
FnArg, FnArgs, FnSignature, Item, ItemKind, TypeField,
FnArg, FnArgs, FnSignature, Item, ItemKind, TraitType, TypeField,
},
keywords::{CommaToken, DoubleColonToken, PubToken},
literal::{LitInt, LitIntType, Literal},
Expand Down
2 changes: 1 addition & 1 deletion sway-ast/src/priv_prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub use {
item_trait::{ItemTrait, Traits},
item_type_alias::ItemTypeAlias,
item_use::ItemUse,
FnSignature, Item, ItemKind, TypeField,
FnSignature, Item, ItemKind, TraitType, TypeField,
},
keywords::*,
literal::{LitBool, LitBoolType, LitChar, LitInt, LitIntType, LitString, Literal},
Expand Down
4 changes: 4 additions & 0 deletions sway-core/src/abi_generation/evm_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ pub fn abi_str(type_info: &TypeInfo, type_engine: &TypeEngine, decl_engine: &Dec
format!("__slice {}", abi_str_type_arg(ty, type_engine, decl_engine))
}
Alias { ty, .. } => abi_str_type_arg(ty, type_engine, decl_engine),
TraitType {
name,
trait_type_id: _,
} => format!("trait type {}", name),
}
}

Expand Down
4 changes: 4 additions & 0 deletions sway-core/src/abi_generation/fuel_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,10 @@ impl TypeInfo {
format!("__slice {}", ty.abi_str(ctx, type_engine, decl_engine))
}
Alias { ty, .. } => ty.abi_str(ctx, type_engine, decl_engine),
TraitType {
name,
trait_type_id: _,
} => format!("trait type {}", name),
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions sway-core/src/control_flow_analysis/analyze_return_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ fn connect_declaration<'eng: 'cfg, 'cfg>(
| ty::TyDecl::EnumVariantDecl(_)
| ty::TyDecl::StorageDecl(_)
| ty::TyDecl::TypeAliasDecl(_)
| ty::TyDecl::TypeDecl(_)
| ty::TyDecl::GenericTypeForFunctionScope(_) => Ok(leaves.to_vec()),
ty::TyDecl::VariableDecl(_) | ty::TyDecl::ConstantDecl(_) => {
let entry_node = graph.add_node(ControlFlowGraphNode::from_node(node));
Expand Down Expand Up @@ -266,6 +267,7 @@ fn connect_impl_trait<'eng: 'cfg, 'cfg>(
methods_and_indexes.push((fn_decl.name.clone(), fn_decl_entry_node));
}
TyImplItem::Constant(_const_decl) => {}
TyImplItem::Type(_type_decl) => {}
}
}
// Now, insert the methods into the trait method namespace.
Expand Down
6 changes: 6 additions & 0 deletions sway-core/src/control_flow_analysis/dead_code_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ fn connect_declaration<'eng: 'cfg, 'cfg>(
connect_type_alias_declaration(engines, &type_alias, graph, entry_node)?;
Ok(leaves.to_vec())
}
ty::TyDecl::TypeDecl(ty::TypeDecl { .. }) => Ok(leaves.to_vec()),
ty::TyDecl::ErrorRecovery(..) | ty::TyDecl::GenericTypeForFunctionScope(_) => {
Ok(leaves.to_vec())
}
Expand Down Expand Up @@ -718,6 +719,7 @@ fn connect_impl_trait<'eng: 'cfg, 'cfg>(
methods_and_indexes.push((fn_decl.name.clone(), fn_decl_entry_node));
}
TyImplItem::Constant(_const_decl) => {}
TyImplItem::Type(_type_decl) => {}
}
}
// we also want to add an edge from the methods back to the trait, so if a method gets called,
Expand Down Expand Up @@ -806,6 +808,7 @@ fn connect_abi_declaration(
}
}
ty::TyTraitInterfaceItem::Constant(_const_decl) => {}
ty::TyTraitInterfaceItem::Type(_type_decl) => {}
}
}

Expand Down Expand Up @@ -2228,6 +2231,9 @@ fn allow_dead_code_ast_node(decl_engine: &DeclEngine, node: &ty::TyAstNode) -> b
ty::TyDecl::ConstantDecl(ty::ConstantDecl { decl_id, .. }) => {
allow_dead_code(decl_engine.get_constant(decl_id).attributes)
}
ty::TyDecl::TypeDecl(ty::TypeDecl { decl_id, .. }) => {
allow_dead_code(decl_engine.get_type(decl_id).attributes)
}
ty::TyDecl::FunctionDecl(ty::FunctionDecl { decl_id, .. }) => {
allow_dead_code(decl_engine.get_function(decl_id).attributes)
}
Expand Down
28 changes: 28 additions & 0 deletions sway-core/src/decl_engine/associated_item_decl_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub enum AssociatedItemDeclId {
TraitFn(DeclId<ty::TyTraitFn>),
Function(DeclId<ty::TyFunctionDecl>),
Constant(DeclId<ty::TyConstantDecl>),
Type(DeclId<ty::TyTraitType>),
}

impl From<DeclId<ty::TyFunctionDecl>> for AssociatedItemDeclId {
Expand Down Expand Up @@ -45,6 +46,22 @@ impl From<&mut DeclId<ty::TyTraitFn>> for AssociatedItemDeclId {
}
}

impl From<DeclId<ty::TyTraitType>> for AssociatedItemDeclId {
fn from(val: DeclId<ty::TyTraitType>) -> Self {
Self::Type(val)
}
}
impl From<&DeclId<ty::TyTraitType>> for AssociatedItemDeclId {
fn from(val: &DeclId<ty::TyTraitType>) -> Self {
Self::Type(*val)
}
}
impl From<&mut DeclId<ty::TyTraitType>> for AssociatedItemDeclId {
fn from(val: &mut DeclId<ty::TyTraitType>) -> Self {
Self::Type(*val)
}
}

impl From<DeclId<ty::TyConstantDecl>> for AssociatedItemDeclId {
fn from(val: DeclId<ty::TyConstantDecl>) -> Self {
Self::Constant(val)
Expand Down Expand Up @@ -73,6 +90,9 @@ impl std::fmt::Display for AssociatedItemDeclId {
Self::Constant(_) => {
write!(f, "decl(constant)",)
}
Self::Type(_) => {
write!(f, "decl(type)",)
}
}
}
}
Expand All @@ -94,6 +114,10 @@ impl TryFrom<DeclRefMixedFunctional> for DeclRefFunction {
actually: actually.to_string(),
span: value.decl_span().clone(),
}),
actually @ AssociatedItemDeclId::Type(_) => Err(CompileError::DeclIsNotAFunction {
actually: actually.to_string(),
span: value.decl_span().clone(),
}),
}
}
}
Expand All @@ -117,6 +141,10 @@ impl TryFrom<AssociatedItemDeclId> for DeclId<TyFunctionDecl> {
actually: actually.to_string(),
span: Span::dummy(), // FIXME
}),
actually @ AssociatedItemDeclId::Type(_) => Err(CompileError::DeclIsNotAFunction {
actually: actually.to_string(),
span: Span::dummy(), // FIXME
}),
}
}
}
Expand Down
19 changes: 18 additions & 1 deletion sway-core/src/decl_engine/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
engine_threading::*,
language::ty::{
self, TyAbiDecl, TyConstantDecl, TyEnumDecl, TyFunctionDecl, TyImplTrait, TyStorageDecl,
TyStructDecl, TyTraitDecl, TyTraitFn, TyTypeAliasDecl,
TyStructDecl, TyTraitDecl, TyTraitFn, TyTraitType, TyTypeAliasDecl,
},
};

Expand All @@ -21,6 +21,7 @@ pub struct DeclEngine {
function_slab: ConcurrentSlab<TyFunctionDecl>,
trait_slab: ConcurrentSlab<TyTraitDecl>,
trait_fn_slab: ConcurrentSlab<TyTraitFn>,
trait_type_slab: ConcurrentSlab<TyTraitType>,
impl_trait_slab: ConcurrentSlab<TyImplTrait>,
struct_slab: ConcurrentSlab<TyStructDecl>,
storage_slab: ConcurrentSlab<TyStorageDecl>,
Expand Down Expand Up @@ -72,6 +73,7 @@ macro_rules! decl_engine_get {
decl_engine_get!(function_slab, ty::TyFunctionDecl);
decl_engine_get!(trait_slab, ty::TyTraitDecl);
decl_engine_get!(trait_fn_slab, ty::TyTraitFn);
decl_engine_get!(trait_type_slab, ty::TyTraitType);
decl_engine_get!(impl_trait_slab, ty::TyImplTrait);
decl_engine_get!(struct_slab, ty::TyStructDecl);
decl_engine_get!(storage_slab, ty::TyStorageDecl);
Expand All @@ -97,6 +99,7 @@ macro_rules! decl_engine_insert {
decl_engine_insert!(function_slab, ty::TyFunctionDecl);
decl_engine_insert!(trait_slab, ty::TyTraitDecl);
decl_engine_insert!(trait_fn_slab, ty::TyTraitFn);
decl_engine_insert!(trait_type_slab, ty::TyTraitType);
decl_engine_insert!(impl_trait_slab, ty::TyImplTrait);
decl_engine_insert!(struct_slab, ty::TyStructDecl);
decl_engine_insert!(storage_slab, ty::TyStorageDecl);
Expand All @@ -117,6 +120,7 @@ macro_rules! decl_engine_replace {
decl_engine_replace!(function_slab, ty::TyFunctionDecl);
decl_engine_replace!(trait_slab, ty::TyTraitDecl);
decl_engine_replace!(trait_fn_slab, ty::TyTraitFn);
decl_engine_replace!(trait_type_slab, ty::TyTraitType);
decl_engine_replace!(impl_trait_slab, ty::TyImplTrait);
decl_engine_replace!(struct_slab, ty::TyStructDecl);
decl_engine_replace!(storage_slab, ty::TyStorageDecl);
Expand All @@ -133,6 +137,7 @@ macro_rules! decl_engine_index {
decl_engine_index!(function_slab, ty::TyFunctionDecl);
decl_engine_index!(trait_slab, ty::TyTraitDecl);
decl_engine_index!(trait_fn_slab, ty::TyTraitFn);
decl_engine_index!(trait_type_slab, ty::TyTraitType);
decl_engine_index!(impl_trait_slab, ty::TyImplTrait);
decl_engine_index!(struct_slab, ty::TyStructDecl);
decl_engine_index!(storage_slab, ty::TyStorageDecl);
Expand Down Expand Up @@ -298,6 +303,18 @@ impl DeclEngine {
self.get(index)
}

/// Friendly helper method for calling the `get` method from the
/// implementation of [DeclEngineGet] for [DeclEngine]
///
/// Calling [DeclEngine][get] directly is equivalent to this method, but
/// this method adds additional syntax that some users may find helpful.
pub fn get_type<I>(&self, index: &I) -> ty::TyTraitType
where
DeclEngine: DeclEngineGet<I, ty::TyTraitType>,
{
self.get(index)
}

/// Friendly helper method for calling the `get` method from the
/// implementation of [DeclEngineGet] for [DeclEngine]
///
Expand Down
17 changes: 17 additions & 0 deletions sway-core/src/decl_engine/id.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::marker::PhantomData;
use std::{fmt, hash::Hash};

use crate::language::ty::TyTraitType;
use crate::{
decl_engine::*,
engine_threading::*,
Expand Down Expand Up @@ -133,6 +134,14 @@ impl SubstTypes for DeclId<TyTypeAliasDecl> {
decl_engine.replace(*self, decl);
}
}
impl SubstTypes for DeclId<TyTraitType> {
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: &Engines) {
let decl_engine = engines.de();
let mut decl = decl_engine.get(self);
decl.subst(type_mapping, engines);
decl_engine.replace(*self, decl);
}
}

impl ReplaceSelfType for DeclId<TyFunctionDecl> {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
Expand Down Expand Up @@ -190,3 +199,11 @@ impl ReplaceSelfType for DeclId<TyTypeAliasDecl> {
decl_engine.replace(*self, decl);
}
}
impl ReplaceSelfType for DeclId<TyTraitType> {
fn replace_self_type(&mut self, engines: &Engines, self_type: TypeId) {
let decl_engine = engines.de();
let mut decl = decl_engine.get(self);
decl.replace_self_type(engines, self_type);
decl_engine.replace(*self, decl);
}
}
6 changes: 6 additions & 0 deletions sway-core/src/decl_engine/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ impl fmt::Display for DeclMapping {
AssociatedItemDeclId::TraitFn(decl_id) => decl_id.inner(),
AssociatedItemDeclId::Function(decl_id) => decl_id.inner(),
AssociatedItemDeclId::Constant(decl_id) => decl_id.inner(),
AssociatedItemDeclId::Type(decl_id) => decl_id.inner(),
}
)
})
Expand Down Expand Up @@ -70,10 +71,12 @@ impl DeclMapping {
let interface_decl_ref = match interface_item {
TyTraitInterfaceItem::TraitFn(decl_ref) => decl_ref.id().into(),
TyTraitInterfaceItem::Constant(decl_ref) => decl_ref.id().into(),
TyTraitInterfaceItem::Type(decl_ref) => decl_ref.id().into(),
};
let new_decl_ref = match new_item {
TyTraitItem::Fn(decl_ref) => decl_ref.id().into(),
TyTraitItem::Constant(decl_ref) => decl_ref.id().into(),
TyTraitItem::Type(decl_ref) => decl_ref.id().into(),
};
mapping.push((interface_decl_ref, new_decl_ref));
}
Expand All @@ -83,10 +86,12 @@ impl DeclMapping {
let interface_decl_ref = match item {
TyTraitItem::Fn(decl_ref) => decl_ref.id().into(),
TyTraitItem::Constant(decl_ref) => decl_ref.id().into(),
TyTraitItem::Type(decl_ref) => decl_ref.id().into(),
};
let new_decl_ref = match new_item {
TyTraitItem::Fn(decl_ref) => decl_ref.id().into(),
TyTraitItem::Constant(decl_ref) => decl_ref.id().into(),
TyTraitItem::Type(decl_ref) => decl_ref.id().into(),
};
mapping.push((interface_decl_ref, new_decl_ref));
}
Expand Down Expand Up @@ -124,6 +129,7 @@ impl DeclMapping {
}
}
AssociatedItemDeclId::Constant(_) => mapping.push((source_decl_ref, dest_decl_ref)),
AssociatedItemDeclId::Type(_) => mapping.push((source_decl_ref, dest_decl_ref)),
}
}
DeclMapping { mapping }
Expand Down
3 changes: 2 additions & 1 deletion sway-core/src/decl_engine/ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::{
engine_threading::*,
language::ty::{
self, TyAbiDecl, TyConstantDecl, TyEnumDecl, TyFunctionDecl, TyImplTrait, TyStorageDecl,
TyStructDecl, TyTraitDecl, TyTraitFn,
TyStructDecl, TyTraitDecl, TyTraitFn, TyTraitType,
},
semantic_analysis::TypeCheckContext,
type_system::*,
Expand All @@ -39,6 +39,7 @@ use crate::{
pub type DeclRefFunction = DeclRef<DeclId<TyFunctionDecl>>;
pub type DeclRefTrait = DeclRef<DeclId<TyTraitDecl>>;
pub type DeclRefTraitFn = DeclRef<DeclId<TyTraitFn>>;
pub type DeclRefTraitType = DeclRef<DeclId<TyTraitType>>;
pub type DeclRefImplTrait = DeclRef<DeclId<TyImplTrait>>;
pub type DeclRefStruct = DeclRef<DeclId<TyStructDecl>>;
pub type DeclRefStorage = DeclRef<DeclId<TyStorageDecl>>;
Expand Down
1 change: 1 addition & 0 deletions sway-core/src/ir_generation/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ fn compile_declarations(
| ty::TyDecl::GenericTypeForFunctionScope { .. }
| ty::TyDecl::StorageDecl { .. }
| ty::TyDecl::TypeAliasDecl { .. }
| ty::TyDecl::TypeDecl { .. }
| ty::TyDecl::ErrorRecovery(..) => (),
}
}
Expand Down
1 change: 1 addition & 0 deletions sway-core/src/ir_generation/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,6 @@ fn convert_resolved_type(
TypeInfo::TypeParam(_) => reject_type!("TypeParam"),
TypeInfo::ErrorRecovery(_) => reject_type!("Error recovery"),
TypeInfo::Storage { .. } => reject_type!("Storage"),
TypeInfo::TraitType { .. } => reject_type!("TraitType"),
})
}
Loading

0 comments on commit cbe2832

Please sign in to comment.