Skip to content

Commit

Permalink
Merge a008494 into 3e3a704
Browse files Browse the repository at this point in the history
  • Loading branch information
xunilrj authored Apr 3, 2024
2 parents 3e3a704 + a008494 commit d8c8acd
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 46 deletions.
102 changes: 63 additions & 39 deletions sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use crate::{
Engines, TypeId, TypeInfo, TypeParameter,
};
use itertools::Itertools;
use sway_error::handler::Handler;
use sway_error::{error::CompileError, handler::{ErrorEmitted, Handler}};
use sway_parse::Parse;
use sway_types::{integer_bits::IntegerBits, BaseIdent, ModuleId, Named, Spanned};
use sway_types::{integer_bits::IntegerBits, BaseIdent, ModuleId, Named, Span, Spanned};

/// Contains all information needed to implement AbiEncode
pub struct AutoImplAbiEncodeContext<'a, 'b>
Expand Down Expand Up @@ -262,7 +262,7 @@ where
module_id: Option<ModuleId>,
kind: FunctionDeclarationKind,
code: &str,
) -> Option<TyAstNode> {
) -> Result<TyAstNode, Handler> {
let mut ctx = crate::transform::to_parsed_lang::Context::new(
crate::BuildTarget::Fuel,
self.ctx.experimental,
Expand Down Expand Up @@ -302,32 +302,24 @@ where
assert!(!handler.has_warnings(), "{:?}", handler);

let ctx = self.ctx.by_ref();
let decl = TyDecl::type_check(
&handler,
ctx,
parsed::Declaration::FunctionDeclaration(decl),
)
.unwrap();
let decl = ctx.scoped(|ctx| {
TyDecl::type_check(
&handler,
ctx,
parsed::Declaration::FunctionDeclaration(decl),
)
}).unwrap();

if handler.has_errors() {
panic!(
"{:?} {} {:?}",
handler,
code,
module_id
.and_then(|x| engines.se().get_source_ids_from_module_id(x))
.unwrap()
.iter()
.map(|x| engines.se().get_path(x))
.collect::<Vec<_>>()
);
}
assert!(!handler.has_warnings(), "{:?}", handler);

Some(TyAstNode {
span: decl.span(),
content: ty::TyAstNodeContent::Declaration(decl),
})
if handler.has_errors() {
Err(handler)
} else {
Ok(TyAstNode {
span: decl.span(),
content: ty::TyAstNodeContent::Declaration(decl),
})
}
}

fn parse_item_impl_to_typed_ast_node(
Expand Down Expand Up @@ -357,7 +349,11 @@ where
assert!(!handler.has_errors(), "{:?}", handler);

let ctx = self.ctx.by_ref();
let decl = TyDecl::type_check(&handler, ctx, Declaration::ImplTrait(decl)).unwrap();
let decl = ctx.scoped(|ctx| {
TyDecl::type_check(&handler, ctx, Declaration::ImplTrait(decl))
}).unwrap();

//println!("HASERROR: {code}, {}", handler.has_errors());

if handler.has_errors() {
None
Expand Down Expand Up @@ -538,7 +534,8 @@ where
module_id: Option<ModuleId>,
contract_fns: &[DeclRef<DeclId<TyFunctionDecl>>],
fallback_fn: Option<DeclId<TyFunctionDecl>>,
) -> Option<TyAstNode> {
handler: &Handler,
) -> Result<TyAstNode, ErrorEmitted> {
let mut code = String::new();

let mut reads = false;
Expand Down Expand Up @@ -591,7 +588,7 @@ where
}}\n"));
} else {
code.push_str(&format!("if method_name == \"{method_name}\" {{
let args = decode_second_param::<{args_types}>();
let args: {args_types} = decode_second_param::<{args_types}>();
let result_{method_name}: raw_slice = encode::<{return_type}>(__contract_entry_{method_name}({expanded_args}));
__contract_ret(result_{method_name}.ptr(), result_{method_name}.len::<u8>());
}}\n"));
Expand Down Expand Up @@ -624,19 +621,29 @@ where
{fallback}
}}"
);
self.parse_item_fn_to_typed_ast_node(

let entry_fn = self.parse_item_fn_to_typed_ast_node(
engines,
module_id,
FunctionDeclarationKind::Entry,
&code,
)
);

match entry_fn {
Ok(entry_fn) => Ok(entry_fn),
Err(gen_handler) => {
handler.append(gen_handler);
Err(handler.emit_err(CompileError::CouldNotGenerateEntry { span: Span::dummy() }))
},
}
}

pub(crate) fn generate_predicate_entry(
&mut self,
engines: &Engines,
decl: &TyFunctionDecl,
) -> Option<TyAstNode> {
handler: &Handler,
) -> Result<TyAstNode, ErrorEmitted> {
let module_id = decl.span.source_id().map(|sid| sid.module_id());

let args_types = itertools::intersperse(
Expand All @@ -662,25 +669,34 @@ where
let args_types = format!("({args_types},)");
format!(
"pub fn __entry() -> bool {{
let args = decode_predicate_data::<{args_types}>();
let args: {args_types} = decode_predicate_data::<{args_types}>();
main({expanded_args})
}}"
)
};

self.parse_item_fn_to_typed_ast_node(
let entry_fn = self.parse_item_fn_to_typed_ast_node(
engines,
module_id,
FunctionDeclarationKind::Entry,
&code,
)
);

match entry_fn {
Ok(entry_fn) => Ok(entry_fn),
Err(gen_handler) => {
handler.append(gen_handler);
Err(handler.emit_err(CompileError::CouldNotGenerateEntry { span: Span::dummy() }))
},
}
}

pub(crate) fn generate_script_entry(
&mut self,
engines: &Engines,
decl: &TyFunctionDecl,
) -> Option<TyAstNode> {
handler: &Handler,
) -> Result<TyAstNode, ErrorEmitted> {
let module_id = decl.span.source_id().map(|sid| sid.module_id());

let args_types = itertools::intersperse(
Expand Down Expand Up @@ -718,18 +734,26 @@ where
} else {
format!(
"pub fn __entry() -> raw_slice {{
let args = decode_script_data::<{args_types}>();
let args: {args_types} = decode_script_data::<{args_types}>();
let result: {return_type} = main({expanded_args});
encode::<{return_type}>(result)
}}"
)
};

self.parse_item_fn_to_typed_ast_node(
let entry_fn = self.parse_item_fn_to_typed_ast_node(
engines,
module_id,
FunctionDeclarationKind::Entry,
&code,
)
);

match entry_fn {
Ok(entry_fn) => Ok(entry_fn),
Err(gen_handler) => {
handler.append(gen_handler);
Err(handler.emit_err(CompileError::CouldNotGenerateEntry { span: Span::dummy() }))
},
}
}
}
12 changes: 5 additions & 7 deletions sway-core/src/semantic_analysis/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use sway_error::{
error::CompileError,
handler::{ErrorEmitted, Handler},
};
use sway_types::{BaseIdent, Named};
use sway_types::{BaseIdent, Named, Span};

use crate::{
decl_engine::{DeclEngineGet, DeclId},
Expand Down Expand Up @@ -329,16 +329,14 @@ impl ty::TyModule {
let mut fn_generator =
auto_impl::AutoImplAbiEncodeContext::new(&mut ctx).unwrap();
let node = fn_generator
.generate_predicate_entry(engines, main_decl.as_ref().unwrap())
.unwrap();
.generate_predicate_entry(engines, main_decl.as_ref().unwrap(), handler)?;
all_nodes.push(node)
}
(TreeType::Script, true) => {
let mut fn_generator =
auto_impl::AutoImplAbiEncodeContext::new(&mut ctx).unwrap();
let node = fn_generator
.generate_script_entry(engines, main_decl.as_ref().unwrap())
.unwrap();
.generate_script_entry(engines, main_decl.as_ref().unwrap(), handler)?;
all_nodes.push(node)
}
(TreeType::Contract, _) => {
Expand All @@ -358,8 +356,8 @@ impl ty::TyModule {
parsed.span.source_id().map(|x| x.module_id()),
&contract_fns,
fallback_fn,
)
.unwrap();
handler,
)?;
all_nodes.push(node)
}
_ => {}
Expand Down
3 changes: 3 additions & 0 deletions sway-error/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,8 @@ pub enum CompileError {
FallbackFnsAreContractOnly { span: Span },
#[error("Fallback functions cannot have parameters")]
FallbackFnsCannotHaveParameters { span: Span },
#[error("Could not generate the entry method because one of the arguments does not implement AbiEncode/AbiDecode")]
CouldNotGenerateEntry { span: Span }
}

impl std::convert::From<TypeError> for CompileError {
Expand Down Expand Up @@ -1067,6 +1069,7 @@ impl Spanned for CompileError {
ExpressionCannotBeDereferenced { span, .. } => span.clone(),
FallbackFnsAreContractOnly { span } => span.clone(),
FallbackFnsCannotHaveParameters { span } => span.clone(),
CouldNotGenerateEntry { span } => span.clone(),
}
}
}
Expand Down

0 comments on commit d8c8acd

Please sign in to comment.