diff --git a/forc-pkg/src/manifest.rs b/forc-pkg/src/manifest.rs index d4c35607a1d..6252f9c751d 100644 --- a/forc-pkg/src/manifest.rs +++ b/forc-pkg/src/manifest.rs @@ -233,6 +233,14 @@ pub struct BuildProfile { #[serde(default)] pub error_on_warnings: bool, pub reverse_results: bool, + #[serde(default)] + pub experimental: ExperimentalFlags, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)] +#[serde(rename_all = "kebab-case")] +pub struct ExperimentalFlags { + pub new_encoding: bool, } impl DependencyDetails { @@ -718,6 +726,9 @@ impl BuildProfile { json_abi_with_callpaths: false, error_on_warnings: false, reverse_results: false, + experimental: ExperimentalFlags { + new_encoding: false, + }, } } @@ -736,6 +747,9 @@ impl BuildProfile { json_abi_with_callpaths: false, error_on_warnings: false, reverse_results: false, + experimental: ExperimentalFlags { + new_encoding: false, + }, } } } diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index b8865133fa3..5424264aff7 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -1,6 +1,9 @@ use crate::{ lock::Lock, - manifest::{BuildProfile, Dependency, ManifestFile, MemberManifestFiles, PackageManifestFile}, + manifest::{ + BuildProfile, Dependency, ExperimentalFlags, ManifestFile, MemberManifestFiles, + PackageManifestFile, + }, source::{self, IPFSNode, Source}, }; use anyhow::{anyhow, bail, Context, Error, Result}; @@ -308,6 +311,8 @@ pub struct BuildOpts { pub tests: bool, /// The set of options to filter by member project kind. pub member_filter: MemberFilter, + /// Set of experimental flags + pub experimental: ExperimentalFlags, } /// The set of options to filter type of projects to build in a workspace. @@ -1551,14 +1556,17 @@ pub fn sway_build_config( manifest_dir.to_path_buf(), build_target, ) - .print_dca_graph(build_profile.print_dca_graph.clone()) - .print_dca_graph_url_format(build_profile.print_dca_graph_url_format.clone()) - .print_finalized_asm(build_profile.print_finalized_asm) - .print_intermediate_asm(build_profile.print_intermediate_asm) - .print_ir(build_profile.print_ir) - .include_tests(build_profile.include_tests) - .time_phases(build_profile.time_phases) - .metrics(build_profile.metrics_outfile.clone()); + .with_print_dca_graph(build_profile.print_dca_graph.clone()) + .with_print_dca_graph_url_format(build_profile.print_dca_graph_url_format.clone()) + .with_print_finalized_asm(build_profile.print_finalized_asm) + .with_print_intermediate_asm(build_profile.print_intermediate_asm) + .with_print_ir(build_profile.print_ir) + .with_include_tests(build_profile.include_tests) + .with_time_phases(build_profile.time_phases) + .with_metrics(build_profile.metrics_outfile.clone()) + .with_experimental(sway_core::ExperimentalFlags { + new_encoding: build_profile.experimental.new_encoding, + }); Ok(build_config) } @@ -2030,6 +2038,7 @@ fn build_profile_from_opts( metrics_outfile, tests, error_on_warnings, + experimental, .. } = build_options; let mut selected_build_profile = BuildProfile::DEBUG; @@ -2083,6 +2092,7 @@ fn build_profile_from_opts( profile.include_tests |= tests; profile.json_abi_with_callpaths |= pkg.json_abi_with_callpaths; profile.error_on_warnings |= error_on_warnings; + profile.experimental = experimental.clone(); Ok((selected_build_profile.to_string(), profile)) } @@ -2625,7 +2635,7 @@ pub fn check( build_target, &profile, )? - .include_tests(include_tests); + .with_include_tests(include_tests); let input = manifest.entry_string()?; let handler = Handler::default(); diff --git a/forc-plugins/forc-client/src/cmd/deploy.rs b/forc-plugins/forc-client/src/cmd/deploy.rs index c6d04ddcbb9..3256fc89907 100644 --- a/forc-plugins/forc-client/src/cmd/deploy.rs +++ b/forc-plugins/forc-client/src/cmd/deploy.rs @@ -72,4 +72,7 @@ pub struct Command { /// ] #[clap(long, verbatim_doc_comment, name = "JSON_FILE_PATH")] pub override_storage_slots: Option, + + #[clap(long)] + pub experimental_new_encoding: bool, } diff --git a/forc-plugins/forc-client/src/cmd/run.rs b/forc-plugins/forc-client/src/cmd/run.rs index df2f2f69aef..5a1e4f6ec34 100644 --- a/forc-plugins/forc-client/src/cmd/run.rs +++ b/forc-plugins/forc-client/src/cmd/run.rs @@ -58,4 +58,7 @@ pub struct Command { /// Arguments to pass into main function with forc run. #[clap(long)] pub args: Option>, + + #[clap(long)] + pub experimental_new_encoding: bool, } diff --git a/forc-plugins/forc-client/src/op/deploy.rs b/forc-plugins/forc-client/src/op/deploy.rs index cad9e15025c..a2c03acca36 100644 --- a/forc-plugins/forc-client/src/op/deploy.rs +++ b/forc-plugins/forc-client/src/op/deploy.rs @@ -18,7 +18,7 @@ use fuel_tx::{Output, Salt, TransactionBuilder}; use fuel_vm::prelude::*; use fuels_accounts::provider::Provider; use futures::FutureExt; -use pkg::BuiltPackage; +use pkg::{manifest::ExperimentalFlags, BuiltPackage}; use serde::{Deserialize, Serialize}; use std::time::Duration; use std::{ @@ -348,6 +348,9 @@ fn build_opts_from_cmd(cmd: &cmd::Deploy) -> pkg::BuildOpts { build_target: BuildTarget::default(), tests: false, member_filter: pkg::MemberFilter::only_contracts(), + experimental: ExperimentalFlags { + new_encoding: cmd.experimental_new_encoding, + }, } } diff --git a/forc-plugins/forc-client/src/op/run/mod.rs b/forc-plugins/forc-client/src/op/run/mod.rs index 76270092c46..ff19d7c2355 100644 --- a/forc-plugins/forc-client/src/op/run/mod.rs +++ b/forc-plugins/forc-client/src/op/run/mod.rs @@ -15,7 +15,7 @@ use forc_util::tx_utils::format_log_receipts; use fuel_core_client::client::FuelClient; use fuel_tx::{ContractId, Transaction, TransactionBuilder}; use fuels_accounts::provider::Provider; -use pkg::BuiltPackage; +use pkg::{manifest::ExperimentalFlags, BuiltPackage}; use std::time::Duration; use std::{path::PathBuf, str::FromStr}; use sway_core::language::parsed::TreeType; @@ -231,5 +231,8 @@ fn build_opts_from_cmd(cmd: &cmd::Run) -> pkg::BuildOpts { debug_outfile: cmd.build_output.debug_file.clone(), tests: false, member_filter: pkg::MemberFilter::only_scripts(), + experimental: ExperimentalFlags { + new_encoding: cmd.experimental_new_encoding, + }, } } diff --git a/forc-test/src/lib.rs b/forc-test/src/lib.rs index 0aa8efe0734..03184f840eb 100644 --- a/forc-test/src/lib.rs +++ b/forc-test/src/lib.rs @@ -9,7 +9,8 @@ use forc_pkg as pkg; use fuel_abi_types::error_codes::ErrorSignal; use fuel_tx as tx; use fuel_vm::checked_transaction::builder::TransactionBuilderExt; -use fuel_vm::{self as vm}; +use fuel_vm::{self as vm, fuel_asm, prelude::Instruction}; +use pkg::manifest::ExperimentalFlags; use pkg::TestPassCondition; use pkg::{Built, BuiltPackage}; use rand::{Rng, SeedableRng}; @@ -147,6 +148,8 @@ pub struct Opts { pub time_phases: bool, /// Output compilation metrics into file. pub metrics_outfile: Option, + /// Set of experimental flags + pub experimental: ExperimentalFlags, } /// The set of options provided for controlling logs printed for each test. @@ -405,6 +408,7 @@ impl Opts { metrics_outfile: self.metrics_outfile, tests: true, member_filter: Default::default(), + experimental: self.experimental, } } } diff --git a/forc/src/cli/commands/build.rs b/forc/src/cli/commands/build.rs index ba52e6811d9..8329eae11fd 100644 --- a/forc/src/cli/commands/build.rs +++ b/forc/src/cli/commands/build.rs @@ -23,6 +23,10 @@ pub struct Command { /// Also build all tests within the project. #[clap(long)] pub tests: bool, + + #[clap(long)] + /// Experimental flags for the "new encoding" feature + pub experimental_new_encoding: bool, } pub(crate) fn exec(command: Command) -> ForcResult<()> { diff --git a/forc/src/cli/commands/contract_id.rs b/forc/src/cli/commands/contract_id.rs index 78bb806257d..a9140e1acc6 100644 --- a/forc/src/cli/commands/contract_id.rs +++ b/forc/src/cli/commands/contract_id.rs @@ -20,6 +20,10 @@ pub struct Command { pub build_profile: BuildProfile, #[clap(flatten)] pub salt: Salt, + + #[clap(long)] + /// Experimental flags for the "new encoding" feature + pub experimental_new_encoding: bool, } pub(crate) fn exec(cmd: Command) -> ForcResult<()> { diff --git a/forc/src/cli/commands/predicate_root.rs b/forc/src/cli/commands/predicate_root.rs index cc81b88614c..d05a770da53 100644 --- a/forc/src/cli/commands/predicate_root.rs +++ b/forc/src/cli/commands/predicate_root.rs @@ -18,6 +18,10 @@ pub struct Command { pub build_output: BuildOutput, #[clap(flatten)] pub build_profile: BuildProfile, + + #[clap(long)] + /// Experimental flags for the "new encoding" feature + pub experimental_new_encoding: bool, } pub(crate) fn exec(cmd: Command) -> ForcResult<()> { diff --git a/forc/src/cli/commands/test.rs b/forc/src/cli/commands/test.rs index 91a84e75ac8..d973eb929f0 100644 --- a/forc/src/cli/commands/test.rs +++ b/forc/src/cli/commands/test.rs @@ -4,6 +4,7 @@ use clap::Parser; use forc_pkg as pkg; use forc_test::{TestFilter, TestRunnerCount, TestedPackage}; use forc_util::{tx_utils::format_log_receipts, ForcError, ForcResult}; +use pkg::manifest::ExperimentalFlags; use tracing::info; /// Run the Sway unit tests for the current project. @@ -38,6 +39,10 @@ pub struct Command { /// Number of threads to utilize when running the tests. By default, this is the number of /// threads available in your system. pub test_threads: Option, + + #[clap(long)] + /// Experimental flags for the "new encoding" feature + pub experimental_new_encoding: bool, } /// The set of options provided for controlling output of a test. @@ -215,6 +220,9 @@ fn opts_from_cmd(cmd: Command) -> forc_test::Opts { binary_outfile: cmd.build.output.bin_file, debug_outfile: cmd.build.output.debug_file, build_target: cmd.build.build_target, + experimental: ExperimentalFlags { + new_encoding: cmd.experimental_new_encoding, + }, } } diff --git a/forc/src/ops/forc_build.rs b/forc/src/ops/forc_build.rs index a3fe6fe0a5d..2446e7f5888 100644 --- a/forc/src/ops/forc_build.rs +++ b/forc/src/ops/forc_build.rs @@ -1,6 +1,7 @@ use crate::cli::BuildCommand; use forc_pkg as pkg; use forc_util::ForcResult; +use pkg::manifest::ExperimentalFlags; pub fn build(cmd: BuildCommand) -> ForcResult { let opts = opts_from_cmd(cmd); @@ -42,5 +43,8 @@ fn opts_from_cmd(cmd: BuildCommand) -> pkg::BuildOpts { build_target: cmd.build.build_target, tests: cmd.tests, member_filter: Default::default(), + experimental: ExperimentalFlags { + new_encoding: cmd.experimental_new_encoding, + }, } } diff --git a/forc/src/ops/forc_contract_id.rs b/forc/src/ops/forc_contract_id.rs index e28690a7aec..b377c10b399 100644 --- a/forc/src/ops/forc_contract_id.rs +++ b/forc/src/ops/forc_contract_id.rs @@ -2,6 +2,7 @@ use crate::cli::ContractIdCommand; use anyhow::{bail, Result}; use forc_pkg::{self as pkg, build_with_options}; use forc_tracing::println_green; +use pkg::manifest::ExperimentalFlags; use sway_core::{fuel_prelude::fuel_tx, BuildTarget}; use tracing::info; @@ -78,5 +79,8 @@ fn build_opts_from_cmd(cmd: &ContractIdCommand) -> pkg::BuildOpts { build_target: BuildTarget::default(), tests: false, member_filter: pkg::MemberFilter::only_contracts(), + experimental: ExperimentalFlags { + new_encoding: cmd.experimental_new_encoding, + }, } } diff --git a/forc/src/ops/forc_predicate_root.rs b/forc/src/ops/forc_predicate_root.rs index a06c4535ddb..0a032e8291b 100644 --- a/forc/src/ops/forc_predicate_root.rs +++ b/forc/src/ops/forc_predicate_root.rs @@ -1,6 +1,7 @@ use crate::cli::PredicateRootCommand; use anyhow::Result; use forc_pkg::{self as pkg, build_with_options}; +use pkg::manifest::ExperimentalFlags; use sway_core::BuildTarget; pub fn predicate_root(command: PredicateRootCommand) -> Result<()> { @@ -46,5 +47,8 @@ fn build_opts_from_cmd(cmd: PredicateRootCommand) -> pkg::BuildOpts { build_target: BuildTarget::default(), tests: false, member_filter: pkg::MemberFilter::only_predicates(), + experimental: ExperimentalFlags { + new_encoding: cmd.experimental_new_encoding, + }, } } diff --git a/sway-core/src/build_config.rs b/sway-core/src/build_config.rs index 5dd49b661c5..fd6657c2896 100644 --- a/sway-core/src/build_config.rs +++ b/sway-core/src/build_config.rs @@ -48,6 +48,7 @@ pub struct BuildConfig { pub(crate) include_tests: bool, pub time_phases: bool, pub metrics_outfile: Option, + pub experimental: ExperimentalFlags, } impl BuildConfig { @@ -92,52 +93,53 @@ impl BuildConfig { include_tests: false, time_phases: false, metrics_outfile: None, + experimental: ExperimentalFlags::default(), } } - pub fn print_dca_graph(self, a: Option) -> Self { + pub fn with_print_dca_graph(self, a: Option) -> Self { Self { print_dca_graph: a, ..self } } - pub fn print_dca_graph_url_format(self, a: Option) -> Self { + pub fn with_print_dca_graph_url_format(self, a: Option) -> Self { Self { print_dca_graph_url_format: a, ..self } } - pub fn print_intermediate_asm(self, a: bool) -> Self { + pub fn with_print_intermediate_asm(self, a: bool) -> Self { Self { print_intermediate_asm: a, ..self } } - pub fn print_finalized_asm(self, a: bool) -> Self { + pub fn with_print_finalized_asm(self, a: bool) -> Self { Self { print_finalized_asm: a, ..self } } - pub fn print_ir(self, a: bool) -> Self { + pub fn with_print_ir(self, a: bool) -> Self { Self { print_ir: a, ..self } } - pub fn time_phases(self, a: bool) -> Self { + pub fn with_time_phases(self, a: bool) -> Self { Self { time_phases: a, ..self } } - pub fn metrics(self, a: Option) -> Self { + pub fn with_metrics(self, a: Option) -> Self { Self { metrics_outfile: a, ..self @@ -149,14 +151,26 @@ impl BuildConfig { /// This should be set to `true` by invocations like `forc test` or `forc check --tests`. /// /// Default: `false` - pub fn include_tests(self, include_tests: bool) -> Self { + pub fn with_include_tests(self, include_tests: bool) -> Self { Self { include_tests, ..self } } + pub fn with_experimental(self, experimental: ExperimentalFlags) -> Self { + Self { + experimental, + ..self + } + } + pub fn canonical_root_module(&self) -> Arc { self.canonical_root_module.clone() } } + +#[derive(Debug, Default, Clone, Copy)] +pub struct ExperimentalFlags { + pub new_encoding: bool, +} diff --git a/sway-core/src/ir_generation.rs b/sway-core/src/ir_generation.rs index 178c7bad8b2..ba7fad6a4ab 100644 --- a/sway-core/src/ir_generation.rs +++ b/sway-core/src/ir_generation.rs @@ -13,12 +13,13 @@ use sway_types::span::Span; pub(crate) use purity::{check_function_purity, PurityEnv}; -use crate::{language::ty, Engines}; +use crate::{language::ty, Engines, ExperimentalFlags}; pub fn compile_program<'eng>( program: &ty::TyProgram, include_tests: bool, engines: &'eng Engines, + experimental: ExperimentalFlags, ) -> Result, Vec> { let declaration_engine = engines.de(); @@ -46,7 +47,12 @@ pub fn compile_program<'eng>( .map(|(message_id, type_id)| (*type_id, *message_id)) .collect(); - let mut ctx = Context::new(engines.se()); + let mut ctx = Context::new( + engines.se(), + sway_ir::ExperimentalFlags { + new_encoding: experimental.new_encoding, + }, + ); ctx.program_kind = match kind { ty::TyProgramKind::Script { .. } => Kind::Script, ty::TyProgramKind::Predicate { .. } => Kind::Predicate, diff --git a/sway-core/src/ir_generation/const_eval.rs b/sway-core/src/ir_generation/const_eval.rs index e3ab77d5e92..76f99579fcc 100644 --- a/sway-core/src/ir_generation/const_eval.rs +++ b/sway-core/src/ir_generation/const_eval.rs @@ -1123,7 +1123,7 @@ mod tests { fn assert_is_constant(is_constant: bool, prefix: &str, expr: &str) { let engines = Engines::default(); let handler = Handler::default(); - let mut context = Context::new(engines.se()); + let mut context = Context::new(engines.se(), sway_ir::ExperimentalFlags::default()); let mut md_mgr = MetadataManager::default(); let core_lib = namespace::Module::default(); diff --git a/sway-core/src/ir_generation/function.rs b/sway-core/src/ir_generation/function.rs index 7910829cbed..2661d23d64b 100644 --- a/sway-core/src/ir_generation/function.rs +++ b/sway-core/src/ir_generation/function.rs @@ -891,7 +891,9 @@ impl<'eng> FnCompiler<'eng> { // The log value and the log ID are just Value. let log_val = self.compile_expression_to_value(context, md_mgr, &arguments[0])?; - let logged_type = i.get_logged_type().unwrap(); + let logged_type = i + .get_logged_type(context.experimental.new_encoding) + .expect("Could not return logged type."); let log_id = match self.logged_types_map.get(&logged_type) { None => { return Err(CompileError::Internal( diff --git a/sway-core/src/language/ty/expression/intrinsic_function.rs b/sway-core/src/language/ty/expression/intrinsic_function.rs index 5e3222310d7..4c56f0b8ba3 100644 --- a/sway-core/src/language/ty/expression/intrinsic_function.rs +++ b/sway-core/src/language/ty/expression/intrinsic_function.rs @@ -20,21 +20,25 @@ pub struct TyIntrinsicFunctionKind { } impl TyIntrinsicFunctionKind { - pub fn get_logged_type(&self) -> Option { - if matches!(self.kind, Intrinsic::Log) { - match &self.arguments[0].expression { - TyExpressionVariant::FunctionApplication { - call_path, - arguments, - .. - } => { - assert!(call_path.suffix.as_str() == "encode"); - Some(arguments[0].1.return_type) + pub fn get_logged_type(&self, new_encoding: bool) -> Option { + if new_encoding { + if matches!(self.kind, Intrinsic::Log) { + match &self.arguments[0].expression { + TyExpressionVariant::FunctionApplication { + call_path, + arguments, + .. + } => { + assert!(call_path.suffix.as_str() == "encode"); + Some(arguments[0].1.return_type) + } + _ => None, } - _ => None, + } else { + None } } else { - None + Some(self.arguments[0].return_type) } } } @@ -118,7 +122,7 @@ impl CollectTypesMetadata for TyIntrinsicFunctionKind { match self.kind { Intrinsic::Log => { - let logged_type = self.get_logged_type().unwrap(); + let logged_type = self.get_logged_type(ctx.experimental.new_encoding).unwrap(); types_metadata.push(TypeMetadata::LoggedType( LogId::new(ctx.log_id_counter()), logged_type, diff --git a/sway-core/src/lib.rs b/sway-core/src/lib.rs index d390800cd56..16bef34a11c 100644 --- a/sway-core/src/lib.rs +++ b/sway-core/src/lib.rs @@ -64,6 +64,7 @@ pub mod fuel_prelude { pub use fuel_vm::{self, fuel_asm, fuel_crypto, fuel_tx, fuel_types}; } +pub use build_config::ExperimentalFlags; pub use engine_threading::Engines; /// Given an input `Arc` and an optional [BuildConfig], parse the input into a [lexed::LexedProgram] and [parsed::ParseProgram]. @@ -97,6 +98,7 @@ pub fn parse( None, config.build_target, config.include_tests, + config.experimental, ) .map( |ParsedModuleTree { @@ -229,6 +231,7 @@ pub struct Submodule { pub type Submodules = Vec; /// Parse all dependencies `deps` as submodules. +#[allow(clippy::too_many_arguments)] fn parse_submodules( handler: &Handler, engines: &Engines, @@ -237,6 +240,7 @@ fn parse_submodules( module_dir: &Path, build_target: BuildTarget, include_tests: bool, + experimental: ExperimentalFlags, ) -> Submodules { // Assume the happy path, so there'll be as many submodules as dependencies, but no more. let mut submods = Vec::with_capacity(module.submodules().count()); @@ -269,6 +273,7 @@ fn parse_submodules( Some(submod.name.as_str()), build_target, include_tests, + experimental, ) { if !matches!(kind, parsed::TreeType::Library) { let source_id = engines.se().get_source_id(submod_path.as_ref()); @@ -312,6 +317,7 @@ pub struct ParsedModuleTree { /// Given the source of the module along with its path, /// parse this module including all of its submodules. +#[allow(clippy::too_many_arguments)] fn parse_module_tree( handler: &Handler, engines: &Engines, @@ -320,6 +326,7 @@ fn parse_module_tree( module_name: Option<&str>, build_target: BuildTarget, include_tests: bool, + experimental: ExperimentalFlags, ) -> Result { let query_engine = engines.qe(); @@ -338,11 +345,12 @@ fn parse_module_tree( module_dir, build_target, include_tests, + experimental, ); // Convert from the raw parsed module to the `ParseTree` ready for type-check. let (kind, tree) = to_parsed_lang::convert_parse_tree( - &mut to_parsed_lang::Context::new(build_target), + &mut to_parsed_lang::Context::new(build_target, experimental), handler, engines, module.value.clone(), @@ -468,6 +476,8 @@ pub fn parsed_to_ast( build_config: Option<&BuildConfig>, package_name: &str, ) -> Result { + let experimental = build_config.map(|x| x.experimental).unwrap_or_default(); + // Type check the program. let typed_program_opt = ty::TyProgram::type_check( handler, @@ -475,6 +485,7 @@ pub fn parsed_to_ast( parse_program, initial_namespace, package_name, + build_config, ); let mut typed_program = match typed_program_opt { @@ -493,8 +504,10 @@ pub fn parsed_to_ast( }; // Collect information about the types used in this program - let types_metadata_result = typed_program - .collect_types_metadata(handler, &mut CollectTypesMetadataContext::new(engines)); + let types_metadata_result = typed_program.collect_types_metadata( + handler, + &mut CollectTypesMetadataContext::new(engines, experimental), + ); let types_metadata = match types_metadata_result { Ok(types_metadata) => types_metadata, Err(e) => { @@ -534,7 +547,12 @@ pub fn parsed_to_ast( ); // Evaluate const declarations, to allow storage slots initialization with consts. - let mut ctx = Context::new(engines.se()); + let mut ctx = Context::new( + engines.se(), + sway_ir::ExperimentalFlags { + new_encoding: experimental.new_encoding, + }, + ); let mut md_mgr = MetadataManager::default(); let module = Module::new(&mut ctx, Kind::Contract); if let Err(e) = ir_generation::compile::compile_constants( @@ -737,8 +755,12 @@ pub(crate) fn compile_ast_to_ir_to_asm( // errors and then hold as a runtime invariant that none of the types will be unresolved in the // IR phase. - let mut ir = match ir_generation::compile_program(program, build_config.include_tests, engines) - { + let mut ir = match ir_generation::compile_program( + program, + build_config.include_tests, + engines, + build_config.experimental, + ) { Ok(ir) => ir, Err(errors) => { let mut last = None; diff --git a/sway-core/src/semantic_analysis/program.rs b/sway-core/src/semantic_analysis/program.rs index b795ca8f9e9..98dc6f0524c 100644 --- a/sway-core/src/semantic_analysis/program.rs +++ b/sway-core/src/semantic_analysis/program.rs @@ -8,7 +8,7 @@ use crate::{ namespace::{self, Namespace}, TypeCheckContext, }, - Engines, + BuildConfig, Engines, }; use sway_error::handler::{ErrorEmitted, Handler}; use sway_ir::{Context, Module}; @@ -29,10 +29,18 @@ impl TyProgram { parsed: &ParseProgram, initial_namespace: namespace::Module, package_name: &str, + 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 ParseProgram { root, kind } = parsed; // Analyze the dependency order for the submodules. diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index fcf03136a92..4828ff3483b 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -1,6 +1,7 @@ use std::collections::{HashMap, VecDeque}; use crate::{ + build_config::ExperimentalFlags, decl_engine::{DeclEngineInsert, DeclRefFunction}, engine_threading::*, language::{ @@ -91,6 +92,9 @@ pub struct TypeCheckContext<'a> { /// case of impl trait methods after the initial type checked AST is constructed, and /// after we perform a dependency analysis on the tree. defer_monomorphization: bool, + + /// Set of experimental flags + pub experimental: ExperimentalFlags, } impl<'a> TypeCheckContext<'a> { @@ -122,6 +126,7 @@ impl<'a> TypeCheckContext<'a> { kind: TreeType::Contract, disallow_functions: false, defer_monomorphization: false, + experimental: ExperimentalFlags::default(), } } @@ -149,6 +154,7 @@ impl<'a> TypeCheckContext<'a> { engines: self.engines, disallow_functions: self.disallow_functions, defer_monomorphization: self.defer_monomorphization, + experimental: self.experimental, } } @@ -169,6 +175,7 @@ impl<'a> TypeCheckContext<'a> { engines: self.engines, disallow_functions: self.disallow_functions, defer_monomorphization: self.defer_monomorphization, + experimental: self.experimental, } } @@ -1510,6 +1517,13 @@ impl<'a> TypeCheckContext<'a> { .implemented_traits .insert_for_type(self.engines, type_id); } + + pub(crate) fn with_experimental_flags(self, experimental: ExperimentalFlags) -> Self { + Self { + experimental, + ..self + } + } } pub(crate) trait MonomorphizeHelper { diff --git a/sway-core/src/transform/to_parsed_lang/context.rs b/sway-core/src/transform/to_parsed_lang/context.rs index 90c0acb0af1..bb5bcd32f1d 100644 --- a/sway-core/src/transform/to_parsed_lang/context.rs +++ b/sway-core/src/transform/to_parsed_lang/context.rs @@ -1,7 +1,9 @@ -use crate::{language::parsed::TreeType, BuildTarget}; +use crate::{build_config::ExperimentalFlags, language::parsed::TreeType, BuildTarget}; #[derive(Default)] pub struct Context { + pub experimental: ExperimentalFlags, + /// Indicates whether the module being parsed has a `configurable` block. module_has_configurable_block: bool, @@ -24,9 +26,10 @@ pub struct Context { impl Context { /// Create a new context. - pub fn new(build_target: BuildTarget) -> Self { + pub fn new(build_target: BuildTarget, experimental: ExperimentalFlags) -> Self { Self { build_target, + experimental, ..Default::default() } } 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 467a50cd8f5..7280fc6a9f4 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 @@ -1773,7 +1773,9 @@ fn expr_func_app_to_expression_kind( // Route intrinsic calls to different AST node. match Intrinsic::try_from_str(call_seg.name.as_str()) { - Some(Intrinsic::Log) if last.is_none() && !is_absolute => { + Some(Intrinsic::Log) + if context.experimental.new_encoding && last.is_none() && !is_absolute => + { let span = name_args_span(span, type_arguments_span); return Ok(ExpressionKind::IntrinsicFunction( IntrinsicFunctionExpression { diff --git a/sway-core/src/types/collect_types_metadata.rs b/sway-core/src/types/collect_types_metadata.rs index a219ecc20a7..a62a0c5bff9 100644 --- a/sway-core/src/types/collect_types_metadata.rs +++ b/sway-core/src/types/collect_types_metadata.rs @@ -8,7 +8,7 @@ use std::{ sync::{Arc, Mutex}, }; -use crate::{type_system::TypeId, Engines}; +use crate::{type_system::TypeId, Engines, ExperimentalFlags}; use sway_error::handler::{ErrorEmitted, Handler}; use sway_types::{Ident, Span}; @@ -70,6 +70,8 @@ pub struct CollectTypesMetadataContext<'cx> { call_site_spans: Vec>>>, pub(crate) engines: &'cx Engines, + + pub experimental: ExperimentalFlags, } impl<'cx> CollectTypesMetadataContext<'cx> { @@ -117,12 +119,13 @@ impl<'cx> CollectTypesMetadataContext<'cx> { None } - pub fn new(engines: &'cx Engines) -> Self { + pub fn new(engines: &'cx Engines, experimental: ExperimentalFlags) -> Self { let mut ctx = Self { engines, log_id_counter: 0, message_id_counter: 0, call_site_spans: vec![], + experimental, }; ctx.call_site_push(); ctx diff --git a/sway-ir/src/bin/opt.rs b/sway-ir/src/bin/opt.rs index a5a9a2f3310..22da9e58e24 100644 --- a/sway-ir/src/bin/opt.rs +++ b/sway-ir/src/bin/opt.rs @@ -5,8 +5,8 @@ use std::{ use anyhow::anyhow; use sway_ir::{ - insert_after_each, register_known_passes, PassGroup, PassManager, MODULEPRINTER_NAME, - MODULEVERIFIER_NAME, + insert_after_each, register_known_passes, ExperimentalFlags, PassGroup, PassManager, + MODULEPRINTER_NAME, MODULEVERIFIER_NAME, }; use sway_types::SourceEngine; @@ -26,7 +26,7 @@ fn main() -> Result<(), anyhow::Error> { let source_engine = SourceEngine::default(); // Parse it. XXX Improve this error message too. - let mut ir = sway_ir::parser::parse(&input_str, &source_engine)?; + let mut ir = sway_ir::parser::parse(&input_str, &source_engine, ExperimentalFlags::default())?; // Perform optimisation passes in order. let mut passes = PassGroup::default(); diff --git a/sway-ir/src/context.rs b/sway-ir/src/context.rs index e27f5780cc2..487d6eb6d55 100644 --- a/sway-ir/src/context.rs +++ b/sway-ir/src/context.rs @@ -35,10 +35,17 @@ pub struct Context<'eng> { pub program_kind: Kind, next_unique_sym_tag: u64, + + pub experimental: ExperimentalFlags, +} + +#[derive(Default)] +pub struct ExperimentalFlags { + pub new_encoding: bool, } impl<'eng> Context<'eng> { - pub fn new(source_engine: &'eng SourceEngine) -> Self { + pub fn new(source_engine: &'eng SourceEngine, experimental: ExperimentalFlags) -> Self { let mut def = Self { source_engine, modules: Default::default(), @@ -51,6 +58,7 @@ impl<'eng> Context<'eng> { metadata: Default::default(), next_unique_sym_tag: Default::default(), program_kind: Kind::Contract, + experimental, }; Type::create_basic_types(&mut def); def diff --git a/sway-ir/src/irtype.rs b/sway-ir/src/irtype.rs index 6d9ff4cd4e5..5115f550a0c 100644 --- a/sway-ir/src/irtype.rs +++ b/sway-ir/src/irtype.rs @@ -643,7 +643,7 @@ mod tests { /// Unit tests in this module document and assert decisions on memory layout. mod memory_layout { use super::*; - use crate::Context; + use crate::{Context, ExperimentalFlags}; use once_cell::sync::Lazy; use sway_types::SourceEngine; @@ -927,7 +927,7 @@ mod tests { static SOURCE_ENGINE: Lazy = Lazy::new(SourceEngine::default); fn create_context() -> Context<'static> { - Context::new(&SOURCE_ENGINE) + Context::new(&SOURCE_ENGINE, ExperimentalFlags::default()) } /// Creates sample types that are not aggregates and do not point to diff --git a/sway-ir/src/optimize.rs b/sway-ir/src/optimize.rs index 2684dbca61b..f0b722cc704 100644 --- a/sway-ir/src/optimize.rs +++ b/sway-ir/src/optimize.rs @@ -42,7 +42,7 @@ mod target_fuel; #[cfg(test)] pub mod tests { - use crate::{PassGroup, PassManager}; + use crate::{ExperimentalFlags, PassGroup, PassManager}; use sway_types::SourceEngine; /// This function parses the IR text representation and run the specified optimizers passes. @@ -81,6 +81,7 @@ pub mod tests { " ), &source_engine, + ExperimentalFlags::default(), ) .unwrap(); diff --git a/sway-ir/src/parser.rs b/sway-ir/src/parser.rs index eac71926224..d7427848284 100644 --- a/sway-ir/src/parser.rs +++ b/sway-ir/src/parser.rs @@ -2,13 +2,14 @@ use sway_types::SourceEngine; -use crate::{context::Context, error::IrError}; +use crate::{context::Context, error::IrError, ExperimentalFlags}; // ------------------------------------------------------------------------------------------------- /// Parse a string produced by [`crate::printer::to_string`] into a new [`Context`]. pub fn parse<'eng>( input: &str, source_engine: &'eng SourceEngine, + experimental: ExperimentalFlags, ) -> Result, IrError> { let irmod = ir_builder::parser::ir_descrs(input).map_err(|err| { let found = if input.len() - err.location.offset <= 20 { @@ -18,7 +19,7 @@ pub fn parse<'eng>( }; IrError::ParseFailure(err.to_string(), found.into()) })?; - ir_builder::build_context(irmod, source_engine)?.verify() + ir_builder::build_context(irmod, source_engine, experimental)?.verify() } // ------------------------------------------------------------------------------------------------- @@ -651,7 +652,7 @@ mod ir_builder { metadata::{MetadataIndex, Metadatum}, module::{Kind, Module}, value::Value, - BinaryOpKind, BlockArgument, Instruction, UnaryOpKind, B256, + BinaryOpKind, BlockArgument, ExperimentalFlags, Instruction, UnaryOpKind, B256, }; #[derive(Debug)] @@ -916,8 +917,9 @@ mod ir_builder { pub(super) fn build_context( ir_ast_mod: IrAstModule, source_engine: &SourceEngine, + experimental: ExperimentalFlags, ) -> Result { - let mut ctx = Context::new(source_engine); + let mut ctx = Context::new(source_engine, experimental); let md_map = build_metadata_map(&mut ctx, ir_ast_mod.metadata); let module = Module::new(&mut ctx, ir_ast_mod.kind); let mut builder = IrBuilder { diff --git a/sway-ir/tests/tests.rs b/sway-ir/tests/tests.rs index bc66c74efab..c2ee5aca417 100644 --- a/sway-ir/tests/tests.rs +++ b/sway-ir/tests/tests.rs @@ -5,7 +5,7 @@ use sway_ir::{ create_dce_pass, create_dom_fronts_pass, create_dominators_pass, create_escaped_symbols_pass, create_mem2reg_pass, create_memcpyopt_pass, create_misc_demotion_pass, create_postorder_pass, create_ret_demotion_pass, create_simplify_cfg_pass, optimize as opt, register_known_passes, - Context, PassGroup, PassManager, DCE_NAME, MEM2REG_NAME, SROA_NAME, + Context, ExperimentalFlags, PassGroup, PassManager, DCE_NAME, MEM2REG_NAME, SROA_NAME, }; use sway_types::SourceEngine; @@ -22,10 +22,11 @@ fn run_tests bool>(sub_dir: &str, opt_fn: F) { let input_bytes = std::fs::read(&path).unwrap(); let input = String::from_utf8_lossy(&input_bytes); - let mut ir = sway_ir::parser::parse(&input, &source_engine).unwrap_or_else(|parse_err| { - println!("{}: {parse_err}", path.display()); - panic!() - }); + let mut ir = sway_ir::parser::parse(&input, &source_engine, ExperimentalFlags::default()) + .unwrap_or_else(|parse_err| { + println!("{}: {parse_err}", path.display()); + panic!() + }); let first_line = input.split('\n').next().unwrap(); diff --git a/test/src/e2e_vm_tests/harness.rs b/test/src/e2e_vm_tests/harness.rs index b10e8e28cb4..c372461d5c3 100644 --- a/test/src/e2e_vm_tests/harness.rs +++ b/test/src/e2e_vm_tests/harness.rs @@ -5,7 +5,7 @@ use forc_client::{ op::{deploy, run}, NodeTarget, }; -use forc_pkg::{Built, BuiltPackage}; +use forc_pkg::{manifest::ExperimentalFlags, Built, BuiltPackage}; use fuel_tx::TransactionBuilder; use fuel_vm::fuel_tx; use fuel_vm::interpreter::Interpreter; @@ -190,17 +190,6 @@ pub(crate) fn runs_in_vm( Interpreter::with_storage(storage, Default::default()); let transition = i.transact(tx).map_err(anyhow::Error::msg)?; - // for r in transition.receipts() { - // match r { - // Receipt::LogData { data, .. } => { - // eprintln!("LogData: {:?}", data); - // } - // _ => { - // dbg!(r); - // } - // } - // } - Ok(VMExecutionResult::Fuel( *transition.state(), transition.receipts().to_vec(), @@ -272,6 +261,9 @@ pub(crate) async fn compile_to_bytes(file_name: &str, run_config: &RunConfig) -> json_abi_with_callpaths: true, ..Default::default() }, + experimental: ExperimentalFlags { + new_encoding: run_config.experimental.new_encoding, + }, ..Default::default() }; match std::panic::catch_unwind(|| forc_pkg::build_with_options(build_opts)) { diff --git a/test/src/e2e_vm_tests/mod.rs b/test/src/e2e_vm_tests/mod.rs index 1fcf57ab75a..f8a983d95b6 100644 --- a/test/src/e2e_vm_tests/mod.rs +++ b/test/src/e2e_vm_tests/mod.rs @@ -77,12 +77,131 @@ struct TestContext { deployed_contracts: Arc>>, } -fn print_receipt(receipt: &Receipt) { - if let Receipt::ReturnData { - data: Some(data), .. - } = receipt - { - println!("Data: {:?}", data); +fn print_receipts(output: &mut String, receipts: &[Receipt]) { + use std::fmt::Write; + let _ = writeln!(output, " {}", "Receipts".green().bold()); + for (i, receipt) in receipts.iter().enumerate() { + let _ = write!(output, " {}", format!("#{i}").bold()); + match receipt { + Receipt::LogData { + id, + ra, + rb, + ptr, + len, + digest, + pc, + is, + data, + } => { + let _ = write!(output, " LogData\n ID: {id:?}\n RA: {ra:?}\n RB: {rb:?}\n Ptr: {ptr:?}\n Len: {len:?}\n Digest: {digest:?}\n PC: {pc:?}\n IS: {is:?}\n Data: {data:?}\n"); + } + Receipt::ReturnData { + id, + ptr, + len, + digest, + pc, + is, + data, + } => { + let _ = write!(output, " ReturnData\n ID: {id:?}\n Ptr: {ptr:?}\n Len: {len:?}\n Digest: {digest:?}\n PC: {pc:?}\n IS: {is:?}\n Data: {data:?}\n"); + } + Receipt::Call { + id, + to, + amount, + asset_id, + gas, + param1, + param2, + pc, + is, + } => { + let _ = write!(output, " Call\n ID: {id:?}\n To: {to:?}\n Amount: {amount:?}\n Asset ID: {asset_id:?}\n Gas: {gas:?}\n Param #1: {param1:?}\n Param #2: {param2:?}\n PC: {pc:?}\n IS: {is:?}\n"); + } + Receipt::Return { id, val, pc, is } => { + let _ = write!(output, " Return\n ID: {id:?}\n Value: {val:?}\n PC: {pc:?}\n IS: {is:?}\n"); + } + Receipt::Panic { + id, + reason, + pc, + is, + contract_id, + } => { + let _ = write!(output, " Panic\n ID: {id:?}\n Reason: {reason:?}\n PC: {pc:?}\n IS: {is:?}\n Contract ID: {contract_id:?}\n"); + } + Receipt::Revert { id, ra, pc, is } => { + let _ = write!(output, " Revert\n ID: {id:?}\n RA: {ra:?}\n PC: {pc:?}\n IS: {is:?}\n"); + } + Receipt::Log { + id, + ra, + rb, + rc, + rd, + pc, + is, + } => { + let _ = write!(output, " Log\n ID: {id:?}\n RA: {ra:?}\n RB: {rb:?}\n RC: {rc:?}\n RD: {rd:?}\n PC: {pc:?}\n IS: {is:?}\n"); + } + Receipt::Transfer { + id, + to, + amount, + asset_id, + pc, + is, + } => { + let _ = write!(output, " Transfer\n ID: {id:?}\n To: {to:?}\n Amount: {amount:?}\n Asset ID: {asset_id:?}\n PC: {pc:?}\n IS: {is:?}\n"); + } + Receipt::TransferOut { + id, + to, + amount, + asset_id, + pc, + is, + } => { + let _ = write!(output, " TransferOut\n ID: {id:?}\n To: {to:?}\n Amount: {amount:?}\n Asset ID: {asset_id:?}\n PC: {pc:?}\n IS: {is:?}\n"); + } + Receipt::ScriptResult { result, gas_used } => { + let _ = write!( + output, + " ScriptResult\n Result: {result:?}\n Gas Used: {gas_used:?}\n" + ); + } + Receipt::MessageOut { + sender, + recipient, + amount, + nonce, + len, + digest, + data, + } => { + let _ = write!(output, " MessageOut\n Sender: {sender:?}\n Recipient: {recipient:?}\n Amount: {amount:?}\n Nonce: {nonce:?}\n Len: {len:?}\n Digest: {digest:?}\n Data: {data:?}\n"); + } + Receipt::Mint { + sub_id, + contract_id, + val, + pc, + is, + } => { + let _ = write!(output, " Mint\n Sub ID: {sub_id:?}\n Contract ID: {contract_id:?}\n Val: {val:?}\n PC: {pc:?}\n IS: {is:?}\n"); + } + Receipt::Burn { + sub_id, + contract_id, + val, + pc, + is, + } => { + let _ = write!(output, " Burn\n Sub ID: {sub_id:?}\n Contract ID: {contract_id:?}\n Val: {val:?}\n PC: {pc:?}\n IS: {is:?}\n"); + } + } } } @@ -154,12 +273,7 @@ impl TestContext { let result = harness::runs_in_vm(compiled.clone(), script_data, witness_data)?; let result = match result { harness::VMExecutionResult::Fuel(state, receipts) => { - if verbose { - for receipt in receipts.iter() { - print_receipt(receipt); - } - } - + print_receipts(output, &receipts); match state { ProgramState::Return(v) => TestResult::Return(v), ProgramState::ReturnData(digest) => { @@ -447,6 +561,8 @@ pub async fn run(filter_config: &FilterConfig, run_config: &RunConfig) -> Result continue; } + use std::fmt::Write; + let _ = writeln!(output, " {}", "Verbose Output".green().bold()); let result = if !filter_config.first_only { context .run(test, &mut output, run_config.verbose) @@ -466,7 +582,7 @@ pub async fn run(filter_config: &FilterConfig, run_config: &RunConfig) -> Result println!(" {}", "ok".green().bold()); // If verbosity is requested then print it out. - if run_config.verbose { + if run_config.verbose && !output.is_empty() { println!("{}", textwrap::indent(&output, " ")); } } diff --git a/test/src/ir_generation/mod.rs b/test/src/ir_generation/mod.rs index 682473d6a3e..34423253274 100644 --- a/test/src/ir_generation/mod.rs +++ b/test/src/ir_generation/mod.rs @@ -14,8 +14,9 @@ use sway_core::{ use sway_error::handler::Handler; use sway_ir::{ - create_inline_in_module_pass, register_known_passes, PassGroup, PassManager, ARGDEMOTION_NAME, - CONSTDEMOTION_NAME, DCE_NAME, MEMCPYOPT_NAME, MISCDEMOTION_NAME, RETDEMOTION_NAME, + create_inline_in_module_pass, register_known_passes, ExperimentalFlags, PassGroup, PassManager, + ARGDEMOTION_NAME, CONSTDEMOTION_NAME, DCE_NAME, MEMCPYOPT_NAME, MISCDEMOTION_NAME, + RETDEMOTION_NAME, }; enum Checker { @@ -162,7 +163,11 @@ fn pretty_print_error_report(error: &str) { } } -pub(super) async fn run(filter_regex: Option<®ex::Regex>, verbose: bool) -> Result<()> { +pub(super) async fn run( + filter_regex: Option<®ex::Regex>, + verbose: bool, + experimental: ExperimentalFlags, +) -> Result<()> { // Compile core library and reuse it when compiling tests. let engines = Engines::default(); let build_target = BuildTarget::default(); @@ -216,7 +221,7 @@ pub(super) async fn run(filter_regex: Option<®ex::Regex>, verbose: bool) -> R build_target, ); // Include unit tests in the build. - let bld_cfg = bld_cfg.include_tests(true); + let bld_cfg = bld_cfg.with_include_tests(true); let sway_str = String::from_utf8_lossy(&sway_str); let handler = Handler::default(); let compile_res = compile_to_ast( @@ -247,7 +252,9 @@ pub(super) async fn run(filter_regex: Option<®ex::Regex>, verbose: bool) -> R // Compile to IR. let include_tests = true; - let mut ir = compile_program(typed_program, include_tests, &engines) + let mut ir = compile_program(typed_program, include_tests, &engines, sway_core::ExperimentalFlags { + new_encoding: experimental.new_encoding, + }) .unwrap_or_else(|e| { use sway_types::span::Spanned; let e = e[0].clone(); @@ -342,7 +349,10 @@ pub(super) async fn run(filter_regex: Option<®ex::Regex>, verbose: bool) -> R // Parse the IR again avoiding mutating the original ir let mut ir = sway_ir::parser::parse( &ir_output, - engines.se() + engines.se(), + sway_ir::ExperimentalFlags { + new_encoding: experimental.new_encoding, + } ) .unwrap_or_else(|e| panic!("{}: {e}\n{ir_output}", path.display())); @@ -437,7 +447,9 @@ pub(super) async fn run(filter_regex: Option<®ex::Regex>, verbose: bool) -> R } // Parse the IR again, and print it yet again to make sure that IR de/serialisation works. - let parsed_ir = sway_ir::parser::parse(&ir_output, engines.se()) + let parsed_ir = sway_ir::parser::parse(&ir_output, engines.se(), sway_ir::ExperimentalFlags { + new_encoding: experimental.new_encoding + }) .unwrap_or_else(|e| panic!("{}: {e}\n{ir_output}", path.display())); let parsed_ir_output = sway_ir::printer::to_string(&parsed_ir); if ir_output != parsed_ir_output { diff --git a/test/src/main.rs b/test/src/main.rs index 3d228f016fc..2274b8d2446 100644 --- a/test/src/main.rs +++ b/test/src/main.rs @@ -6,7 +6,7 @@ use anyhow::Result; use clap::Parser; use forc_tracing::init_tracing_subscriber; use std::str::FromStr; -use sway_core::BuildTarget; +use sway_core::{BuildTarget, ExperimentalFlags}; use tracing::Instrument; #[derive(Parser)] @@ -46,6 +46,10 @@ struct Cli { /// Build target. #[arg(long, visible_alias = "target")] build_target: Option, + + /// Experimental flag for new encoding + #[arg(long)] + experimental_new_encoding: bool, } #[derive(Debug, Clone)] @@ -63,6 +67,7 @@ pub struct RunConfig { pub build_target: BuildTarget, pub locked: bool, pub verbose: bool, + pub experimental: ExperimentalFlags, } #[tokio::main] @@ -90,6 +95,9 @@ async fn main() -> Result<()> { locked: cli.locked, verbose: cli.verbose, build_target, + experimental: sway_core::ExperimentalFlags { + new_encoding: cli.experimental_new_encoding, + }, }; // Check that the tests are consistent @@ -103,9 +111,15 @@ async fn main() -> Result<()> { // Run IR tests if !filter_config.first_only { println!("\n"); - ir_generation::run(filter_config.include.as_ref(), cli.verbose) - .instrument(tracing::trace_span!("IR")) - .await?; + ir_generation::run( + filter_config.include.as_ref(), + cli.verbose, + sway_ir::ExperimentalFlags { + new_encoding: run_config.experimental.new_encoding, + }, + ) + .instrument(tracing::trace_span!("IR")) + .await?; } Ok(())