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

Support for aliased import for encoding v1 #6628

Merged
merged 3 commits into from
Nov 22, 2024
Merged
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
118 changes: 20 additions & 98 deletions sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ use crate::{
Purity,
},
semantic_analysis::TypeCheckContext,
Engines, TypeId, TypeInfo, TypeParameter,
Engines, TypeArgument, TypeInfo, TypeParameter,
};
use sway_error::{
error::CompileError,
handler::{ErrorEmitted, Handler},
};
use sway_parse::Parse;
use sway_types::{integer_bits::IntegerBits, BaseIdent, Named, ProgramId, Span, Spanned};
use sway_types::{BaseIdent, Named, ProgramId, Span, Spanned};

/// Contains all information needed to implement AbiEncode
pub struct EncodingAutoImplContext<'a, 'b>
Expand All @@ -38,7 +38,7 @@ where
T: Parse,
{
// Uncomment this to see what is being generated
//println!("{}", input);
// println!("{}", input);

let handler = <_>::default();
let source_id =
Expand Down Expand Up @@ -195,7 +195,7 @@ where
code.push_str(&format!(
"{field_name}: buffer.decode::<{field_type_name}>(),",
field_name = f.name.as_str(),
field_type_name = Self::generate_type(engines, f.type_argument.type_id)?,
field_type_name = Self::generate_type(engines, &f.type_argument)?,
));
}

Expand All @@ -217,7 +217,7 @@ where
format!("{} => {}::{}, \n", x.tag, enum_name, name)
},
_ => {
let variant_type_name = Self::generate_type(engines, x.type_argument.type_id)?;
let variant_type_name = Self::generate_type(engines, &x.type_argument)?;
format!("{tag_value} => {enum_name}::{variant_name}(buffer.decode::<{variant_type}>()), \n",
tag_value = x.tag,
enum_name = enum_name,
Expand Down Expand Up @@ -496,92 +496,15 @@ where
}
}

fn generate_type(engines: &Engines, type_id: TypeId) -> Option<String> {
let name = match &*engines.te().get(type_id) {
TypeInfo::UnknownGeneric { name, .. } => name.to_string(),
TypeInfo::Placeholder(type_param) => type_param.name.to_string(),
TypeInfo::StringSlice => "str".into(),
TypeInfo::StringArray(x) => format!("str[{}]", x.val()),
TypeInfo::UnsignedInteger(x) => match x {
IntegerBits::Eight => "u8",
IntegerBits::Sixteen => "u16",
IntegerBits::ThirtyTwo => "u32",
IntegerBits::SixtyFour => "u64",
IntegerBits::V256 => "u256",
}
.into(),
TypeInfo::Boolean => "bool".into(),
TypeInfo::Custom {
qualified_call_path: call_path,
..
} => call_path.call_path.suffix.to_string(),
TypeInfo::Tuple(fields) => {
if fields.is_empty() {
return Some("()".into());
}
let field_strs = fields
.iter()
.map(|field| Self::generate_type(engines, field.type_id))
.collect::<Option<Vec<String>>>()?;
format!("({},)", field_strs.join(", "))
}
TypeInfo::B256 => "b256".into(),
TypeInfo::Enum(decl_id) => {
let decl = engines.de().get_enum(decl_id);

let type_parameters = decl
.type_parameters
.iter()
.map(|x| Self::generate_type(engines, x.type_id))
.collect::<Option<Vec<String>>>()?
.join(", ");

let type_parameters = if !type_parameters.is_empty() {
format!("<{type_parameters}>")
} else {
type_parameters
};

format!("{}{type_parameters}", decl.call_path.suffix.as_str())
}
TypeInfo::Struct(decl_id) => {
let decl = engines.de().get(decl_id);

let type_parameters = decl
.type_parameters
.iter()
.map(|x| Self::generate_type(engines, x.type_id))
.collect::<Option<Vec<String>>>()?
.join(", ");

let type_parameters = if !type_parameters.is_empty() {
format!("<{type_parameters}>")
} else {
type_parameters
};

format!("{}{type_parameters}", decl.call_path.suffix.as_str())
}
TypeInfo::Array(elem_ty, count) => {
format!(
"[{}; {}]",
Self::generate_type(engines, elem_ty.type_id)?,
count.val()
)
}
TypeInfo::Slice(elem_ty) => {
format!(
"__slice[{}]",
Self::generate_type(engines, elem_ty.type_id)?
)
}
TypeInfo::RawUntypedPtr => "raw_ptr".into(),
TypeInfo::RawUntypedSlice => "raw_slice".into(),
TypeInfo::Alias { name, .. } => name.to_string(),
_ => return None,
};

Some(name)
// The safest way would be to return a canonical fully qualified type path.
// We do not have a way to do this at the moment, so the best way is to use
// exactly what was typed by the user, to accommodate aliased imports.
fn generate_type(engines: &Engines, t: &TypeArgument) -> Option<String> {
match &*engines.te().get(t.type_id) {
// when a function does not define a return type, the span points to the whole signature.
TypeInfo::Tuple(v) if v.is_empty() => Some("()".into()),
_ => Some(t.span().as_str().to_string()),
}
}

pub(crate) fn generate_contract_entry(
Expand Down Expand Up @@ -613,7 +536,7 @@ where
let Some(args_types) = decl
.parameters
.iter()
.map(|x| Self::generate_type(engines, x.type_argument.type_id))
.map(|x| Self::generate_type(engines, &x.type_argument))
.collect::<Option<Vec<String>>>()
else {
let err = handler.emit_err(CompileError::UnknownType {
Expand All @@ -638,7 +561,7 @@ where
)
.collect::<String>();

let Some(return_type) = Self::generate_type(engines, decl.return_type.type_id) else {
let Some(return_type) = Self::generate_type(engines, &decl.return_type) else {
let err = handler.emit_err(CompileError::UnknownType {
span: Span::dummy(),
});
Expand Down Expand Up @@ -674,8 +597,7 @@ where

let fallback = if let Some(fallback_fn) = fallback_fn {
let fallback_fn = engines.de().get(&fallback_fn);
let Some(return_type) = Self::generate_type(engines, fallback_fn.return_type.type_id)
else {
let Some(return_type) = Self::generate_type(engines, &fallback_fn.return_type) else {
let err = handler.emit_err(CompileError::UnknownType {
span: Span::dummy(),
});
Expand Down Expand Up @@ -743,7 +665,7 @@ where
let Some(args_types) = decl
.parameters
.iter()
.map(|x| Self::generate_type(engines, x.type_argument.type_id))
.map(|x| Self::generate_type(engines, &x.type_argument))
.collect::<Option<Vec<String>>>()
else {
let err = handler.emit_err(CompileError::UnknownType {
Expand Down Expand Up @@ -836,7 +758,7 @@ where
let Some(args_types) = decl
.parameters
.iter()
.map(|x| Self::generate_type(engines, x.type_argument.type_id))
.map(|x| Self::generate_type(engines, &x.type_argument))
.collect::<Option<Vec<String>>>()
else {
let err = handler.emit_err(CompileError::UnknownType {
Expand All @@ -860,7 +782,7 @@ where
)
.collect::<String>();

let Some(return_type) = Self::generate_type(engines, decl.return_type.type_id) else {
let Some(return_type) = Self::generate_type(engines, &decl.return_type) else {
let err = handler.emit_err(CompileError::UnknownType {
span: Span::dummy(),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ license = "Apache-2.0"
name = "main_args_various_types"

[dependencies]
std = { path = "../../../../../reduced_std_libs/sway-lib-std-assert" }
std = { path = "../../../../../../../../sway-lib-std" }
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"type": "[(struct OpName, enum SignedNum); 2]"
},
{
"concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
"type": "u64"
"concreteTypeId": "d489af6a272dc02bb98c58446e5250345c65721ecfef3f43b26c263819725668",
"type": "generic AliasedS"
}
],
"configurables": [],
Expand All @@ -22,7 +22,7 @@
}
],
"name": "main",
"output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
"output": "d489af6a272dc02bb98c58446e5250345c65721ecfef3f43b26c263819725668"
}
],
"loggedTypes": [
Expand Down Expand Up @@ -61,11 +61,11 @@
"components": [
{
"name": "Positive",
"typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
"typeId": 5
},
{
"name": "Negative",
"typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
"typeId": 5
}
],
"metadataTypeId": 2,
Expand All @@ -84,6 +84,10 @@
],
"metadataTypeId": 4,
"type": "struct OpName"
},
{
"metadataTypeId": 5,
"type": "u64"
}
],
"programType": "script",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
script;

mod types;

use types::{S as AliasedS};

fn eq_str_3(a: str[3], b: str) -> bool {
let ptr_b = b.as_ptr();
asm(a: a, b: ptr_b, len: 3, r) {
Expand All @@ -17,7 +21,7 @@ struct OpName {
val: str[3]
}

fn main(ops: [(OpName, SignedNum); 2]) -> u64 {
fn main(ops: [(OpName, SignedNum); 2]) -> AliasedS {
__log(ops);
assert(eq_str_3(ops[0].0.val, "set"));
assert(match ops[0].1 {
Expand All @@ -31,5 +35,7 @@ fn main(ops: [(OpName, SignedNum); 2]) -> u64 {
_ => revert(2),
} == 1);

1
AliasedS{
v: 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
library;

pub struct S {
pub v: u64
}
Loading