Skip to content

Commit

Permalink
Rework trait/ABI/impl and constant related code. (FuelLabs#4140)
Browse files Browse the repository at this point in the history
## Description

This splits off the refactoring changes out of
FuelLabs#4036 into two commits:

[Rework trait/ABI/impl-related structures to be
item-based.](FuelLabs@3a8d6ea)

[Refactor constant items/decls to have an optional
expression.](FuelLabs@3ec0903)

No functional changes intended.

## Checklist

- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
  • Loading branch information
tritao authored Feb 22, 2023
1 parent 92b6b0d commit 1e3a734
Show file tree
Hide file tree
Showing 60 changed files with 1,343 additions and 727 deletions.
20 changes: 17 additions & 3 deletions forc-plugins/forc-doc/src/descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
use anyhow::Result;
use sway_core::{
decl_engine::*,
language::ty::{TyDeclaration, TyTraitFn},
language::ty::{TyDeclaration, TyTraitFn, TyTraitInterfaceItem},
};

trait RequiredMethods {
Expand Down Expand Up @@ -123,7 +123,14 @@ impl Descriptor {
.then(|| trait_decl.attributes.to_html_string());
let context = (!trait_decl.interface_surface.is_empty()).then_some(
ContextType::RequiredMethods(
trait_decl.interface_surface.to_methods(decl_engine)?,
trait_decl
.interface_surface
.into_iter()
.flat_map(|item| match item {
TyTraitInterfaceItem::TraitFn(fn_decl) => Some(fn_decl),
})
.collect::<Vec<_>>()
.to_methods(decl_engine)?,
),
);

Expand Down Expand Up @@ -157,7 +164,14 @@ impl Descriptor {
(!abi_decl.attributes.is_empty()).then(|| abi_decl.attributes.to_html_string());
let context = (!abi_decl.interface_surface.is_empty()).then_some(
ContextType::RequiredMethods(
abi_decl.interface_surface.to_methods(decl_engine)?,
abi_decl
.interface_surface
.into_iter()
.flat_map(|item| match item {
TyTraitInterfaceItem::TraitFn(fn_decl) => Some(fn_decl),
})
.collect::<Vec<_>>()
.to_methods(decl_engine)?,
),
);

Expand Down
4 changes: 2 additions & 2 deletions sway-ast/src/item/item_abi.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::priv_prelude::*;
use crate::{priv_prelude::*, ItemTraitItem};

#[derive(Clone, Debug)]
pub struct ItemAbi {
pub abi_token: AbiToken,
pub name: Ident,
pub super_traits: Option<(ColonToken, Traits)>,
pub abi_items: Braces<Vec<(Annotated<FnSignature>, SemicolonToken)>>,
pub abi_items: Braces<Vec<(Annotated<ItemTraitItem>, SemicolonToken)>>,
pub abi_defs_opt: Option<Braces<Vec<Annotated<ItemFn>>>>,
}

Expand Down
12 changes: 9 additions & 3 deletions sway-ast/src/item/item_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ pub struct ItemConst {
pub const_token: ConstToken,
pub name: Ident,
pub ty_opt: Option<(ColonToken, Ty)>,
pub eq_token: EqToken,
pub expr: Expr,
pub eq_token_opt: Option<EqToken>,
pub expr_opt: Option<Expr>,
pub semicolon_token: SemicolonToken,
}

Expand All @@ -17,7 +17,13 @@ impl Spanned for ItemConst {
Some(pub_token) => pub_token.span(),
None => self.const_token.span(),
};
let end = self.semicolon_token.span();
let end = match &self.expr_opt {
Some(expr) => expr.span(),
None => match &self.ty_opt {
Some((_colon, ty)) => ty.span(),
None => self.name.span(),
},
};
Span::join(start, end)
}
}
15 changes: 14 additions & 1 deletion sway-ast/src/item/item_impl.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
use crate::priv_prelude::*;

#[derive(Clone, Debug)]
pub enum ItemImplItem {
Fn(ItemFn),
}

#[derive(Clone, Debug)]
pub struct ItemImpl {
pub impl_token: ImplToken,
pub generic_params_opt: Option<GenericParams>,
pub trait_opt: Option<(PathType, ForToken)>,
pub ty: Ty,
pub where_clause_opt: Option<WhereClause>,
pub contents: Braces<Vec<Annotated<ItemFn>>>,
pub contents: Braces<Vec<Annotated<ItemImplItem>>>,
}

impl Spanned for ItemImpl {
fn span(&self) -> Span {
Span::join(self.impl_token.span(), self.contents.span())
}
}

impl Spanned for ItemImplItem {
fn span(&self) -> Span {
match self {
ItemImplItem::Fn(fn_decl) => fn_decl.span(),
}
}
}
15 changes: 14 additions & 1 deletion sway-ast/src/item/item_trait.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use crate::priv_prelude::*;

#[derive(Clone, Debug)]
pub enum ItemTraitItem {
Fn(FnSignature),
}

#[derive(Clone, Debug)]
pub struct ItemTrait {
pub visibility: Option<PubToken>,
Expand All @@ -8,7 +13,7 @@ pub struct ItemTrait {
pub generics: Option<GenericParams>,
pub where_clause_opt: Option<WhereClause>,
pub super_traits: Option<(ColonToken, Traits)>,
pub trait_items: Braces<Vec<(Annotated<FnSignature>, SemicolonToken)>>,
pub trait_items: Braces<Vec<(Annotated<ItemTraitItem>, SemicolonToken)>>,
pub trait_defs_opt: Option<Braces<Vec<Annotated<ItemFn>>>>,
}

Expand All @@ -26,6 +31,14 @@ impl Spanned for ItemTrait {
}
}

impl Spanned for ItemTraitItem {
fn span(&self) -> Span {
match self {
ItemTraitItem::Fn(fn_decl) => fn_decl.span(),
}
}
}

#[derive(Clone, Debug)]
pub struct Traits {
pub prefix: PathType,
Expand Down
8 changes: 8 additions & 0 deletions sway-ast/src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ macro_rules! define_token (
span: Span,
}

impl Default for $ty_name {
fn default() -> Self {
Self {
span: Span::dummy()
}
}
}

impl Spanned for $ty_name {
fn span(&self) -> Span {
self.span.clone()
Expand Down
4 changes: 2 additions & 2 deletions sway-ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ pub use crate::{
item_const::ItemConst,
item_enum::ItemEnum,
item_fn::ItemFn,
item_impl::ItemImpl,
item_impl::{ItemImpl, ItemImplItem},
item_storage::{ItemStorage, StorageField},
item_struct::ItemStruct,
item_trait::{ItemTrait, Traits},
item_trait::{ItemTrait, ItemTraitItem, Traits},
item_use::{ItemUse, UseTree},
FnArg, FnArgs, FnSignature, Item, ItemKind, TypeField,
},
Expand Down
56 changes: 30 additions & 26 deletions sway-core/src/control_flow_analysis/analyze_return_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
use crate::{
control_flow_analysis::*,
decl_engine::DeclRef,
language::{ty, CallPath},
language::{
ty::{self, TyImplItem},
CallPath,
},
type_system::*,
Engines,
};
Expand Down Expand Up @@ -206,16 +208,14 @@ fn connect_declaration<'eng: 'cfg, 'cfg>(
}
ImplTrait { decl_id, .. } => {
let ty::TyImplTrait {
trait_name,
methods,
..
trait_name, items, ..
} = decl_engine.get_impl_trait(decl_id, &span)?;
let entry_node = graph.add_node(node.into());
for leaf in leaves {
graph.add_edge(*leaf, entry_node, "".into());
}

connect_impl_trait(engines, &trait_name, graph, &methods, entry_node)?;
connect_impl_trait(engines, &trait_name, graph, &items, entry_node)?;
Ok(leaves.to_vec())
}
ErrorRecovery(_) => Ok(leaves.to_vec()),
Expand All @@ -231,31 +231,35 @@ fn connect_impl_trait<'eng: 'cfg, 'cfg>(
engines: Engines<'eng>,
trait_name: &CallPath,
graph: &mut ControlFlowGraph<'cfg>,
methods: &[DeclRef],
items: &[TyImplItem],
entry_node: NodeIndex,
) -> Result<(), CompileError> {
let decl_engine = engines.de();
let mut methods_and_indexes = vec![];
// insert method declarations into the graph
for method_decl_ref in methods {
let fn_decl = decl_engine.get_function(method_decl_ref, &trait_name.span())?;
let fn_decl_entry_node = graph.add_node(ControlFlowGraphNode::MethodDeclaration {
span: fn_decl.span.clone(),
method_name: fn_decl.name.clone(),
method_decl_ref: method_decl_ref.clone(),
engines,
});
graph.add_edge(entry_node, fn_decl_entry_node, "".into());
// connect the impl declaration node to the functions themselves, as all trait functions are
// public if the trait is in scope
connect_typed_fn_decl(
engines,
&fn_decl,
graph,
fn_decl_entry_node,
fn_decl.span.clone(),
)?;
methods_and_indexes.push((fn_decl.name.clone(), fn_decl_entry_node));
for item in items {
match item {
TyImplItem::Fn(method_decl_ref) => {
let fn_decl = decl_engine.get_function(method_decl_ref, &trait_name.span())?;
let fn_decl_entry_node = graph.add_node(ControlFlowGraphNode::MethodDeclaration {
span: fn_decl.span.clone(),
method_name: fn_decl.name.clone(),
method_decl_ref: method_decl_ref.clone(),
engines,
});
graph.add_edge(entry_node, fn_decl_entry_node, "".into());
// connect the impl declaration node to the functions themselves, as all trait functions are
// public if the trait is in scope
connect_typed_fn_decl(
engines,
&fn_decl,
graph,
fn_decl_entry_node,
fn_decl.span.clone(),
)?;
methods_and_indexes.push((fn_decl.name.clone(), fn_decl_entry_node));
}
}
}
// Now, insert the methods into the trait method namespace.
graph
Expand Down
Loading

0 comments on commit 1e3a734

Please sign in to comment.