From 501df7a4b59e72109c18ff73b5f7c0dc82052422 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Mon, 24 Apr 2023 10:56:32 +0100 Subject: [PATCH] Improves error message when log is used in predicate. Previously when log was used in predicate the error message would be: `Internal compiler error: Unable to determine ID for log instance.` Now the error message is: `Using intrinsic "log" in a predicate is not allowed.` Closes #4415 --- sway-core/src/ir_generation.rs | 9 ++++++++- sway-core/src/ir_generation/function.rs | 7 +++++++ sway-error/src/error.rs | 3 +++ sway-ir/src/context.rs | 7 +++++-- .../should_fail/predicate_log/Forc.lock | 13 +++++++++++++ .../should_fail/predicate_log/Forc.toml | 9 +++++++++ .../should_fail/predicate_log/src/main.sw | 12 ++++++++++++ .../should_fail/predicate_log/test.toml | 4 ++++ 8 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/test.toml diff --git a/sway-core/src/ir_generation.rs b/sway-core/src/ir_generation.rs index 0ef23f5e4a0..e2a18516397 100644 --- a/sway-core/src/ir_generation.rs +++ b/sway-core/src/ir_generation.rs @@ -8,7 +8,7 @@ pub mod storage; mod types; use sway_error::error::CompileError; -use sway_ir::Context; +use sway_ir::{Context, Kind}; use sway_types::span::Span; pub(crate) use purity::{check_function_purity, PurityEnv}; @@ -48,6 +48,13 @@ pub fn compile_program( .collect(); let mut ctx = Context::default(); + ctx.program_kind = match kind { + ty::TyProgramKind::Script { .. } => Kind::Script, + ty::TyProgramKind::Predicate { .. } => Kind::Predicate, + ty::TyProgramKind::Contract { .. } => Kind::Contract, + ty::TyProgramKind::Library { .. } => Kind::Library, + }; + match kind { // predicates and scripts have the same codegen, their only difference is static // type-check time checks. diff --git a/sway-core/src/ir_generation/function.rs b/sway-core/src/ir_generation/function.rs index 7a835695945..a6a1b4a833b 100644 --- a/sway-core/src/ir_generation/function.rs +++ b/sway-core/src/ir_generation/function.rs @@ -746,6 +746,13 @@ impl<'eng> FnCompiler<'eng> { } } Intrinsic::Log => { + if context.program_kind == Kind::Predicate { + return Err(CompileError::DisallowedIntrinsicInPredicate { + intrinsic: kind.to_string(), + span: span.clone(), + }); + } + // The log value and the log ID are just Value. let log_val = self.compile_expression_to_value(context, md_mgr, &arguments[0])?; let log_id = match self.logged_types_map.get(&arguments[0].return_type) { diff --git a/sway-error/src/error.rs b/sway-error/src/error.rs index af52766f813..b8b6b6bad7b 100644 --- a/sway-error/src/error.rs +++ b/sway-error/src/error.rs @@ -612,6 +612,8 @@ pub enum CompileError { CallingPrivateLibraryMethod { name: String, span: Span }, #[error("Using \"while\" in a predicate is not allowed.")] DisallowedWhileInPredicate { span: Span }, + #[error("Using intrinsic \"{intrinsic}\" in a predicate is not allowed.")] + DisallowedIntrinsicInPredicate { intrinsic: String, span: Span }, #[error("Possibly non-zero amount of coins transferred to non-payable contract method \"{fn_name}\".")] CoinsPassedToNonPayableMethod { fn_name: Ident, span: Span }, #[error( @@ -799,6 +801,7 @@ impl Spanned for CompileError { DisallowedControlFlowInstruction { span, .. } => span.clone(), CallingPrivateLibraryMethod { span, .. } => span.clone(), DisallowedWhileInPredicate { span } => span.clone(), + DisallowedIntrinsicInPredicate { span, .. } => span.clone(), CoinsPassedToNonPayableMethod { span, .. } => span.clone(), TraitImplPayabilityMismatch { span, .. } => span.clone(), ConfigurableInLibrary { span } => span.clone(), diff --git a/sway-ir/src/context.rs b/sway-ir/src/context.rs index 7b1625d5aca..49e79d58b75 100644 --- a/sway-ir/src/context.rs +++ b/sway-ir/src/context.rs @@ -11,8 +11,8 @@ use rustc_hash::FxHashMap; use crate::{ asm::AsmBlockContent, block::BlockContent, function::FunctionContent, - local_var::LocalVarContent, metadata::Metadatum, module::ModuleContent, module::ModuleIterator, - value::ValueContent, Type, TypeContent, + local_var::LocalVarContent, metadata::Metadatum, module::Kind, module::ModuleContent, + module::ModuleIterator, value::ValueContent, Type, TypeContent, }; /// The main IR context handle. @@ -30,6 +30,8 @@ pub struct Context { pub(crate) asm_blocks: Arena, pub(crate) metadata: Arena, + pub program_kind: Kind, + next_unique_sym_tag: u64, } @@ -46,6 +48,7 @@ impl Default for Context { asm_blocks: Default::default(), metadata: Default::default(), next_unique_sym_tag: Default::default(), + program_kind: Kind::Contract, }; Type::create_basic_types(&mut def); def diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/Forc.lock new file mode 100644 index 00000000000..6ad7d6c3e1b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = 'core' +source = 'path+from-root-58F9DCE1E1853B21' + +[[package]] +name = 'predicate_log' +source = 'member' +dependencies = ['std'] + +[[package]] +name = 'std' +source = 'path+from-root-58F9DCE1E1853B21' +dependencies = ['core'] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/Forc.toml new file mode 100644 index 00000000000..986604b7986 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "predicate_log" +entry = "main.sw" +implicit-std = false + +[dependencies] +std = { path = "../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/src/main.sw new file mode 100644 index 00000000000..d49bb4e3bbe --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/src/main.sw @@ -0,0 +1,12 @@ +predicate; + +use std::{ + inputs::input_owner, + logging::log, +}; + +fn main() -> bool { + log::
(input_owner(0).unwrap()); + + true +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/test.toml new file mode 100644 index 00000000000..116efc6a488 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/predicate_log/test.toml @@ -0,0 +1,4 @@ +category = "fail" + +# check: __log::(value); +# nextln: $()Using intrinsic "log" in a predicate is not allowed.