mirror of
https://github.com/FuelLabs/sway.git
synced 2025-08-13 23:28:46 +00:00
Support for aliased import for encoding v1 (#6628)
## Description Fixes https://github.com/FuelLabs/sway/issues/6569 ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] 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). - [ ] I have requested a review from the relevant team or maintainers.
This commit is contained in:
parent
278bb8cd19
commit
64d1c6ec2b
5 changed files with 43 additions and 106 deletions
|
@ -8,14 +8,14 @@ use crate::{
|
||||||
Purity,
|
Purity,
|
||||||
},
|
},
|
||||||
semantic_analysis::TypeCheckContext,
|
semantic_analysis::TypeCheckContext,
|
||||||
Engines, TypeId, TypeInfo, TypeParameter,
|
Engines, TypeArgument, TypeInfo, TypeParameter,
|
||||||
};
|
};
|
||||||
use sway_error::{
|
use sway_error::{
|
||||||
error::CompileError,
|
error::CompileError,
|
||||||
handler::{ErrorEmitted, Handler},
|
handler::{ErrorEmitted, Handler},
|
||||||
};
|
};
|
||||||
use sway_parse::Parse;
|
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
|
/// Contains all information needed to implement AbiEncode
|
||||||
pub struct EncodingAutoImplContext<'a, 'b>
|
pub struct EncodingAutoImplContext<'a, 'b>
|
||||||
|
@ -38,7 +38,7 @@ where
|
||||||
T: Parse,
|
T: Parse,
|
||||||
{
|
{
|
||||||
// Uncomment this to see what is being generated
|
// Uncomment this to see what is being generated
|
||||||
//println!("{}", input);
|
// println!("{}", input);
|
||||||
|
|
||||||
let handler = <_>::default();
|
let handler = <_>::default();
|
||||||
let source_id =
|
let source_id =
|
||||||
|
@ -195,7 +195,7 @@ where
|
||||||
code.push_str(&format!(
|
code.push_str(&format!(
|
||||||
"{field_name}: buffer.decode::<{field_type_name}>(),",
|
"{field_name}: buffer.decode::<{field_type_name}>(),",
|
||||||
field_name = f.name.as_str(),
|
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)?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ where
|
||||||
format!("{} => {}::{}, \n", x.tag, enum_name, name)
|
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",
|
format!("{tag_value} => {enum_name}::{variant_name}(buffer.decode::<{variant_type}>()), \n",
|
||||||
tag_value = x.tag,
|
tag_value = x.tag,
|
||||||
enum_name = enum_name,
|
enum_name = enum_name,
|
||||||
|
@ -496,92 +496,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_type(engines: &Engines, type_id: TypeId) -> Option<String> {
|
// The safest way would be to return a canonical fully qualified type path.
|
||||||
let name = match &*engines.te().get(type_id) {
|
// We do not have a way to do this at the moment, so the best way is to use
|
||||||
TypeInfo::UnknownGeneric { name, .. } => name.to_string(),
|
// exactly what was typed by the user, to accommodate aliased imports.
|
||||||
TypeInfo::Placeholder(type_param) => type_param.name.to_string(),
|
fn generate_type(engines: &Engines, t: &TypeArgument) -> Option<String> {
|
||||||
TypeInfo::StringSlice => "str".into(),
|
match &*engines.te().get(t.type_id) {
|
||||||
TypeInfo::StringArray(x) => format!("str[{}]", x.val()),
|
// when a function does not define a return type, the span points to the whole signature.
|
||||||
TypeInfo::UnsignedInteger(x) => match x {
|
TypeInfo::Tuple(v) if v.is_empty() => Some("()".into()),
|
||||||
IntegerBits::Eight => "u8",
|
_ => Some(t.span().as_str().to_string()),
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn generate_contract_entry(
|
pub(crate) fn generate_contract_entry(
|
||||||
|
@ -613,7 +536,7 @@ where
|
||||||
let Some(args_types) = decl
|
let Some(args_types) = decl
|
||||||
.parameters
|
.parameters
|
||||||
.iter()
|
.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>>>()
|
.collect::<Option<Vec<String>>>()
|
||||||
else {
|
else {
|
||||||
let err = handler.emit_err(CompileError::UnknownType {
|
let err = handler.emit_err(CompileError::UnknownType {
|
||||||
|
@ -638,7 +561,7 @@ where
|
||||||
)
|
)
|
||||||
.collect::<String>();
|
.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 {
|
let err = handler.emit_err(CompileError::UnknownType {
|
||||||
span: Span::dummy(),
|
span: Span::dummy(),
|
||||||
});
|
});
|
||||||
|
@ -674,8 +597,7 @@ where
|
||||||
|
|
||||||
let fallback = if let Some(fallback_fn) = fallback_fn {
|
let fallback = if let Some(fallback_fn) = fallback_fn {
|
||||||
let fallback_fn = engines.de().get(&fallback_fn);
|
let fallback_fn = engines.de().get(&fallback_fn);
|
||||||
let Some(return_type) = Self::generate_type(engines, fallback_fn.return_type.type_id)
|
let Some(return_type) = Self::generate_type(engines, &fallback_fn.return_type) else {
|
||||||
else {
|
|
||||||
let err = handler.emit_err(CompileError::UnknownType {
|
let err = handler.emit_err(CompileError::UnknownType {
|
||||||
span: Span::dummy(),
|
span: Span::dummy(),
|
||||||
});
|
});
|
||||||
|
@ -743,7 +665,7 @@ where
|
||||||
let Some(args_types) = decl
|
let Some(args_types) = decl
|
||||||
.parameters
|
.parameters
|
||||||
.iter()
|
.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>>>()
|
.collect::<Option<Vec<String>>>()
|
||||||
else {
|
else {
|
||||||
let err = handler.emit_err(CompileError::UnknownType {
|
let err = handler.emit_err(CompileError::UnknownType {
|
||||||
|
@ -836,7 +758,7 @@ where
|
||||||
let Some(args_types) = decl
|
let Some(args_types) = decl
|
||||||
.parameters
|
.parameters
|
||||||
.iter()
|
.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>>>()
|
.collect::<Option<Vec<String>>>()
|
||||||
else {
|
else {
|
||||||
let err = handler.emit_err(CompileError::UnknownType {
|
let err = handler.emit_err(CompileError::UnknownType {
|
||||||
|
@ -860,7 +782,7 @@ where
|
||||||
)
|
)
|
||||||
.collect::<String>();
|
.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 {
|
let err = handler.emit_err(CompileError::UnknownType {
|
||||||
span: Span::dummy(),
|
span: Span::dummy(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,4 +5,4 @@ license = "Apache-2.0"
|
||||||
name = "main_args_various_types"
|
name = "main_args_various_types"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
std = { path = "../../../../../reduced_std_libs/sway-lib-std-assert" }
|
std = { path = "../../../../../../../../sway-lib-std" }
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
"type": "[(struct OpName, enum SignedNum); 2]"
|
"type": "[(struct OpName, enum SignedNum); 2]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
|
"concreteTypeId": "d489af6a272dc02bb98c58446e5250345c65721ecfef3f43b26c263819725668",
|
||||||
"type": "u64"
|
"type": "generic AliasedS"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"configurables": [],
|
"configurables": [],
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "main",
|
"name": "main",
|
||||||
"output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
|
"output": "d489af6a272dc02bb98c58446e5250345c65721ecfef3f43b26c263819725668"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"loggedTypes": [
|
"loggedTypes": [
|
||||||
|
@ -61,11 +61,11 @@
|
||||||
"components": [
|
"components": [
|
||||||
{
|
{
|
||||||
"name": "Positive",
|
"name": "Positive",
|
||||||
"typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
|
"typeId": 5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Negative",
|
"name": "Negative",
|
||||||
"typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
|
"typeId": 5
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadataTypeId": 2,
|
"metadataTypeId": 2,
|
||||||
|
@ -84,6 +84,10 @@
|
||||||
],
|
],
|
||||||
"metadataTypeId": 4,
|
"metadataTypeId": 4,
|
||||||
"type": "struct OpName"
|
"type": "struct OpName"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"metadataTypeId": 5,
|
||||||
|
"type": "u64"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"programType": "script",
|
"programType": "script",
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
script;
|
script;
|
||||||
|
|
||||||
|
mod types;
|
||||||
|
|
||||||
|
use types::{S as AliasedS};
|
||||||
|
|
||||||
fn eq_str_3(a: str[3], b: str) -> bool {
|
fn eq_str_3(a: str[3], b: str) -> bool {
|
||||||
let ptr_b = b.as_ptr();
|
let ptr_b = b.as_ptr();
|
||||||
asm(a: a, b: ptr_b, len: 3, r) {
|
asm(a: a, b: ptr_b, len: 3, r) {
|
||||||
|
@ -17,7 +21,7 @@ struct OpName {
|
||||||
val: str[3]
|
val: str[3]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main(ops: [(OpName, SignedNum); 2]) -> u64 {
|
fn main(ops: [(OpName, SignedNum); 2]) -> AliasedS {
|
||||||
__log(ops);
|
__log(ops);
|
||||||
assert(eq_str_3(ops[0].0.val, "set"));
|
assert(eq_str_3(ops[0].0.val, "set"));
|
||||||
assert(match ops[0].1 {
|
assert(match ops[0].1 {
|
||||||
|
@ -31,5 +35,7 @@ fn main(ops: [(OpName, SignedNum); 2]) -> u64 {
|
||||||
_ => revert(2),
|
_ => revert(2),
|
||||||
} == 1);
|
} == 1);
|
||||||
|
|
||||||
1
|
AliasedS{
|
||||||
|
v: 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
library;
|
||||||
|
|
||||||
|
pub struct S {
|
||||||
|
pub v: u64
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue