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

ABI Encode Unit Type #671

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/abi/src/elements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl JsonAbi for Base {
Base::Numeric(Integer::I8) => "int8".to_string(),
Base::Address => "address".to_string(),
Base::Bool => "bool".to_string(),
Base::Unit => panic!("unit type is not abi encodable"),
Base::Unit => "".to_string(),
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions crates/yulgen/src/db/queries/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ pub fn function_def(db: &dyn YulgenDb, function: FunctionId) -> yul::Statement {

let function_name = identifier! { (db.function_yul_name(function)) };
// all user-defined functions are given a return value during lowering

// ^ this is no longer true. functions that return the unit type do not
// get a return statement. Need a way to identify what functions don't have a
// return statement from here, so we can remove the '-> return_val' in those cases.

// let has_return_value = function_statements.iter().any(|x| x);

function_definition! {
function [function_name]([param_names...]) -> return_val {
[function_statements...]
Expand Down
8 changes: 7 additions & 1 deletion crates/yulgen/src/mappers/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ pub fn expr(context: &mut FnContext, exp: &Node<fe::Expr>) -> yul::Expression {
fe::Expr::List { .. } => panic!("list expressions should be lowered"),
fe::Expr::Tuple { .. } => panic!("tuple expressions should be lowered"),
fe::Expr::Str(_) => expr_str(exp),
fe::Expr::Unit => expression! { 0x0 },
// fe::Expr::Unit => expression! { 0x0 },
fe::Expr::Unit => yultsur::yul::Expression::Literal({
yul::Literal {
literal: "".to_string(),
yultype: None
}
})
};

let attributes = context.expression_attributes(exp);
Expand Down
13 changes: 10 additions & 3 deletions crates/yulgen/src/mappers/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,16 @@ fn func_return(context: &mut FnContext, stmt: &Node<fe::FuncStmt>) -> yul::State
.expect("valueless return made it to Yul codegen");
let value = expressions::expr(context, value);

block_statement! {
(return_val := [value])
(leave)
if let yul::Expression::Literal(yultype) = value {
block_statement! {
(leave)
}
}
else {
block_statement! {
(return_val := [value])
(leave)
}
}
} else {
unreachable!()
Expand Down
42 changes: 21 additions & 21 deletions crates/yulgen/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,11 @@ impl AbiType {
}

pub trait AsAbiType {
fn as_abi_type(&self, db: &dyn AnalyzerDb) -> AbiType;
fn as_abi_type(&self, db: &dyn AnalyzerDb) -> Option<AbiType>;
}

impl AsAbiType for FixedSize {
fn as_abi_type(&self, db: &dyn AnalyzerDb) -> AbiType {
fn as_abi_type(&self, db: &dyn AnalyzerDb) -> Option<AbiType> {
match self {
FixedSize::Base(base) => base.as_abi_type(db),
FixedSize::Array(array) => array.as_abi_type(db),
Expand All @@ -188,38 +188,38 @@ impl AsAbiType for FixedSize {
}

impl AsAbiType for Base {
fn as_abi_type(&self, _db: &dyn AnalyzerDb) -> AbiType {
fn as_abi_type(&self, _db: &dyn AnalyzerDb) -> Option<AbiType> {
match self {
Base::Numeric(integer) => {
let size = integer.size();
if integer.is_signed() {
AbiType::Int { size }
Some(AbiType::Int { size })
} else {
AbiType::Uint { size }
Some(AbiType::Uint { size })
}
}
Base::Address => AbiType::Address,
Base::Bool => AbiType::Bool,
Base::Unit => panic!("unit type is not abi encodable"),
Base::Address => Some(AbiType::Address),
Base::Bool => Some(AbiType::Bool),
Base::Unit => None,
}
}
}

impl AsAbiType for Array {
fn as_abi_type(&self, db: &dyn AnalyzerDb) -> AbiType {
fn as_abi_type(&self, db: &dyn AnalyzerDb) -> Option<AbiType> {
if matches!(self.inner, Base::Numeric(Integer::U8)) {
AbiType::Bytes { size: self.size }
Some(AbiType::Bytes { size: self.size })
} else {
AbiType::StaticArray {
inner: Box::new(self.inner.as_abi_type(db)),
Some(AbiType::StaticArray {
inner: Box::new(self.inner.as_abi_type(db).unwrap()),
size: self.size,
}
})
}
}
}

impl AsAbiType for Struct {
fn as_abi_type(&self, db: &dyn AnalyzerDb) -> AbiType {
fn as_abi_type(&self, db: &dyn AnalyzerDb) -> Option<AbiType> {
let components = self
.id
.fields(db)
Expand All @@ -231,22 +231,22 @@ impl AsAbiType for Struct {
.as_abi_type(db)
})
.collect();
AbiType::Tuple { components }
Some(AbiType::Tuple { components })
}
}

impl AsAbiType for Tuple {
fn as_abi_type(&self, db: &dyn AnalyzerDb) -> AbiType {
AbiType::Tuple {
fn as_abi_type(&self, db: &dyn AnalyzerDb) -> Option<AbiType> {
Some(AbiType::Tuple {
components: self.items.iter().map(|typ| typ.as_abi_type(db)).collect(),
}
})
}
}

impl AsAbiType for FeString {
fn as_abi_type(&self, _db: &dyn AnalyzerDb) -> AbiType {
AbiType::String {
fn as_abi_type(&self, _db: &dyn AnalyzerDb) -> Option<AbiType> {
Some(AbiType::String {
max_size: self.max_size,
}
})
}
}