diff --git a/Cargo.lock b/Cargo.lock index bddd41f71ff..55685f0adc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1995,7 +1995,7 @@ dependencies = [ "forc-tx", "forc-util", "forc-wallet", - "fuel-abi-types 0.3.0", + "fuel-abi-types 0.4.0", "fuel-core-client 0.22.0", "fuel-crypto", "fuel-tx", @@ -2121,7 +2121,7 @@ dependencies = [ "cid", "forc-tracing 0.49.1", "forc-util", - "fuel-abi-types 0.1.0", + "fuel-abi-types 0.4.0", "futures", "git2", "gix-url", @@ -2154,7 +2154,7 @@ version = "0.49.1" dependencies = [ "anyhow", "forc-pkg", - "fuel-abi-types 0.2.1", + "fuel-abi-types 0.4.0", "fuel-tx", "fuel-vm", "rand", @@ -2292,32 +2292,26 @@ dependencies = [ [[package]] name = "fuel-abi-types" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af523c38969b431b33b06a82756659c9a07ea9aa185cb8a770c15fd5c95a0da6" -dependencies = [ - "proc-macro2", - "serde", - "strum_macros 0.21.1", -] - -[[package]] -name = "fuel-abi-types" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d99a7aeb41cdabffa38418b00fd57b5571dc58ee5af606e845a088befecd36" +checksum = "f8118789261e77d67569859a06a886d53dbf7bd00ea23a18a2dfae26a1f5be25" dependencies = [ + "itertools 0.10.5", "lazy_static", + "proc-macro2", + "quote", "regex", "serde", + "serde_json", + "syn 2.0.48", "thiserror", ] [[package]] name = "fuel-abi-types" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8118789261e77d67569859a06a886d53dbf7bd00ea23a18a2dfae26a1f5be25" +checksum = "2351bb0b743c23ac13ac2559756b3929502cd6e29091f2e5302fb9a1bdddaf35" dependencies = [ "itertools 0.10.5", "lazy_static", @@ -2645,7 +2639,7 @@ dependencies = [ "serde", "serde_json", "strum", - "strum_macros 0.24.3", + "strum_macros", ] [[package]] @@ -6429,19 +6423,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" dependencies = [ - "strum_macros 0.24.3", -] - -[[package]] -name = "strum_macros" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn 1.0.109", + "strum_macros", ] [[package]] @@ -6496,7 +6478,7 @@ dependencies = [ "derivative", "dirs 3.0.2", "either", - "fuel-abi-types 0.1.0", + "fuel-abi-types 0.4.0", "fuel-ethabi", "fuel-etk-asm", "fuel-etk-dasm", diff --git a/Cargo.toml b/Cargo.toml index 662c320ebd9..33d68b5d837 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,9 @@ fuels-accounts = "0.54.0" # Dependencies from the `forc-wallet` repository: forc-wallet = "0.4.2" +# Dependencies from the `fuel-abi-types` repository: +fuel-abi-types = "0.4.0" + [workspace.package] edition = "2021" authors = ["Fuel Labs "] diff --git a/forc-pkg/Cargo.toml b/forc-pkg/Cargo.toml index 77b6699993e..1f564f697de 100644 --- a/forc-pkg/Cargo.toml +++ b/forc-pkg/Cargo.toml @@ -14,7 +14,7 @@ anyhow = "1" cid = "0.10" forc-tracing = { version = "0.49.1", path = "../forc-tracing" } forc-util = { version = "0.49.1", path = "../forc-util" } -fuel-abi-types = "0.1" +fuel-abi-types = { workspace = true } futures = "0.3" git2 = { version = "0.17.2", features = [ "vendored-libgit2", diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index d6436bf21eb..9aa3554f1fe 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -11,7 +11,7 @@ use forc_util::{ default_output_directory, find_file_name, kebab_to_snake_case, print_compiling, print_on_failure, print_warnings, }; -use fuel_abi_types::program_abi; +use fuel_abi_types::abi::program as program_abi; use petgraph::{ self, dot, visit::{Bfs, Dfs, EdgeRef, Walker}, @@ -1821,6 +1821,8 @@ pub fn compile( metrics ); + const NEW_ENCODING_VERSION: &str = "1"; + let mut program_abi = match pkg.target { BuildTarget::Fuel => { let mut types = vec![]; @@ -1834,7 +1836,11 @@ pub fn compile( }, engines.te(), engines.de(), - &mut types + &mut types, + profile + .experimental + .new_encoding + .then(|| NEW_ENCODING_VERSION.into()), ), Some(sway_build_config.clone()), metrics diff --git a/forc-plugins/forc-client/Cargo.toml b/forc-plugins/forc-client/Cargo.toml index 88fddff5265..68d793b954e 100644 --- a/forc-plugins/forc-client/Cargo.toml +++ b/forc-plugins/forc-client/Cargo.toml @@ -20,7 +20,7 @@ forc-tracing = { version = "0.49.1", path = "../../forc-tracing" } forc-tx = { version = "0.49.1", path = "../forc-tx" } forc-util = { version = "0.49.1", path = "../../forc-util" } forc-wallet = { workspace = true } -fuel-abi-types = "0.3" +fuel-abi-types = { workspace = true } fuel-core-client = { workspace = true, features = ["subscriptions"] } fuel-crypto = { workspace = true } fuel-tx = { workspace = true, features = ["builder"] } diff --git a/forc-test/Cargo.toml b/forc-test/Cargo.toml index 53459492413..239324236d4 100644 --- a/forc-test/Cargo.toml +++ b/forc-test/Cargo.toml @@ -11,7 +11,7 @@ repository.workspace = true [dependencies] anyhow = "1" forc-pkg = { version = "0.49.1", path = "../forc-pkg" } -fuel-abi-types = "0.2" +fuel-abi-types = { workspace = true } fuel-tx = { workspace = true, features = ["builder"] } fuel-vm = { workspace = true, features = ["random"] } rand = "0.8" diff --git a/forc/src/cli/commands/build.rs b/forc/src/cli/commands/build.rs index ea87576d0ff..183d77e1764 100644 --- a/forc/src/cli/commands/build.rs +++ b/forc/src/cli/commands/build.rs @@ -32,7 +32,7 @@ pub struct Command { pub tests: bool, #[clap(long)] - /// Experimental flags for the "new encoding" feature + /// Experimental flag for the "new encoding" feature pub experimental_new_encoding: bool, } diff --git a/forc/src/cli/commands/contract_id.rs b/forc/src/cli/commands/contract_id.rs index a9140e1acc6..9347a4b05e6 100644 --- a/forc/src/cli/commands/contract_id.rs +++ b/forc/src/cli/commands/contract_id.rs @@ -22,7 +22,7 @@ pub struct Command { pub salt: Salt, #[clap(long)] - /// Experimental flags for the "new encoding" feature + /// Experimental flag for the "new encoding" feature pub experimental_new_encoding: bool, } diff --git a/forc/src/cli/commands/predicate_root.rs b/forc/src/cli/commands/predicate_root.rs index d05a770da53..d011025a1fe 100644 --- a/forc/src/cli/commands/predicate_root.rs +++ b/forc/src/cli/commands/predicate_root.rs @@ -20,7 +20,7 @@ pub struct Command { pub build_profile: BuildProfile, #[clap(long)] - /// Experimental flags for the "new encoding" feature + /// Experimental flag for the "new encoding" feature pub experimental_new_encoding: bool, } diff --git a/forc/src/cli/commands/test.rs b/forc/src/cli/commands/test.rs index f0587402b1a..34f1b459e48 100644 --- a/forc/src/cli/commands/test.rs +++ b/forc/src/cli/commands/test.rs @@ -48,7 +48,7 @@ pub struct Command { pub test_threads: Option, #[clap(long)] - /// Experimental flags for the "new encoding" feature + /// Experimental flag for the "new encoding" feature pub experimental_new_encoding: bool, } diff --git a/sway-core/Cargo.toml b/sway-core/Cargo.toml index ae944959956..8db4dbdc121 100644 --- a/sway-core/Cargo.toml +++ b/sway-core/Cargo.toml @@ -19,7 +19,7 @@ etk-asm = { package = "fuel-etk-asm", version = "0.3.1-dev", features = [ ] } etk-dasm = { package = "fuel-etk-dasm", version = "0.3.1-dev" } etk-ops = { package = "fuel-etk-ops", version = "0.3.1-dev" } -fuel-abi-types = "0.1" +fuel-abi-types = { workspace = true } fuel-vm = { workspace = true, features = ["serde"] } graph-cycles = "0.1.0" hashbrown = "0.13.1" diff --git a/sway-core/src/abi_generation/fuel_abi.rs b/sway-core/src/abi_generation/fuel_abi.rs index edd970761ed..5d6185847a6 100644 --- a/sway-core/src/abi_generation/fuel_abi.rs +++ b/sway-core/src/abi_generation/fuel_abi.rs @@ -1,4 +1,4 @@ -use fuel_abi_types::program_abi; +use fuel_abi_types::abi::program as program_abi; use sway_types::integer_bits::IntegerBits; use crate::{ @@ -21,6 +21,7 @@ pub fn generate_program_abi( type_engine: &TypeEngine, decl_engine: &DeclEngine, types: &mut Vec, + encoding: Option, ) -> program_abi::ProgramABI { match &ctx.program.kind { TyProgramKind::Contract { abi_entries, .. } => { @@ -35,6 +36,7 @@ pub fn generate_program_abi( let messages_types = generate_messages_types(ctx, type_engine, decl_engine, types); let configurables = generate_configurables(ctx, type_engine, decl_engine, types); program_abi::ProgramABI { + encoding, types: types.to_vec(), functions, logged_types: Some(logged_types), @@ -51,6 +53,7 @@ pub fn generate_program_abi( let messages_types = generate_messages_types(ctx, type_engine, decl_engine, types); let configurables = generate_configurables(ctx, type_engine, decl_engine, types); program_abi::ProgramABI { + encoding, types: types.to_vec(), functions, logged_types: Some(logged_types), @@ -59,6 +62,7 @@ pub fn generate_program_abi( } } _ => program_abi::ProgramABI { + encoding, types: vec![], functions: vec![], logged_types: None, diff --git a/sway-core/src/asm_generation/abi.rs b/sway-core/src/asm_generation/abi.rs index 4dd5e2bc28a..b4a769fac69 100644 --- a/sway-core/src/asm_generation/abi.rs +++ b/sway-core/src/asm_generation/abi.rs @@ -2,7 +2,7 @@ use super::EvmAbiResult; #[derive(Clone, Debug)] pub enum ProgramABI { - Fuel(fuel_abi_types::program_abi::ProgramABI), + Fuel(fuel_abi_types::abi::program::ProgramABI), Evm(EvmAbiResult), MidenVM(()), } diff --git a/sway-core/src/semantic_analysis/program.rs b/sway-core/src/semantic_analysis/program.rs index 98dc6f0524c..3ccba467d3e 100644 --- a/sway-core/src/semantic_analysis/program.rs +++ b/sway-core/src/semantic_analysis/program.rs @@ -32,14 +32,9 @@ impl TyProgram { build_config: Option<&BuildConfig>, ) -> Result { let mut namespace = Namespace::init_root(initial_namespace); - let ctx = - TypeCheckContext::from_root(&mut namespace, engines).with_kind(parsed.kind.clone()); - - let ctx = if let Some(build_config) = build_config { - ctx.with_experimental_flags(build_config.experimental) - } else { - ctx - }; + let ctx = TypeCheckContext::from_root(&mut namespace, engines) + .with_kind(parsed.kind.clone()) + .with_experimental_flags(build_config.map(|x| x.experimental)); let ParseProgram { root, kind } = parsed; diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 000356f20f7..c2040b77dd0 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -1538,7 +1538,11 @@ impl<'a> TypeCheckContext<'a> { .insert_for_type(self.engines, type_id); } - pub(crate) fn with_experimental_flags(self, experimental: ExperimentalFlags) -> Self { + pub(crate) fn with_experimental_flags(self, experimental: Option) -> Self { + let Some(experimental) = experimental else { + return self; + }; + Self { experimental, ..self diff --git a/sway-core/src/transform/attribute.rs b/sway-core/src/transform/attribute.rs index cfdd5567601..cbebf8449ea 100644 --- a/sway-core/src/transform/attribute.rs +++ b/sway-core/src/transform/attribute.rs @@ -23,7 +23,8 @@ use sway_ast::Literal; use sway_types::{ constants::{ - ALLOW_DEAD_CODE_NAME, ALLOW_DEPRECATED_NAME, CFG_PROGRAM_TYPE_ARG_NAME, CFG_TARGET_ARG_NAME, + ALLOW_DEAD_CODE_NAME, ALLOW_DEPRECATED_NAME, CFG_EXPERIMENTAL_NEW_ENCODING, + CFG_PROGRAM_TYPE_ARG_NAME, CFG_TARGET_ARG_NAME, }, Ident, Span, Spanned, }; @@ -100,6 +101,7 @@ impl AttributeKind { AttributeKind::Cfg => Some(vec![ CFG_TARGET_ARG_NAME.to_string(), CFG_PROGRAM_TYPE_ARG_NAME.to_string(), + CFG_EXPERIMENTAL_NEW_ENCODING.to_string(), ]), AttributeKind::Deprecated => None, } diff --git a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs index 8fcedefb7b7..593ea6b912d 100644 --- a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs +++ b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs @@ -6,7 +6,7 @@ use crate::{ language::{parsed::*, *}, transform::{attribute::*, to_parsed_lang::context::Context}, type_system::*, - BuildTarget, Engines, + BuildTarget, Engines, ExperimentalFlags, }; use itertools::Itertools; @@ -28,11 +28,11 @@ use sway_error::handler::{ErrorEmitted, Handler}; use sway_error::warning::{CompileWarning, Warning}; use sway_types::{ constants::{ - ALLOW_ATTRIBUTE_NAME, CFG_ATTRIBUTE_NAME, CFG_PROGRAM_TYPE_ARG_NAME, CFG_TARGET_ARG_NAME, - DEPRECATED_ATTRIBUTE_NAME, DOC_ATTRIBUTE_NAME, DOC_COMMENT_ATTRIBUTE_NAME, - INLINE_ATTRIBUTE_NAME, PAYABLE_ATTRIBUTE_NAME, STORAGE_PURITY_ATTRIBUTE_NAME, - STORAGE_PURITY_READ_NAME, STORAGE_PURITY_WRITE_NAME, TEST_ATTRIBUTE_NAME, - VALID_ATTRIBUTE_NAMES, + ALLOW_ATTRIBUTE_NAME, CFG_ATTRIBUTE_NAME, CFG_EXPERIMENTAL_NEW_ENCODING, + CFG_PROGRAM_TYPE_ARG_NAME, CFG_TARGET_ARG_NAME, DEPRECATED_ATTRIBUTE_NAME, + DOC_ATTRIBUTE_NAME, DOC_COMMENT_ATTRIBUTE_NAME, INLINE_ATTRIBUTE_NAME, + PAYABLE_ATTRIBUTE_NAME, STORAGE_PURITY_ATTRIBUTE_NAME, STORAGE_PURITY_READ_NAME, + STORAGE_PURITY_WRITE_NAME, TEST_ATTRIBUTE_NAME, VALID_ATTRIBUTE_NAMES, }, integer_bits::IntegerBits, }; @@ -108,7 +108,7 @@ fn item_to_ast_nodes( prev_item: Option>, ) -> Result, ErrorEmitted> { let attributes = item_attrs_to_map(context, handler, &item.attribute_list)?; - if !cfg_eval(context, handler, &attributes)? { + if !cfg_eval(context, handler, &attributes, context.experimental)? { return Ok(vec![]); } @@ -349,7 +349,7 @@ fn item_struct_to_struct_declaration( .into_iter() .map(|type_field| { let attributes = item_attrs_to_map(context, handler, &type_field.attribute_list)?; - if !cfg_eval(context, handler, &attributes)? { + if !cfg_eval(context, handler, &attributes, context.experimental)? { return Ok(None); } Ok(Some(type_field_to_struct_field( @@ -417,7 +417,7 @@ fn item_enum_to_enum_declaration( .enumerate() .map(|(tag, type_field)| { let attributes = item_attrs_to_map(context, handler, &type_field.attribute_list)?; - if !cfg_eval(context, handler, &attributes)? { + if !cfg_eval(context, handler, &attributes, context.experimental)? { return Ok(None); } Ok(Some(type_field_to_enum_variant( @@ -603,7 +603,7 @@ fn item_trait_to_trait_declaration( .into_iter() .map(|annotated| { let attributes = item_attrs_to_map(context, handler, &annotated.attribute_list)?; - if !cfg_eval(context, handler, &attributes)? { + if !cfg_eval(context, handler, &attributes, context.experimental)? { return Ok(None); } Ok(Some(match annotated.value { @@ -631,7 +631,7 @@ fn item_trait_to_trait_declaration( .into_iter() .map(|item_fn| { let attributes = item_attrs_to_map(context, handler, &item_fn.attribute_list)?; - if !cfg_eval(context, handler, &attributes)? { + if !cfg_eval(context, handler, &attributes, context.experimental)? { return Ok(None); } Ok(Some(item_fn_to_function_declaration( @@ -678,7 +678,7 @@ fn item_impl_to_declaration( .into_iter() .map(|item| { let attributes = item_attrs_to_map(context, handler, &item.attribute_list)?; - if !cfg_eval(context, handler, &attributes)? { + if !cfg_eval(context, handler, &attributes, context.experimental)? { return Ok(None); } Ok(Some(match item.value { @@ -792,7 +792,7 @@ fn item_abi_to_abi_declaration( .map(|annotated| { let attributes = item_attrs_to_map(context, handler, &annotated.attribute_list)?; - if !cfg_eval(context, handler, &attributes)? { + if !cfg_eval(context, handler, &attributes, context.experimental)? { return Ok(None); } Ok(Some(match annotated.value { @@ -838,7 +838,7 @@ fn item_abi_to_abi_declaration( .into_iter() .map(|item_fn| { let attributes = item_attrs_to_map(context, handler, &item_fn.attribute_list)?; - if !cfg_eval(context, handler, &attributes)? { + if !cfg_eval(context, handler, &attributes, context.experimental)? { return Ok(None); } let function_declaration = item_fn_to_function_declaration( @@ -951,7 +951,7 @@ fn item_storage_to_storage_declaration( .into_iter() .map(|storage_field| { let attributes = item_attrs_to_map(context, handler, &storage_field.attribute_list)?; - if !cfg_eval(context, handler, &attributes)? { + if !cfg_eval(context, handler, &attributes, context.experimental)? { return Ok(None); } Ok(Some(storage_field_to_storage_field( @@ -1011,7 +1011,7 @@ fn item_configurable_to_constant_declarations( .map(|configurable_field| { let attributes = item_attrs_to_map(context, handler, &configurable_field.attribute_list)?; - if !cfg_eval(context, handler, &attributes)? { + if !cfg_eval(context, handler, &attributes, context.experimental)? { return Ok(None); } Ok(Some(configurable_field_to_constant_declaration( @@ -4331,6 +4331,7 @@ pub fn cfg_eval( context: &Context, handler: &Handler, attrs_map: &AttributesMap, + experimental: ExperimentalFlags, ) -> Result { if let Some(cfg_attrs) = attrs_map.get(&AttributeKind::Cfg) { for cfg_attr in cfg_attrs { @@ -4396,6 +4397,19 @@ pub fn cfg_eval( return Err(handler.emit_err(error.into())); } } + CFG_EXPERIMENTAL_NEW_ENCODING => match &arg.value { + Some(sway_ast::Literal::Bool(v)) => { + let is_true = matches!(v.kind, sway_ast::literal::LitBoolType::True); + return Ok(experimental.new_encoding == is_true); + } + _ => { + let error = + ConvertParseTreeError::ExpectedExperimentalNewEncodingArgValue { + span: arg.span(), + }; + return Err(handler.emit_err(error.into())); + } + }, _ => { // Already checked with `AttributeKind::expected_args_*` unreachable!("cfg attribute should only have the `target` or the `program_type` argument"); diff --git a/sway-core/src/type_system/id.rs b/sway-core/src/type_system/id.rs index 52f4efe6e5f..c80d19f2e39 100644 --- a/sway-core/src/type_system/id.rs +++ b/sway-core/src/type_system/id.rs @@ -15,6 +15,8 @@ use std::{ fmt, }; +const EXTRACT_ANY_MAX_DEPTH: usize = 128; + /// A identifier to uniquely refer to our type terms #[derive(PartialEq, Eq, Hash, Clone, Copy, Ord, PartialOrd, Debug)] pub struct TypeId(usize); @@ -190,8 +192,8 @@ impl TypeId { where F: Fn(&TypeInfo) -> bool, { - if depth >= 128 { - panic!("possible infinite recursion at extract_any"); + if depth >= EXTRACT_ANY_MAX_DEPTH { + panic!("Possible infinite recursion at extract_any"); } fn extend( diff --git a/sway-error/src/convert_parse_tree_error.rs b/sway-error/src/convert_parse_tree_error.rs index 8bc84c100e0..992a310326e 100644 --- a/sway-error/src/convert_parse_tree_error.rs +++ b/sway-error/src/convert_parse_tree_error.rs @@ -117,6 +117,8 @@ pub enum ConvertParseTreeError { InvalidCfgProgramTypeArgValue { span: Span, value: String }, #[error("Expected a value for the program_type argument")] ExpectedCfgProgramTypeArgValue { span: Span }, + #[error("Expected \"true\" or \"false\" for experimental_new_encoding")] + ExpectedExperimentalNewEncodingArgValue { span: Span }, } impl Spanned for ConvertParseTreeError { @@ -179,6 +181,7 @@ impl Spanned for ConvertParseTreeError { ConvertParseTreeError::ExpectedCfgTargetArgValue { span } => span.clone(), ConvertParseTreeError::InvalidCfgProgramTypeArgValue { span, .. } => span.clone(), ConvertParseTreeError::ExpectedCfgProgramTypeArgValue { span } => span.clone(), + ConvertParseTreeError::ExpectedExperimentalNewEncodingArgValue { span } => span.clone(), } } } diff --git a/sway-lib-core/src/codec.sw b/sway-lib-core/src/codec.sw index 505ba82ca7f..56f6f1e7db3 100644 --- a/sway-lib-core/src/codec.sw +++ b/sway-lib-core/src/codec.sw @@ -271,14 +271,7 @@ impl AbiEncode for str[5] { } } -// arrays - -impl AbiEncode for [T; 0] -where - T: AbiEncode, -{ - fn abi_encode(self, ref mut _buffer: Buffer) {} -} +// arrays and slices impl AbiEncode for [T; 1] where @@ -402,16 +395,116 @@ where buffer.as_raw_slice() } -#[test] -fn ok_encode() { - let _ = encode(true); +fn assert_encoding(value: T, expected: SLICE) +where + T: AbiEncode, +{ + let len = __size_of::(); + + if len == 0 { + __revert(0); + } + + let expected = raw_slice::from_parts::(__addr_of(expected), len); + let actual = encode(value); + + if actual.len::() != expected.len::() { + __revert(0); + } - let _ = encode(0u8); - let _ = encode(0u16); - let _ = encode(0u32); - let _ = encode(0u64); - let _ = encode(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFu256); + let result = asm( + result, + expected: expected.ptr(), + actual: actual.ptr(), + len: len, + ) { + meq result expected actual len; + result: bool + }; + + if !result { + __revert(0); + } +} - // b256 - let _ = encode(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); +#[test] +fn ok_encode() { + // bool + assert_encoding(false, [0u8]); + assert_encoding(true, [1u8]); + + // numbers + assert_encoding(0u8, [0u8; 1]); + assert_encoding(255u8, [255u8; 1]); + assert_encoding(0u16, [0u8; 2]); + assert_encoding(65535u16, [255u8; 2]); + assert_encoding(0u32, [0u8; 4]); + assert_encoding(4294967295u32, [255u8; 4]); + assert_encoding(0u64, [0u8; 8]); + assert_encoding(18446744073709551615u64, [255u8; 8]); + assert_encoding( + 0x0000000000000000000000000000000000000000000000000000000000000000u256, + [0u8; 32], + ); + assert_encoding( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFu256, + [255u8; 32], + ); + assert_encoding( + 0x0000000000000000000000000000000000000000000000000000000000000000, + [0u8; 32], + ); + assert_encoding( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, + [255u8; 32], + ); + + // strings + assert_encoding( + "Hello", + [0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 72u8, 101u8, 108u8, 108u8, 111u8], + ); + + assert_encoding( + { + let a: str[1] = __to_str_array("a"); + a + }, + [97u8], + ); + assert_encoding( + { + let a: str[2] = __to_str_array("aa"); + a + }, + [97u8, 97u8], + ); + assert_encoding( + { + let a: str[3] = __to_str_array("aaa"); + a + }, + [97u8, 97u8, 97u8], + ); + assert_encoding( + { + let a: str[4] = __to_str_array("aaaa"); + a + }, + [97u8, 97u8, 97u8, 97u8], + ); + assert_encoding( + { + let a: str[5] = __to_str_array("aaaaa"); + a + }, + [97u8, 97u8, 97u8, 97u8, 97u8], + ); + + // arrays + assert_encoding([255u8; 1], [255u8; 1]); + assert_encoding([255u8; 2], [255u8; 2]); + assert_encoding([255u8; 3], [255u8; 3]); + assert_encoding([255u8; 4], [255u8; 4]); + assert_encoding([255u8; 5], [255u8; 5]); } diff --git a/sway-lib-std/src/logging.sw b/sway-lib-std/src/logging.sw index a7fe29a99e5..900e6f1045e 100644 --- a/sway-lib-std/src/logging.sw +++ b/sway-lib-std/src/logging.sw @@ -19,6 +19,12 @@ library; /// log("Fuel is blazingly fast"); /// } /// ``` +#[cfg(experimental_new_encoding = false)] +pub fn log(value: T) { + __log::(value); +} + +#[cfg(experimental_new_encoding = true)] pub fn log(value: T) where T: AbiEncode, diff --git a/sway-lib-std/src/revert.sw b/sway-lib-std/src/revert.sw index 29c58e5ad7e..04ba3f75bbd 100644 --- a/sway-lib-std/src/revert.sw +++ b/sway-lib-std/src/revert.sw @@ -53,6 +53,15 @@ pub fn revert(code: u64) { /// log("The require function did not revert"); /// } /// ``` +#[cfg(experimental_new_encoding = false)] +pub fn require(condition: bool, value: T) { + if !condition { + log(value); + revert(FAILED_REQUIRE_SIGNAL) + } +} + +#[cfg(experimental_new_encoding = true)] pub fn require(condition: bool, value: T) where T: AbiEncode, diff --git a/sway-parse/src/attribute.rs b/sway-parse/src/attribute.rs index fb77dd63c81..d6f683d06c0 100644 --- a/sway-parse/src/attribute.rs +++ b/sway-parse/src/attribute.rs @@ -4,11 +4,13 @@ use crate::{Parse, ParseBracket, ParseResult, ParseToEnd, Parser, ParserConsumed use sway_ast::attribute::{Annotated, Attribute, AttributeArg, AttributeDecl, AttributeHashKind}; use sway_ast::brackets::{Parens, SquareBrackets}; use sway_ast::keywords::{EqToken, HashBangToken, HashToken, StorageToken, Token}; +use sway_ast::literal::LitBool; use sway_ast::punctuated::Punctuated; use sway_ast::token::{DocComment, DocStyle}; +use sway_ast::Literal; use sway_error::parser_error::ParseErrorKind; use sway_types::constants::DOC_COMMENT_ATTRIBUTE_NAME; -use sway_types::Ident; +use sway_types::{Ident, Spanned}; impl Peek for DocComment { fn peek(peeker: Peeker<'_>) -> Option { @@ -125,7 +127,18 @@ impl Parse for AttributeArg { let name = parser.parse()?; match parser.take::() { Some(_) => { - let value = parser.parse()?; + let value = match parser.take::() { + Some(ident) if ident.as_str() == "true" => Literal::Bool(LitBool { + span: ident.span(), + kind: sway_ast::literal::LitBoolType::True, + }), + Some(ident) if ident.as_str() == "false" => Literal::Bool(LitBool { + span: ident.span(), + kind: sway_ast::literal::LitBoolType::False, + }), + _ => parser.parse()?, + }; + Ok(AttributeArg { name, value: Some(value), diff --git a/sway-types/src/constants.rs b/sway-types/src/constants.rs index 190da5a6b34..2c68a34da8b 100644 --- a/sway-types/src/constants.rs +++ b/sway-types/src/constants.rs @@ -49,6 +49,7 @@ pub const ALLOW_DEPRECATED_NAME: &str = "deprecated"; pub const CFG_ATTRIBUTE_NAME: &str = "cfg"; pub const CFG_TARGET_ARG_NAME: &str = "target"; pub const CFG_PROGRAM_TYPE_ARG_NAME: &str = "program_type"; +pub const CFG_EXPERIMENTAL_NEW_ENCODING: &str = "experimental_new_encoding"; pub const DEPRECATED_ATTRIBUTE_NAME: &str = "deprecated"; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/logging/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/logging/json_abi_oracle.json index e22b991d1e8..018c52f800b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/logging/json_abi_oracle.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/logging/json_abi_oracle.json @@ -7,7 +7,7 @@ "name": "main", "output": { "name": "", - "type": 13, + "type": 14, "typeArguments": null } } @@ -17,7 +17,7 @@ "logId": 0, "loggedType": { "name": "", - "type": 6, + "type": 7, "typeArguments": [] } }, @@ -25,11 +25,11 @@ "logId": 1, "loggedType": { "name": "", - "type": 7, + "type": 8, "typeArguments": [ { "name": "", - "type": 13, + "type": 14, "typeArguments": null } ] @@ -58,6 +58,22 @@ "type": 5, "typeArguments": [] } + }, + { + "logId": 5, + "loggedType": { + "name": "", + "type": 6, + "typeArguments": [] + } + }, + { + "logId": 6, + "loggedType": { + "name": "", + "type": 6, + "typeArguments": [] + } } ], "messagesTypes": [], @@ -72,11 +88,11 @@ "components": [ { "name": "A", - "type": 7, + "type": 8, "typeArguments": [ { "name": "", - "type": 13, + "type": 14, "typeArguments": null } ] @@ -115,35 +131,47 @@ "typeId": 5, "typeParameters": null }, + { + "components": [ + { + "name": "p", + "type": 3, + "typeArguments": null + } + ], + "type": "struct NotAutoEncodable", + "typeId": 6, + "typeParameters": null + }, { "components": [ { "name": "a", - "type": 13, + "type": 14, "typeArguments": null }, { "name": "b", - "type": 12, + "type": 13, "typeArguments": null }, { "name": "c", - "type": 10, + "type": 11, "typeArguments": null }, { "name": "d", - "type": 14, + "type": 15, "typeArguments": null }, { "name": "e", - "type": 9, + "type": 10, "typeArguments": [ { "name": "", - "type": 13, + "type": 14, "typeArguments": null } ] @@ -155,12 +183,12 @@ }, { "name": "g", - "type": 11, + "type": 12, "typeArguments": null } ], "type": "struct S", - "typeId": 6, + "typeId": 7, "typeParameters": null }, { @@ -172,7 +200,7 @@ } ], "type": "struct SS", - "typeId": 7, + "typeId": 8, "typeParameters": [ 2 ] @@ -186,12 +214,12 @@ }, { "name": "cap", - "type": 13, + "type": 14, "typeArguments": null } ], "type": "struct std::vec::RawVec", - "typeId": 8, + "typeId": 9, "typeParameters": [ 2 ] @@ -200,7 +228,7 @@ "components": [ { "name": "buf", - "type": 8, + "type": 9, "typeArguments": [ { "name": "", @@ -211,12 +239,12 @@ }, { "name": "len", - "type": 13, + "type": 14, "typeArguments": null } ], "type": "struct std::vec::Vec", - "typeId": 9, + "typeId": 10, "typeParameters": [ 2 ] @@ -224,31 +252,31 @@ { "components": null, "type": "u16", - "typeId": 10, + "typeId": 11, "typeParameters": null }, { "components": null, "type": "u256", - "typeId": 11, + "typeId": 12, "typeParameters": null }, { "components": null, "type": "u32", - "typeId": 12, + "typeId": 13, "typeParameters": null }, { "components": null, "type": "u64", - "typeId": 13, + "typeId": 14, "typeParameters": null }, { "components": null, "type": "u8", - "typeId": 14, + "typeId": 15, "typeParameters": null } ] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/logging/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/logging/src/main.sw index 8599f4c2a1a..138051e1ed3 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/logging/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/logging/src/main.sw @@ -36,6 +36,10 @@ impl AbiEncode for CustomAbiEncode { } } +struct NotAutoEncodable { + p: raw_ptr +} + fn main() -> u64 { let mut e = Vec::new(); e.push(1); @@ -60,5 +64,16 @@ fn main() -> u64 { __log(E::B); __log(CustomAbiEncode {}); + // These must compile when experimental-new-encoding is not set + // and fail when it is set + let not_encodable = NotAutoEncodable{ + p: asm(size: 1) { + aloc size; + hp: raw_ptr + } + }; + log(not_encodable); + require(true, not_encodable); + 1 }