From 461ce8078246933547a46732c716c84b50dfd86f Mon Sep 17 00:00:00 2001 From: Francesco Leacche Date: Wed, 17 Sep 2025 14:42:44 +0200 Subject: [PATCH 01/34] rename InterpreterError -> VmInternalError --- clarity-types/src/errors/mod.rs | 22 +-- clarity-types/src/tests/types/mod.rs | 130 +++++++++--------- .../src/tests/types/serialization.rs | 14 +- clarity-types/src/types/mod.rs | 66 ++++----- clarity-types/src/types/serialization.rs | 8 +- clarity/src/vm/callables.rs | 8 +- clarity/src/vm/contexts.rs | 32 ++--- clarity/src/vm/database/clarity_db.rs | 96 ++++++------- clarity/src/vm/database/clarity_store.rs | 10 +- clarity/src/vm/database/key_value_wrapper.rs | 38 ++--- clarity/src/vm/database/sqlite.rs | 34 ++--- clarity/src/vm/database/structures.rs | 99 +++++++------ clarity/src/vm/errors.rs | 2 +- clarity/src/vm/functions/arithmetic.rs | 6 +- clarity/src/vm/functions/assets.rs | 22 +-- clarity/src/vm/functions/conversions.rs | 16 +-- clarity/src/vm/functions/crypto.rs | 12 +- clarity/src/vm/functions/database.rs | 10 +- clarity/src/vm/functions/mod.rs | 6 +- clarity/src/vm/functions/options.rs | 4 +- clarity/src/vm/functions/principals.rs | 18 +-- clarity/src/vm/functions/tuples.rs | 4 +- clarity/src/vm/mod.rs | 18 +-- clarity/src/vm/types/serialization.rs | 6 +- clarity/src/vm/variables.rs | 4 +- .../src/chainstate/stacks/db/transactions.rs | 2 +- stackslib/src/clarity_vm/database/marf.rs | 54 ++++---- 27 files changed, 369 insertions(+), 372 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 58b42b8a99..3c579d661c 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -44,15 +44,15 @@ pub enum Error { /// TypeChecker and other check passes. Test executions may /// trigger these errors. Unchecked(CheckErrors), - Interpreter(InterpreterError), + Interpreter(VmInternalError), Runtime(RuntimeErrorType, Option), ShortReturn(ShortReturnType), } -/// InterpreterErrors are errors that *should never* occur. +/// VmInternalErrors are errors that *should never* occur. /// Test executions may trigger these errors. #[derive(Debug, PartialEq)] -pub enum InterpreterError { +pub enum VmInternalError { BadSymbolicRepresentation(String), InterpreterError(String), FailedToConstructAssetTable, @@ -168,7 +168,7 @@ impl error::Error for RuntimeErrorType { impl From for Error { fn from(err: ParseError) -> Self { match *err.err { - ParseErrors::InterpreterFailure => Error::from(InterpreterError::Expect( + ParseErrors::InterpreterFailure => Error::from(VmInternalError::Expect( "Unexpected interpreter failure during parsing".into(), )), _ => Error::from(RuntimeErrorType::ASTError(Box::new(err))), @@ -179,10 +179,10 @@ impl From for Error { impl From for Error { fn from(err: CostErrors) -> Self { match err { - CostErrors::InterpreterFailure => Error::from(InterpreterError::Expect( + CostErrors::InterpreterFailure => Error::from(VmInternalError::Expect( "Interpreter failure during cost calculation".into(), )), - CostErrors::Expect(s) => Error::from(InterpreterError::Expect(format!( + CostErrors::Expect(s) => Error::from(VmInternalError::Expect(format!( "Interpreter failure during cost calculation: {s}" ))), other_err => Error::from(CheckErrors::from(other_err)), @@ -214,8 +214,8 @@ impl From for Error { } } -impl From for Error { - fn from(err: InterpreterError) -> Self { +impl From for Error { + fn from(err: VmInternalError) -> Self { Error::Interpreter(err) } } @@ -245,12 +245,12 @@ mod test { Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))) ); assert_eq!( - Error::Interpreter(InterpreterError::InterpreterError("".to_string())), - Error::Interpreter(InterpreterError::InterpreterError("".to_string())) + Error::Interpreter(VmInternalError::InterpreterError("".to_string())), + Error::Interpreter(VmInternalError::InterpreterError("".to_string())) ); assert!( Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))) - != Error::Interpreter(InterpreterError::InterpreterError("".to_string())) + != Error::Interpreter(VmInternalError::InterpreterError("".to_string())) ); } } diff --git a/clarity-types/src/tests/types/mod.rs b/clarity-types/src/tests/types/mod.rs index 8c8d861c7c..37708f0aa5 100644 --- a/clarity-types/src/tests/types/mod.rs +++ b/clarity-types/src/tests/types/mod.rs @@ -19,7 +19,7 @@ use rstest::rstest; use stacks_common::types::StacksEpochId; use crate::Error; -use crate::errors::{CheckErrors, InterpreterError, RuntimeErrorType}; +use crate::errors::{CheckErrors, RuntimeErrorType, VmInternalError}; use crate::types::{ ASCIIData, BuffData, CharType, ListTypeData, MAX_VALUE_SIZE, PrincipalData, QualifiedContractIdentifier, SequenceData, SequencedValue as _, StandardPrincipalData, @@ -34,7 +34,7 @@ fn test_constructors() { vec![Value::Int(5), Value::Int(2)], ListTypeData::new_list(TypeSignature::BoolType, 3).unwrap() ), - Err(InterpreterError::FailureConstructingListWithType.into()) + Err(VmInternalError::FailureConstructingListWithType.into()) ); assert_eq!( ListTypeData::new_list(TypeSignature::IntType, MAX_VALUE_SIZE), @@ -289,7 +289,7 @@ fn test_principal_data_parse_standard_principal_returns_runtime_error( ))] #[case::invalid_contract_name("SM2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0G.1nvalid-name", RuntimeErrorType::BadNameValue("ContractName", "1nvalid-name".into()))] -fn test_qualified_contract_identifier_parse_returns_interpreter_error( +fn test_qualified_contract_identifier_parse_returns_vm_internal_error( #[case] input: &str, #[case] expected_err: RuntimeErrorType, ) { @@ -336,58 +336,58 @@ fn test_trait_identifier_parse_fully_qualified_returns_runtime_error( assert_eq!(Error::from(expected_err), err); } -/// The returned InterpreterError is consensus-critical. +/// The returned VMInternalError is consensus-critical. #[test] -fn test_standard_principal_data_new_returns_interpreter_error_consensus_critical() { +fn test_standard_principal_data_new_returns_vm_internal_error_consensus_critical() { let result = StandardPrincipalData::new(32, [0; 20]); let err = result.expect_err("Unexpected principal data"); assert_eq!( - Error::from(InterpreterError::Expect("Unexpected principal data".into())), + Error::from(VmInternalError::Expect("Unexpected principal data".into())), err.into(), ); } -/// The returned InterpreterError is consensus-critical. +/// The returned VMInternalError is consensus-critical. #[test] -fn test_sequence_data_element_at_returns_interpreter_error_consensus_critical() { +fn test_sequence_data_element_at_returns_vm_internal_error_consensus_critical() { let buff = SequenceData::String(CharType::ASCII(ASCIIData { data: vec![1] })); let err = buff.element_at(0).unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + Error::from(VmInternalError::Expect( "BUG: failed to initialize single-byte ASCII buffer".into() )), err ); } -/// The returned InterpreterError is consensus-critical. +/// The returned VMInternalError is consensus-critical. #[test] -fn test_ascii_data_to_value_returns_interpreter_error_consensus_critical() { +fn test_ascii_data_to_value_returns_vm_internal_error_consensus_critical() { let err = ASCIIData::to_value(&1).unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + Error::from(VmInternalError::Expect( "ERROR: Invalid ASCII string successfully constructed".into() )), err ); } -/// The returned InterpreterError is consensus-critical. +/// The returned VMInternalError is consensus-critical. #[test] -fn test_utf8_data_to_value_returns_interpreter_error_consensus_critical() { +fn test_utf8_data_to_value_returns_vm_internal_error_consensus_critical() { let err = UTF8Data::to_value(&vec![0xED, 0xA0, 0x80]).unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + Error::from(VmInternalError::Expect( "ERROR: Invalid UTF8 string successfully constructed".into() )), err ); } -/// The returned InterpreterError is consensus-critical. +/// The returned VMInternalError is consensus-critical. #[test] -fn test_tuple_data_from_data_typed_returns_interpreter_error_consensus_critical() { +fn test_tuple_data_from_data_typed_returns_vm_internal_error_consensus_critical() { let tuple_type = TupleTypeSignature::try_from(vec![("a".into(), TypeSignature::IntType)]).unwrap(); let err = TupleData::from_data_typed( @@ -397,159 +397,159 @@ fn test_tuple_data_from_data_typed_returns_interpreter_error_consensus_critical( ) .unwrap_err(); assert_eq!( - Error::from(InterpreterError::FailureConstructingTupleWithType), + Error::from(VmInternalError::FailureConstructingTupleWithType), err ); } #[rstest] -#[case::not_a_string(Value::none(), InterpreterError::Expect("Expected ASCII string".to_string()))] -#[case::invalid_utf8(Value::Sequence(SequenceData::String(CharType::ASCII(ASCIIData { data: vec![0xED, 0xA0, 0x80] }))), InterpreterError::Expect("Non UTF-8 data in string".to_string()))] -fn test_value_expect_ascii_returns_interpreter_error( +#[case::not_a_string(Value::none(), VmInternalError::Expect("Expected ASCII string".to_string()))] +#[case::invalid_utf8(Value::Sequence(SequenceData::String(CharType::ASCII(ASCIIData { data: vec![0xED, 0xA0, 0x80] }))), VmInternalError::Expect("Non UTF-8 data in string".to_string()))] +fn test_value_expect_ascii_returns_vm_internal_error( #[case] value: Value, - #[case] expected_err: InterpreterError, + #[case] expected_err: VmInternalError, ) { let err = value.expect_ascii().unwrap_err(); assert_eq!(Error::from(expected_err), err); } -/// The returned InterpreterError is consensus-critical. +/// The returned VMInternalError is consensus-critical. #[test] -fn test_value_expect_u128_returns_interpreter_error_consensus_critical() { +fn test_value_expect_u128_returns_vm_internal_error_consensus_critical() { let err = Value::none().expect_u128().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected u128".to_string())), + Error::from(VmInternalError::Expect("Expected u128".to_string())), err ); } #[test] -fn test_value_expect_i128_returns_interpreter_error() { +fn test_value_expect_i128_returns_vm_internal_error() { let err = Value::none().expect_i128().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected i128".to_string())), + Error::from(VmInternalError::Expect("Expected i128".to_string())), err ); } #[rstest] -#[case::not_a_buffer(Value::none(), InterpreterError::Expect("Expected buff".to_string()))] -#[case::too_small(Value::buff_from(vec![1, 2, 3, 4]).unwrap(), InterpreterError::Expect("Unexpected buff length".to_string()))] -fn test_value_expect_buff_returns_interpreter_error( +#[case::not_a_buffer(Value::none(), VmInternalError::Expect("Expected buff".to_string()))] +#[case::too_small(Value::buff_from(vec![1, 2, 3, 4]).unwrap(), VmInternalError::Expect("Unexpected buff length".to_string()))] +fn test_value_expect_buff_returns_vm_internal_error( #[case] value: Value, - #[case] expected_err: InterpreterError, + #[case] expected_err: VmInternalError, ) { let err = value.expect_buff(1).unwrap_err(); assert_eq!(Error::from(expected_err), err); } #[test] -fn test_value_expect_tuple_returns_interpreter_error() { +fn test_value_expect_tuple_returns_vm_internal_error() { let err = Value::none().expect_tuple().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected tuple".to_string())), + Error::from(VmInternalError::Expect("Expected tuple".to_string())), err ); } #[test] -fn test_value_expect_list_returns_interpreter_error() { +fn test_value_expect_list_returns_vm_internal_error() { let err = Value::none().expect_list().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected list".to_string())), + Error::from(VmInternalError::Expect("Expected list".to_string())), err ); } #[test] -fn test_value_expect_buff_padded_returns_interpreter_error() { +fn test_value_expect_buff_padded_returns_vm_internal_error() { let err = Value::none().expect_buff_padded(10, 0).unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected buff".to_string())), + Error::from(VmInternalError::Expect("Expected buff".to_string())), err ); } #[test] -fn test_value_expect_bool_returns_interpreter_error() { +fn test_value_expect_bool_returns_vm_internal_error() { let err = Value::none().expect_bool().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected bool".to_string())), + Error::from(VmInternalError::Expect("Expected bool".to_string())), err ); } -/// The returned InterpreterError is consensus-critical. +/// The returned VMInternalError is consensus-critical. #[test] -fn test_value_expect_optional_returns_interpreter_error_consensus_critical() { +fn test_value_expect_optional_returns_vm_internal_error_consensus_critical() { let err = Value::okay_true().expect_optional().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected optional".to_string())), + Error::from(VmInternalError::Expect("Expected optional".to_string())), err ); } -/// The returned InterpreterError is consensus-critical. +/// The returned VMInternalError is consensus-critical. #[test] -fn test_value_expect_principal_returns_interpreter_error_consensus_critical() { +fn test_value_expect_principal_returns_vm_internal_error_consensus_critical() { let err = Value::none().expect_principal().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected principal".to_string())), + Error::from(VmInternalError::Expect("Expected principal".to_string())), err ); } -/// The returned InterpreterError is consensus-critical. +/// The returned VMInternalError is consensus-critical. #[test] -fn test_value_expect_callable_returns_interpreter_error_consensus_critical() { +fn test_value_expect_callable_returns_vm_internal_error_consensus_critical() { let err = Value::none().expect_callable().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected callable".to_string())), + Error::from(VmInternalError::Expect("Expected callable".to_string())), err ); } #[test] -fn test_value_expect_result_returns_interpreter_error() { +fn test_value_expect_result_returns_vm_internal_error() { let err = Value::none().expect_result().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected response".to_string())), + Error::from(VmInternalError::Expect("Expected response".to_string())), err ); } #[rstest] -#[case::not_a_response(Value::none(), InterpreterError::Expect("Expected response".to_string()))] -#[case::not_an_ok_response(Value::error(Value::Int(1)).unwrap(), InterpreterError::Expect("Expected ok response".to_string()))] -fn test_value_expect_result_ok_returns_interpreter_error( +#[case::not_a_response(Value::none(), VmInternalError::Expect("Expected response".to_string()))] +#[case::not_an_ok_response(Value::error(Value::Int(1)).unwrap(), VmInternalError::Expect("Expected ok response".to_string()))] +fn test_value_expect_result_ok_returns_vm_internal_error( #[case] value: Value, - #[case] expected_err: InterpreterError, + #[case] expected_err: VmInternalError, ) { let err = value.expect_result_ok().unwrap_err(); assert_eq!(Error::from(expected_err), err); } #[rstest] -#[case::not_a_response(Value::none(), InterpreterError::Expect("Expected response".to_string()))] -#[case::not_an_err_response(Value::okay_true(), InterpreterError::Expect("Expected err response".to_string()))] -fn test_value_expect_result_err_returns_interpreter_error( +#[case::not_a_response(Value::none(), VmInternalError::Expect("Expected response".to_string()))] +#[case::not_an_err_response(Value::okay_true(), VmInternalError::Expect("Expected err response".to_string()))] +fn test_value_expect_result_err_returns_vm_internal_error( #[case] value: Value, - #[case] expected_err: InterpreterError, + #[case] expected_err: VmInternalError, ) { let err = value.expect_result_err().unwrap_err(); assert_eq!(Error::from(expected_err), err); } -/// The returned InterpreterError is consensus-critical. +/// The returned VMInternalError is consensus-critical. #[test] -fn test_buff_data_len_returns_interpreter_error_consensus_critical() { +fn test_buff_data_len_returns_vm_internal_error_consensus_critical() { let err = BuffData { data: vec![1; MAX_VALUE_SIZE as usize + 1], } .len() .unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + Error::from(VmInternalError::Expect( "Data length should be valid".into() )), err @@ -557,14 +557,14 @@ fn test_buff_data_len_returns_interpreter_error_consensus_critical() { } #[test] -fn test_ascii_data_len_returns_interpreter_error() { +fn test_ascii_data_len_returns_vm_internal_error() { let err = ASCIIData { data: vec![1; MAX_VALUE_SIZE as usize + 1], } .len() .unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + Error::from(VmInternalError::Expect( "Data length should be valid".into() )), err @@ -572,14 +572,14 @@ fn test_ascii_data_len_returns_interpreter_error() { } #[test] -fn test_utf8_data_len_returns_interpreter_error() { +fn test_utf8_data_len_returns_vm_internal_error() { let err = UTF8Data { data: vec![vec![]; MAX_VALUE_SIZE as usize + 1], } .len() .unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + Error::from(VmInternalError::Expect( "Data length should be valid".into() )), err diff --git a/clarity-types/src/tests/types/serialization.rs b/clarity-types/src/tests/types/serialization.rs index 679befd351..59d2f4d36b 100644 --- a/clarity-types/src/tests/types/serialization.rs +++ b/clarity-types/src/tests/types/serialization.rs @@ -15,7 +15,7 @@ use std::io::Write; use crate::Error; -use crate::errors::{CheckErrors, InterpreterError}; +use crate::errors::{CheckErrors, VmInternalError}; use crate::types::serialization::SerializationError; use crate::types::{ ASCIIData, CharType, MAX_VALUE_SIZE, PrincipalData, QualifiedContractIdentifier, SequenceData, @@ -416,30 +416,30 @@ fn test_principals() { test_bad_expectation(standard_p, TypeSignature::BoolType); } -/// The returned InterpreterError is consensus-critical. +/// The returned VmInternalError is consensus-critical. #[test] -fn test_serialize_to_vec_returns_interpreter_error_consensus_critical() { +fn test_serialize_to_vec_returns_vm_internal_error_consensus_critical() { let value = Value::Sequence(SequenceData::String(CharType::ASCII(ASCIIData { data: vec![0; MAX_VALUE_SIZE as usize + 1], }))); let err = value.serialize_to_vec().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + Error::from(VmInternalError::Expect( "IOError filling byte buffer.".into() )), err.into() ); } -/// The returned InterpreterError is consensus-critical. +/// The returned VmInternalError is consensus-critical. #[test] -fn test_serialize_to_hex_returns_interpreter_error_consensus_critical() { +fn test_serialize_to_hex_returns_vm_internal_error_consensus_critical() { let value = Value::Sequence(SequenceData::String(CharType::ASCII(ASCIIData { data: vec![0; MAX_VALUE_SIZE as usize + 1], }))); let err = value.serialize_to_hex().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + Error::from(VmInternalError::Expect( "IOError filling byte buffer.".into() )), err.into() diff --git a/clarity-types/src/types/mod.rs b/clarity-types/src/types/mod.rs index c28dc0c275..30c38fea85 100644 --- a/clarity-types/src/types/mod.rs +++ b/clarity-types/src/types/mod.rs @@ -37,7 +37,7 @@ pub use self::signatures::{ ListTypeData, SequenceSubtype, StringSubtype, StringUTF8Length, TupleTypeSignature, TypeSignature, }; -use crate::errors::{CheckErrors, InterpreterError, InterpreterResult as Result, RuntimeErrorType}; +use crate::errors::{CheckErrors, InterpreterResult as Result, RuntimeErrorType, VmInternalError}; use crate::representations::{ClarityName, ContractName, SymbolicExpression}; // use crate::vm::ClarityVersion; @@ -81,9 +81,9 @@ impl StandardPrincipalData { } impl StandardPrincipalData { - pub fn new(version: u8, bytes: [u8; 20]) -> std::result::Result { + pub fn new(version: u8, bytes: [u8; 20]) -> std::result::Result { if version >= 32 { - return Err(InterpreterError::Expect("Unexpected principal data".into())); + return Err(VmInternalError::Expect("Unexpected principal data".into())); } Ok(Self(version, bytes)) } @@ -372,7 +372,7 @@ impl SequenceData { SequenceData::List(mut data) => data.data.remove(index), SequenceData::String(CharType::ASCII(data)) => { Value::string_ascii_from_bytes(vec![data.data[index]]).map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "BUG: failed to initialize single-byte ASCII buffer".into(), ) })? @@ -770,7 +770,7 @@ impl SequencedValue for ASCIIData { fn to_value(v: &u8) -> Result { Value::string_ascii_from_bytes(vec![*v]).map_err(|_| { - InterpreterError::Expect("ERROR: Invalid ASCII string successfully constructed".into()) + VmInternalError::Expect("ERROR: Invalid ASCII string successfully constructed".into()) .into() }) } @@ -796,7 +796,7 @@ impl SequencedValue> for UTF8Data { fn to_value(v: &Vec) -> Result { Value::string_utf8_from_bytes(v.clone()).map_err(|_| { - InterpreterError::Expect("ERROR: Invalid UTF8 string successfully constructed".into()) + VmInternalError::Expect("ERROR: Invalid UTF8 string successfully constructed".into()) .into() }) } @@ -930,7 +930,7 @@ impl Value { // be greater than MAX_VALUE_SIZE (they error on such constructions) // so we do not need to perform that check here. if (expected_type.get_max_len() as usize) < list_data.len() { - return Err(InterpreterError::FailureConstructingListWithType.into()); + return Err(VmInternalError::FailureConstructingListWithType.into()); } { @@ -938,7 +938,7 @@ impl Value { for item in &list_data { if !expected_item_type.admits(epoch, item)? { - return Err(InterpreterError::FailureConstructingListWithType.into()); + return Err(VmInternalError::FailureConstructingListWithType.into()); } } } @@ -1016,7 +1016,7 @@ impl Value { pub fn string_utf8_from_string_utf8_literal(tokenized_str: String) -> Result { let wrapped_codepoints_matcher = Regex::new("^\\\\u\\{(?P[[:xdigit:]]+)\\}") - .map_err(|_| InterpreterError::Expect("Bad regex".into()))?; + .map_err(|_| VmInternalError::Expect("Bad regex".into()))?; let mut window = tokenized_str.as_str(); let mut cursor = 0; let mut data: Vec> = vec![]; @@ -1024,7 +1024,7 @@ impl Value { if let Some(captures) = wrapped_codepoints_matcher.captures(window) { let matched = captures .name("value") - .ok_or_else(|| InterpreterError::Expect("Expected capture".into()))?; + .ok_or_else(|| VmInternalError::Expect("Expected capture".into()))?; let scalar_value = window[matched.start()..matched.end()].to_string(); let unicode_char = { let u = u32::from_str_radix(&scalar_value, 16) @@ -1077,10 +1077,10 @@ impl Value { pub fn expect_ascii(self) -> Result { if let Value::Sequence(SequenceData::String(CharType::ASCII(ASCIIData { data }))) = self { Ok(String::from_utf8(data) - .map_err(|_| InterpreterError::Expect("Non UTF-8 data in string".into()))?) + .map_err(|_| VmInternalError::Expect("Non UTF-8 data in string".into()))?) } else { error!("Value '{self:?}' is not an ASCII string"); - Err(InterpreterError::Expect("Expected ASCII string".into()).into()) + Err(VmInternalError::Expect("Expected ASCII string".into()).into()) } } @@ -1089,7 +1089,7 @@ impl Value { Ok(inner) } else { error!("Value '{self:?}' is not a u128"); - Err(InterpreterError::Expect("Expected u128".into()).into()) + Err(VmInternalError::Expect("Expected u128".into()).into()) } } @@ -1098,7 +1098,7 @@ impl Value { Ok(inner) } else { error!("Value '{self:?}' is not an i128"); - Err(InterpreterError::Expect("Expected i128".into()).into()) + Err(VmInternalError::Expect("Expected i128".into()).into()) } } @@ -1111,11 +1111,11 @@ impl Value { "Value buffer has len {}, expected {sz}", buffdata.data.len() ); - Err(InterpreterError::Expect("Unexpected buff length".into()).into()) + Err(VmInternalError::Expect("Unexpected buff length".into()).into()) } } else { error!("Value '{self:?}' is not a buff"); - Err(InterpreterError::Expect("Expected buff".into()).into()) + Err(VmInternalError::Expect("Expected buff".into()).into()) } } @@ -1124,7 +1124,7 @@ impl Value { Ok(listdata.data) } else { error!("Value '{self:?}' is not a list"); - Err(InterpreterError::Expect("Expected list".into()).into()) + Err(VmInternalError::Expect("Expected list".into()).into()) } } @@ -1143,7 +1143,7 @@ impl Value { Ok(b) } else { error!("Value '{self:?}' is not a bool"); - Err(InterpreterError::Expect("Expected bool".into()).into()) + Err(VmInternalError::Expect("Expected bool".into()).into()) } } @@ -1152,7 +1152,7 @@ impl Value { Ok(data) } else { error!("Value '{self:?}' is not a tuple"); - Err(InterpreterError::Expect("Expected tuple".into()).into()) + Err(VmInternalError::Expect("Expected tuple".into()).into()) } } @@ -1164,7 +1164,7 @@ impl Value { } } else { error!("Value '{self:?}' is not an optional"); - Err(InterpreterError::Expect("Expected optional".into()).into()) + Err(VmInternalError::Expect("Expected optional".into()).into()) } } @@ -1173,7 +1173,7 @@ impl Value { Ok(p) } else { error!("Value '{self:?}' is not a principal"); - Err(InterpreterError::Expect("Expected principal".into()).into()) + Err(VmInternalError::Expect("Expected principal".into()).into()) } } @@ -1182,7 +1182,7 @@ impl Value { Ok(t) } else { error!("Value '{self:?}' is not a callable contract"); - Err(InterpreterError::Expect("Expected callable".into()).into()) + Err(VmInternalError::Expect("Expected callable".into()).into()) } } @@ -1195,7 +1195,7 @@ impl Value { } } else { error!("Value '{self:?}' is not a response"); - Err(InterpreterError::Expect("Expected response".into()).into()) + Err(VmInternalError::Expect("Expected response".into()).into()) } } @@ -1205,11 +1205,11 @@ impl Value { Ok(*res_data.data) } else { error!("Value is not a (ok ..)"); - Err(InterpreterError::Expect("Expected ok response".into()).into()) + Err(VmInternalError::Expect("Expected ok response".into()).into()) } } else { error!("Value '{self:?}' is not a response"); - Err(InterpreterError::Expect("Expected response".into()).into()) + Err(VmInternalError::Expect("Expected response".into()).into()) } } @@ -1219,11 +1219,11 @@ impl Value { Ok(*res_data.data) } else { error!("Value is not a (err ..)"); - Err(InterpreterError::Expect("Expected err response".into()).into()) + Err(VmInternalError::Expect("Expected err response".into()).into()) } } else { error!("Value '{self:?}' is not a response"); - Err(InterpreterError::Expect("Expected response".into()).into()) + Err(VmInternalError::Expect("Expected response".into()).into()) } } } @@ -1233,7 +1233,7 @@ impl BuffData { self.data .len() .try_into() - .map_err(|_| InterpreterError::Expect("Data length should be valid".into()).into()) + .map_err(|_| VmInternalError::Expect("Data length should be valid".into()).into()) } pub fn as_slice(&self) -> &[u8] { @@ -1255,7 +1255,7 @@ impl ListData { self.data .len() .try_into() - .map_err(|_| InterpreterError::Expect("Data length should be valid".into()).into()) + .map_err(|_| VmInternalError::Expect("Data length should be valid".into()).into()) } pub fn is_empty(&self) -> bool { @@ -1288,7 +1288,7 @@ impl ASCIIData { self.data .len() .try_into() - .map_err(|_| InterpreterError::Expect("Data length should be valid".into()).into()) + .map_err(|_| VmInternalError::Expect("Data length should be valid".into()).into()) } } @@ -1302,7 +1302,7 @@ impl UTF8Data { self.data .len() .try_into() - .map_err(|_| InterpreterError::Expect("Data length should be valid".into()).into()) + .map_err(|_| VmInternalError::Expect("Data length should be valid".into()).into()) } } @@ -1575,9 +1575,9 @@ impl TupleData { for (name, value) in data.into_iter() { let expected_type = expected .field_type(&name) - .ok_or(InterpreterError::FailureConstructingTupleWithType)?; + .ok_or(VmInternalError::FailureConstructingTupleWithType)?; if !expected_type.admits(epoch, &value)? { - return Err(InterpreterError::FailureConstructingTupleWithType.into()); + return Err(VmInternalError::FailureConstructingTupleWithType.into()); } data_map.insert(name, value); } diff --git a/clarity-types/src/types/serialization.rs b/clarity-types/src/types/serialization.rs index 2179efd824..1dde1fc073 100644 --- a/clarity-types/src/types/serialization.rs +++ b/clarity-types/src/types/serialization.rs @@ -23,7 +23,7 @@ use stacks_common::util::hash::{hex_bytes, to_hex}; use stacks_common::util::retry::BoundReader; use super::{ListTypeData, TupleTypeSignature}; -use crate::errors::{CheckErrors, IncomparableError, InterpreterError}; +use crate::errors::{CheckErrors, IncomparableError, VmInternalError}; use crate::representations::{ClarityName, ContractName, MAX_STRING_LEN}; use crate::types::{ BOUND_VALUE_SERIALIZATION_BYTES, BufferLength, CallableData, CharType, MAX_TYPE_DEPTH, @@ -1215,15 +1215,15 @@ impl Write for WriteCounter { } impl Value { - pub fn serialize_to_vec(&self) -> Result, InterpreterError> { + pub fn serialize_to_vec(&self) -> Result, VmInternalError> { let mut byte_serialization = Vec::new(); self.serialize_write(&mut byte_serialization) - .map_err(|_| InterpreterError::Expect("IOError filling byte buffer.".into()))?; + .map_err(|_| VmInternalError::Expect("IOError filling byte buffer.".into()))?; Ok(byte_serialization) } /// This does *not* perform any data sanitization - pub fn serialize_to_hex(&self) -> Result { + pub fn serialize_to_hex(&self) -> Result { let byte_serialization = self.serialize_to_vec()?; Ok(to_hex(byte_serialization.as_slice())) } diff --git a/clarity/src/vm/callables.rs b/clarity/src/vm/callables.rs index b697b3a095..d629b2a508 100644 --- a/clarity/src/vm/callables.rs +++ b/clarity/src/vm/callables.rs @@ -21,7 +21,7 @@ pub use clarity_types::types::FunctionIdentifier; use stacks_common::types::StacksEpochId; use super::costs::{CostErrors, CostOverflowingMath}; -use super::errors::InterpreterError; +use super::errors::VmInternalError; use super::types::signatures::CallableSubtype; use super::ClarityVersion; use crate::vm::analysis::errors::CheckErrors; @@ -89,17 +89,17 @@ impl NativeHandle { check_argument_count(1, &args)?; function( args.pop() - .ok_or_else(|| InterpreterError::Expect("Unexpected list length".into()))?, + .ok_or_else(|| VmInternalError::Expect("Unexpected list length".into()))?, ) } Self::DoubleArg(function) => { check_argument_count(2, &args)?; let second = args .pop() - .ok_or_else(|| InterpreterError::Expect("Unexpected list length".into()))?; + .ok_or_else(|| VmInternalError::Expect("Unexpected list length".into()))?; let first = args .pop() - .ok_or_else(|| InterpreterError::Expect("Unexpected list length".into()))?; + .ok_or_else(|| VmInternalError::Expect("Unexpected list length".into()))?; function(first, second) } Self::MoreArg(function) => function(args), diff --git a/clarity/src/vm/contexts.rs b/clarity/src/vm/contexts.rs index 355a0e9d53..2e78249297 100644 --- a/clarity/src/vm/contexts.rs +++ b/clarity/src/vm/contexts.rs @@ -37,7 +37,7 @@ use crate::vm::database::{ NonFungibleTokenMetadata, }; use crate::vm::errors::{ - CheckErrors, InterpreterError, InterpreterResult as Result, RuntimeErrorType, + CheckErrors, VmInternalError, InterpreterResult as Result, RuntimeErrorType, }; use crate::vm::events::*; use crate::vm::representations::SymbolicExpression; @@ -441,7 +441,7 @@ impl AssetMap { for principal in self.burn_map.keys() { total = total .checked_add(*self.burn_map.get(principal).unwrap_or(&0u128)) - .ok_or_else(|| InterpreterError::Expect("BURN OVERFLOW".into()))?; + .ok_or_else(|| VmInternalError::Expect("BURN OVERFLOW".into()))?; } Ok(total) } @@ -798,8 +798,8 @@ impl<'a, 'hooks> OwnedEnvironment<'a, 'hooks> { pub fn commit(&mut self) -> Result<(AssetMap, EventBatch)> { let (asset_map, event_batch) = self.context.commit()?; - let asset_map = asset_map.ok_or(InterpreterError::FailedToConstructAssetTable)?; - let event_batch = event_batch.ok_or(InterpreterError::FailedToConstructEventBatch)?; + let asset_map = asset_map.ok_or(VmInternalError::FailedToConstructAssetTable)?; + let event_batch = event_batch.ok_or(VmInternalError::FailedToConstructEventBatch)?; Ok((asset_map, event_batch)) } @@ -1126,7 +1126,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { let args: Result> = args.iter() .map(|arg| { let value = arg.match_atom_value() - .ok_or_else(|| InterpreterError::InterpreterError(format!("Passed non-value expression to exec_tx on {tx_name}!")))?; + .ok_or_else(|| VmInternalError::InterpreterError(format!("Passed non-value expression to exec_tx on {tx_name}!")))?; // sanitize contract-call inputs in epochs >= 2.4 // testing todo: ensure sanitize_value() preserves trait callability! let expected_type = TypeSignature::type_of(value)?; @@ -1230,7 +1230,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { .database .set_block_hash(prior_bhh, true) .map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "ERROR: Failed to restore prior active block after time-shifted evaluation." .into()) })?; @@ -1355,7 +1355,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { } Err(_) => { self.global_context.roll_back()?; - Err(InterpreterError::InsufficientBalance.into()) + Err(VmInternalError::InsufficientBalance.into()) } }, Err(e) => { @@ -1583,7 +1583,7 @@ impl<'a, 'hooks> GlobalContext<'a, 'hooks> { fn get_asset_map(&mut self) -> Result<&mut AssetMap> { self.asset_maps .last_mut() - .ok_or_else(|| InterpreterError::Expect("Failed to obtain asset map".into()).into()) + .ok_or_else(|| VmInternalError::Expect("Failed to obtain asset map".into()).into()) } pub fn log_asset_transfer( @@ -1700,10 +1700,10 @@ impl<'a, 'hooks> GlobalContext<'a, 'hooks> { trace!("Calling commit"); self.read_only.pop(); let asset_map = self.asset_maps.pop().ok_or_else(|| { - InterpreterError::Expect("ERROR: Committed non-nested context.".into()) + VmInternalError::Expect("ERROR: Committed non-nested context.".into()) })?; let mut event_batch = self.event_batches.pop().ok_or_else(|| { - InterpreterError::Expect("ERROR: Committed non-nested context.".into()) + VmInternalError::Expect("ERROR: Committed non-nested context.".into()) })?; let out_map = match self.asset_maps.last_mut() { @@ -1732,15 +1732,15 @@ impl<'a, 'hooks> GlobalContext<'a, 'hooks> { pub fn roll_back(&mut self) -> Result<()> { let popped = self.asset_maps.pop(); if popped.is_none() { - return Err(InterpreterError::Expect("Expected entry to rollback".into()).into()); + return Err(VmInternalError::Expect("Expected entry to rollback".into()).into()); } let popped = self.read_only.pop(); if popped.is_none() { - return Err(InterpreterError::Expect("Expected entry to rollback".into()).into()); + return Err(VmInternalError::Expect("Expected entry to rollback".into()).into()); } let popped = self.event_batches.pop(); if popped.is_none() { - return Err(InterpreterError::Expect("Expected entry to rollback".into()).into()); + return Err(VmInternalError::Expect("Expected entry to rollback".into()).into()); } self.database.roll_back() @@ -1961,20 +1961,20 @@ impl CallStack { pub fn remove(&mut self, function: &FunctionIdentifier, tracked: bool) -> Result<()> { if let Some(removed) = self.stack.pop() { if removed != *function { - return Err(InterpreterError::InterpreterError( + return Err(VmInternalError::InterpreterError( "Tried to remove item from empty call stack.".to_string(), ) .into()); } if tracked && !self.set.remove(function) { - return Err(InterpreterError::InterpreterError( + return Err(VmInternalError::InterpreterError( "Tried to remove tracked function from call stack, but could not find in current context.".into() ) .into()); } Ok(()) } else { - Err(InterpreterError::InterpreterError( + Err(VmInternalError::InterpreterError( "Tried to remove item from empty call stack.".to_string(), ) .into()) diff --git a/clarity/src/vm/database/clarity_db.rs b/clarity/src/vm/database/clarity_db.rs index a895b00ddb..f64cca0c35 100644 --- a/clarity/src/vm/database/clarity_db.rs +++ b/clarity/src/vm/database/clarity_db.rs @@ -38,7 +38,7 @@ use crate::vm::database::structures::{ }; use crate::vm::database::{ClarityBackingStore, RollbackWrapper}; use crate::vm::errors::{ - CheckErrors, Error, InterpreterError, InterpreterResult as Result, RuntimeErrorType, + CheckErrors, Error, VmInternalError, InterpreterResult as Result, RuntimeErrorType, }; use crate::vm::representations::ClarityName; use crate::vm::types::serialization::NONE_SERIALIZATION_LEN; @@ -548,7 +548,7 @@ impl<'a> ClarityDatabase<'a> { let serialized = if sanitize { let value_size = value .serialized_size() - .map_err(|e| InterpreterError::Expect(e.to_string()))? + .map_err(|e| VmInternalError::Expect(e.to_string()))? as u64; let (sanitized_value, did_sanitize) = @@ -578,7 +578,7 @@ impl<'a> ClarityDatabase<'a> { ) -> Result> { self.store .get_value(key, expected, epoch) - .map_err(|e| InterpreterError::DBError(e.to_string()).into()) + .map_err(|e| VmInternalError::DBError(e.to_string()).into()) } pub fn get_data_with_proof(&mut self, key: &str) -> Result)>> @@ -706,7 +706,7 @@ impl<'a> ClarityDatabase<'a> { data: &T, ) -> Result<()> { if self.store.has_metadata_entry(contract_identifier, key) { - Err(InterpreterError::Expect(format!( + Err(VmInternalError::Expect(format!( "Metadata entry '{key}' already exists for contract: {contract_identifier}" )) .into()) @@ -779,7 +779,7 @@ impl<'a> ClarityDatabase<'a> { let contract_size: u64 = self.fetch_metadata(contract_identifier, &key)? .ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "Failed to read non-consensus contract metadata, even though contract exists in MARF." .into()) })?; @@ -790,7 +790,7 @@ impl<'a> ClarityDatabase<'a> { let data_size: u64 = self .fetch_metadata(contract_identifier, &key)? .ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "Failed to read non-consensus contract metadata, even though contract exists in MARF." .into()) })?; @@ -812,7 +812,7 @@ impl<'a> ClarityDatabase<'a> { let contract_size: u64 = self.fetch_metadata(contract_identifier, &key)? .ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "Failed to read non-consensus contract metadata, even though contract exists in MARF." .into()) })?; @@ -856,7 +856,7 @@ impl<'a> ClarityDatabase<'a> { ContractDataVarName::Contract.as_str(), ); let mut data: Contract = self.fetch_metadata(contract_identifier, &key)? - .ok_or_else(|| InterpreterError::Expect( + .ok_or_else(|| VmInternalError::Expect( "Failed to read non-consensus contract metadata, even though contract exists in MARF." .into()))?; data.canonicalize_types(&self.get_clarity_epoch_version()?); @@ -874,7 +874,7 @@ impl<'a> ClarityDatabase<'a> { pub fn get_clarity_epoch_version(&mut self) -> Result { let out = match self.get_data(Self::clarity_state_epoch_key())? { Some(x) => u32::try_into(x).map_err(|_| { - InterpreterError::Expect("Bad Clarity epoch version in stored Clarity state".into()) + VmInternalError::Expect("Bad Clarity epoch version in stored Clarity state".into()) })?, None => StacksEpochId::Epoch20, }; @@ -892,7 +892,7 @@ impl<'a> ClarityDatabase<'a> { let epoch = self.get_clarity_epoch_version()?; if epoch.uses_marfed_block_time() { let block_time = block_time.ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "FATAL: Marfed block time not provided to Clarity DB setup".into(), ) })?; @@ -918,7 +918,7 @@ impl<'a> ClarityDatabase<'a> { &epoch, ) .map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "FATAL: failed to load ustx_liquid_supply Clarity key".into(), ) })? @@ -935,7 +935,7 @@ impl<'a> ClarityDatabase<'a> { &StacksEpochId::Epoch21, ) .map_err(|_| { - InterpreterError::Expect("FATAL: Failed to store STX liquid supply".into()).into() + VmInternalError::Expect("FATAL: Failed to store STX liquid supply".into()).into() }) } @@ -969,11 +969,11 @@ impl<'a> ClarityDatabase<'a> { self.get_data(TENURE_HEIGHT_KEY)? .ok_or_else(|| { - InterpreterError::Expect("No tenure height in stored Clarity state".into()).into() + VmInternalError::Expect("No tenure height in stored Clarity state".into()).into() }) .and_then(|x| { u32::try_into(x).map_err(|_| { - InterpreterError::Expect("Bad tenure height in stored Clarity state".into()) + VmInternalError::Expect("Bad tenure height in stored Clarity state".into()) .into() }) }) @@ -984,7 +984,7 @@ impl<'a> ClarityDatabase<'a> { /// transactions in the block. pub fn set_tenure_height(&mut self, height: u32) -> Result<()> { if self.get_clarity_epoch_version()? < StacksEpochId::Epoch30 { - return Err(Error::Interpreter(InterpreterError::Expect( + return Err(Error::Interpreter(VmInternalError::Expect( "Setting tenure height in Clarity state is not supported before epoch 3.0".into(), ))); } @@ -1012,7 +1012,7 @@ impl ClarityDatabase<'_> { // the caller is responsible for ensuring that the block_height given // is < current_block_height, so this should _always_ return a value. .ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "Block header hash must return for provided block height".into(), ) .into() @@ -1115,7 +1115,7 @@ impl ClarityDatabase<'_> { self.get_burnchain_block_height(&last_mined_bhh) .ok_or_else(|| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "Block header hash '{last_mined_bhh}' must return for provided stacks block height {cur_stacks_height}" )) .into() @@ -1125,7 +1125,7 @@ impl ClarityDatabase<'_> { self.burn_state_db .get_tip_burn_block_height() .ok_or_else(|| { - InterpreterError::Expect("Failed to get burnchain tip height.".into()).into() + VmInternalError::Expect("Failed to get burnchain tip height.".into()).into() }) } } @@ -1135,7 +1135,7 @@ impl ClarityDatabase<'_> { let epoch = self.get_stacks_epoch_for_block(&id_bhh)?; self.headers_db .get_stacks_block_header_hash_for_block(&id_bhh, &epoch) - .ok_or_else(|| InterpreterError::Expect("Failed to get block data.".into()).into()) + .ok_or_else(|| VmInternalError::Expect("Failed to get block data.".into()).into()) } pub fn get_burn_block_time( @@ -1150,7 +1150,7 @@ impl ClarityDatabase<'_> { let epoch = self.get_stacks_epoch_for_block(&id_bhh)?; self.headers_db .get_burn_block_time_for_block(&id_bhh, Some(&epoch)) - .ok_or_else(|| InterpreterError::Expect("Failed to get block data.".into()).into()) + .ok_or_else(|| VmInternalError::Expect("Failed to get block data.".into()).into()) } pub fn get_block_time(&mut self, block_height: u32) -> Result { @@ -1162,7 +1162,7 @@ impl ClarityDatabase<'_> { self.headers_db .get_stacks_block_time_for_block(&id_bhh) - .ok_or_else(|| InterpreterError::Expect("Failed to get block data.".into()).into()) + .ok_or_else(|| VmInternalError::Expect("Failed to get block data.".into()).into()) } pub fn get_burnchain_block_header_hash( @@ -1172,7 +1172,7 @@ impl ClarityDatabase<'_> { let id_bhh = self.get_index_block_header_hash(block_height)?; self.headers_db .get_burn_header_hash_for_block(&id_bhh) - .ok_or_else(|| InterpreterError::Expect("Failed to get block data.".into()).into()) + .ok_or_else(|| VmInternalError::Expect("Failed to get block data.".into()).into()) } /// In Epoch 2.x: @@ -1205,7 +1205,7 @@ impl ClarityDatabase<'_> { .headers_db .get_consensus_hash_for_block(&parent_id_bhh, &epoch) .ok_or_else(|| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "FATAL: no consensus hash found for StacksBlockId {parent_id_bhh}" )) })?; @@ -1215,7 +1215,7 @@ impl ClarityDatabase<'_> { .burn_state_db .get_sortition_id_from_consensus_hash(&consensus_hash) .ok_or_else(|| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "FATAL: no SortitionID found for consensus hash {consensus_hash}" )) })?; @@ -1270,7 +1270,7 @@ impl ClarityDatabase<'_> { let epoch = self.get_stacks_epoch_for_block(&id_bhh)?; self.headers_db .get_vrf_seed_for_block(&id_bhh, &epoch) - .ok_or_else(|| InterpreterError::Expect("Failed to get block data.".into()).into()) + .ok_or_else(|| VmInternalError::Expect("Failed to get block data.".into()).into()) } pub fn get_miner_address(&mut self, block_height: u32) -> Result { @@ -1279,7 +1279,7 @@ impl ClarityDatabase<'_> { Ok(self .headers_db .get_miner_address(&id_bhh, &epoch) - .ok_or_else(|| InterpreterError::Expect("Failed to get block data.".into()))? + .ok_or_else(|| VmInternalError::Expect("Failed to get block data.".into()))? .into()) } @@ -1294,7 +1294,7 @@ impl ClarityDatabase<'_> { .headers_db .get_burnchain_tokens_spent_for_winning_block(&id_bhh, &epoch) .ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "FATAL: no winning burnchain token spend record for block".into(), ) })?) @@ -1311,7 +1311,7 @@ impl ClarityDatabase<'_> { .headers_db .get_burnchain_tokens_spent_for_block(&id_bhh, &epoch) .ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "FATAL: no total burnchain token spend record for block".into(), ) })?) @@ -1336,7 +1336,7 @@ impl ClarityDatabase<'_> { .headers_db .get_tokens_earned_for_block(&id_bhh, &epoch) .ok_or_else(|| { - InterpreterError::Expect("FATAL: matured block has no recorded reward".into()) + VmInternalError::Expect("FATAL: matured block has no recorded reward".into()) })?; Ok(Some(reward)) @@ -1390,22 +1390,22 @@ impl ClarityDatabase<'_> { TupleData::from_data(vec![ ( ClarityName::try_from("reporter").map_err(|_| { - InterpreterError::Expect("BUG: valid string representation".into()) + VmInternalError::Expect("BUG: valid string representation".into()) })?, Value::Principal(PrincipalData::Standard(reporter.clone())), ), ( ClarityName::try_from("sequence").map_err(|_| { - InterpreterError::Expect("BUG: valid string representation".into()) + VmInternalError::Expect("BUG: valid string representation".into()) })?, Value::UInt(seq as u128), ), ]) - .map_err(|_| InterpreterError::Expect("BUG: valid tuple representation".into()))?, + .map_err(|_| VmInternalError::Expect("BUG: valid tuple representation".into()))?, ); let mut value_bytes = vec![]; value.serialize_write(&mut value_bytes).map_err(|_| { - InterpreterError::Expect("BUG: valid tuple representation did not serialize".into()) + VmInternalError::Expect("BUG: valid tuple representation did not serialize".into()) })?; let value_str = to_hex(&value_bytes); @@ -1420,7 +1420,7 @@ impl ClarityDatabase<'_> { self.get_data(&key)? .map(|height_str: String| { height_str.parse::().map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "BUG: inserted non-u32 as height of microblock pubkey hash".into(), ) .into() @@ -1439,7 +1439,7 @@ impl ClarityDatabase<'_> { .map(|reporter_hex_str: String| { let reporter_value = Value::try_deserialize_hex_untyped(&reporter_hex_str) .map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "BUG: failed to decode serialized poison-microblock reporter".into(), ) })?; @@ -1447,7 +1447,7 @@ impl ClarityDatabase<'_> { let reporter_value = tuple_data .get("reporter") .map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "BUG: poison-microblock report has no 'reporter'".into(), ) })? @@ -1455,7 +1455,7 @@ impl ClarityDatabase<'_> { let seq_value = tuple_data .get("sequence") .map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "BUG: poison-microblock report has no 'sequence'".into(), ) })? @@ -1466,11 +1466,11 @@ impl ClarityDatabase<'_> { let seq: u16 = seq_u128 .try_into() - .map_err(|_| InterpreterError::Expect("BUG: seq exceeds u16 max".into()))?; + .map_err(|_| VmInternalError::Expect("BUG: seq exceeds u16 max".into()))?; if let PrincipalData::Standard(principal_data) = reporter_principal { Ok((principal_data, seq)) } else { - Err(InterpreterError::Expect( + Err(VmInternalError::Expect( "BUG: poison-microblock report principal is not a standard principal" .into(), ) @@ -1767,7 +1767,7 @@ impl ClarityDatabase<'_> { serialized_byte_len: serialized_byte_len .checked_add(byte_len_of_serialization(&key_serialized)) .ok_or_else(|| { - InterpreterError::Expect("Overflowed Clarity key/value size".into()) + VmInternalError::Expect("Overflowed Clarity key/value size".into()) })?, }), } @@ -1922,7 +1922,7 @@ impl ClarityDatabase<'_> { serialized_byte_len: key_serialized_byte_len .checked_add(placed_size) .ok_or_else(|| { - InterpreterError::Expect("Overflowed Clarity key/value size".into()) + VmInternalError::Expect("Overflowed Clarity key/value size".into()) })?, }) } @@ -1969,7 +1969,7 @@ impl ClarityDatabase<'_> { serialized_byte_len: key_serialized_byte_len .checked_add(*NONE_SERIALIZATION_LEN) .ok_or_else(|| { - InterpreterError::Expect("Overflowed Clarity key/value size".into()) + VmInternalError::Expect("Overflowed Clarity key/value size".into()) })?, }) } @@ -2052,7 +2052,7 @@ impl ClarityDatabase<'_> { token_name, ); let current_supply: u128 = self.get_data(&key)?.ok_or_else(|| { - InterpreterError::Expect("ERROR: Clarity VM failed to track token supply.".into()) + VmInternalError::Expect("ERROR: Clarity VM failed to track token supply.".into()) })?; let new_supply = current_supply @@ -2080,7 +2080,7 @@ impl ClarityDatabase<'_> { token_name, ); let current_supply: u128 = self.get_data(&key)?.ok_or_else(|| { - InterpreterError::Expect("ERROR: Clarity VM failed to track token supply.".into()) + VmInternalError::Expect("ERROR: Clarity VM failed to track token supply.".into()) })?; if amount > current_supply { @@ -2144,7 +2144,7 @@ impl ClarityDatabase<'_> { token_name, ); let supply = self.get_data(&key)?.ok_or_else(|| { - InterpreterError::Expect("ERROR: Clarity VM failed to track token supply.".into()) + VmInternalError::Expect("ERROR: Clarity VM failed to track token supply.".into()) })?; Ok(supply) } @@ -2175,7 +2175,7 @@ impl ClarityDatabase<'_> { let value: Option = self.get_value( &key, &TypeSignature::new_option(TypeSignature::PrincipalType) - .map_err(|_| InterpreterError::Expect("Unexpected type failure".into()))?, + .map_err(|_| VmInternalError::Expect("Unexpected type failure".into()))?, &epoch, )?; let owner = match value { @@ -2381,13 +2381,13 @@ impl ClarityDatabase<'_> { pub fn get_stacks_epoch_for_block(&self, id_bhh: &StacksBlockId) -> Result { let burn_block = self.get_burnchain_block_height(id_bhh).ok_or_else(|| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "FATAL: no burnchain block height found for Stacks block {id_bhh}" )) })?; let epoch = self .get_stacks_epoch(burn_block) - .ok_or_else(|| InterpreterError::Expect("Failed to get block data.".into()))?; + .ok_or_else(|| VmInternalError::Expect("Failed to get block data.".into()))?; Ok(epoch.epoch_id) } } diff --git a/clarity/src/vm/database/clarity_store.rs b/clarity/src/vm/database/clarity_store.rs index e1d6dacaee..2a5c816e41 100644 --- a/clarity/src/vm/database/clarity_store.rs +++ b/clarity/src/vm/database/clarity_store.rs @@ -24,7 +24,7 @@ use crate::vm::contexts::GlobalContext; use crate::vm::database::{ ClarityDatabase, ClarityDeserializable, ClaritySerializable, NULL_BURN_STATE_DB, NULL_HEADER_DB, }; -use crate::vm::errors::{InterpreterError, InterpreterResult as Result}; +use crate::vm::errors::{VmInternalError, InterpreterResult as Result}; use crate::vm::types::{PrincipalData, QualifiedContractIdentifier}; use crate::vm::Value; @@ -160,17 +160,17 @@ impl ClaritySerializable for ContractCommitment { impl ClarityDeserializable for ContractCommitment { fn deserialize(input: &str) -> Result { if input.len() != 72 { - return Err(InterpreterError::Expect("Unexpected input length".into()).into()); + return Err(VmInternalError::Expect("Unexpected input length".into()).into()); } let hash = Sha512Trunc256Sum::from_hex(&input[0..64]) - .map_err(|_| InterpreterError::Expect("Hex decode fail.".into()))?; + .map_err(|_| VmInternalError::Expect("Hex decode fail.".into()))?; let height_bytes = hex_bytes(&input[64..72]) - .map_err(|_| InterpreterError::Expect("Hex decode fail.".into()))?; + .map_err(|_| VmInternalError::Expect("Hex decode fail.".into()))?; let block_height = u32::from_be_bytes( height_bytes .as_slice() .try_into() - .map_err(|_| InterpreterError::Expect("Block height decode fail.".into()))?, + .map_err(|_| VmInternalError::Expect("Block height decode fail.".into()))?, ); Ok(ContractCommitment { hash, block_height }) } diff --git a/clarity/src/vm/database/key_value_wrapper.rs b/clarity/src/vm/database/key_value_wrapper.rs index 5578ac549d..c100c35e8a 100644 --- a/clarity/src/vm/database/key_value_wrapper.rs +++ b/clarity/src/vm/database/key_value_wrapper.rs @@ -24,7 +24,7 @@ use stacks_common::util::hash::Sha512Trunc256Sum; use super::clarity_store::SpecialCaseHandler; use super::{ClarityBackingStore, ClarityDeserializable}; use crate::vm::database::clarity_store::{make_contract_hash_key, ContractCommitment}; -use crate::vm::errors::{InterpreterError, InterpreterResult}; +use crate::vm::errors::{VmInternalError, InterpreterResult}; use crate::vm::types::serialization::SerializationError; use crate::vm::types::{QualifiedContractIdentifier, TypeSignature}; use crate::vm::Value; @@ -49,7 +49,7 @@ fn rollback_edits_push(edits: &mut Vec<(T, RollbackValueCheck)>, key: T, _val fn rollback_check_pre_bottom_commit( edits: Vec<(T, RollbackValueCheck)>, lookup_map: &mut HashMap>, -) -> Result, InterpreterError> +) -> Result, VmInternalError> where T: Eq + Hash + Clone, { @@ -86,7 +86,7 @@ where fn rollback_check_pre_bottom_commit( edits: Vec<(T, RollbackValueCheck)>, lookup_map: &mut HashMap>, -) -> Result, InterpreterError> +) -> Result, VmInternalError> where T: Eq + Hash + Clone, { @@ -179,19 +179,19 @@ fn rollback_lookup_map( key: &T, value: &RollbackValueCheck, lookup_map: &mut HashMap>, -) -> Result +) -> Result where T: Eq + Hash + Clone, { let popped_value; let remove_edit_deque = { let key_edit_history = lookup_map.get_mut(key).ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "ERROR: Clarity VM had edit log entry, but not lookup_map entry".into(), ) })?; popped_value = key_edit_history.pop().ok_or_else(|| { - InterpreterError::Expect("ERROR: expected value in edit history".into()) + VmInternalError::Expect("ERROR: expected value in edit history".into()) })?; rollback_value_check(&popped_value, value); key_edit_history.is_empty() @@ -240,9 +240,9 @@ impl<'a> RollbackWrapper<'a> { // Rollback the child's edits. // this clears all edits from the child's edit queue, // and removes any of those edits from the lookup map. - pub fn rollback(&mut self) -> Result<(), InterpreterError> { + pub fn rollback(&mut self) -> Result<(), VmInternalError> { let mut last_item = self.stack.pop().ok_or_else(|| { - InterpreterError::Expect("ERROR: Clarity VM attempted to commit past the stack.".into()) + VmInternalError::Expect("ERROR: Clarity VM attempted to commit past the stack.".into()) })?; last_item.edits.reverse(); @@ -263,9 +263,9 @@ impl<'a> RollbackWrapper<'a> { self.stack.len() } - pub fn commit(&mut self) -> Result<(), InterpreterError> { + pub fn commit(&mut self) -> Result<(), VmInternalError> { let mut last_item = self.stack.pop().ok_or_else(|| { - InterpreterError::Expect("ERROR: Clarity VM attempted to commit past the stack.".into()) + VmInternalError::Expect("ERROR: Clarity VM attempted to commit past the stack.".into()) })?; if let Some(next_up) = self.stack.last_mut() { @@ -283,7 +283,7 @@ impl<'a> RollbackWrapper<'a> { rollback_check_pre_bottom_commit(last_item.edits, &mut self.lookup_map)?; if !all_edits.is_empty() { self.store.put_all_data(all_edits).map_err(|e| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "ERROR: Failed to commit data to sql store: {e:?}" )) })?; @@ -295,7 +295,7 @@ impl<'a> RollbackWrapper<'a> { )?; if !metadata_edits.is_empty() { self.store.put_all_metadata(metadata_edits).map_err(|e| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "ERROR: Failed to commit data to sql store: {e:?}" )) })?; @@ -322,7 +322,7 @@ fn inner_put_data( impl RollbackWrapper<'_> { pub fn put_data(&mut self, key: &str, value: &str) -> InterpreterResult<()> { let current = self.stack.last_mut().ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "ERROR: Clarity VM attempted PUT on non-nested context.".into(), ) })?; @@ -387,7 +387,7 @@ impl RollbackWrapper<'_> { T: ClarityDeserializable, { self.stack.last().ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "ERROR: Clarity VM attempted GET on non-nested context.".into(), ) })?; @@ -503,9 +503,9 @@ impl RollbackWrapper<'_> { contract: &QualifiedContractIdentifier, key: &str, value: &str, - ) -> Result<(), InterpreterError> { + ) -> Result<(), VmInternalError> { let current = self.stack.last_mut().ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "ERROR: Clarity VM attempted PUT on non-nested context.".into(), ) })?; @@ -529,7 +529,7 @@ impl RollbackWrapper<'_> { key: &str, ) -> InterpreterResult> { self.stack.last().ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "ERROR: Clarity VM attempted GET on non-nested context.".into(), ) })?; @@ -560,7 +560,7 @@ impl RollbackWrapper<'_> { key: &str, ) -> InterpreterResult> { self.stack.last().ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "ERROR: Clarity VM attempted GET on non-nested context.".into(), ) })?; @@ -584,7 +584,7 @@ impl RollbackWrapper<'_> { pub fn has_entry(&mut self, key: &str) -> InterpreterResult { self.stack.last().ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "ERROR: Clarity VM attempted GET on non-nested context.".into(), ) })?; diff --git a/clarity/src/vm/database/sqlite.rs b/clarity/src/vm/database/sqlite.rs index c1af553041..7409f8f643 100644 --- a/clarity/src/vm/database/sqlite.rs +++ b/clarity/src/vm/database/sqlite.rs @@ -27,7 +27,7 @@ use super::{ }; use crate::vm::analysis::{AnalysisDatabase, CheckErrors}; use crate::vm::errors::{ - IncomparableError, InterpreterError, InterpreterResult as Result, RuntimeErrorType, + IncomparableError, VmInternalError, InterpreterResult as Result, RuntimeErrorType, }; use crate::vm::types::QualifiedContractIdentifier; @@ -43,7 +43,7 @@ fn sqlite_put(conn: &Connection, key: &str, value: &str) -> Result<()> { Ok(_) => Ok(()), Err(e) => { error!("Failed to insert/replace ({key},{value}): {e:?}"); - Err(InterpreterError::DBError(SQL_FAIL_MESSAGE.into()).into()) + Err(VmInternalError::DBError(SQL_FAIL_MESSAGE.into()).into()) } } } @@ -62,7 +62,7 @@ fn sqlite_get(conn: &Connection, key: &str) -> Result> { Ok(x) => Ok(x), Err(e) => { error!("Failed to query '{key}': {e:?}"); - Err(InterpreterError::DBError(SQL_FAIL_MESSAGE.into()).into()) + Err(VmInternalError::DBError(SQL_FAIL_MESSAGE.into()).into()) } }; @@ -88,7 +88,7 @@ pub fn sqlite_get_contract_hash( hash: contract_hash, } = contract_commitment?; let bhh = store.get_block_at_height(block_height) - .ok_or_else(|| InterpreterError::Expect("Should always be able to map from height to block hash when looking up contract information.".into()))?; + .ok_or_else(|| VmInternalError::Expect("Should always be able to map from height to block hash when looking up contract information.".into()))?; Ok((bhh, contract_hash)) } @@ -154,7 +154,7 @@ impl SqliteConnection { params, ) { error!("Failed to insert ({bhh},{key},{value}): {e:?}"); - return Err(InterpreterError::DBError(SQL_FAIL_MESSAGE.into()).into()); + return Err(VmInternalError::DBError(SQL_FAIL_MESSAGE.into()).into()); } Ok(()) } @@ -170,7 +170,7 @@ impl SqliteConnection { params, ) { error!("Failed to update {from} to {to}: {e:?}"); - return Err(InterpreterError::DBError(SQL_FAIL_MESSAGE.into()).into()); + return Err(VmInternalError::DBError(SQL_FAIL_MESSAGE.into()).into()); } Ok(()) } @@ -181,7 +181,7 @@ impl SqliteConnection { params![from], ) { error!("Failed to drop metadata from {from}: {e:?}"); - return Err(InterpreterError::DBError(SQL_FAIL_MESSAGE.into()).into()); + return Err(VmInternalError::DBError(SQL_FAIL_MESSAGE.into()).into()); } Ok(()) } @@ -206,7 +206,7 @@ impl SqliteConnection { Ok(x) => Ok(x), Err(e) => { error!("Failed to query ({bhh},{key}): {e:?}"); - Err(InterpreterError::DBError(SQL_FAIL_MESSAGE.into()).into()) + Err(VmInternalError::DBError(SQL_FAIL_MESSAGE.into()).into()) } } } @@ -219,14 +219,14 @@ impl SqliteConnection { impl SqliteConnection { pub fn initialize_conn(conn: &Connection) -> Result<()> { conn.query_row("PRAGMA journal_mode = WAL;", NO_PARAMS, |_row| Ok(())) - .map_err(|x| InterpreterError::SqliteError(IncomparableError { err: x }))?; + .map_err(|x| VmInternalError::SqliteError(IncomparableError { err: x }))?; conn.execute( "CREATE TABLE IF NOT EXISTS data_table (key TEXT PRIMARY KEY, value TEXT)", NO_PARAMS, ) - .map_err(|x| InterpreterError::SqliteError(IncomparableError { err: x }))?; + .map_err(|x| VmInternalError::SqliteError(IncomparableError { err: x }))?; conn.execute( "CREATE TABLE IF NOT EXISTS metadata_table @@ -234,13 +234,13 @@ impl SqliteConnection { UNIQUE (key, blockhash))", NO_PARAMS, ) - .map_err(|x| InterpreterError::SqliteError(IncomparableError { err: x }))?; + .map_err(|x| VmInternalError::SqliteError(IncomparableError { err: x }))?; conn.execute( "CREATE INDEX IF NOT EXISTS md_blockhashes ON metadata_table(blockhash)", NO_PARAMS, ) - .map_err(|x| InterpreterError::SqliteError(IncomparableError { err: x }))?; + .map_err(|x| VmInternalError::SqliteError(IncomparableError { err: x }))?; Self::check_schema(conn)?; @@ -257,22 +257,22 @@ impl SqliteConnection { let sql = "SELECT sql FROM sqlite_master WHERE name=?"; let _: String = conn .query_row(sql, params!["data_table"], |row| row.get(0)) - .map_err(|x| InterpreterError::SqliteError(IncomparableError { err: x }))?; + .map_err(|x| VmInternalError::SqliteError(IncomparableError { err: x }))?; let _: String = conn .query_row(sql, params!["metadata_table"], |row| row.get(0)) - .map_err(|x| InterpreterError::SqliteError(IncomparableError { err: x }))?; + .map_err(|x| VmInternalError::SqliteError(IncomparableError { err: x }))?; let _: String = conn .query_row(sql, params!["md_blockhashes"], |row| row.get(0)) - .map_err(|x| InterpreterError::SqliteError(IncomparableError { err: x }))?; + .map_err(|x| VmInternalError::SqliteError(IncomparableError { err: x }))?; Ok(()) } fn inner_open(filename: &str) -> Result { let conn = Connection::open(filename) - .map_err(|x| InterpreterError::SqliteError(IncomparableError { err: x }))?; + .map_err(|x| VmInternalError::SqliteError(IncomparableError { err: x }))?; conn.busy_handler(Some(tx_busy_handler)) - .map_err(|x| InterpreterError::SqliteError(IncomparableError { err: x }))?; + .map_err(|x| VmInternalError::SqliteError(IncomparableError { err: x }))?; Ok(conn) } diff --git a/clarity/src/vm/database/structures.rs b/clarity/src/vm/database/structures.rs index c4fec9f382..a106bfc105 100644 --- a/clarity/src/vm/database/structures.rs +++ b/clarity/src/vm/database/structures.rs @@ -22,7 +22,7 @@ use stacks_common::util::hash::{hex_bytes, to_hex}; use crate::vm::analysis::ContractAnalysis; use crate::vm::contracts::Contract; use crate::vm::database::ClarityDatabase; -use crate::vm::errors::{Error, InterpreterError, RuntimeErrorType}; +use crate::vm::errors::{Error, RuntimeErrorType, VmInternalError}; use crate::vm::types::{PrincipalData, TypeSignature}; pub trait ClaritySerializable { @@ -63,13 +63,13 @@ macro_rules! clarity_serializable { // this will instead spill to the heap let deserializer = serde_stacker::Deserializer::new(&mut deserializer); Deserialize::deserialize(deserializer).map_err(|_| { - InterpreterError::Expect("Failed to deserialize vm.Value".into()).into() + VmInternalError::Expect("Failed to deserialize vm.Value".into()).into() }) } #[cfg(target_family = "wasm")] fn deserialize(json: &str) -> Result { serde_json::from_str(json).map_err(|_| { - InterpreterError::Expect("Failed to deserialize vm.Value".into()).into() + VmInternalError::Expect("Failed to deserialize vm.Value".into()).into() }) } } @@ -259,21 +259,21 @@ impl ClaritySerializable for STXBalance { impl ClarityDeserializable for STXBalance { fn deserialize(input: &str) -> Result { let bytes = hex_bytes(input).map_err(|_| { - InterpreterError::Expect("STXBalance deserialization: failed decoding bytes.".into()) + VmInternalError::Expect("STXBalance deserialization: failed decoding bytes.".into()) })?; let result = if bytes.len() == STXBalance::unlocked_and_v1_size { let amount_unlocked = u128::from_be_bytes(bytes[0..16].try_into().map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "STXBalance deserialization: failed reading amount_unlocked.".into(), ) })?); let amount_locked = u128::from_be_bytes(bytes[16..32].try_into().map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "STXBalance deserialization: failed reading amount_locked.".into(), ) })?); let unlock_height = u64::from_be_bytes(bytes[32..40].try_into().map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "STXBalance deserialization: failed reading unlock_height.".into(), ) })?); @@ -295,23 +295,23 @@ impl ClarityDeserializable for STXBalance { && version != &STXBalance::pox_3_version && version != &STXBalance::pox_4_version { - return Err(InterpreterError::Expect(format!( + return Err(VmInternalError::Expect(format!( "Bad version byte in STX Balance serialization = {version}" )) .into()); } let amount_unlocked = u128::from_be_bytes(bytes[1..17].try_into().map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "STXBalance deserialization: failed reading amount_unlocked.".into(), ) })?); let amount_locked = u128::from_be_bytes(bytes[17..33].try_into().map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "STXBalance deserialization: failed reading amount_locked.".into(), ) })?); let unlock_height = u64::from_be_bytes(bytes[33..41].try_into().map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "STXBalance deserialization: failed reading unlock_height.".into(), ) })?); @@ -339,13 +339,13 @@ impl ClarityDeserializable for STXBalance { unlock_height, } } else { - return Err(InterpreterError::Expect( + return Err(VmInternalError::Expect( "Version is checked for pox_3 or pox_2 version compliance above".into(), ) .into()); } } else { - return Err(InterpreterError::Expect(format!( + return Err(VmInternalError::Expect(format!( "Bad STX Balance serialization size = {}", bytes.len() )) @@ -381,7 +381,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { pub fn transfer_to(mut self, recipient: &PrincipalData, amount: u128) -> Result<(), Error> { if !self.can_transfer(amount)? { - return Err(InterpreterError::InsufficientBalance.into()); + return Err(VmInternalError::InsufficientBalance.into()); } let recipient_key = ClarityDatabase::make_key_for_account_balance(recipient); @@ -472,7 +472,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { self.balance .checked_add_unlocked_amount(amount) - .ok_or_else(|| InterpreterError::Expect("STX balance overflow".into()))?; + .ok_or_else(|| VmInternalError::Expect("STX balance overflow".into()))?; Ok(()) } @@ -495,7 +495,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if unlock_burn_height <= self.burn_block_height { // caller needs to have checked this - return Err(InterpreterError::Expect( + return Err(VmInternalError::Expect( "FATAL: cannot set a lock with expired unlock burn height".into(), ) .into()); @@ -503,10 +503,9 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if self.has_locked_tokens()? { // caller needs to have checked this - return Err(InterpreterError::Expect( - "FATAL: account already has locked tokens".into(), - ) - .into()); + return Err( + VmInternalError::Expect("FATAL: account already has locked tokens".into()).into(), + ); } // from `unlock_available_tokens_if_any` call above, `self.balance` should @@ -516,7 +515,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { .balance .get_total_balance()? .checked_sub(amount_to_lock) - .ok_or_else(|| InterpreterError::Expect("STX underflow".into()))?; + .ok_or_else(|| VmInternalError::Expect("STX underflow".into()))?; self.balance = STXBalance::LockedPoxOne { amount_unlocked: new_amount_unlocked, @@ -547,7 +546,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if !self.has_locked_tokens()? { // caller needs to have checked this - return Err(InterpreterError::Expect( + return Err(VmInternalError::Expect( "FATAL: account does not have locked tokens".into(), ) .into()); @@ -556,12 +555,12 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if !self.is_v2_locked()? { // caller needs to have checked this return Err( - InterpreterError::Expect("FATAL: account must be locked by pox-2".into()).into(), + VmInternalError::Expect("FATAL: account must be locked by pox-2".into()).into(), ); } if self.balance.amount_locked() > new_total_locked { - return Err(InterpreterError::Expect( + return Err(VmInternalError::Expect( "FATAL: account must lock more after `increase_lock_v2`".into(), ) .into()); @@ -571,9 +570,9 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { .balance .amount_unlocked() .checked_add(self.balance.amount_locked()) - .ok_or_else(|| InterpreterError::Expect("STX balance overflowed u128".into()))?; + .ok_or_else(|| VmInternalError::Expect("STX balance overflowed u128".into()))?; let amount_unlocked = total_amount.checked_sub(new_total_locked).ok_or_else(|| { - InterpreterError::Expect("STX underflow: more is locked than total balance".into()) + VmInternalError::Expect("STX underflow: more is locked than total balance".into()) })?; self.balance = STXBalance::LockedPoxTwo { @@ -596,7 +595,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if !self.has_locked_tokens()? { // caller needs to have checked this - return Err(InterpreterError::Expect( + return Err(VmInternalError::Expect( "FATAL: account does not have locked tokens".into(), ) .into()); @@ -604,7 +603,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if unlock_burn_height <= self.burn_block_height { // caller needs to have checked this - return Err(InterpreterError::Expect( + return Err(VmInternalError::Expect( "FATAL: cannot set a lock with expired unlock burn height".into(), ) .into()); @@ -633,12 +632,12 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { // caller needs to have checked this if amount_to_lock == 0 { - return Err(InterpreterError::Expect("BUG: cannot lock 0 tokens".into()).into()); + return Err(VmInternalError::Expect("BUG: cannot lock 0 tokens".into()).into()); } if unlock_burn_height <= self.burn_block_height { // caller needs to have checked this - return Err(InterpreterError::Expect( + return Err(VmInternalError::Expect( "FATAL: cannot set a lock with expired unlock burn height".into(), ) .into()); @@ -646,10 +645,9 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if self.has_locked_tokens()? { // caller needs to have checked this - return Err(InterpreterError::Expect( - "FATAL: account already has locked tokens".into(), - ) - .into()); + return Err( + VmInternalError::Expect("FATAL: account already has locked tokens".into()).into(), + ); } // from `unlock_available_tokens_if_any` call above, `self.balance` should @@ -659,7 +657,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { .balance .get_total_balance()? .checked_sub(amount_to_lock) - .ok_or_else(|| InterpreterError::Expect("STX underflow".into()))?; + .ok_or_else(|| VmInternalError::Expect("STX underflow".into()))?; self.balance = STXBalance::LockedPoxTwo { amount_unlocked: new_amount_unlocked, @@ -689,7 +687,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if unlock_burn_height <= self.burn_block_height { // caller needs to have checked this - return Err(InterpreterError::Expect( + return Err(VmInternalError::Expect( "FATAL: cannot set a lock with expired unlock burn height".into(), ) .into()); @@ -697,10 +695,9 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if self.has_locked_tokens()? { // caller needs to have checked this - return Err(InterpreterError::Expect( - "FATAL: account already has locked tokens".into(), - ) - .into()); + return Err( + VmInternalError::Expect("FATAL: account already has locked tokens".into()).into(), + ); } // from `unlock_available_tokens_if_any` call above, `self.balance` should @@ -711,7 +708,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { .get_total_balance()? .checked_sub(amount_to_lock) .ok_or_else(|| { - InterpreterError::Expect( + VmInternalError::Expect( "FATAL: account locks more STX than balance possessed".into(), ) })?; @@ -736,7 +733,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if !self.has_locked_tokens()? { // caller needs to have checked this - return Err(InterpreterError::Expect( + return Err(VmInternalError::Expect( "FATAL: account does not have locked tokens".into(), ) .into()); @@ -744,7 +741,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if unlock_burn_height <= self.burn_block_height { // caller needs to have checked this - return Err(InterpreterError::Expect( + return Err(VmInternalError::Expect( "FATAL: cannot set a lock with expired unlock burn height".into(), ) .into()); @@ -768,7 +765,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if !self.has_locked_tokens()? { // caller needs to have checked this - return Err(InterpreterError::Expect( + return Err(VmInternalError::Expect( "FATAL: account does not have locked tokens".into(), ) .into()); @@ -777,7 +774,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { if !self.is_v3_locked()? { // caller needs to have checked this return Err( - InterpreterError::Expect("FATAL: account must be locked by pox-3".into()).into(), + VmInternalError::Expect("FATAL: account must be locked by pox-3".into()).into(), ); } @@ -790,9 +787,9 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { .balance .amount_unlocked() .checked_add(self.balance.amount_locked()) - .ok_or_else(|| InterpreterError::Expect("STX balance overflowed u128".into()))?; + .ok_or_else(|| VmInternalError::Expect("STX balance overflowed u128".into()))?; let amount_unlocked = total_amount.checked_sub(new_total_locked).ok_or_else(|| { - InterpreterError::Expect("STX underflow: more is locked than total balance".into()) + VmInternalError::Expect("STX underflow: more is locked than total balance".into()) })?; self.balance = STXBalance::LockedPoxThree { @@ -947,10 +944,10 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { self.balance = match self.balance { STXBalance::Unlocked { amount } => STXBalance::Unlocked { amount }, STXBalance::LockedPoxOne { .. } => { - return Err(InterpreterError::Expect( + return Err(VmInternalError::Expect( "Attempted to accelerate the unlock of a lockup created by PoX-1".into(), ) - .into()) + .into()); } STXBalance::LockedPoxTwo { amount_unlocked, @@ -1121,7 +1118,7 @@ impl STXBalance { } => { *amount_unlocked = amount_unlocked .checked_sub(delta) - .ok_or_else(|| InterpreterError::Expect("STX underflow".into()))?; + .ok_or_else(|| VmInternalError::Expect("STX underflow".into()))?; Ok(()) } } @@ -1283,7 +1280,7 @@ impl STXBalance { }; unlocked .checked_add(locked) - .ok_or_else(|| InterpreterError::Expect("STX overflow".into()).into()) + .ok_or_else(|| VmInternalError::Expect("STX overflow".into()).into()) } pub fn was_locked_by_v1(&self) -> bool { diff --git a/clarity/src/vm/errors.rs b/clarity/src/vm/errors.rs index 764ac466e5..25f6145b08 100644 --- a/clarity/src/vm/errors.rs +++ b/clarity/src/vm/errors.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . pub use clarity_types::errors::{ - Error, IncomparableError, InterpreterError, InterpreterResult, RuntimeErrorType, + Error, IncomparableError, VmInternalError, InterpreterResult, RuntimeErrorType, ShortReturnType, }; diff --git a/clarity/src/vm/functions/arithmetic.rs b/clarity/src/vm/functions/arithmetic.rs index 2d5c2aff3a..29c065688b 100644 --- a/clarity/src/vm/functions/arithmetic.rs +++ b/clarity/src/vm/functions/arithmetic.rs @@ -21,7 +21,7 @@ use integer_sqrt::IntegerSquareRoot; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, CheckErrors, InterpreterError, InterpreterResult, RuntimeErrorType, + check_argument_count, CheckErrors, InterpreterResult, RuntimeErrorType, VmInternalError, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::{ @@ -586,7 +586,7 @@ pub fn native_mod(a: Value, b: Value) -> InterpreterResult { pub fn native_bitwise_left_shift(input: Value, pos: Value) -> InterpreterResult { if let Value::UInt(u128_val) = pos { let shamt = u32::try_from(u128_val & 0x7f).map_err(|_| { - InterpreterError::Expect("FATAL: lower 32 bits did not convert to u32".into()) + VmInternalError::Expect("FATAL: lower 32 bits did not convert to u32".into()) })?; match input { @@ -612,7 +612,7 @@ pub fn native_bitwise_left_shift(input: Value, pos: Value) -> InterpreterResult< pub fn native_bitwise_right_shift(input: Value, pos: Value) -> InterpreterResult { if let Value::UInt(u128_val) = pos { let shamt = u32::try_from(u128_val & 0x7f).map_err(|_| { - InterpreterError::Expect("FATAL: lower 32 bits did not convert to u32".into()) + VmInternalError::Expect("FATAL: lower 32 bits did not convert to u32".into()) })?; match input { diff --git a/clarity/src/vm/functions/assets.rs b/clarity/src/vm/functions/assets.rs index 62763fa3fc..ebbcbd5ed9 100644 --- a/clarity/src/vm/functions/assets.rs +++ b/clarity/src/vm/functions/assets.rs @@ -20,7 +20,7 @@ use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostTracker}; use crate::vm::database::STXBalance; use crate::vm::errors::{ - check_argument_count, CheckErrors, Error, InterpreterError, InterpreterResult as Result, + check_argument_count, CheckErrors, Error, VmInternalError, InterpreterResult as Result, RuntimeErrorType, }; use crate::vm::representations::SymbolicExpression; @@ -245,19 +245,19 @@ pub fn special_stx_account( ( "unlocked" .try_into() - .map_err(|_| InterpreterError::Expect("Bad special tuple name".into()))?, + .map_err(|_| VmInternalError::Expect("Bad special tuple name".into()))?, Value::UInt(stx_balance.amount_unlocked()), ), ( "locked" .try_into() - .map_err(|_| InterpreterError::Expect("Bad special tuple name".into()))?, + .map_err(|_| VmInternalError::Expect("Bad special tuple name".into()))?, Value::UInt(stx_balance.amount_locked()), ), ( "unlock-height" .try_into() - .map_err(|_| InterpreterError::Expect("Bad special tuple name".into()))?, + .map_err(|_| VmInternalError::Expect("Bad special tuple name".into()))?, Value::UInt(u128::from(stx_balance.effective_unlock_height( v1_unlock_ht, v2_unlock_ht, @@ -354,7 +354,7 @@ pub fn special_mint_token( let final_to_bal = to_bal .checked_add(amount) - .ok_or_else(|| InterpreterError::Expect("STX overflow".into()))?; + .ok_or_else(|| VmInternalError::Expect("STX overflow".into()))?; env.add_memory(TypeSignature::PrincipalType.size()? as u64)?; env.add_memory(TypeSignature::UIntType.size()? as u64)?; @@ -474,7 +474,7 @@ pub fn special_mint_asset_v205( let asset_size = asset .serialized_size() - .map_err(|e| InterpreterError::Expect(e.to_string()))? as u64; + .map_err(|e| VmInternalError::Expect(e.to_string()))? as u64; runtime_cost(ClarityCostFunction::NftMint, env, asset_size)?; if !expected_asset_type.admits(env.epoch(), &asset)? { @@ -642,7 +642,7 @@ pub fn special_transfer_asset_v205( let asset_size = asset .serialized_size() - .map_err(|e| InterpreterError::Expect(e.to_string()))? as u64; + .map_err(|e| VmInternalError::Expect(e.to_string()))? as u64; runtime_cost(ClarityCostFunction::NftTransfer, env, asset_size)?; if !expected_asset_type.admits(env.epoch(), &asset)? { @@ -887,7 +887,7 @@ pub fn special_get_owner_v200( expected_asset_type, ) { Ok(owner) => Ok(Value::some(Value::Principal(owner)).map_err(|_| { - InterpreterError::Expect("Principal should always fit in optional.".into()) + VmInternalError::Expect("Principal should always fit in optional.".into()) })?), Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(Value::none()), Err(e) => Err(e), @@ -916,7 +916,7 @@ pub fn special_get_owner_v205( let asset_size = asset .serialized_size() - .map_err(|e| InterpreterError::Expect(e.to_string()))? as u64; + .map_err(|e| VmInternalError::Expect(e.to_string()))? as u64; runtime_cost(ClarityCostFunction::NftOwner, env, asset_size)?; if !expected_asset_type.admits(env.epoch(), &asset)? { @@ -934,7 +934,7 @@ pub fn special_get_owner_v205( expected_asset_type, ) { Ok(owner) => Ok(Value::some(Value::Principal(owner)).map_err(|_| { - InterpreterError::Expect("Principal should always fit in optional.".into()) + VmInternalError::Expect("Principal should always fit in optional.".into()) })?), Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(Value::none()), Err(e) => Err(e), @@ -1138,7 +1138,7 @@ pub fn special_burn_asset_v205( let asset_size = asset .serialized_size() - .map_err(|e| InterpreterError::Expect(e.to_string()))? as u64; + .map_err(|e| VmInternalError::Expect(e.to_string()))? as u64; runtime_cost(ClarityCostFunction::NftBurn, env, asset_size)?; if !expected_asset_type.admits(env.epoch(), &asset)? { diff --git a/clarity/src/vm/functions/conversions.rs b/clarity/src/vm/functions/conversions.rs index bd7834a552..84528045a1 100644 --- a/clarity/src/vm/functions/conversions.rs +++ b/clarity/src/vm/functions/conversions.rs @@ -19,7 +19,7 @@ use clarity_types::types::serialization::SerializationError; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, CheckErrors, InterpreterError, InterpreterResult as Result, + check_argument_count, CheckErrors, VmInternalError, InterpreterResult as Result, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::signatures::TO_ASCII_MAX_BUFF; @@ -55,12 +55,12 @@ pub fn buff_to_int_generic( Value::Sequence(SequenceData::Buffer(ref sequence_data)) => { if sequence_data.len()? > BufferLength::try_from(16_u32) - .map_err(|_| InterpreterError::Expect("Failed to construct".into()))? + .map_err(|_| VmInternalError::Expect("Failed to construct".into()))? { Err(CheckErrors::TypeValueError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32) - .map_err(|_| InterpreterError::Expect("Failed to construct".into()))?, + .map_err(|_| VmInternalError::Expect("Failed to construct".into()))?, ))), Box::new(value), ) @@ -86,7 +86,7 @@ pub fn buff_to_int_generic( _ => Err(CheckErrors::TypeValueError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32) - .map_err(|_| InterpreterError::Expect("Failed to construct".into()))?, + .map_err(|_| VmInternalError::Expect("Failed to construct".into()))?, ))), Box::new(value), ) @@ -196,13 +196,13 @@ pub fn native_int_to_string_generic( Value::Int(ref int_value) => { let as_string = int_value.to_string(); Ok(bytes_to_value_fn(as_string.into()).map_err(|_| { - InterpreterError::Expect("Unexpected error converting Int to string.".into()) + VmInternalError::Expect("Unexpected error converting Int to string.".into()) })?) } Value::UInt(ref uint_value) => { let as_string = uint_value.to_string(); Ok(bytes_to_value_fn(as_string.into()).map_err(|_| { - InterpreterError::Expect("Unexpected error converting UInt to string.".into()) + VmInternalError::Expect("Unexpected error converting UInt to string.".into()) })?) } _ => Err(CheckErrors::UnionTypeValueError( @@ -227,7 +227,7 @@ pub fn native_int_to_utf8(value: Value) -> Result { /// This should only fail due to system errors, not conversion failures fn convert_string_to_ascii_ok(s: String) -> Result { let ascii_value = Value::string_ascii_from_bytes(s.into_bytes()).map_err(|_| { - InterpreterError::Expect("Unexpected error converting string to ASCII".into()) + VmInternalError::Expect("Unexpected error converting string to ASCII".into()) })?; Value::okay(ascii_value) } @@ -293,7 +293,7 @@ pub fn to_consensus_buff(value: Value) -> Result { let mut clar_buff_serialized = vec![]; value .serialize_write(&mut clar_buff_serialized) - .map_err(|_| InterpreterError::Expect("FATAL: failed to serialize to vec".into()))?; + .map_err(|_| VmInternalError::Expect("FATAL: failed to serialize to vec".into()))?; let clar_buff_serialized = match Value::buff_from(clar_buff_serialized) { Ok(x) => x, diff --git a/clarity/src/vm/functions/crypto.rs b/clarity/src/vm/functions/crypto.rs index 3b5223bd72..2b5685470c 100644 --- a/clarity/src/vm/functions/crypto.rs +++ b/clarity/src/vm/functions/crypto.rs @@ -24,7 +24,7 @@ use stacks_common::util::secp256k1::{secp256k1_recover, secp256k1_verify, Secp25 use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, CheckErrors, InterpreterError, InterpreterResult as Result, + check_argument_count, CheckErrors, VmInternalError, InterpreterResult as Result, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::{BuffData, SequenceData, TypeSignature, Value, BUFF_32, BUFF_33, BUFF_65}; @@ -67,7 +67,7 @@ fn pubkey_to_address_v1(pub_key: Secp256k1PublicKey) -> Result { 1, &vec![pub_key], ) - .ok_or_else(|| InterpreterError::Expect("Failed to create address from pubkey".into()).into()) + .ok_or_else(|| VmInternalError::Expect("Failed to create address from pubkey".into()).into()) } // Note: Clarity1 had a bug in how the address is computed (issues/2619). @@ -84,7 +84,7 @@ fn pubkey_to_address_v2(pub_key: Secp256k1PublicKey, is_mainnet: bool) -> Result 1, &vec![pub_key], ) - .ok_or_else(|| InterpreterError::Expect("Failed to create address from pubkey".into()).into()) + .ok_or_else(|| VmInternalError::Expect("Failed to create address from pubkey".into()).into()) } pub fn special_principal_of( @@ -127,7 +127,7 @@ pub fn special_principal_of( }; let principal = addr.into(); Ok(Value::okay(Value::Principal(principal)) - .map_err(|_| InterpreterError::Expect("Failed to construct ok".into()))?) + .map_err(|_| VmInternalError::Expect("Failed to construct ok".into()))?) } else { Ok(Value::err_uint(1)) } @@ -188,9 +188,9 @@ pub fn special_secp256k1_recover( match secp256k1_recover(message, signature).map_err(|_| CheckErrors::InvalidSecp65k1Signature) { Ok(pubkey) => Ok(Value::okay( Value::buff_from(pubkey.to_vec()) - .map_err(|_| InterpreterError::Expect("Failed to construct buff".into()))?, + .map_err(|_| VmInternalError::Expect("Failed to construct buff".into()))?, ) - .map_err(|_| InterpreterError::Expect("Failed to construct ok".into()))?), + .map_err(|_| VmInternalError::Expect("Failed to construct ok".into()))?), _ => Ok(Value::err_uint(1)), } } diff --git a/clarity/src/vm/functions/database.rs b/clarity/src/vm/functions/database.rs index 93fbef0258..313749f7e6 100644 --- a/clarity/src/vm/functions/database.rs +++ b/clarity/src/vm/functions/database.rs @@ -22,8 +22,8 @@ use crate::vm::callables::DefineType; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{constants as cost_constants, runtime_cost, CostTracker, MemoryConsumer}; use crate::vm::errors::{ - check_argument_count, check_arguments_at_least, CheckErrors, InterpreterError, - InterpreterResult as Result, RuntimeErrorType, + check_argument_count, check_arguments_at_least, CheckErrors, InterpreterResult as Result, + RuntimeErrorType, VmInternalError, }; use crate::vm::representations::{SymbolicExpression, SymbolicExpressionType}; use crate::vm::types::{ @@ -956,7 +956,7 @@ pub fn special_get_burn_block_info( env.epoch(), ) .map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "FATAL: could not convert address list to Value".into(), ) })?, @@ -964,12 +964,12 @@ pub fn special_get_burn_block_info( ("payout".into(), Value::UInt(payout)), ]) .map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "FATAL: failed to build pox addrs and payout tuple".into(), ) })?, )) - .map_err(|_| InterpreterError::Expect("FATAL: could not build Some(..)".into()))?), + .map_err(|_| VmInternalError::Expect("FATAL: could not build Some(..)".into()))?), None => Ok(Value::none()), } } diff --git a/clarity/src/vm/functions/mod.rs b/clarity/src/vm/functions/mod.rs index f458c282e6..6c9d821757 100644 --- a/clarity/src/vm/functions/mod.rs +++ b/clarity/src/vm/functions/mod.rs @@ -65,7 +65,7 @@ macro_rules! switch_on_global_epoch { }; } -use super::errors::InterpreterError; +use super::errors::VmInternalError; use crate::vm::ClarityVersion; mod arithmetic; @@ -610,7 +610,7 @@ fn special_print( context: &LocalContext, ) -> Result { let arg = args.first().ok_or_else(|| { - InterpreterError::BadSymbolicRepresentation("Print should have an argument".into()) + VmInternalError::BadSymbolicRepresentation("Print should have an argument".into()) })?; let input = eval(arg, env, context)?; @@ -777,7 +777,7 @@ fn special_let( last_result.replace(body_result); } // last_result should always be Some(...), because of the arg len check above. - last_result.ok_or_else(|| InterpreterError::Expect("Failed to get let result".into()).into()) + last_result.ok_or_else(|| VmInternalError::Expect("Failed to get let result".into()).into()) }) } diff --git a/clarity/src/vm/functions/options.rs b/clarity/src/vm/functions/options.rs index c47dae91cc..ad72429ce8 100644 --- a/clarity/src/vm/functions/options.rs +++ b/clarity/src/vm/functions/options.rs @@ -18,7 +18,7 @@ use crate::vm::contexts::{Environment, LocalContext}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostTracker, MemoryConsumer}; use crate::vm::errors::{ - check_arguments_at_least, CheckErrors, InterpreterError, InterpreterResult as Result, + check_arguments_at_least, CheckErrors, VmInternalError, InterpreterResult as Result, RuntimeErrorType, ShortReturnType, }; use crate::vm::types::{CallableData, OptionalData, ResponseData, TypeSignature, Value}; @@ -95,7 +95,7 @@ pub fn native_try_ret(input: Value) -> Result { Ok(*data.data) } else { let short_return_val = Value::error(*data.data).map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "BUG: Failed to construct new response type from old response type".into(), ) })?; diff --git a/clarity/src/vm/functions/principals.rs b/clarity/src/vm/functions/principals.rs index 51fc33136f..fe463bd234 100644 --- a/clarity/src/vm/functions/principals.rs +++ b/clarity/src/vm/functions/principals.rs @@ -8,7 +8,7 @@ use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckErrors, - InterpreterError, InterpreterResult as Result, + VmInternalError, InterpreterResult as Result, }; use crate::vm::representations::{ SymbolicExpression, CONTRACT_MAX_NAME_LENGTH, CONTRACT_MIN_NAME_LENGTH, @@ -102,7 +102,7 @@ fn create_principal_destruct_tuple( }), ), ]) - .map_err(|_| InterpreterError::Expect("FAIL: Failed to initialize tuple.".into()))?, + .map_err(|_| VmInternalError::Expect("FAIL: Failed to initialize tuple.".into()))?, )) } @@ -116,10 +116,10 @@ fn create_principal_true_error_response(error_int: PrincipalConstructErrorCode) ("error_code".into(), Value::UInt(error_int as u128)), ("value".into(), Value::none()), ]) - .map_err(|_| InterpreterError::Expect("FAIL: Failed to initialize tuple.".into()))?, + .map_err(|_| VmInternalError::Expect("FAIL: Failed to initialize tuple.".into()))?, )) .map_err(|_| { - InterpreterError::Expect("FAIL: Failed to initialize (err ..) response".into()).into() + VmInternalError::Expect("FAIL: Failed to initialize (err ..) response".into()).into() }) } @@ -138,14 +138,14 @@ fn create_principal_value_error_response( ( "value".into(), Value::some(value).map_err(|_| { - InterpreterError::Expect("Unexpected problem creating Value.".into()) + VmInternalError::Expect("Unexpected problem creating Value.".into()) })?, ), ]) - .map_err(|_| InterpreterError::Expect("FAIL: Failed to initialize tuple.".into()))?, + .map_err(|_| VmInternalError::Expect("FAIL: Failed to initialize tuple.".into()))?, )) .map_err(|_| { - InterpreterError::Expect("FAIL: Failed to initialize (err ..) response".into()).into() + VmInternalError::Expect("FAIL: Failed to initialize (err ..) response".into()).into() }) } @@ -305,7 +305,7 @@ pub fn special_principal_construct( // it here at runtime. If it's not valid, then it warrants this function evaluating to // (err ..). let name_string = String::from_utf8(name_bytes.data).map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "FAIL: could not convert bytes of type (string-ascii 40) back to a UTF-8 string" .into(), ) @@ -332,7 +332,7 @@ pub fn special_principal_construct( if version_byte_is_valid { Ok(Value::okay(principal).map_err(|_| { - InterpreterError::Expect("FAIL: failed to build an (ok ..) response".into()) + VmInternalError::Expect("FAIL: failed to build an (ok ..) response".into()) })?) } else { create_principal_value_error_response(PrincipalConstructErrorCode::VERSION_BYTE, principal) diff --git a/clarity/src/vm/functions/tuples.rs b/clarity/src/vm/functions/tuples.rs index 7db8f13959..cc6e4fc3c9 100644 --- a/clarity/src/vm/functions/tuples.rs +++ b/clarity/src/vm/functions/tuples.rs @@ -16,7 +16,7 @@ use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, check_arguments_at_least, CheckErrors, InterpreterError, + check_argument_count, check_arguments_at_least, CheckErrors, VmInternalError, InterpreterResult as Result, SyntaxBindingErrorType, }; use crate::vm::representations::SymbolicExpression; @@ -60,7 +60,7 @@ pub fn tuple_get( if let Value::Tuple(tuple_data) = *data { runtime_cost(ClarityCostFunction::TupleGet, env, tuple_data.len())?; Ok(Value::some(tuple_data.get_owned(arg_name)?).map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "Tuple contents should *always* fit in a some wrapper".into(), ) })?) diff --git a/clarity/src/vm/mod.rs b/clarity/src/vm/mod.rs index 781c7d4d7b..c7ada711f1 100644 --- a/clarity/src/vm/mod.rs +++ b/clarity/src/vm/mod.rs @@ -73,7 +73,7 @@ use crate::vm::costs::{ // publish the non-generic StacksEpoch form for use throughout module pub use crate::vm::database::clarity_db::StacksEpoch; use crate::vm::errors::{ - CheckErrors, Error, InterpreterError, InterpreterResult as Result, RuntimeErrorType, + CheckErrors, Error, VmInternalError, InterpreterResult as Result, RuntimeErrorType, }; use crate::vm::events::StacksTransactionEvent; use crate::vm::functions::define::DefineResult; @@ -164,7 +164,7 @@ pub trait EvalHook { fn lookup_variable(name: &str, context: &LocalContext, env: &mut Environment) -> Result { if name.starts_with(char::is_numeric) || name.starts_with('\'') { - Err(InterpreterError::BadSymbolicRepresentation(format!( + Err(VmInternalError::BadSymbolicRepresentation(format!( "Unexpected variable name: {name}" )) .into()) @@ -292,7 +292,7 @@ pub fn apply( .and_then(|_| function.apply(evaluated_args, env)) } CallableType::UserFunction(function) => function.apply(&evaluated_args, env), - _ => return Err(InterpreterError::Expect("Should be unreachable.".into()).into()), + _ => return Err(VmInternalError::Expect("Should be unreachable.".into()).into()), }; add_stack_trace(&mut resp, env); env.drop_memory(used_memory)?; @@ -350,7 +350,7 @@ pub fn eval( apply(&f, rest, env, context) } TraitReference(_, _) | Field(_) => { - return Err(InterpreterError::BadSymbolicRepresentation( + return Err(VmInternalError::BadSymbolicRepresentation( "Unexpected trait reference".into(), ) .into()) @@ -414,7 +414,7 @@ pub fn eval_all( contract_context.persisted_names.insert(name.clone()); global_context.add_memory(value_type.type_size() - .map_err(|_| InterpreterError::Expect("Type size should be realizable".into()))? as u64)?; + .map_err(|_| VmInternalError::Expect("Type size should be realizable".into()))? as u64)?; global_context.add_memory(value.size()? as u64)?; @@ -430,9 +430,9 @@ pub fn eval_all( contract_context.persisted_names.insert(name.clone()); global_context.add_memory(key_type.type_size() - .map_err(|_| InterpreterError::Expect("Type size should be realizable".into()))? as u64)?; + .map_err(|_| VmInternalError::Expect("Type size should be realizable".into()))? as u64)?; global_context.add_memory(value_type.type_size() - .map_err(|_| InterpreterError::Expect("Type size should be realizable".into()))? as u64)?; + .map_err(|_| VmInternalError::Expect("Type size should be realizable".into()))? as u64)?; let data_type = global_context.database.create_map(&contract_context.contract_identifier, &name, key_type, value_type)?; @@ -443,7 +443,7 @@ pub fn eval_all( contract_context.persisted_names.insert(name.clone()); global_context.add_memory(TypeSignature::UIntType.type_size() - .map_err(|_| InterpreterError::Expect("Type size should be realizable".into()))? as u64)?; + .map_err(|_| VmInternalError::Expect("Type size should be realizable".into()))? as u64)?; let data_type = global_context.database.create_fungible_token(&contract_context.contract_identifier, &name, &total_supply)?; @@ -454,7 +454,7 @@ pub fn eval_all( contract_context.persisted_names.insert(name.clone()); global_context.add_memory(asset_type.type_size() - .map_err(|_| InterpreterError::Expect("Type size should be realizable".into()))? as u64)?; + .map_err(|_| VmInternalError::Expect("Type size should be realizable".into()))? as u64)?; let data_type = global_context.database.create_non_fungible_token(&contract_context.contract_identifier, &name, &asset_type)?; diff --git a/clarity/src/vm/types/serialization.rs b/clarity/src/vm/types/serialization.rs index 16e62f2409..b83f752e29 100644 --- a/clarity/src/vm/types/serialization.rs +++ b/clarity/src/vm/types/serialization.rs @@ -22,7 +22,7 @@ pub use clarity_types::types::serialization::{ use stacks_common::util::hash::{hex_bytes, to_hex}; use crate::vm::database::{ClarityDeserializable, ClaritySerializable}; -use crate::vm::errors::{Error as ClarityError, InterpreterError}; +use crate::vm::errors::{Error as ClarityError, VmInternalError}; impl ClaritySerializable for u32 { fn serialize(&self) -> String { @@ -33,11 +33,11 @@ impl ClaritySerializable for u32 { impl ClarityDeserializable for u32 { fn deserialize(input: &str) -> Result { let bytes = hex_bytes(input).map_err(|_| { - InterpreterError::Expect("u32 deserialization: failed decoding bytes.".into()) + VmInternalError::Expect("u32 deserialization: failed decoding bytes.".into()) })?; assert_eq!(bytes.len(), 4); Ok(u32::from_be_bytes(bytes[0..4].try_into().map_err( - |_| InterpreterError::Expect("u32 deserialization: failed reading.".into()), + |_| VmInternalError::Expect("u32 deserialization: failed reading.".into()), )?)) } } diff --git a/clarity/src/vm/variables.rs b/clarity/src/vm/variables.rs index 3f11d6e4b9..b0453737d4 100644 --- a/clarity/src/vm/variables.rs +++ b/clarity/src/vm/variables.rs @@ -16,7 +16,7 @@ use stacks_common::types::StacksEpochId; -use super::errors::InterpreterError; +use super::errors::VmInternalError; use crate::vm::contexts::{Environment, LocalContext}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; @@ -73,7 +73,7 @@ pub fn lookup_reserved_variable( let sponsor = match env.sponsor.clone() { None => Value::none(), Some(p) => Value::some(Value::Principal(p)).map_err(|_| { - InterpreterError::Expect( + VmInternalError::Expect( "ERROR: principal should be a valid Clarity object".into(), ) })?, diff --git a/stackslib/src/chainstate/stacks/db/transactions.rs b/stackslib/src/chainstate/stacks/db/transactions.rs index 2deee7b642..59ad890091 100644 --- a/stackslib/src/chainstate/stacks/db/transactions.rs +++ b/stackslib/src/chainstate/stacks/db/transactions.rs @@ -49,7 +49,7 @@ impl TryFrom for HashableClarityValue { fn try_from(value: Value) -> Result { // check that serialization _will_ be successful when hashed let _bytes = value.serialize_to_vec().map_err(|_| { - InterpreterError::Interpreter(clarity::vm::errors::InterpreterError::Expect( + InterpreterError::Interpreter(clarity::vm::errors::VmInternalError::Expect( "Failed to serialize asset in NFT during post-condition checks".into(), )) })?; diff --git a/stackslib/src/clarity_vm/database/marf.rs b/stackslib/src/clarity_vm/database/marf.rs index b19ff76def..0d2a1bd960 100644 --- a/stackslib/src/clarity_vm/database/marf.rs +++ b/stackslib/src/clarity_vm/database/marf.rs @@ -12,7 +12,7 @@ use clarity::vm::database::{ SqliteConnection, }; use clarity::vm::errors::{ - IncomparableError, InterpreterError, InterpreterResult, RuntimeErrorType, + IncomparableError, VmInternalError, InterpreterResult, RuntimeErrorType, }; use clarity::vm::types::QualifiedContractIdentifier; use rusqlite::Connection; @@ -46,12 +46,12 @@ impl MarfedKV { let mut path = PathBuf::from(path_str); std::fs::create_dir_all(&path) - .map_err(|_| InterpreterError::FailedToCreateDataDirectory)?; + .map_err(|_| VmInternalError::FailedToCreateDataDirectory)?; path.push("marf.sqlite"); let marf_path = path .to_str() - .ok_or_else(|| InterpreterError::BadFileName)? + .ok_or_else(|| VmInternalError::BadFileName)? .to_string(); let mut marf_opts = marf_opts.unwrap_or(MARFOpenOpts::default()); @@ -59,10 +59,10 @@ impl MarfedKV { let mut marf: MARF = if unconfirmed { MARF::from_path_unconfirmed(&marf_path, marf_opts) - .map_err(|err| InterpreterError::MarfFailure(err.to_string()))? + .map_err(|err| VmInternalError::MarfFailure(err.to_string()))? } else { MARF::from_path(&marf_path, marf_opts) - .map_err(|err| InterpreterError::MarfFailure(err.to_string()))? + .map_err(|err| VmInternalError::MarfFailure(err.to_string()))? }; if SqliteConnection::check_schema(marf.sqlite_conn()).is_ok() { @@ -72,11 +72,11 @@ impl MarfedKV { let tx = marf .storage_tx() - .map_err(|err| InterpreterError::DBError(err.to_string()))?; + .map_err(|err| VmInternalError::DBError(err.to_string()))?; SqliteConnection::initialize_conn(&tx)?; tx.commit() - .map_err(|err| InterpreterError::SqliteError(IncomparableError { err }))?; + .map_err(|err| VmInternalError::SqliteError(IncomparableError { err }))?; Ok(marf) } @@ -170,7 +170,7 @@ impl MarfedKV { "Failed to open read only connection at {}: {:?}", at_block, &e ); - InterpreterError::MarfFailure(Error::NotFoundError.to_string()) + VmInternalError::MarfFailure(Error::NotFoundError.to_string()) })?; at_block.clone() } else { @@ -397,12 +397,12 @@ impl ClarityBackingStore for ReadOnlyMarfStore<'_> { Error::NotFoundError => Ok(None), _ => Err(e), }) - .map_err(|_| InterpreterError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? + .map_err(|_| VmInternalError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? .map(|(marf_value, proof)| { let side_key = marf_value.to_hex(); let data = SqliteConnection::get(self.get_side_store(), &side_key)?.ok_or_else(|| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "ERROR: MARF contained value_hash not found in side storage: {}", side_key )) @@ -422,12 +422,12 @@ impl ClarityBackingStore for ReadOnlyMarfStore<'_> { Error::NotFoundError => Ok(None), _ => Err(e), }) - .map_err(|_| InterpreterError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? + .map_err(|_| VmInternalError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? .map(|(marf_value, proof)| { let side_key = marf_value.to_hex(); let data = SqliteConnection::get(self.get_side_store(), &side_key)?.ok_or_else(|| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "ERROR: MARF contained value_hash not found in side storage: {}", side_key )) @@ -452,12 +452,12 @@ impl ClarityBackingStore for ReadOnlyMarfStore<'_> { } _ => Err(e), }) - .map_err(|_| InterpreterError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? + .map_err(|_| VmInternalError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? .map(|marf_value| { let side_key = marf_value.to_hex(); trace!("MarfedKV get side-key for {:?}: {:?}", key, &side_key); SqliteConnection::get(self.get_side_store(), &side_key)?.ok_or_else(|| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "ERROR: MARF contained value_hash not found in side storage: {}", side_key )) @@ -482,12 +482,12 @@ impl ClarityBackingStore for ReadOnlyMarfStore<'_> { } _ => Err(e), }) - .map_err(|_| InterpreterError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? + .map_err(|_| VmInternalError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? .map(|marf_value| { let side_key = marf_value.to_hex(); trace!("MarfedKV get side-key for {:?}: {:?}", hash, &side_key); SqliteConnection::get(self.get_side_store(), &side_key)?.ok_or_else(|| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "ERROR: MARF contained value_hash not found in side storage: {}", side_key )) @@ -566,7 +566,7 @@ impl WritableMarfStore<'_> { let _ = self.marf.commit_to(final_bhh).map_err(|e| { error!("Failed to commit to MARF block {}: {:?}", &final_bhh, &e); - InterpreterError::Expect("Failed to commit to MARF block".into()) + VmInternalError::Expect("Failed to commit to MARF block".into()) })?; Ok(()) } @@ -605,7 +605,7 @@ impl WritableMarfStore<'_> { "Failed to commit to mined MARF block {}: {:?}", &will_move_to, &e ); - InterpreterError::Expect("Failed to commit to MARF block".into()) + VmInternalError::Expect("Failed to commit to MARF block".into()) })?; Ok(()) } @@ -661,12 +661,12 @@ impl ClarityBackingStore for WritableMarfStore<'_> { } _ => Err(e), }) - .map_err(|_| InterpreterError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? + .map_err(|_| VmInternalError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? .map(|marf_value| { let side_key = marf_value.to_hex(); trace!("MarfedKV get side-key for {:?}: {:?}", key, &side_key); SqliteConnection::get(self.marf.sqlite_tx(), &side_key)?.ok_or_else(|| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "ERROR: MARF contained value_hash not found in side storage: {}", side_key )) @@ -691,12 +691,12 @@ impl ClarityBackingStore for WritableMarfStore<'_> { } _ => Err(e), }) - .map_err(|_| InterpreterError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? + .map_err(|_| VmInternalError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? .map(|marf_value| { let side_key = marf_value.to_hex(); trace!("MarfedKV get side-key for {:?}: {:?}", hash, &side_key); SqliteConnection::get(self.marf.sqlite_tx(), &side_key)?.ok_or_else(|| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "ERROR: MARF contained value_hash not found in side storage: {}", side_key )) @@ -713,12 +713,12 @@ impl ClarityBackingStore for WritableMarfStore<'_> { Error::NotFoundError => Ok(None), _ => Err(e), }) - .map_err(|_| InterpreterError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? + .map_err(|_| VmInternalError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? .map(|(marf_value, proof)| { let side_key = marf_value.to_hex(); let data = SqliteConnection::get(self.marf.sqlite_tx(), &side_key)?.ok_or_else(|| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "ERROR: MARF contained value_hash not found in side storage: {}", side_key )) @@ -738,12 +738,12 @@ impl ClarityBackingStore for WritableMarfStore<'_> { Error::NotFoundError => Ok(None), _ => Err(e), }) - .map_err(|_| InterpreterError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? + .map_err(|_| VmInternalError::Expect("ERROR: Unexpected MARF Failure on GET".into()))? .map(|(marf_value, proof)| { let side_key = marf_value.to_hex(); let data = SqliteConnection::get(self.marf.sqlite_tx(), &side_key)?.ok_or_else(|| { - InterpreterError::Expect(format!( + VmInternalError::Expect(format!( "ERROR: MARF contained value_hash not found in side storage: {}", side_key )) @@ -828,7 +828,7 @@ impl ClarityBackingStore for WritableMarfStore<'_> { } self.marf .insert_batch(&keys, values) - .map_err(|_| InterpreterError::Expect("ERROR: Unexpected MARF Failure".into()).into()) + .map_err(|_| VmInternalError::Expect("ERROR: Unexpected MARF Failure".into()).into()) } fn get_contract_hash( From 51180defdfec7772c33e8173c6934a6d3067ce5f Mon Sep 17 00:00:00 2001 From: Francesco Leacche Date: Wed, 17 Sep 2025 15:36:55 +0200 Subject: [PATCH 02/34] add docstring for VmInternalError and its variants --- clarity-types/src/errors/mod.rs | 51 +++++++++++++++---- clarity/src/vm/contexts.rs | 10 ++-- clarity/src/vm/database/clarity_db.rs | 12 ++--- clarity/src/vm/database/clarity_store.rs | 2 +- clarity/src/vm/database/key_value_wrapper.rs | 26 +++------- clarity/src/vm/database/sqlite.rs | 2 +- clarity/src/vm/errors.rs | 3 +- clarity/src/vm/functions/assets.rs | 4 +- clarity/src/vm/functions/conversions.rs | 2 +- clarity/src/vm/functions/crypto.rs | 2 +- clarity/src/vm/functions/options.rs | 4 +- clarity/src/vm/functions/principals.rs | 2 +- clarity/src/vm/functions/tuples.rs | 4 +- clarity/src/vm/mod.rs | 10 ++-- .../src/chainstate/stacks/db/transactions.rs | 2 +- stackslib/src/clarity_vm/database/marf.rs | 5 +- 16 files changed, 80 insertions(+), 61 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 3c579d661c..21f905ea88 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -44,28 +44,61 @@ pub enum Error { /// TypeChecker and other check passes. Test executions may /// trigger these errors. Unchecked(CheckErrors), - Interpreter(VmInternalError), + /// A critical, unrecoverable bug within the VM's internal logic. + /// + /// The presence of this error indicates a violation of one of the VM's + /// invariants or a corrupted state. This is **not** an error in the user's + /// Clarity code, but a bug in the VM's Rust implementation. + /// + /// # Example + /// The VM's evaluation loop attempts to `pop` from an empty internal call stack, + /// indicating a mismatch in function entry/exit logic. + Internal(VmInternalError), Runtime(RuntimeErrorType, Option), ShortReturn(ShortReturnType), } -/// VmInternalErrors are errors that *should never* occur. -/// Test executions may trigger these errors. +/// Represents an internal, unrecoverable error within the Clarity VM. +/// +/// These errors signify a bug in the VM's logic or a violation of its internal +/// invariants. They are not meant to be caught or handled by Clarity contracts. #[derive(Debug, PartialEq)] pub enum VmInternalError { BadSymbolicRepresentation(String), - InterpreterError(String), + /// A generic, unexpected internal error, indicating a logic failure within + /// the VM. + /// TODO: merge with VmInternalError::Expect + AssertionFailed(String), + /// The VM failed to produce the final `AssetMap` when finalizing the + /// execution environment for a transaction. FailedToConstructAssetTable, + /// The VM failed to produce the final `EventBatch` when finalizing the + /// execution environment for a transaction. FailedToConstructEventBatch, + /// An error occurred during an interaction with the database. #[cfg(feature = "rusqlite")] SqliteError(IncomparableError), + /// The file path provided for the MARF database is invalid because it + /// contains non-UTF-8 characters. BadFileName, + /// The VM failed to create the necessary directory for the MARF persistent + /// storage. Likely due to a file system permissions error or an invalid path FailedToCreateDataDirectory, + /// A failure occurred within the MARF implementation. MarfFailure(String), + /// Failed to construct a tuple value from provided data because it did not + /// match the expected type signature. FailureConstructingTupleWithType, + /// Failed to construct a list value from provided data because it + /// did not match the expected type signature. FailureConstructingListWithType, + /// An STX transfer failed due to insufficient balance. InsufficientBalance, + /// A generic error occurred during a database operation. DBError(String), + /// An internal expectation or assertion failed. This is used for conditions + /// that are believed to be unreachable but are handled gracefully to prevent + /// a panic. Expect(String), } @@ -123,7 +156,7 @@ impl PartialEq for Error { (Error::Runtime(x, _), Error::Runtime(y, _)) => x == y, (Error::Unchecked(x), Error::Unchecked(y)) => x == y, (Error::ShortReturn(x), Error::ShortReturn(y)) => x == y, - (Error::Interpreter(x), Error::Interpreter(y)) => x == y, + (Error::Internal(x), Error::Internal(y)) => x == y, _ => false, } } @@ -216,7 +249,7 @@ impl From for Error { impl From for Error { fn from(err: VmInternalError) -> Self { - Error::Interpreter(err) + Error::Internal(err) } } @@ -245,12 +278,12 @@ mod test { Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))) ); assert_eq!( - Error::Interpreter(VmInternalError::InterpreterError("".to_string())), - Error::Interpreter(VmInternalError::InterpreterError("".to_string())) + Error::Internal(VmInternalError::AssertionFailed("".to_string())), + Error::Internal(VmInternalError::AssertionFailed("".to_string())) ); assert!( Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))) - != Error::Interpreter(VmInternalError::InterpreterError("".to_string())) + != Error::Internal(VmInternalError::AssertionFailed("".to_string())) ); } } diff --git a/clarity/src/vm/contexts.rs b/clarity/src/vm/contexts.rs index 2e78249297..9154040e28 100644 --- a/clarity/src/vm/contexts.rs +++ b/clarity/src/vm/contexts.rs @@ -37,7 +37,7 @@ use crate::vm::database::{ NonFungibleTokenMetadata, }; use crate::vm::errors::{ - CheckErrors, VmInternalError, InterpreterResult as Result, RuntimeErrorType, + CheckErrors, InterpreterResult as Result, RuntimeErrorType, VmInternalError, }; use crate::vm::events::*; use crate::vm::representations::SymbolicExpression; @@ -1126,7 +1126,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { let args: Result> = args.iter() .map(|arg| { let value = arg.match_atom_value() - .ok_or_else(|| VmInternalError::InterpreterError(format!("Passed non-value expression to exec_tx on {tx_name}!")))?; + .ok_or_else(|| VmInternalError::AssertionFailed(format!("Passed non-value expression to exec_tx on {tx_name}!")))?; // sanitize contract-call inputs in epochs >= 2.4 // testing todo: ensure sanitize_value() preserves trait callability! let expected_type = TypeSignature::type_of(value)?; @@ -1961,20 +1961,20 @@ impl CallStack { pub fn remove(&mut self, function: &FunctionIdentifier, tracked: bool) -> Result<()> { if let Some(removed) = self.stack.pop() { if removed != *function { - return Err(VmInternalError::InterpreterError( + return Err(VmInternalError::AssertionFailed( "Tried to remove item from empty call stack.".to_string(), ) .into()); } if tracked && !self.set.remove(function) { - return Err(VmInternalError::InterpreterError( + return Err(VmInternalError::AssertionFailed( "Tried to remove tracked function from call stack, but could not find in current context.".into() ) .into()); } Ok(()) } else { - Err(VmInternalError::InterpreterError( + Err(VmInternalError::AssertionFailed( "Tried to remove item from empty call stack.".to_string(), ) .into()) diff --git a/clarity/src/vm/database/clarity_db.rs b/clarity/src/vm/database/clarity_db.rs index f64cca0c35..ae0a4930d1 100644 --- a/clarity/src/vm/database/clarity_db.rs +++ b/clarity/src/vm/database/clarity_db.rs @@ -24,7 +24,7 @@ use stacks_common::types::chainstate::{ TrieHash, VRFSeed, }; use stacks_common::types::{StacksEpoch as GenericStacksEpoch, StacksEpochId}; -use stacks_common::util::hash::{to_hex, Hash160, Sha512Trunc256Sum}; +use stacks_common::util::hash::{Hash160, Sha512Trunc256Sum, to_hex}; use super::clarity_store::SpecialCaseHandler; use super::key_value_wrapper::ValueResult; @@ -38,13 +38,13 @@ use crate::vm::database::structures::{ }; use crate::vm::database::{ClarityBackingStore, RollbackWrapper}; use crate::vm::errors::{ - CheckErrors, Error, VmInternalError, InterpreterResult as Result, RuntimeErrorType, + CheckErrors, Error, InterpreterResult as Result, RuntimeErrorType, VmInternalError, }; use crate::vm::representations::ClarityName; use crate::vm::types::serialization::NONE_SERIALIZATION_LEN; use crate::vm::types::{ - byte_len_of_serialization, PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, - TupleData, TypeSignature, Value, + PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, TupleData, TypeSignature, + Value, byte_len_of_serialization, }; pub const STORE_CONTRACT_SRC_INTERFACE: bool = true; @@ -148,7 +148,7 @@ pub trait HeadersDB { epoch: &StacksEpochId, ) -> Option; fn get_burn_header_hash_for_block(&self, id_bhh: &StacksBlockId) - -> Option; + -> Option; fn get_consensus_hash_for_block( &self, id_bhh: &StacksBlockId, @@ -984,7 +984,7 @@ impl<'a> ClarityDatabase<'a> { /// transactions in the block. pub fn set_tenure_height(&mut self, height: u32) -> Result<()> { if self.get_clarity_epoch_version()? < StacksEpochId::Epoch30 { - return Err(Error::Interpreter(VmInternalError::Expect( + return Err(Error::Internal(VmInternalError::Expect( "Setting tenure height in Clarity state is not supported before epoch 3.0".into(), ))); } diff --git a/clarity/src/vm/database/clarity_store.rs b/clarity/src/vm/database/clarity_store.rs index 2a5c816e41..c3d388aa43 100644 --- a/clarity/src/vm/database/clarity_store.rs +++ b/clarity/src/vm/database/clarity_store.rs @@ -24,7 +24,7 @@ use crate::vm::contexts::GlobalContext; use crate::vm::database::{ ClarityDatabase, ClarityDeserializable, ClaritySerializable, NULL_BURN_STATE_DB, NULL_HEADER_DB, }; -use crate::vm::errors::{VmInternalError, InterpreterResult as Result}; +use crate::vm::errors::{InterpreterResult as Result, VmInternalError}; use crate::vm::types::{PrincipalData, QualifiedContractIdentifier}; use crate::vm::Value; diff --git a/clarity/src/vm/database/key_value_wrapper.rs b/clarity/src/vm/database/key_value_wrapper.rs index c100c35e8a..236a7d0cfb 100644 --- a/clarity/src/vm/database/key_value_wrapper.rs +++ b/clarity/src/vm/database/key_value_wrapper.rs @@ -24,7 +24,7 @@ use stacks_common::util::hash::Sha512Trunc256Sum; use super::clarity_store::SpecialCaseHandler; use super::{ClarityBackingStore, ClarityDeserializable}; use crate::vm::database::clarity_store::{make_contract_hash_key, ContractCommitment}; -use crate::vm::errors::{VmInternalError, InterpreterResult}; +use crate::vm::errors::{InterpreterResult, VmInternalError}; use crate::vm::types::serialization::SerializationError; use crate::vm::types::{QualifiedContractIdentifier, TypeSignature}; use crate::vm::Value; @@ -322,9 +322,7 @@ fn inner_put_data( impl RollbackWrapper<'_> { pub fn put_data(&mut self, key: &str, value: &str) -> InterpreterResult<()> { let current = self.stack.last_mut().ok_or_else(|| { - VmInternalError::Expect( - "ERROR: Clarity VM attempted PUT on non-nested context.".into(), - ) + VmInternalError::Expect("ERROR: Clarity VM attempted PUT on non-nested context.".into()) })?; inner_put_data( @@ -387,9 +385,7 @@ impl RollbackWrapper<'_> { T: ClarityDeserializable, { self.stack.last().ok_or_else(|| { - VmInternalError::Expect( - "ERROR: Clarity VM attempted GET on non-nested context.".into(), - ) + VmInternalError::Expect("ERROR: Clarity VM attempted GET on non-nested context.".into()) })?; if self.query_pending_data { @@ -505,9 +501,7 @@ impl RollbackWrapper<'_> { value: &str, ) -> Result<(), VmInternalError> { let current = self.stack.last_mut().ok_or_else(|| { - VmInternalError::Expect( - "ERROR: Clarity VM attempted PUT on non-nested context.".into(), - ) + VmInternalError::Expect("ERROR: Clarity VM attempted PUT on non-nested context.".into()) })?; let metadata_key = (contract.clone(), key.to_string()); @@ -529,9 +523,7 @@ impl RollbackWrapper<'_> { key: &str, ) -> InterpreterResult> { self.stack.last().ok_or_else(|| { - VmInternalError::Expect( - "ERROR: Clarity VM attempted GET on non-nested context.".into(), - ) + VmInternalError::Expect("ERROR: Clarity VM attempted GET on non-nested context.".into()) })?; // This is THEORETICALLY a spurious clone, but it's hard to turn something like @@ -560,9 +552,7 @@ impl RollbackWrapper<'_> { key: &str, ) -> InterpreterResult> { self.stack.last().ok_or_else(|| { - VmInternalError::Expect( - "ERROR: Clarity VM attempted GET on non-nested context.".into(), - ) + VmInternalError::Expect("ERROR: Clarity VM attempted GET on non-nested context.".into()) })?; // This is THEORETICALLY a spurious clone, but it's hard to turn something like @@ -584,9 +574,7 @@ impl RollbackWrapper<'_> { pub fn has_entry(&mut self, key: &str) -> InterpreterResult { self.stack.last().ok_or_else(|| { - VmInternalError::Expect( - "ERROR: Clarity VM attempted GET on non-nested context.".into(), - ) + VmInternalError::Expect("ERROR: Clarity VM attempted GET on non-nested context.".into()) })?; if self.query_pending_data && self.lookup_map.contains_key(key) { Ok(true) diff --git a/clarity/src/vm/database/sqlite.rs b/clarity/src/vm/database/sqlite.rs index 7409f8f643..90234a92b6 100644 --- a/clarity/src/vm/database/sqlite.rs +++ b/clarity/src/vm/database/sqlite.rs @@ -27,7 +27,7 @@ use super::{ }; use crate::vm::analysis::{AnalysisDatabase, CheckErrors}; use crate::vm::errors::{ - IncomparableError, VmInternalError, InterpreterResult as Result, RuntimeErrorType, + IncomparableError, InterpreterResult as Result, RuntimeErrorType, VmInternalError, }; use crate::vm::types::QualifiedContractIdentifier; diff --git a/clarity/src/vm/errors.rs b/clarity/src/vm/errors.rs index 25f6145b08..eacfa91a46 100644 --- a/clarity/src/vm/errors.rs +++ b/clarity/src/vm/errors.rs @@ -15,8 +15,7 @@ // along with this program. If not, see . pub use clarity_types::errors::{ - Error, IncomparableError, VmInternalError, InterpreterResult, RuntimeErrorType, - ShortReturnType, + Error, IncomparableError, InterpreterResult, RuntimeErrorType, ShortReturnType, VmInternalError, }; pub use crate::vm::analysis::errors::{ diff --git a/clarity/src/vm/functions/assets.rs b/clarity/src/vm/functions/assets.rs index ebbcbd5ed9..d799ba7b46 100644 --- a/clarity/src/vm/functions/assets.rs +++ b/clarity/src/vm/functions/assets.rs @@ -20,8 +20,8 @@ use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostTracker}; use crate::vm::database::STXBalance; use crate::vm::errors::{ - check_argument_count, CheckErrors, Error, VmInternalError, InterpreterResult as Result, - RuntimeErrorType, + check_argument_count, CheckErrors, Error, InterpreterResult as Result, RuntimeErrorType, + VmInternalError, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::{ diff --git a/clarity/src/vm/functions/conversions.rs b/clarity/src/vm/functions/conversions.rs index 84528045a1..64f2435f36 100644 --- a/clarity/src/vm/functions/conversions.rs +++ b/clarity/src/vm/functions/conversions.rs @@ -19,7 +19,7 @@ use clarity_types::types::serialization::SerializationError; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, CheckErrors, VmInternalError, InterpreterResult as Result, + check_argument_count, CheckErrors, InterpreterResult as Result, VmInternalError, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::signatures::TO_ASCII_MAX_BUFF; diff --git a/clarity/src/vm/functions/crypto.rs b/clarity/src/vm/functions/crypto.rs index 2b5685470c..a700c7c82a 100644 --- a/clarity/src/vm/functions/crypto.rs +++ b/clarity/src/vm/functions/crypto.rs @@ -24,7 +24,7 @@ use stacks_common::util::secp256k1::{secp256k1_recover, secp256k1_verify, Secp25 use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, CheckErrors, VmInternalError, InterpreterResult as Result, + check_argument_count, CheckErrors, InterpreterResult as Result, VmInternalError, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::{BuffData, SequenceData, TypeSignature, Value, BUFF_32, BUFF_33, BUFF_65}; diff --git a/clarity/src/vm/functions/options.rs b/clarity/src/vm/functions/options.rs index ad72429ce8..2379eb03df 100644 --- a/clarity/src/vm/functions/options.rs +++ b/clarity/src/vm/functions/options.rs @@ -18,8 +18,8 @@ use crate::vm::contexts::{Environment, LocalContext}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostTracker, MemoryConsumer}; use crate::vm::errors::{ - check_arguments_at_least, CheckErrors, VmInternalError, InterpreterResult as Result, - RuntimeErrorType, ShortReturnType, + check_arguments_at_least, CheckErrors, InterpreterResult as Result, RuntimeErrorType, + ShortReturnType, VmInternalError, }; use crate::vm::types::{CallableData, OptionalData, ResponseData, TypeSignature, Value}; use crate::vm::Value::CallableContract; diff --git a/clarity/src/vm/functions/principals.rs b/clarity/src/vm/functions/principals.rs index fe463bd234..449338edff 100644 --- a/clarity/src/vm/functions/principals.rs +++ b/clarity/src/vm/functions/principals.rs @@ -8,7 +8,7 @@ use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckErrors, - VmInternalError, InterpreterResult as Result, + InterpreterResult as Result, VmInternalError, }; use crate::vm::representations::{ SymbolicExpression, CONTRACT_MAX_NAME_LENGTH, CONTRACT_MIN_NAME_LENGTH, diff --git a/clarity/src/vm/functions/tuples.rs b/clarity/src/vm/functions/tuples.rs index cc6e4fc3c9..e1d053634f 100644 --- a/clarity/src/vm/functions/tuples.rs +++ b/clarity/src/vm/functions/tuples.rs @@ -16,8 +16,8 @@ use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, check_arguments_at_least, CheckErrors, VmInternalError, - InterpreterResult as Result, SyntaxBindingErrorType, + check_argument_count, check_arguments_at_least, CheckErrors, InterpreterResult as Result, + SyntaxBindingErrorType, VmInternalError, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::{TupleData, TypeSignature, Value}; diff --git a/clarity/src/vm/mod.rs b/clarity/src/vm/mod.rs index c7ada711f1..7cbe719747 100644 --- a/clarity/src/vm/mod.rs +++ b/clarity/src/vm/mod.rs @@ -73,7 +73,7 @@ use crate::vm::costs::{ // publish the non-generic StacksEpoch form for use throughout module pub use crate::vm::database::clarity_db::StacksEpoch; use crate::vm::errors::{ - CheckErrors, Error, VmInternalError, InterpreterResult as Result, RuntimeErrorType, + CheckErrors, Error, InterpreterResult as Result, RuntimeErrorType, VmInternalError, }; use crate::vm::events::StacksTransactionEvent; use crate::vm::functions::define::DefineResult; @@ -164,10 +164,10 @@ pub trait EvalHook { fn lookup_variable(name: &str, context: &LocalContext, env: &mut Environment) -> Result { if name.starts_with(char::is_numeric) || name.starts_with('\'') { - Err(VmInternalError::BadSymbolicRepresentation(format!( - "Unexpected variable name: {name}" - )) - .into()) + Err( + VmInternalError::BadSymbolicRepresentation(format!("Unexpected variable name: {name}")) + .into(), + ) } else if let Some(value) = variables::lookup_reserved_variable(name, context, env)? { Ok(value) } else { diff --git a/stackslib/src/chainstate/stacks/db/transactions.rs b/stackslib/src/chainstate/stacks/db/transactions.rs index 59ad890091..a1d915dc68 100644 --- a/stackslib/src/chainstate/stacks/db/transactions.rs +++ b/stackslib/src/chainstate/stacks/db/transactions.rs @@ -49,7 +49,7 @@ impl TryFrom for HashableClarityValue { fn try_from(value: Value) -> Result { // check that serialization _will_ be successful when hashed let _bytes = value.serialize_to_vec().map_err(|_| { - InterpreterError::Interpreter(clarity::vm::errors::VmInternalError::Expect( + InterpreterError::Internal(clarity::vm::errors::VmInternalError::Expect( "Failed to serialize asset in NFT during post-condition checks".into(), )) })?; diff --git a/stackslib/src/clarity_vm/database/marf.rs b/stackslib/src/clarity_vm/database/marf.rs index 0d2a1bd960..391ab5703b 100644 --- a/stackslib/src/clarity_vm/database/marf.rs +++ b/stackslib/src/clarity_vm/database/marf.rs @@ -12,7 +12,7 @@ use clarity::vm::database::{ SqliteConnection, }; use clarity::vm::errors::{ - IncomparableError, VmInternalError, InterpreterResult, RuntimeErrorType, + IncomparableError, InterpreterResult, RuntimeErrorType, VmInternalError, }; use clarity::vm::types::QualifiedContractIdentifier; use rusqlite::Connection; @@ -45,8 +45,7 @@ impl MarfedKV { ) -> InterpreterResult> { let mut path = PathBuf::from(path_str); - std::fs::create_dir_all(&path) - .map_err(|_| VmInternalError::FailedToCreateDataDirectory)?; + std::fs::create_dir_all(&path).map_err(|_| VmInternalError::FailedToCreateDataDirectory)?; path.push("marf.sqlite"); let marf_path = path From b2856023cbcfc903240cabefe7e856068174c9b4 Mon Sep 17 00:00:00 2001 From: Francesco Leacche Date: Wed, 17 Sep 2025 15:41:39 +0200 Subject: [PATCH 03/34] cargo fmt --- clarity/src/vm/database/clarity_db.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clarity/src/vm/database/clarity_db.rs b/clarity/src/vm/database/clarity_db.rs index ae0a4930d1..1f7170851a 100644 --- a/clarity/src/vm/database/clarity_db.rs +++ b/clarity/src/vm/database/clarity_db.rs @@ -24,7 +24,7 @@ use stacks_common::types::chainstate::{ TrieHash, VRFSeed, }; use stacks_common::types::{StacksEpoch as GenericStacksEpoch, StacksEpochId}; -use stacks_common::util::hash::{Hash160, Sha512Trunc256Sum, to_hex}; +use stacks_common::util::hash::{to_hex, Hash160, Sha512Trunc256Sum}; use super::clarity_store::SpecialCaseHandler; use super::key_value_wrapper::ValueResult; @@ -43,8 +43,8 @@ use crate::vm::errors::{ use crate::vm::representations::ClarityName; use crate::vm::types::serialization::NONE_SERIALIZATION_LEN; use crate::vm::types::{ - PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, TupleData, TypeSignature, - Value, byte_len_of_serialization, + byte_len_of_serialization, PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, + TupleData, TypeSignature, Value, }; pub const STORE_CONTRACT_SRC_INTERFACE: bool = true; @@ -148,7 +148,7 @@ pub trait HeadersDB { epoch: &StacksEpochId, ) -> Option; fn get_burn_header_hash_for_block(&self, id_bhh: &StacksBlockId) - -> Option; + -> Option; fn get_consensus_hash_for_block( &self, id_bhh: &StacksBlockId, From 0ccff9f7ed294234a1a66576af704081c991fa1e Mon Sep 17 00:00:00 2001 From: Francesco Leacche Date: Wed, 17 Sep 2025 16:01:00 +0200 Subject: [PATCH 04/34] add docstring for VmInternalError::BadSymbolicRepresentation(String) --- clarity-types/src/errors/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 21f905ea88..f40e22cf2a 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -64,6 +64,8 @@ pub enum Error { /// invariants. They are not meant to be caught or handled by Clarity contracts. #[derive(Debug, PartialEq)] pub enum VmInternalError { + /// Raised when the VM encounters an invalid or malformed `SymbolicExpression` + /// e.g., bad variable name or missing argument. BadSymbolicRepresentation(String), /// A generic, unexpected internal error, indicating a logic failure within /// the VM. From 632dd49a8147a7130708e69907ca4bdeb3d35dd7 Mon Sep 17 00:00:00 2001 From: Francesco Leacche Date: Wed, 17 Sep 2025 16:01:28 +0200 Subject: [PATCH 05/34] rename VmInternalError::AssertionFailed -> InvariantViolation --- clarity-types/src/errors/mod.rs | 8 ++++---- clarity/src/vm/contexts.rs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index f40e22cf2a..ad7c19a03f 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -70,7 +70,7 @@ pub enum VmInternalError { /// A generic, unexpected internal error, indicating a logic failure within /// the VM. /// TODO: merge with VmInternalError::Expect - AssertionFailed(String), + InvariantViolation(String), /// The VM failed to produce the final `AssetMap` when finalizing the /// execution environment for a transaction. FailedToConstructAssetTable, @@ -280,12 +280,12 @@ mod test { Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))) ); assert_eq!( - Error::Internal(VmInternalError::AssertionFailed("".to_string())), - Error::Internal(VmInternalError::AssertionFailed("".to_string())) + Error::Internal(VmInternalError::InvariantViolation("".to_string())), + Error::Internal(VmInternalError::InvariantViolation("".to_string())) ); assert!( Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))) - != Error::Internal(VmInternalError::AssertionFailed("".to_string())) + != Error::Internal(VmInternalError::InvariantViolation("".to_string())) ); } } diff --git a/clarity/src/vm/contexts.rs b/clarity/src/vm/contexts.rs index 9154040e28..153bd0ddff 100644 --- a/clarity/src/vm/contexts.rs +++ b/clarity/src/vm/contexts.rs @@ -1126,7 +1126,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { let args: Result> = args.iter() .map(|arg| { let value = arg.match_atom_value() - .ok_or_else(|| VmInternalError::AssertionFailed(format!("Passed non-value expression to exec_tx on {tx_name}!")))?; + .ok_or_else(|| VmInternalError::InvariantViolation(format!("Passed non-value expression to exec_tx on {tx_name}!")))?; // sanitize contract-call inputs in epochs >= 2.4 // testing todo: ensure sanitize_value() preserves trait callability! let expected_type = TypeSignature::type_of(value)?; @@ -1961,20 +1961,20 @@ impl CallStack { pub fn remove(&mut self, function: &FunctionIdentifier, tracked: bool) -> Result<()> { if let Some(removed) = self.stack.pop() { if removed != *function { - return Err(VmInternalError::AssertionFailed( + return Err(VmInternalError::InvariantViolation( "Tried to remove item from empty call stack.".to_string(), ) .into()); } if tracked && !self.set.remove(function) { - return Err(VmInternalError::AssertionFailed( + return Err(VmInternalError::InvariantViolation( "Tried to remove tracked function from call stack, but could not find in current context.".into() ) .into()); } Ok(()) } else { - Err(VmInternalError::AssertionFailed( + Err(VmInternalError::InvariantViolation( "Tried to remove item from empty call stack.".to_string(), ) .into()) From 5612c96bded87a9d021aaa94340c207a09222d7f Mon Sep 17 00:00:00 2001 From: Francesco Leacche Date: Wed, 17 Sep 2025 17:30:36 +0200 Subject: [PATCH 06/34] fix stx_transfer_consolidate_regr_24010 --- clarity/src/vm/contexts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clarity/src/vm/contexts.rs b/clarity/src/vm/contexts.rs index 153bd0ddff..1321ca6bf2 100644 --- a/clarity/src/vm/contexts.rs +++ b/clarity/src/vm/contexts.rs @@ -2175,7 +2175,7 @@ mod test { &BuffData::empty(), ) .unwrap_err(); - assert_eq!(e.to_string(), "Interpreter(InsufficientBalance)"); + assert_eq!(e.to_string(), "Internal(InsufficientBalance)"); } #[test] From 00d2e17cca2b17ace1e1e37e93ab009edaffc11b Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 10:31:16 -0700 Subject: [PATCH 07/34] Rename ParseErrors to ParseErrorKind Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/ast.rs | 160 +++++++++-------- clarity-types/src/errors/mod.rs | 4 +- .../src/vm/analysis/trait_checker/tests.rs | 12 +- .../analysis/type_checker/v2_05/tests/mod.rs | 20 +-- .../analysis/type_checker/v2_1/tests/mod.rs | 20 +-- clarity/src/vm/ast/definition_sorter/mod.rs | 8 +- clarity/src/vm/ast/definition_sorter/tests.rs | 20 +-- clarity/src/vm/ast/errors.rs | 2 +- .../src/vm/ast/expression_identifier/mod.rs | 6 +- clarity/src/vm/ast/mod.rs | 16 +- clarity/src/vm/ast/parser/v1.rs | 168 ++++++++++-------- clarity/src/vm/ast/parser/v2/mod.rs | 132 ++++++++------ clarity/src/vm/ast/stack_depth_checker.rs | 6 +- clarity/src/vm/ast/sugar_expander/mod.rs | 6 +- clarity/src/vm/ast/traits_resolver/mod.rs | 31 ++-- clarity/src/vm/clarity.rs | 10 +- clarity/src/vm/tests/contracts.rs | 4 +- clarity/src/vm/tests/defines.rs | 20 +-- .../src/chainstate/stacks/db/transactions.rs | 6 +- stackslib/src/chainstate/stacks/miner.rs | 6 +- stackslib/src/net/relay.rs | 6 +- 21 files changed, 356 insertions(+), 307 deletions(-) diff --git a/clarity-types/src/errors/ast.rs b/clarity-types/src/errors/ast.rs index a18e6242aa..506bc84a8f 100644 --- a/clarity-types/src/errors/ast.rs +++ b/clarity-types/src/errors/ast.rs @@ -25,7 +25,7 @@ use crate::token::Token; pub type ParseResult = Result; #[derive(Debug, PartialEq)] -pub enum ParseErrors { +pub enum ParseErrorKind { // Cost errors CostOverflow, CostBalanceExceeded(ExecutionCost, ExecutionCost), @@ -98,13 +98,13 @@ pub enum ParseErrors { #[derive(Debug, PartialEq)] pub struct ParseError { - pub err: Box, + pub err: Box, pub pre_expressions: Option>, pub diagnostic: Diagnostic, } impl ParseError { - pub fn new(err: ParseErrors) -> ParseError { + pub fn new(err: ParseErrorKind) -> ParseError { let diagnostic = Diagnostic::err(&err); ParseError { err: Box::new(err), @@ -114,7 +114,7 @@ impl ParseError { } pub fn rejectable(&self) -> bool { - matches!(*self.err, ParseErrors::InterpreterFailure) + matches!(*self.err, ParseErrorKind::InterpreterFailure) } pub fn has_pre_expression(&self) -> bool { @@ -150,8 +150,8 @@ impl error::Error for ParseError { } } -impl From for ParseError { - fn from(err: ParseErrors) -> Self { +impl From for ParseError { + fn from(err: ParseErrorKind) -> Self { ParseError::new(err) } } @@ -159,143 +159,153 @@ impl From for ParseError { impl From for ParseError { fn from(err: CostErrors) -> Self { match err { - CostErrors::CostOverflow => ParseError::new(ParseErrors::CostOverflow), + CostErrors::CostOverflow => ParseError::new(ParseErrorKind::CostOverflow), CostErrors::CostBalanceExceeded(a, b) => { - ParseError::new(ParseErrors::CostBalanceExceeded(a, b)) + ParseError::new(ParseErrorKind::CostBalanceExceeded(a, b)) } CostErrors::MemoryBalanceExceeded(a, b) => { - ParseError::new(ParseErrors::MemoryBalanceExceeded(a, b)) + ParseError::new(ParseErrorKind::MemoryBalanceExceeded(a, b)) } CostErrors::CostComputationFailed(s) => { - ParseError::new(ParseErrors::CostComputationFailed(s)) + ParseError::new(ParseErrorKind::CostComputationFailed(s)) } CostErrors::CostContractLoadFailure => ParseError::new( - ParseErrors::CostComputationFailed("Failed to load cost contract".into()), + ParseErrorKind::CostComputationFailed("Failed to load cost contract".into()), ), CostErrors::InterpreterFailure | CostErrors::Expect(_) => { - ParseError::new(ParseErrors::InterpreterFailure) + ParseError::new(ParseErrorKind::InterpreterFailure) + } + CostErrors::ExecutionTimeExpired => { + ParseError::new(ParseErrorKind::ExecutionTimeExpired) } - CostErrors::ExecutionTimeExpired => ParseError::new(ParseErrors::ExecutionTimeExpired), } } } -impl DiagnosableError for ParseErrors { +impl DiagnosableError for ParseErrorKind { fn message(&self) -> String { match &self { - ParseErrors::CostOverflow => "Used up cost budget during the parse".into(), - ParseErrors::CostBalanceExceeded(bal, used) => { + ParseErrorKind::CostOverflow => "Used up cost budget during the parse".into(), + ParseErrorKind::CostBalanceExceeded(bal, used) => { format!("Used up cost budget during the parse: {bal} balance, {used} used") } - ParseErrors::MemoryBalanceExceeded(bal, used) => { + ParseErrorKind::MemoryBalanceExceeded(bal, used) => { format!("Used up memory budget during the parse: {bal} balance, {used} used") } - ParseErrors::TooManyExpressions => "Too many expressions".into(), - ParseErrors::FailedCapturingInput => "Failed to capture value from input".into(), - ParseErrors::SeparatorExpected(found) => { + ParseErrorKind::TooManyExpressions => "Too many expressions".into(), + ParseErrorKind::FailedCapturingInput => "Failed to capture value from input".into(), + ParseErrorKind::SeparatorExpected(found) => { format!("Expected whitespace or a close parens. Found: '{found}'") } - ParseErrors::SeparatorExpectedAfterColon(found) => { + ParseErrorKind::SeparatorExpectedAfterColon(found) => { format!("Whitespace expected after colon (:), Found: '{found}'") } - ParseErrors::ProgramTooLarge => "Program too large to parse".into(), - ParseErrors::IllegalContractName(contract_name) => { + ParseErrorKind::ProgramTooLarge => "Program too large to parse".into(), + ParseErrorKind::IllegalContractName(contract_name) => { format!("Illegal contract name: '{contract_name}'") } - ParseErrors::IllegalVariableName(var_name) => { + ParseErrorKind::IllegalVariableName(var_name) => { format!("Illegal variable name: '{var_name}'") } - ParseErrors::FailedParsingIntValue(value) => { + ParseErrorKind::FailedParsingIntValue(value) => { format!("Failed to parse int literal '{value}'") } - ParseErrors::FailedParsingUIntValue(value) => { + ParseErrorKind::FailedParsingUIntValue(value) => { format!("Failed to parse uint literal 'u{value}'") } - ParseErrors::FailedParsingHexValue(value, x) => { + ParseErrorKind::FailedParsingHexValue(value, x) => { format!("Invalid hex-string literal {value}: {x}") } - ParseErrors::FailedParsingPrincipal(value) => { + ParseErrorKind::FailedParsingPrincipal(value) => { format!("Invalid principal literal: {value}") } - ParseErrors::FailedParsingBuffer(value) => format!("Invalid buffer literal: {value}"), - ParseErrors::FailedParsingField(value) => format!("Invalid field literal: {value}"), - ParseErrors::FailedParsingRemainder(remainder) => { + ParseErrorKind::FailedParsingBuffer(value) => { + format!("Invalid buffer literal: {value}") + } + ParseErrorKind::FailedParsingField(value) => format!("Invalid field literal: {value}"), + ParseErrorKind::FailedParsingRemainder(remainder) => { format!("Failed to lex input remainder: '{remainder}'") } - ParseErrors::ClosingParenthesisUnexpected => { + ParseErrorKind::ClosingParenthesisUnexpected => { "Tried to close list which isn't open.".into() } - ParseErrors::ClosingParenthesisExpected => "List expressions (..) left opened.".into(), - ParseErrors::ClosingTupleLiteralUnexpected => { + ParseErrorKind::ClosingParenthesisExpected => { + "List expressions (..) left opened.".into() + } + ParseErrorKind::ClosingTupleLiteralUnexpected => { "Tried to close tuple literal which isn't open.".into() } - ParseErrors::ClosingTupleLiteralExpected => "Tuple literal {{..}} left opened.".into(), - ParseErrors::ColonSeparatorUnexpected => "Misplaced colon.".into(), - ParseErrors::CommaSeparatorUnexpected => "Misplaced comma.".into(), - ParseErrors::TupleColonExpected(i) => { + ParseErrorKind::ClosingTupleLiteralExpected => { + "Tuple literal {{..}} left opened.".into() + } + ParseErrorKind::ColonSeparatorUnexpected => "Misplaced colon.".into(), + ParseErrorKind::CommaSeparatorUnexpected => "Misplaced comma.".into(), + ParseErrorKind::TupleColonExpected(i) => { format!("Tuple literal construction expects a colon at index {i}") } - ParseErrors::TupleCommaExpected(i) => { + ParseErrorKind::TupleCommaExpected(i) => { format!("Tuple literal construction expects a comma at index {i}") } - ParseErrors::TupleItemExpected(i) => { + ParseErrorKind::TupleItemExpected(i) => { format!("Tuple literal construction expects a key or value at index {i}") } - ParseErrors::CircularReference(function_names) => format!( + ParseErrorKind::CircularReference(function_names) => format!( "detected interdependent functions ({})", function_names.join(", ") ), - ParseErrors::NameAlreadyUsed(name) => { + ParseErrorKind::NameAlreadyUsed(name) => { format!("defining '{name}' conflicts with previous value") } - ParseErrors::ImportTraitBadSignature => { + ParseErrorKind::ImportTraitBadSignature => { "(use-trait ...) expects a trait name and a trait identifier".into() } - ParseErrors::DefineTraitBadSignature => { + ParseErrorKind::DefineTraitBadSignature => { "(define-trait ...) expects a trait name and a trait definition".into() } - ParseErrors::ImplTraitBadSignature => { + ParseErrorKind::ImplTraitBadSignature => { "(impl-trait ...) expects a trait identifier".into() } - ParseErrors::TraitReferenceNotAllowed => "trait references can not be stored".into(), - ParseErrors::TraitReferenceUnknown(trait_name) => { + ParseErrorKind::TraitReferenceNotAllowed => "trait references can not be stored".into(), + ParseErrorKind::TraitReferenceUnknown(trait_name) => { format!("use of undeclared trait <{trait_name}>") } - ParseErrors::ExpressionStackDepthTooDeep => format!( + ParseErrorKind::ExpressionStackDepthTooDeep => format!( "AST has too deep of an expression nesting. The maximum stack depth is {MAX_CALL_STACK_DEPTH}" ), - ParseErrors::VaryExpressionStackDepthTooDeep => format!( + ParseErrorKind::VaryExpressionStackDepthTooDeep => format!( "AST has too deep of an expression nesting. The maximum stack depth is {MAX_CALL_STACK_DEPTH}" ), - ParseErrors::InvalidCharactersDetected => "invalid characters detected".into(), - ParseErrors::InvalidEscaping => "invalid escaping detected in string".into(), - ParseErrors::CostComputationFailed(s) => format!("Cost computation failed: {s}"), + ParseErrorKind::InvalidCharactersDetected => "invalid characters detected".into(), + ParseErrorKind::InvalidEscaping => "invalid escaping detected in string".into(), + ParseErrorKind::CostComputationFailed(s) => format!("Cost computation failed: {s}"), // Parser v2 errors - ParseErrors::Lexer(le) => le.message(), - ParseErrors::ContractNameTooLong(name) => { + ParseErrorKind::Lexer(le) => le.message(), + ParseErrorKind::ContractNameTooLong(name) => { format!("contract name '{name}' is too long") } - ParseErrors::ExpectedContractIdentifier => "expected contract identifier".into(), - ParseErrors::ExpectedTraitIdentifier => "expected trait identifier".into(), - ParseErrors::IllegalTraitName(name) => format!("illegal trait name, '{name}'"), - ParseErrors::InvalidPrincipalLiteral => "invalid principal literal".into(), - ParseErrors::InvalidBuffer => "invalid hex-string literal".into(), - ParseErrors::NameTooLong(name) => format!("illegal name (too long), '{name}'"), - ParseErrors::UnexpectedToken(token) => format!("unexpected '{token}'"), - ParseErrors::ExpectedClosing(token) => format!("expected closing '{token}'"), - ParseErrors::TupleColonExpectedv2 => "expected ':' after key in tuple".into(), - ParseErrors::TupleCommaExpectedv2 => { + ParseErrorKind::ExpectedContractIdentifier => "expected contract identifier".into(), + ParseErrorKind::ExpectedTraitIdentifier => "expected trait identifier".into(), + ParseErrorKind::IllegalTraitName(name) => format!("illegal trait name, '{name}'"), + ParseErrorKind::InvalidPrincipalLiteral => "invalid principal literal".into(), + ParseErrorKind::InvalidBuffer => "invalid hex-string literal".into(), + ParseErrorKind::NameTooLong(name) => format!("illegal name (too long), '{name}'"), + ParseErrorKind::UnexpectedToken(token) => format!("unexpected '{token}'"), + ParseErrorKind::ExpectedClosing(token) => format!("expected closing '{token}'"), + ParseErrorKind::TupleColonExpectedv2 => "expected ':' after key in tuple".into(), + ParseErrorKind::TupleCommaExpectedv2 => { "expected ',' separating key-value pairs in tuple".into() } - ParseErrors::TupleValueExpected => "expected value expression for tuple".into(), - ParseErrors::IllegalClarityName(name) => format!("illegal clarity name, '{name}'"), - ParseErrors::IllegalASCIIString(s) => format!("illegal ascii string \"{s}\""), - ParseErrors::ExpectedWhitespace => "expected whitespace before expression".into(), - ParseErrors::NoteToMatchThis(token) => format!("to match this '{token}'"), - ParseErrors::UnexpectedParserFailure => "unexpected failure while parsing".to_string(), - ParseErrors::InterpreterFailure => "unexpected failure while parsing".to_string(), - ParseErrors::ExecutionTimeExpired => "max execution time expired".to_string(), + ParseErrorKind::TupleValueExpected => "expected value expression for tuple".into(), + ParseErrorKind::IllegalClarityName(name) => format!("illegal clarity name, '{name}'"), + ParseErrorKind::IllegalASCIIString(s) => format!("illegal ascii string \"{s}\""), + ParseErrorKind::ExpectedWhitespace => "expected whitespace before expression".into(), + ParseErrorKind::NoteToMatchThis(token) => format!("to match this '{token}'"), + ParseErrorKind::UnexpectedParserFailure => { + "unexpected failure while parsing".to_string() + } + ParseErrorKind::InterpreterFailure => "unexpected failure while parsing".to_string(), + ParseErrorKind::ExecutionTimeExpired => "max execution time expired".to_string(), } } @@ -305,14 +315,14 @@ impl DiagnosableError for ParseErrors { fn level(&self) -> Level { match self { - ParseErrors::NoteToMatchThis(_) => Level::Note, - ParseErrors::Lexer(lexer_error) => lexer_error.level(), + ParseErrorKind::NoteToMatchThis(_) => Level::Note, + ParseErrorKind::Lexer(lexer_error) => lexer_error.level(), _ => Level::Error, } } } pub struct PlacedError { - pub e: ParseErrors, + pub e: ParseErrorKind, pub span: Span, } diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 58b42b8a99..5a720e74a2 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -21,7 +21,7 @@ pub mod lexer; use std::{error, fmt}; pub use analysis::{CheckError, CheckErrors}; -pub use ast::{ParseError, ParseErrors, ParseResult}; +pub use ast::{ParseError, ParseErrorKind, ParseResult}; pub use cost::CostErrors; pub use lexer::LexerError; #[cfg(feature = "rusqlite")] @@ -168,7 +168,7 @@ impl error::Error for RuntimeErrorType { impl From for Error { fn from(err: ParseError) -> Self { match *err.err { - ParseErrors::InterpreterFailure => Error::from(InterpreterError::Expect( + ParseErrorKind::InterpreterFailure => Error::from(InterpreterError::Expect( "Unexpected interpreter failure during parsing".into(), )), _ => Error::from(RuntimeErrorType::ASTError(Box::new(err))), diff --git a/clarity/src/vm/analysis/trait_checker/tests.rs b/clarity/src/vm/analysis/trait_checker/tests.rs index 305781f959..05ea788046 100644 --- a/clarity/src/vm/analysis/trait_checker/tests.rs +++ b/clarity/src/vm/analysis/trait_checker/tests.rs @@ -22,7 +22,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::analysis::errors::CheckErrors; use crate::vm::analysis::{type_check, CheckError}; -use crate::vm::ast::errors::ParseErrors; +use crate::vm::ast::errors::ParseErrorKind; use crate::vm::ast::{build_ast, parse}; use crate::vm::database::MemoryBackingStore; use crate::vm::tests::test_clarity_versions; @@ -359,7 +359,7 @@ fn test_define_map_storing_trait_references( .unwrap_err(); match *err.err { - ParseErrors::TraitReferenceNotAllowed => {} + ParseErrorKind::TraitReferenceNotAllowed => {} _ => panic!("{err:?}"), } } @@ -383,7 +383,7 @@ fn test_cycle_in_traits_1_contract(#[case] version: ClarityVersion, #[case] epoc ) .unwrap_err(); match *err.err { - ParseErrors::CircularReference(_) => {} + ParseErrorKind::CircularReference(_) => {} _ => panic!("{err:?}"), } } @@ -671,7 +671,7 @@ fn test_dynamic_dispatch_collision_trait( ) .unwrap_err(); match *err.err { - ParseErrors::NameAlreadyUsed(_) => {} + ParseErrorKind::NameAlreadyUsed(_) => {} _ => panic!("{err:?}"), } } @@ -700,7 +700,7 @@ fn test_dynamic_dispatch_collision_defined_trait( ) .unwrap_err(); match *err.err { - ParseErrors::NameAlreadyUsed(_) => {} + ParseErrorKind::NameAlreadyUsed(_) => {} _ => panic!("{err:?}"), } } @@ -740,7 +740,7 @@ fn test_dynamic_dispatch_collision_imported_trait( ) .unwrap_err(); match *err.err { - ParseErrors::NameAlreadyUsed(_) => {} + ParseErrorKind::NameAlreadyUsed(_) => {} _ => panic!("{err:?}"), } } diff --git a/clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs b/clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs index 99fd0191ce..0edafe0863 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs @@ -19,7 +19,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::analysis::errors::{CheckError, CheckErrors, SyntaxBindingError}; use crate::vm::analysis::mem_type_check; use crate::vm::ast::build_ast; -use crate::vm::ast::errors::ParseErrors; +use crate::vm::ast::errors::ParseErrorKind; use crate::vm::types::SequenceSubtype::*; use crate::vm::types::StringSubtype::*; use crate::vm::types::TypeSignature::{BoolType, IntType, PrincipalType, UIntType}; @@ -126,8 +126,8 @@ fn test_define_trait() { let bad = ["(define-trait trait-1)", "(define-trait)"]; let bad_expected = [ - ParseErrors::DefineTraitBadSignature, - ParseErrors::DefineTraitBadSignature, + ParseErrorKind::DefineTraitBadSignature, + ParseErrorKind::DefineTraitBadSignature, ]; let contract_identifier = QualifiedContractIdentifier::transient(); @@ -153,10 +153,10 @@ fn test_use_trait() { "(use-trait)", ]; let bad_expected = [ - ParseErrors::ImportTraitBadSignature, - ParseErrors::ImportTraitBadSignature, - ParseErrors::ImportTraitBadSignature, - ParseErrors::ImportTraitBadSignature, + ParseErrorKind::ImportTraitBadSignature, + ParseErrorKind::ImportTraitBadSignature, + ParseErrorKind::ImportTraitBadSignature, + ParseErrorKind::ImportTraitBadSignature, ]; let contract_identifier = QualifiedContractIdentifier::transient(); @@ -177,8 +177,8 @@ fn test_use_trait() { fn test_impl_trait() { let bad = ["(impl-trait trait-1)", "(impl-trait)"]; let bad_expected = [ - ParseErrors::ImplTraitBadSignature, - ParseErrors::ImplTraitBadSignature, + ParseErrorKind::ImplTraitBadSignature, + ParseErrorKind::ImplTraitBadSignature, ]; let contract_identifier = QualifiedContractIdentifier::transient(); @@ -476,7 +476,7 @@ fn test_at_block() { fn test_trait_reference_unknown() { let bad = [( "(+ 1 )", - ParseErrors::TraitReferenceUnknown("kvstore".to_string()), + ParseErrorKind::TraitReferenceUnknown("kvstore".to_string()), )]; let contract_identifier = QualifiedContractIdentifier::transient(); diff --git a/clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs b/clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs index ac978b277b..2737cda72c 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs @@ -24,7 +24,7 @@ use crate::vm::analysis::errors::{CheckError, CheckErrors, SyntaxBindingError}; use crate::vm::analysis::mem_type_check as mem_run_analysis; use crate::vm::analysis::types::ContractAnalysis; use crate::vm::ast::build_ast; -use crate::vm::ast::errors::ParseErrors; +use crate::vm::ast::errors::ParseErrorKind; use crate::vm::tests::test_clarity_versions; use crate::vm::types::signatures::TypeSignature::OptionalType; use crate::vm::types::signatures::{ListTypeData, StringUTF8Length}; @@ -373,8 +373,8 @@ fn test_define_trait(#[case] version: ClarityVersion, #[case] epoch: StacksEpoch let bad = ["(define-trait trait-1)", "(define-trait)"]; let bad_expected = [ - ParseErrors::DefineTraitBadSignature, - ParseErrors::DefineTraitBadSignature, + ParseErrorKind::DefineTraitBadSignature, + ParseErrorKind::DefineTraitBadSignature, ]; let contract_identifier = QualifiedContractIdentifier::transient(); @@ -393,10 +393,10 @@ fn test_use_trait(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) "(use-trait)", ]; let bad_expected = [ - ParseErrors::ImportTraitBadSignature, - ParseErrors::ImportTraitBadSignature, - ParseErrors::ImportTraitBadSignature, - ParseErrors::ImportTraitBadSignature, + ParseErrorKind::ImportTraitBadSignature, + ParseErrorKind::ImportTraitBadSignature, + ParseErrorKind::ImportTraitBadSignature, + ParseErrorKind::ImportTraitBadSignature, ]; let contract_identifier = QualifiedContractIdentifier::transient(); @@ -410,8 +410,8 @@ fn test_use_trait(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) fn test_impl_trait(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) { let bad = ["(impl-trait trait-1)", "(impl-trait)"]; let bad_expected = [ - ParseErrors::ImplTraitBadSignature, - ParseErrors::ImplTraitBadSignature, + ParseErrorKind::ImplTraitBadSignature, + ParseErrorKind::ImplTraitBadSignature, ]; let contract_identifier = QualifiedContractIdentifier::transient(); @@ -770,7 +770,7 @@ fn test_at_block() { fn test_trait_reference_unknown(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) { let bad = [( "(+ 1 )", - ParseErrors::TraitReferenceUnknown("kvstore".to_string()), + ParseErrorKind::TraitReferenceUnknown("kvstore".to_string()), )]; let contract_identifier = QualifiedContractIdentifier::transient(); diff --git a/clarity/src/vm/ast/definition_sorter/mod.rs b/clarity/src/vm/ast/definition_sorter/mod.rs index e740514e55..18eddb59d0 100644 --- a/clarity/src/vm/ast/definition_sorter/mod.rs +++ b/clarity/src/vm/ast/definition_sorter/mod.rs @@ -18,7 +18,7 @@ use std::collections::{HashMap, HashSet}; use clarity_types::representations::ClarityName; -use crate::vm::ast::errors::{ParseError, ParseErrors, ParseResult}; +use crate::vm::ast::errors::{ParseError, ParseErrorKind, ParseResult}; use crate::vm::ast::types::ContractAST; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostTracker}; @@ -99,7 +99,7 @@ impl DefinitionSorter { .map(|i| i.0.to_string()) .collect::>(); - let error = ParseError::new(ParseErrors::CircularReference(functions_names)); + let error = ParseError::new(ParseErrorKind::CircularReference(functions_names)); return Err(error); } @@ -421,7 +421,7 @@ impl Graph { let list = self .adjacency_list .get_mut(src_expr_index) - .ok_or(ParseErrors::InterpreterFailure)?; + .ok_or(ParseErrorKind::InterpreterFailure)?; list.push(dst_expr_index); Ok(()) } @@ -443,7 +443,7 @@ impl Graph { for node in self.adjacency_list.iter() { total = total .checked_add(node.len() as u64) - .ok_or(ParseErrors::CostOverflow)?; + .ok_or(ParseErrorKind::CostOverflow)?; } Ok(total) } diff --git a/clarity/src/vm/ast/definition_sorter/tests.rs b/clarity/src/vm/ast/definition_sorter/tests.rs index 9bbb321178..c05611c3b2 100644 --- a/clarity/src/vm/ast/definition_sorter/tests.rs +++ b/clarity/src/vm/ast/definition_sorter/tests.rs @@ -21,7 +21,7 @@ use rstest_reuse::{self, *}; use crate::vm::analysis::type_checker::v2_1::tests::mem_type_check as run_analysis_helper; use crate::vm::ast::definition_sorter::DefinitionSorter; -use crate::vm::ast::errors::{ParseErrors, ParseResult}; +use crate::vm::ast::errors::{ParseErrorKind, ParseResult}; use crate::vm::ast::expression_identifier::ExpressionIdentifier; use crate::vm::ast::parser; use crate::vm::ast::types::ContractAST; @@ -96,7 +96,7 @@ fn should_raise_dependency_cycle_case_1(#[case] version: ClarityVersion) { "#; let err = run_scoped_parsing_helper(contract, version).unwrap_err(); - assert!(matches!(*err.err, ParseErrors::CircularReference(_))); + assert!(matches!(*err.err, ParseErrorKind::CircularReference(_))); } #[apply(test_clarity_versions_definition_sorter)] @@ -109,7 +109,7 @@ fn should_raise_dependency_cycle_case_2(#[case] version: ClarityVersion) { "#; let err = run_scoped_parsing_helper(contract, version).unwrap_err(); - assert!(matches!(*err.err, ParseErrors::CircularReference(_))); + assert!(matches!(*err.err, ParseErrorKind::CircularReference(_))); } #[apply(test_clarity_versions_definition_sorter)] @@ -131,7 +131,7 @@ fn should_raise_dependency_cycle_case_let(#[case] version: ClarityVersion) { "#; let err = run_scoped_parsing_helper(contract, version).unwrap_err(); - assert!(matches!(*err.err, ParseErrors::CircularReference(_))); + assert!(matches!(*err.err, ParseErrorKind::CircularReference(_))); } #[apply(test_clarity_versions_definition_sorter)] @@ -153,7 +153,7 @@ fn should_raise_dependency_cycle_case_get(#[case] version: ClarityVersion) { "#; let err = run_scoped_parsing_helper(contract, version).unwrap_err(); - assert!(matches!(*err.err, ParseErrors::CircularReference(_))); + assert!(matches!(*err.err, ParseErrorKind::CircularReference(_))); } #[apply(test_clarity_versions_definition_sorter)] @@ -177,7 +177,7 @@ fn should_raise_dependency_cycle_case_fetch_entry(#[case] version: ClarityVersio "#; let err = run_scoped_parsing_helper(contract, version).unwrap_err(); - assert!(matches!(*err.err, ParseErrors::CircularReference(_))); + assert!(matches!(*err.err, ParseErrorKind::CircularReference(_))); } #[apply(test_clarity_versions_definition_sorter)] @@ -201,7 +201,7 @@ fn should_raise_dependency_cycle_case_delete_entry(#[case] version: ClarityVersi "#; let err = run_scoped_parsing_helper(contract, version).unwrap_err(); - assert!(matches!(*err.err, ParseErrors::CircularReference(_))); + assert!(matches!(*err.err, ParseErrorKind::CircularReference(_))); } #[apply(test_clarity_versions_definition_sorter)] @@ -225,7 +225,7 @@ fn should_raise_dependency_cycle_case_set_entry(#[case] version: ClarityVersion) "#; let err = run_scoped_parsing_helper(contract, version).unwrap_err(); - assert!(matches!(*err.err, ParseErrors::CircularReference(_))); + assert!(matches!(*err.err, ParseErrorKind::CircularReference(_))); } #[apply(test_clarity_versions_definition_sorter)] @@ -249,7 +249,7 @@ fn should_raise_dependency_cycle_case_insert_entry(#[case] version: ClarityVersi "#; let err = run_scoped_parsing_helper(contract, version).unwrap_err(); - assert!(matches!(*err.err, ParseErrors::CircularReference(_))); + assert!(matches!(*err.err, ParseErrorKind::CircularReference(_))); } #[apply(test_clarity_versions_definition_sorter)] @@ -260,7 +260,7 @@ fn should_raise_dependency_cycle_case_fetch_contract_entry(#[case] version: Clar "#; let err = run_scoped_parsing_helper(contract, version).unwrap_err(); - assert!(matches!(*err.err, ParseErrors::CircularReference(_))); + assert!(matches!(*err.err, ParseErrorKind::CircularReference(_))); } #[apply(test_clarity_versions_definition_sorter)] diff --git a/clarity/src/vm/ast/errors.rs b/clarity/src/vm/ast/errors.rs index 2b9b5beb3c..897d4fed24 100644 --- a/clarity/src/vm/ast/errors.rs +++ b/clarity/src/vm/ast/errors.rs @@ -14,4 +14,4 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -pub use clarity_types::errors::ast::{ParseError, ParseErrors, ParseResult, PlacedError}; +pub use clarity_types::errors::ast::{ParseError, ParseErrorKind, ParseResult, PlacedError}; diff --git a/clarity/src/vm/ast/expression_identifier/mod.rs b/clarity/src/vm/ast/expression_identifier/mod.rs index 13b9aac2bd..d73d99dc24 100644 --- a/clarity/src/vm/ast/expression_identifier/mod.rs +++ b/clarity/src/vm/ast/expression_identifier/mod.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::vm::ast::errors::{ParseError, ParseErrors, ParseResult}; +use crate::vm::ast::errors::{ParseError, ParseErrorKind, ParseResult}; use crate::vm::ast::types::ContractAST; use crate::vm::representations::SymbolicExpressionCommon; use crate::vm::ClarityVersion; @@ -22,7 +22,7 @@ use crate::vm::ClarityVersion; fn inner_relabel(args: &mut [T], index: u64) -> ParseResult { let mut current = index .checked_add(1) - .ok_or(ParseError::new(ParseErrors::TooManyExpressions))?; + .ok_or(ParseError::new(ParseErrorKind::TooManyExpressions))?; for expression in &mut args[..] { expression.set_id(current); current = if let Some(exprs) = expression.match_list_mut() { @@ -30,7 +30,7 @@ fn inner_relabel(args: &mut [T], index: u64) -> Par } else { current .checked_add(1) - .ok_or(ParseError::new(ParseErrors::TooManyExpressions)) + .ok_or(ParseError::new(ParseErrorKind::TooManyExpressions)) }?; } Ok(current) diff --git a/clarity/src/vm/ast/mod.rs b/clarity/src/vm/ast/mod.rs index ccb7853641..6f16ef7ccf 100644 --- a/clarity/src/vm/ast/mod.rs +++ b/clarity/src/vm/ast/mod.rs @@ -322,7 +322,7 @@ mod test { use stacks_common::types::StacksEpochId; - use crate::vm::ast::errors::ParseErrors; + use crate::vm::ast::errors::ParseErrorKind; use crate::vm::ast::stack_depth_checker::AST_CALL_STACK_DEPTH_BUFFER; use crate::vm::ast::{build_ast, build_ast_with_rules, ASTRules}; use crate::vm::costs::{LimitedCostTracker, *}; @@ -409,7 +409,7 @@ mod test { ) .expect_err("Contract should error in parsing"); - let expected_err = ParseErrors::ExpressionStackDepthTooDeep; + let expected_err = ParseErrorKind::ExpressionStackDepthTooDeep; let expected_list_cost_state = UnitTestTracker { invoked_functions: vec![(ClarityCostFunction::AstParse, vec![500])], invocation_count: 1, @@ -431,7 +431,7 @@ mod test { ) .expect_err("Contract should error in parsing"); - let expected_err = ParseErrors::VaryExpressionStackDepthTooDeep; + let expected_err = ParseErrorKind::VaryExpressionStackDepthTooDeep; let expected_list_cost_state = UnitTestTracker { invoked_functions: vec![(ClarityCostFunction::AstParse, vec![500])], invocation_count: 1, @@ -467,7 +467,7 @@ mod test { ) .expect_err("Contract should error in parsing with ASTRules::PrecheckSize"); - let expected_err = ParseErrors::VaryExpressionStackDepthTooDeep; + let expected_err = ParseErrorKind::VaryExpressionStackDepthTooDeep; let expected_list_cost_state = UnitTestTracker { invoked_functions: vec![(ClarityCostFunction::AstParse, vec![571])], invocation_count: 1, @@ -511,7 +511,7 @@ mod test { ) .expect_err("Contract should error in parsing"); - let expected_err = ParseErrors::ExpressionStackDepthTooDeep; + let expected_err = ParseErrorKind::ExpressionStackDepthTooDeep; let expected_list_cost_state = UnitTestTracker { invoked_functions: vec![(ClarityCostFunction::AstParse, vec![500])], invocation_count: 1, @@ -533,7 +533,7 @@ mod test { ) .expect_err("Contract should error in parsing"); - let expected_err = ParseErrors::ExpressionStackDepthTooDeep; + let expected_err = ParseErrorKind::ExpressionStackDepthTooDeep; let expected_list_cost_state = UnitTestTracker { invoked_functions: vec![(ClarityCostFunction::AstParse, vec![500])], invocation_count: 1, @@ -555,7 +555,7 @@ mod test { ) .expect_err("Contract should error in parsing"); - let expected_err = ParseErrors::ExpressionStackDepthTooDeep; + let expected_err = ParseErrorKind::ExpressionStackDepthTooDeep; let expected_list_cost_state = UnitTestTracker { invoked_functions: vec![(ClarityCostFunction::AstParse, vec![571])], invocation_count: 1, @@ -577,7 +577,7 @@ mod test { ) .expect_err("Contract should error in parsing"); - let expected_err = ParseErrors::ExpressionStackDepthTooDeep; + let expected_err = ParseErrorKind::ExpressionStackDepthTooDeep; let expected_list_cost_state = UnitTestTracker { invoked_functions: vec![(ClarityCostFunction::AstParse, vec![571])], invocation_count: 1, diff --git a/clarity/src/vm/ast/parser/v1.rs b/clarity/src/vm/ast/parser/v1.rs index feb5979895..98fe702872 100644 --- a/clarity/src/vm/ast/parser/v1.rs +++ b/clarity/src/vm/ast/parser/v1.rs @@ -18,7 +18,7 @@ use lazy_static::lazy_static; use regex::{Captures, Regex}; use stacks_common::util::hash::hex_bytes; -use crate::vm::ast::errors::{ParseError, ParseErrors, ParseResult}; +use crate::vm::ast::errors::{ParseError, ParseErrorKind, ParseResult}; use crate::vm::ast::stack_depth_checker::AST_CALL_STACK_DEPTH_BUFFER; use crate::vm::representations::{ ClarityName, ContractName, PreSymbolicExpression, MAX_STRING_LEN, @@ -98,7 +98,7 @@ impl LexMatcher { fn get_value_or_err(input: &str, captures: Captures) -> ParseResult { let matched = captures .name("value") - .ok_or(ParseError::new(ParseErrors::FailedCapturingInput))?; + .ok_or(ParseError::new(ParseErrorKind::FailedCapturingInput))?; Ok(input[matched.start()..matched.end()].to_string()) } @@ -207,7 +207,7 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult ParseResult ParseResult Ok(()), TokenType::Comma => Ok(()), TokenType::Colon => Ok(()), - _ => Err(ParseError::new(ParseErrors::SeparatorExpected( + _ => Err(ParseError::new(ParseErrorKind::SeparatorExpected( current_slice[..whole_match.end()].to_string(), ))), } @@ -244,9 +244,11 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult Ok(()), TokenType::Comma => Ok(()), TokenType::Colon => Ok(()), - _ => Err(ParseError::new(ParseErrors::SeparatorExpectedAfterColon( - current_slice[..whole_match.end()].to_string(), - ))), + _ => Err(ParseError::new( + ParseErrorKind::SeparatorExpectedAfterColon( + current_slice[..whole_match.end()].to_string(), + ), + )), } } }?; @@ -260,7 +262,7 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult max_nesting { return Err(ParseError::new( - ParseErrors::VaryExpressionStackDepthTooDeep, + ParseErrorKind::VaryExpressionStackDepthTooDeep, )); } Ok(LexItem::LeftParen) @@ -289,7 +291,7 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult max_nesting { return Err(ParseError::new( - ParseErrors::VaryExpressionStackDepthTooDeep, + ParseErrorKind::VaryExpressionStackDepthTooDeep, )); } Ok(LexItem::LeftCurly) @@ -302,7 +304,7 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult { let value = get_value_or_err(current_slice, captures)?; if value.contains('#') { - Err(ParseError::new(ParseErrors::IllegalVariableName(value))) + Err(ParseError::new(ParseErrorKind::IllegalVariableName(value))) } else { Ok(LexItem::Variable(value)) } @@ -311,7 +313,7 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult() { Ok(parsed) => Ok(Value::UInt(parsed)), - Err(_e) => Err(ParseError::new(ParseErrors::FailedParsingIntValue( + Err(_e) => Err(ParseError::new(ParseErrorKind::FailedParsingIntValue( str_value.clone(), ))), }?; @@ -321,7 +323,7 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult() { Ok(parsed) => Ok(Value::Int(parsed)), - Err(_e) => Err(ParseError::new(ParseErrors::FailedParsingIntValue( + Err(_e) => Err(ParseError::new(ParseErrorKind::FailedParsingIntValue( str_value.clone(), ))), }?; @@ -333,7 +335,7 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult Ok(Value::Principal(parsed)), Err(_e) => Err(ParseError::new( - ParseErrors::FailedParsingPrincipal(str_value.clone()), + ParseErrorKind::FailedParsingPrincipal(str_value.clone()), )), }?; Ok(LexItem::LiteralValue(str_value.len(), value)) @@ -342,9 +344,9 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult Ok(parsed), - Err(_e) => Err(ParseError::new(ParseErrors::FailedParsingPrincipal( - str_value.clone(), - ))), + Err(_e) => Err(ParseError::new( + ParseErrorKind::FailedParsingPrincipal(str_value.clone()), + )), }?; Ok(LexItem::SugaredContractIdentifier(str_value.len(), value)) } @@ -352,7 +354,7 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult Ok(parsed), - Err(_e) => Err(ParseError::new(ParseErrors::FailedParsingField( + Err(_e) => Err(ParseError::new(ParseErrorKind::FailedParsingField( str_value.clone(), ))), }?; @@ -363,9 +365,9 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult Ok((contract_name, field_name)), - Err(_e) => Err(ParseError::new(ParseErrors::FailedParsingField( - str_value.clone(), - ))), + Err(_e) => Err(ParseError::new( + ParseErrorKind::FailedParsingField(str_value.clone()), + )), }?; Ok(LexItem::SugaredFieldIdentifier( str_value.len(), @@ -377,30 +379,32 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult Ok(Value::Principal(PrincipalData::Standard(parsed))), - Err(_e) => Err(ParseError::new(ParseErrors::FailedParsingPrincipal( - str_value.clone(), - ))), + Err(_e) => Err(ParseError::new( + ParseErrorKind::FailedParsingPrincipal(str_value.clone()), + )), }?; Ok(LexItem::LiteralValue(str_value.len(), value)) } TokenType::TraitReferenceLiteral => { let str_value = get_value_or_err(current_slice, captures)?; let data = str_value.clone().try_into().map_err(|_| { - ParseError::new(ParseErrors::IllegalVariableName(str_value.to_string())) + ParseError::new(ParseErrorKind::IllegalVariableName( + str_value.to_string(), + )) })?; Ok(LexItem::TraitReference(str_value.len(), data)) } TokenType::HexStringLiteral => { let str_value = get_value_or_err(current_slice, captures)?; let byte_vec = hex_bytes(&str_value).map_err(|x| { - ParseError::new(ParseErrors::FailedParsingHexValue( + ParseError::new(ParseErrorKind::FailedParsingHexValue( str_value.clone(), x.to_string(), )) })?; let value = match Value::buff_from(byte_vec) { Ok(parsed) => Ok(parsed), - Err(_e) => Err(ParseError::new(ParseErrors::FailedParsingBuffer( + Err(_e) => Err(ParseError::new(ParseErrorKind::FailedParsingBuffer( str_value.clone(), ))), }?; @@ -414,7 +418,9 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult Ok(parsed), - Err(_e) => Err(ParseError::new(ParseErrors::InvalidCharactersDetected)), + Err(_e) => { + Err(ParseError::new(ParseErrorKind::InvalidCharactersDetected)) + } }?; Ok(LexItem::LiteralValue(str_value_len, value)) } @@ -426,7 +432,9 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult Ok(parsed), - Err(_e) => Err(ParseError::new(ParseErrors::InvalidCharactersDetected)), + Err(_e) => { + Err(ParseError::new(ParseErrorKind::InvalidCharactersDetected)) + } }?; Ok(LexItem::LiteralValue(str_value_len, value)) } @@ -443,7 +451,7 @@ fn inner_lex(input: &str, max_nesting: u64) -> ParseResult Pars 'r' => unescaped_str.push('\r'), '0' => unescaped_str.push('\0'), 'u' if allow_unicode_escape => unescaped_str.push_str("\\u"), - _ => return Err(ParseError::new(ParseErrors::InvalidEscaping)), + _ => return Err(ParseError::new(ParseErrorKind::InvalidEscaping)), } } else { - return Err(ParseError::new(ParseErrors::InvalidEscaping)); + return Err(ParseError::new(ParseErrorKind::InvalidEscaping)); } } else { unescaped_str.push(char); @@ -525,12 +533,12 @@ pub fn parse_lexed(input: Vec<(LexItem, u32, u32)>) -> ParseResult Ok(e), - ParseStackItem::Colon => { - Err(ParseError::new(ParseErrors::ColonSeparatorUnexpected)) - } - ParseStackItem::Comma => { - Err(ParseError::new(ParseErrors::CommaSeparatorUnexpected)) - } + ParseStackItem::Colon => Err(ParseError::new( + ParseErrorKind::ColonSeparatorUnexpected, + )), + ParseStackItem::Comma => Err(ParseError::new( + ParseErrorKind::CommaSeparatorUnexpected, + )), }) .collect(); let checked_list = checked_list?; @@ -540,7 +548,7 @@ pub fn parse_lexed(input: Vec<(LexItem, u32, u32)>) -> ParseResult { let mut error = - ParseError::new(ParseErrors::ClosingTupleLiteralExpected); + ParseError::new(ParseErrorKind::ClosingTupleLiteralExpected); error.diagnostic.add_span( start_line, start_column, @@ -552,7 +560,9 @@ pub fn parse_lexed(input: Vec<(LexItem, u32, u32)>) -> ParseResult { @@ -574,21 +584,21 @@ pub fn parse_lexed(input: Vec<(LexItem, u32, u32)>) -> ParseResult { if let ParseStackItem::Colon = item { Ok(()) } else { - Err(ParseErrors::TupleColonExpected(index)) + Err(ParseErrorKind::TupleColonExpected(index)) } } 3 => { if let ParseStackItem::Comma = item { Ok(()) } else { - Err(ParseErrors::TupleCommaExpected(index)) + Err(ParseErrorKind::TupleCommaExpected(index)) } } _ => unreachable!("More than four modulos of four."), @@ -600,7 +610,7 @@ pub fn parse_lexed(input: Vec<(LexItem, u32, u32)>) -> ParseResult { let mut error = - ParseError::new(ParseErrors::ClosingParenthesisExpected); + ParseError::new(ParseErrorKind::ClosingParenthesisExpected); error.diagnostic.add_span( start_line, start_column, @@ -612,13 +622,15 @@ pub fn parse_lexed(input: Vec<(LexItem, u32, u32)>) -> ParseResult { let end_column = column_pos + (value.len() as u32) - 1; let value = value.clone().try_into().map_err(|_| { - ParseError::new(ParseErrors::IllegalVariableName(value.to_string())) + ParseError::new(ParseErrorKind::IllegalVariableName(value.to_string())) })?; let mut pre_expr = PreSymbolicExpression::atom(value); pre_expr.set_span(line_pos, column_pos, line_pos, end_column); @@ -673,7 +685,7 @@ pub fn parse_lexed(input: Vec<(LexItem, u32, u32)>) -> ParseResult { match parse_stack.last_mut() { - None => return Err(ParseError::new(ParseErrors::ColonSeparatorUnexpected)), + None => return Err(ParseError::new(ParseErrorKind::ColonSeparatorUnexpected)), Some((ref mut list, ..)) => { list.push(ParseStackItem::Colon); } @@ -681,7 +693,7 @@ pub fn parse_lexed(input: Vec<(LexItem, u32, u32)>) -> ParseResult { match parse_stack.last_mut() { - None => return Err(ParseError::new(ParseErrors::CommaSeparatorUnexpected)), + None => return Err(ParseError::new(ParseErrorKind::CommaSeparatorUnexpected)), Some((ref mut list, ..)) => { list.push(ParseStackItem::Comma); } @@ -693,7 +705,7 @@ pub fn parse_lexed(input: Vec<(LexItem, u32, u32)>) -> ParseResult ParseResult Parser<'a> { - pub fn new(input: &'a str, fail_fast: bool) -> Result { + pub fn new(input: &'a str, fail_fast: bool) -> Result { let lexer = match Lexer::new(input, fail_fast) { Ok(lexer) => lexer, - Err(e) => return Err(ParseErrors::Lexer(e)), + Err(e) => return Err(ParseErrorKind::Lexer(e)), }; let mut p = Self { lexer, @@ -89,7 +89,7 @@ impl<'a> Parser<'a> { "Parser::read_token should not return an error when not in fail_fast mode" ); p.success = false; - return Err(ParseErrors::Lexer(e)); + return Err(ParseErrorKind::Lexer(e)); } }; if token.token == Token::Eof { @@ -103,7 +103,7 @@ impl<'a> Parser<'a> { .diagnostics .iter() .map(|lex_error| PlacedError { - e: ParseErrors::Lexer(lex_error.e.clone()), + e: ParseErrorKind::Lexer(lex_error.e.clone()), span: lex_error.span.clone(), }) .collect(); @@ -111,7 +111,7 @@ impl<'a> Parser<'a> { Ok(p) } - fn add_diagnostic(&mut self, e: ParseErrors, span: Span) -> ParseResult<()> { + fn add_diagnostic(&mut self, e: ParseErrorKind, span: Span) -> ParseResult<()> { if self.fail_fast { return Err(ParseError::new(e)); } else { @@ -152,11 +152,11 @@ impl<'a> Parser<'a> { /// raises an UnexpectedParserFailure. fn peek_last_token(&self) -> ParseResult<&PlacedToken> { if self.next_token == 0 { - return Err(ParseError::new(ParseErrors::UnexpectedParserFailure)); + return Err(ParseError::new(ParseErrorKind::UnexpectedParserFailure)); } self.tokens .get(self.next_token - 1) - .ok_or_else(|| ParseError::new(ParseErrors::UnexpectedParserFailure)) + .ok_or_else(|| ParseError::new(ParseErrorKind::UnexpectedParserFailure)) } fn skip_to_end(&mut self) { @@ -222,7 +222,10 @@ impl<'a> Parser<'a> { } => { if let Some(node) = node_opt { if !*whitespace && node.match_comment().is_none() { - self.add_diagnostic(ParseErrors::ExpectedWhitespace, node.span().clone())?; + self.add_diagnostic( + ParseErrorKind::ExpectedWhitespace, + node.span().clone(), + )?; } nodes.push(node); *whitespace = self.ignore_whitespace(); @@ -241,11 +244,11 @@ impl<'a> Parser<'a> { Token::Eof => { // Report an error, but return the list and attempt to continue parsing self.add_diagnostic( - ParseErrors::ExpectedClosing(Token::Rparen), + ParseErrorKind::ExpectedClosing(Token::Rparen), token.span.clone(), )?; self.add_diagnostic( - ParseErrors::NoteToMatchThis(Token::Lparen), + ParseErrorKind::NoteToMatchThis(Token::Lparen), span.clone(), )?; span.end_line = token.span.end_line; @@ -258,7 +261,7 @@ impl<'a> Parser<'a> { _ => { // Report an error, then skip this token self.add_diagnostic( - ParseErrors::UnexpectedToken(token.token.clone()), + ParseErrorKind::UnexpectedToken(token.token.clone()), token.span, )?; *whitespace = self.ignore_whitespace(); @@ -293,11 +296,11 @@ impl<'a> Parser<'a> { match last_token.token { Token::Eof => { self.add_diagnostic( - ParseErrors::ExpectedClosing(Token::Rbrace), + ParseErrorKind::ExpectedClosing(Token::Rbrace), open_tuple.diagnostic_token.span.clone(), )?; self.add_diagnostic( - ParseErrors::NoteToMatchThis(Token::Lbrace), + ParseErrorKind::NoteToMatchThis(Token::Lbrace), open_tuple.span.clone(), )?; let out_nodes: Vec<_> = open_tuple.nodes.drain(..).collect(); @@ -311,7 +314,7 @@ impl<'a> Parser<'a> { _ => { // Report an error, then skip this token self.add_diagnostic( - ParseErrors::UnexpectedToken(last_token.token), + ParseErrorKind::UnexpectedToken(last_token.token), last_token.span, )?; return Ok(None); // Ok(None) yields to the parse loop @@ -335,7 +338,10 @@ impl<'a> Parser<'a> { // This indicates we have reached the end of the input. // Create a placeholder value so that parsing can continue, // then return. - self.add_diagnostic(ParseErrors::TupleColonExpectedv2, token.span.clone())?; + self.add_diagnostic( + ParseErrorKind::TupleColonExpectedv2, + token.span.clone(), + )?; let mut placeholder = PreSymbolicExpression::placeholder("".to_string()); placeholder.copy_span(&token.span); open_tuple.nodes.push(placeholder); // Placeholder value @@ -349,7 +355,10 @@ impl<'a> Parser<'a> { } _ => { // Record an error, then continue to parse - self.add_diagnostic(ParseErrors::TupleColonExpectedv2, token.span.clone())?; + self.add_diagnostic( + ParseErrorKind::TupleColonExpectedv2, + token.span.clone(), + )?; } } open_tuple.diagnostic_token = token; @@ -377,7 +386,7 @@ impl<'a> Parser<'a> { let eof_span = last_token.span; self.add_diagnostic( - ParseErrors::TupleValueExpected, + ParseErrorKind::TupleValueExpected, open_tuple.diagnostic_token.span.clone(), )?; let mut placeholder = @@ -396,7 +405,7 @@ impl<'a> Parser<'a> { _ => { // Report an error, then skip this token self.add_diagnostic( - ParseErrors::UnexpectedToken(last_token.token), + ParseErrorKind::UnexpectedToken(last_token.token), last_token.span, )?; return Ok(None); // Ok(None) yields to the parse loop @@ -425,7 +434,7 @@ impl<'a> Parser<'a> { return Ok(Some(e)); } Token::Eof => (), - _ => self.add_diagnostic(ParseErrors::TupleCommaExpectedv2, token.span)?, + _ => self.add_diagnostic(ParseErrorKind::TupleCommaExpectedv2, token.span)?, } let mut comments = self.ignore_whitespace_and_comments(); @@ -469,7 +478,7 @@ impl<'a> Parser<'a> { let token = self.peek_next_token(); match token.token { Token::Comma => { - self.add_diagnostic(ParseErrors::UnexpectedToken(token.token), token.span)?; + self.add_diagnostic(ParseErrorKind::UnexpectedToken(token.token), token.span)?; self.next_token(); } Token::Rbrace => { @@ -514,7 +523,7 @@ impl<'a> Parser<'a> { let principal = match PrincipalData::parse_standard_principal(&addr) { Ok(principal) => principal, _ => { - self.add_diagnostic(ParseErrors::InvalidPrincipalLiteral, span.clone())?; + self.add_diagnostic(ParseErrorKind::InvalidPrincipalLiteral, span.clone())?; let mut placeholder = PreSymbolicExpression::placeholder(format!("'{addr}")); placeholder.copy_span(&span); return Ok(placeholder); @@ -540,7 +549,7 @@ impl<'a> Parser<'a> { }) => { span.end_line = token_span.end_line; span.end_column = token_span.end_column; - self.add_diagnostic(ParseErrors::ExpectedContractIdentifier, token_span)?; + self.add_diagnostic(ParseErrorKind::ExpectedContractIdentifier, token_span)?; let mut placeholder = PreSymbolicExpression::placeholder(format!( "'{principal}.{}", token.reproduce() @@ -549,7 +558,7 @@ impl<'a> Parser<'a> { return Ok(placeholder); } None => { - self.add_diagnostic(ParseErrors::ExpectedContractIdentifier, dot.span)?; + self.add_diagnostic(ParseErrorKind::ExpectedContractIdentifier, dot.span)?; let mut placeholder = PreSymbolicExpression::placeholder(format!("'{principal}.")); placeholder.copy_span(&span); @@ -559,7 +568,7 @@ impl<'a> Parser<'a> { if name.len() > MAX_CONTRACT_NAME_LEN { self.add_diagnostic( - ParseErrors::ContractNameTooLong(name.clone()), + ParseErrorKind::ContractNameTooLong(name.clone()), contract_span, )?; let mut placeholder = @@ -571,7 +580,7 @@ impl<'a> Parser<'a> { Ok(id) => id, Err(_) => { self.add_diagnostic( - ParseErrors::IllegalContractName(name.clone()), + ParseErrorKind::IllegalContractName(name.clone()), contract_span, )?; let mut placeholder = @@ -600,7 +609,7 @@ impl<'a> Parser<'a> { token, }) => { self.add_diagnostic( - ParseErrors::ExpectedTraitIdentifier, + ParseErrorKind::ExpectedTraitIdentifier, token_span.clone(), )?; let mut placeholder = PreSymbolicExpression::placeholder(format!( @@ -614,7 +623,7 @@ impl<'a> Parser<'a> { } None => { self.add_diagnostic( - ParseErrors::ExpectedTraitIdentifier, + ParseErrorKind::ExpectedTraitIdentifier, dot.span.clone(), )?; let mut placeholder = @@ -626,7 +635,7 @@ impl<'a> Parser<'a> { } }; if name.len() > MAX_STRING_LEN { - self.add_diagnostic(ParseErrors::NameTooLong(name.clone()), trait_span)?; + self.add_diagnostic(ParseErrorKind::NameTooLong(name.clone()), trait_span)?; let mut placeholder = PreSymbolicExpression::placeholder(format!("'{contract_id}.{name}",)); placeholder.copy_span(&span); @@ -636,7 +645,7 @@ impl<'a> Parser<'a> { Ok(id) => id, Err(_) => { self.add_diagnostic( - ParseErrors::IllegalTraitName(name.clone()), + ParseErrorKind::IllegalTraitName(name.clone()), trait_span, )?; let mut placeholder = @@ -682,7 +691,10 @@ impl<'a> Parser<'a> { span: token_span, token, }) => { - self.add_diagnostic(ParseErrors::ExpectedContractIdentifier, token_span.clone())?; + self.add_diagnostic( + ParseErrorKind::ExpectedContractIdentifier, + token_span.clone(), + )?; let mut placeholder = PreSymbolicExpression::placeholder(format!(".{}", token.reproduce())); span.end_line = token_span.end_line; @@ -691,7 +703,7 @@ impl<'a> Parser<'a> { return Ok(placeholder); } None => { - self.add_diagnostic(ParseErrors::ExpectedContractIdentifier, span.clone())?; + self.add_diagnostic(ParseErrorKind::ExpectedContractIdentifier, span.clone())?; let mut placeholder = PreSymbolicExpression::placeholder(".".to_string()); placeholder.copy_span(&span); return Ok(placeholder); @@ -699,7 +711,10 @@ impl<'a> Parser<'a> { }; if name.len() > MAX_CONTRACT_NAME_LEN { - self.add_diagnostic(ParseErrors::ContractNameTooLong(name.clone()), span.clone())?; + self.add_diagnostic( + ParseErrorKind::ContractNameTooLong(name.clone()), + span.clone(), + )?; let mut placeholder = PreSymbolicExpression::placeholder(format!(".{name}")); placeholder.copy_span(&span); return Ok(placeholder); @@ -709,7 +724,7 @@ impl<'a> Parser<'a> { Ok(id) => id, Err(_) => { self.add_diagnostic( - ParseErrors::IllegalContractName(name.clone()), + ParseErrorKind::IllegalContractName(name.clone()), contract_span, )?; let mut placeholder = PreSymbolicExpression::placeholder(format!(".{name}")); @@ -735,7 +750,10 @@ impl<'a> Parser<'a> { span: token_span, token, }) => { - self.add_diagnostic(ParseErrors::ExpectedTraitIdentifier, token_span.clone())?; + self.add_diagnostic( + ParseErrorKind::ExpectedTraitIdentifier, + token_span.clone(), + )?; let mut placeholder = PreSymbolicExpression::placeholder(format!( ".{contract_name}.{}", token.reproduce(), @@ -746,7 +764,7 @@ impl<'a> Parser<'a> { return Ok(placeholder); } None => { - self.add_diagnostic(ParseErrors::ExpectedTraitIdentifier, dot.span.clone())?; + self.add_diagnostic(ParseErrorKind::ExpectedTraitIdentifier, dot.span.clone())?; let mut placeholder = PreSymbolicExpression::placeholder(format!(".{contract_name}.")); span.end_line = dot.span.end_line; @@ -756,7 +774,7 @@ impl<'a> Parser<'a> { } }; if name.len() > MAX_STRING_LEN { - self.add_diagnostic(ParseErrors::NameTooLong(name.clone()), trait_span)?; + self.add_diagnostic(ParseErrorKind::NameTooLong(name.clone()), trait_span)?; let mut placeholder = PreSymbolicExpression::placeholder(format!(".{contract_name}.{name}")); placeholder.copy_span(&span); @@ -765,7 +783,10 @@ impl<'a> Parser<'a> { let trait_name = match ClarityName::try_from(name.clone()) { Ok(id) => id, Err(_) => { - self.add_diagnostic(ParseErrors::IllegalTraitName(name.clone()), trait_span)?; + self.add_diagnostic( + ParseErrorKind::IllegalTraitName(name.clone()), + trait_span, + )?; let mut placeholder = PreSymbolicExpression::placeholder(format!(".{contract_name}.{name}")); placeholder.copy_span(&span); @@ -805,7 +826,7 @@ impl<'a> Parser<'a> { self.nesting_depth += 1; if self.nesting_depth > MAX_NESTING_DEPTH { self.add_diagnostic( - ParseErrors::ExpressionStackDepthTooDeep, + ParseErrorKind::ExpressionStackDepthTooDeep, token.span.clone(), )?; // Do not try to continue, exit cleanly now to avoid a stack overflow. @@ -824,7 +845,7 @@ impl<'a> Parser<'a> { // This sugared syntax for tuple becomes a list of pairs, so depth is increased by 2. if self.nesting_depth + 2 > MAX_NESTING_DEPTH { self.add_diagnostic( - ParseErrors::ExpressionStackDepthTooDeep, + ParseErrorKind::ExpressionStackDepthTooDeep, token.span.clone(), )?; // Do not try to continue, exit cleanly now to avoid a stack overflow. @@ -847,7 +868,7 @@ impl<'a> Parser<'a> { Ok(val) => PreSymbolicExpression::atom_value(Value::Int(val)), Err(_) => { self.add_diagnostic( - ParseErrors::FailedParsingIntValue(val_string.clone()), + ParseErrorKind::FailedParsingIntValue(val_string.clone()), token.span.clone(), )?; PreSymbolicExpression::placeholder(token.token.reproduce()) @@ -861,7 +882,7 @@ impl<'a> Parser<'a> { Ok(val) => PreSymbolicExpression::atom_value(Value::UInt(val)), Err(_) => { self.add_diagnostic( - ParseErrors::FailedParsingUIntValue(val_string.clone()), + ParseErrorKind::FailedParsingUIntValue(val_string.clone()), token.span.clone(), )?; PreSymbolicExpression::placeholder(token.token.reproduce()) @@ -876,7 +897,7 @@ impl<'a> Parser<'a> { Ok(s) => PreSymbolicExpression::atom_value(s), Err(_) => { self.add_diagnostic( - ParseErrors::IllegalASCIIString(val.clone()), + ParseErrorKind::IllegalASCIIString(val.clone()), token.span.clone(), )?; PreSymbolicExpression::placeholder(token.token.reproduce()) @@ -905,7 +926,7 @@ impl<'a> Parser<'a> { Token::Ident(name) => { let mut expr = if name.len() > MAX_STRING_LEN { self.add_diagnostic( - ParseErrors::NameTooLong(name.clone()), + ParseErrorKind::NameTooLong(name.clone()), token.span.clone(), )?; PreSymbolicExpression::placeholder(token.token.reproduce()) @@ -914,7 +935,7 @@ impl<'a> Parser<'a> { Ok(name) => PreSymbolicExpression::atom(name), Err(_) => { self.add_diagnostic( - ParseErrors::IllegalClarityName(name.clone()), + ParseErrorKind::IllegalClarityName(name.clone()), token.span.clone(), )?; PreSymbolicExpression::placeholder(token.token.reproduce()) @@ -927,7 +948,7 @@ impl<'a> Parser<'a> { Token::TraitIdent(name) => { let mut expr = if name.len() > MAX_STRING_LEN { self.add_diagnostic( - ParseErrors::NameTooLong(name.clone()), + ParseErrorKind::NameTooLong(name.clone()), token.span.clone(), )?; PreSymbolicExpression::placeholder(token.token.reproduce()) @@ -936,7 +957,7 @@ impl<'a> Parser<'a> { Ok(name) => PreSymbolicExpression::trait_reference(name), Err(_) => { self.add_diagnostic( - ParseErrors::IllegalTraitName(name.clone()), + ParseErrorKind::IllegalTraitName(name.clone()), token.span.clone(), )?; PreSymbolicExpression::placeholder(token.token.reproduce()) @@ -952,7 +973,7 @@ impl<'a> Parser<'a> { Ok(value) => PreSymbolicExpression::atom_value(value), _ => { self.add_diagnostic( - ParseErrors::InvalidBuffer, + ParseErrorKind::InvalidBuffer, token.span.clone(), )?; PreSymbolicExpression::placeholder(token.token.reproduce()) @@ -960,7 +981,7 @@ impl<'a> Parser<'a> { }, Err(_) => { self.add_diagnostic( - ParseErrors::InvalidBuffer, + ParseErrorKind::InvalidBuffer, token.span.clone(), )?; PreSymbolicExpression::placeholder(token.token.reproduce()) @@ -986,7 +1007,7 @@ impl<'a> Parser<'a> { | Token::Greater | Token::GreaterEqual => { let name = ClarityName::try_from(token.token.to_string()) - .map_err(|_| ParseErrors::InterpreterFailure)?; + .map_err(|_| ParseErrorKind::InterpreterFailure)?; let mut e = PreSymbolicExpression::atom(name); e.copy_span(&token.span); Some(e) @@ -1054,7 +1075,7 @@ impl<'a> Parser<'a> { _ => { // Report an error, then skip this token self.add_diagnostic( - ParseErrors::UnexpectedToken(token.token), + ParseErrorKind::UnexpectedToken(token.token), token.span, )?; } @@ -3533,7 +3554,10 @@ mod tests { fn test_parse_fail_fast() { match parse("42g !ok") { Ok(_) => panic!("fail_fast mode should have returned an error"), - Err(e) => assert_eq!(*e.err, ParseErrors::Lexer(LexerError::InvalidCharInt('g'))), + Err(e) => assert_eq!( + *e.err, + ParseErrorKind::Lexer(LexerError::InvalidCharInt('g')) + ), } } @@ -3561,7 +3585,7 @@ mod tests { ); assert!(match *(parse(&exceeds_stack_depth_list).unwrap_err().err) { - ParseErrors::ExpressionStackDepthTooDeep => true, + ParseErrorKind::ExpressionStackDepthTooDeep => true, x => panic!("expected a stack depth too deep error, got {x:?}"), }); @@ -3584,7 +3608,7 @@ mod tests { ); assert!(match *parse(&exceeds_stack_depth_tuple).unwrap_err().err { - ParseErrors::ExpressionStackDepthTooDeep => true, + ParseErrorKind::ExpressionStackDepthTooDeep => true, x => panic!("expected a stack depth too deep error, got {x:?}"), }); diff --git a/clarity/src/vm/ast/stack_depth_checker.rs b/clarity/src/vm/ast/stack_depth_checker.rs index 5115e10737..0e3bf7db23 100644 --- a/clarity/src/vm/ast/stack_depth_checker.rs +++ b/clarity/src/vm/ast/stack_depth_checker.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::vm::ast::errors::{ParseErrors, ParseResult}; +use crate::vm::ast::errors::{ParseErrorKind, ParseResult}; use crate::vm::ast::types::{BuildASTPass, ContractAST}; use crate::vm::representations::PreSymbolicExpression; use crate::vm::representations::PreSymbolicExpressionType::{List, Tuple}; @@ -27,7 +27,7 @@ pub const AST_CALL_STACK_DEPTH_BUFFER: u64 = 5; fn check(args: &[PreSymbolicExpression], depth: u64) -> ParseResult<()> { if depth >= (AST_CALL_STACK_DEPTH_BUFFER + MAX_CALL_STACK_DEPTH as u64) { - return Err(ParseErrors::ExpressionStackDepthTooDeep.into()); + return Err(ParseErrorKind::ExpressionStackDepthTooDeep.into()); } for expression in args.iter() { match expression.pre_expr { @@ -52,7 +52,7 @@ impl BuildASTPass for StackDepthChecker { fn check_vary(args: &[PreSymbolicExpression], depth: u64) -> ParseResult<()> { if depth >= (AST_CALL_STACK_DEPTH_BUFFER + MAX_CALL_STACK_DEPTH as u64) { - return Err(ParseErrors::VaryExpressionStackDepthTooDeep.into()); + return Err(ParseErrorKind::VaryExpressionStackDepthTooDeep.into()); } for expression in args.iter() { match expression.pre_expr { diff --git a/clarity/src/vm/ast/sugar_expander/mod.rs b/clarity/src/vm/ast/sugar_expander/mod.rs index b7b4965f50..57b2f414c2 100644 --- a/clarity/src/vm/ast/sugar_expander/mod.rs +++ b/clarity/src/vm/ast/sugar_expander/mod.rs @@ -21,7 +21,7 @@ use clarity_types::types::{ PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, TraitIdentifier, Value, }; -use crate::vm::ast::errors::{ParseErrors, ParseResult}; +use crate::vm::ast::errors::{ParseErrorKind, ParseResult}; use crate::vm::ast::types::{BuildASTPass, ContractAST, PreExpressionsDrain}; use crate::vm::representations::{PreSymbolicExpressionType, SymbolicExpression}; use crate::vm::ClarityVersion; @@ -92,7 +92,7 @@ impl SugarExpander { "tuple" .to_string() .try_into() - .map_err(|_| ParseErrors::InterpreterFailure)?, + .map_err(|_| ParseErrorKind::InterpreterFailure)?, ), ); SymbolicExpression::list(pairs) @@ -119,7 +119,7 @@ impl SugarExpander { if let Some(trait_reference) = contract_ast.get_referenced_trait(&name) { SymbolicExpression::trait_reference(name, trait_reference.clone()) } else { - return Err(ParseErrors::TraitReferenceUnknown(name.to_string()).into()); + return Err(ParseErrorKind::TraitReferenceUnknown(name.to_string()).into()); } } #[cfg(not(feature = "developer-mode"))] diff --git a/clarity/src/vm/ast/traits_resolver/mod.rs b/clarity/src/vm/ast/traits_resolver/mod.rs index 90bf989ade..df77ed41f6 100644 --- a/clarity/src/vm/ast/traits_resolver/mod.rs +++ b/clarity/src/vm/ast/traits_resolver/mod.rs @@ -19,7 +19,7 @@ use std::collections::HashMap; use clarity_types::representations::ClarityName; use clarity_types::types::{QualifiedContractIdentifier, TraitIdentifier}; -use crate::vm::ast::errors::{ParseError, ParseErrors, ParseResult}; +use crate::vm::ast::errors::{ParseError, ParseErrorKind, ParseResult}; use crate::vm::ast::types::{BuildASTPass, ContractAST}; use crate::vm::functions::define::DefineFunctions; use crate::vm::representations::PreSymbolicExpressionType::{ @@ -56,16 +56,17 @@ impl TraitsResolver { match define_type { DefineFunctions::Trait => { if args.len() != 2 { - return Err(ParseErrors::DefineTraitBadSignature.into()); + return Err(ParseErrorKind::DefineTraitBadSignature.into()); } match (&args[0].pre_expr, &args[1].pre_expr) { (Atom(trait_name), List(trait_definition)) => { // Check for collisions if contract_ast.referenced_traits.contains_key(trait_name) { - return Err( - ParseErrors::NameAlreadyUsed(trait_name.to_string()).into() - ); + return Err(ParseErrorKind::NameAlreadyUsed( + trait_name.to_string(), + ) + .into()); } // Traverse and probe for generics nested in the trait definition @@ -83,18 +84,20 @@ impl TraitsResolver { .referenced_traits .insert(trait_name.clone(), TraitDefinition::Defined(trait_id)); } - _ => return Err(ParseErrors::DefineTraitBadSignature.into()), + _ => return Err(ParseErrorKind::DefineTraitBadSignature.into()), } } DefineFunctions::UseTrait => { if args.len() != 2 { - return Err(ParseErrors::ImportTraitBadSignature.into()); + return Err(ParseErrorKind::ImportTraitBadSignature.into()); } if let Some(trait_name) = args[0].match_atom() { // Check for collisions if contract_ast.referenced_traits.contains_key(trait_name) { - return Err(ParseErrors::NameAlreadyUsed(trait_name.to_string()).into()); + return Err( + ParseErrorKind::NameAlreadyUsed(trait_name.to_string()).into() + ); } let trait_id = match &args[1].pre_expr { @@ -109,18 +112,18 @@ impl TraitsResolver { } } FieldIdentifier(trait_identifier) => trait_identifier.clone(), - _ => return Err(ParseErrors::ImportTraitBadSignature.into()), + _ => return Err(ParseErrorKind::ImportTraitBadSignature.into()), }; contract_ast .referenced_traits .insert(trait_name.clone(), TraitDefinition::Imported(trait_id)); } else { - return Err(ParseErrors::ImportTraitBadSignature.into()); + return Err(ParseErrorKind::ImportTraitBadSignature.into()); } } DefineFunctions::ImplTrait => { if args.len() != 1 { - return Err(ParseErrors::ImplTraitBadSignature.into()); + return Err(ParseErrorKind::ImplTraitBadSignature.into()); } let trait_id = match &args[0].pre_expr { @@ -135,7 +138,7 @@ impl TraitsResolver { } } FieldIdentifier(trait_identifier) => trait_identifier.clone(), - _ => return Err(ParseErrors::ImplTraitBadSignature.into()), + _ => return Err(ParseErrorKind::ImplTraitBadSignature.into()), }; contract_ast.implemented_traits.insert(trait_id); } @@ -166,7 +169,7 @@ impl TraitsResolver { .referenced_traits .contains_key(&trait_reference) { - let mut err = ParseError::new(ParseErrors::TraitReferenceUnknown( + let mut err = ParseError::new(ParseErrorKind::TraitReferenceUnknown( trait_reference.to_string(), )); err.set_pre_expression(&expr); @@ -207,7 +210,7 @@ impl TraitsResolver { if should_reference { referenced_traits.insert(trait_name.clone(), expression.clone()); } else { - return Err(ParseErrors::TraitReferenceNotAllowed.into()); + return Err(ParseErrorKind::TraitReferenceNotAllowed.into()); } } Tuple(atoms) => { diff --git a/clarity/src/vm/clarity.rs b/clarity/src/vm/clarity.rs index 979d815268..5444ab1df6 100644 --- a/clarity/src/vm/clarity.rs +++ b/clarity/src/vm/clarity.rs @@ -3,7 +3,7 @@ use std::fmt; use stacks_common::types::StacksEpochId; use crate::vm::analysis::{AnalysisDatabase, CheckError, CheckErrors, ContractAnalysis}; -use crate::vm::ast::errors::{ParseError, ParseErrors}; +use crate::vm::ast::errors::{ParseError, ParseErrorKind}; use crate::vm::ast::{ASTRules, ContractAST}; use crate::vm::contexts::{AssetMap, Environment, OwnedEnvironment}; use crate::vm::costs::{ExecutionCost, LimitedCostTracker}; @@ -101,14 +101,14 @@ impl From for Error { impl From for Error { fn from(e: ParseError) -> Self { match *e.err { - ParseErrors::CostOverflow => { + ParseErrorKind::CostOverflow => { Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - ParseErrors::CostBalanceExceeded(a, b) => Error::CostError(a, b), - ParseErrors::MemoryBalanceExceeded(_a, _b) => { + ParseErrorKind::CostBalanceExceeded(a, b) => Error::CostError(a, b), + ParseErrorKind::MemoryBalanceExceeded(_a, _b) => { Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - ParseErrors::ExecutionTimeExpired => { + ParseErrorKind::ExecutionTimeExpired => { Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } _ => Error::Parse(e), diff --git a/clarity/src/vm/tests/contracts.rs b/clarity/src/vm/tests/contracts.rs index da9d4f3731..4d7cddbee4 100644 --- a/clarity/src/vm/tests/contracts.rs +++ b/clarity/src/vm/tests/contracts.rs @@ -26,7 +26,7 @@ use crate::vm::tests::{test_clarity_versions, test_epochs}; use crate::vm::types::{PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, Value}; #[cfg(test)] use crate::vm::{ - ast::{errors::ParseErrors, ASTRules}, + ast::{errors::ParseErrorKind, ASTRules}, errors::{CheckErrors, Error, RuntimeErrorType}, tests::{ env_factory, execute, is_committed, is_err_code_i128 as is_err_code, symbols_from_values, @@ -1052,7 +1052,7 @@ fn test_ast_stack_depth() { assert_eq!( vm_execute(program).unwrap_err(), RuntimeErrorType::ASTError(Box::new( - ParseErrors::VaryExpressionStackDepthTooDeep.into(), + ParseErrorKind::VaryExpressionStackDepthTooDeep.into(), )) .into() ); diff --git a/clarity/src/vm/tests/defines.rs b/clarity/src/vm/tests/defines.rs index 2cd874f2c3..d170da223d 100644 --- a/clarity/src/vm/tests/defines.rs +++ b/clarity/src/vm/tests/defines.rs @@ -26,7 +26,7 @@ use crate::vm::tests::test_clarity_versions; #[cfg(test)] use crate::vm::{ analysis::errors::SyntaxBindingError, - ast::{build_ast, errors::ParseErrors}, + ast::{build_ast, errors::ParseErrorKind}, errors::RuntimeErrorType, types::{QualifiedContractIdentifier, TypeSignature, TypeSignatureExt as _, Value}, {execute, ClarityVersion}, @@ -207,7 +207,7 @@ fn test_recursive_panic(#[case] version: ClarityVersion, #[case] epoch: StacksEp epoch, ) .unwrap_err(); - assert!(matches!(*err.err, ParseErrors::CircularReference(_))); + assert!(matches!(*err.err, ParseErrorKind::CircularReference(_))); } #[test] @@ -475,18 +475,18 @@ fn test_define_trait_arg_count() { // These errors are hit in the trait resolver, before reaching the type-checker match execute(test0).unwrap_err() { Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) - if *parse_err.err == ParseErrors::DefineTraitBadSignature => {} + if *parse_err.err == ParseErrorKind::DefineTraitBadSignature => {} e => panic!("{e:?}"), }; match execute(test1).unwrap_err() { Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) - if *parse_err.err == ParseErrors::DefineTraitBadSignature => {} + if *parse_err.err == ParseErrorKind::DefineTraitBadSignature => {} e => panic!("{e}"), }; execute(test2).unwrap(); match execute(test3).unwrap_err() { Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) - if *parse_err.err == ParseErrors::DefineTraitBadSignature => {} + if *parse_err.err == ParseErrorKind::DefineTraitBadSignature => {} e => panic!("{e}"), }; } @@ -501,18 +501,18 @@ fn test_use_trait_arg_count() { // These errors are hit in the trait resolver, before reaching the type-checker match execute(test0).unwrap_err() { Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) - if *parse_err.err == ParseErrors::ImportTraitBadSignature => {} + if *parse_err.err == ParseErrorKind::ImportTraitBadSignature => {} e => panic!("{e:?}"), }; match execute(test1).unwrap_err() { Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) - if *parse_err.err == ParseErrors::ImportTraitBadSignature => {} + if *parse_err.err == ParseErrorKind::ImportTraitBadSignature => {} e => panic!("{e}"), }; execute(test2).unwrap(); match execute(test3).unwrap_err() { Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) - if *parse_err.err == ParseErrors::ImportTraitBadSignature => {} + if *parse_err.err == ParseErrorKind::ImportTraitBadSignature => {} e => panic!("{e}"), }; } @@ -526,13 +526,13 @@ fn test_impl_trait_arg_count() { // These errors are hit in the trait resolver, before reaching the type-checker match execute(test0).unwrap_err() { Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) - if *parse_err.err == ParseErrors::ImplTraitBadSignature => {} + if *parse_err.err == ParseErrorKind::ImplTraitBadSignature => {} e => panic!("{e:?}"), }; execute(test1).unwrap(); match execute(test2).unwrap_err() { Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) - if *parse_err.err == ParseErrors::ImplTraitBadSignature => {} + if *parse_err.err == ParseErrorKind::ImplTraitBadSignature => {} e => panic!("{e}"), }; } diff --git a/stackslib/src/chainstate/stacks/db/transactions.rs b/stackslib/src/chainstate/stacks/db/transactions.rs index 2deee7b642..9e7e13a666 100644 --- a/stackslib/src/chainstate/stacks/db/transactions.rs +++ b/stackslib/src/chainstate/stacks/db/transactions.rs @@ -17,7 +17,7 @@ use std::collections::{HashMap, HashSet}; use clarity::vm::analysis::types::ContractAnalysis; -use clarity::vm::ast::errors::ParseErrors; +use clarity::vm::ast::errors::ParseErrorKind; use clarity::vm::ast::ASTRules; use clarity::vm::clarity::TransactionConnection; use clarity::vm::contexts::{AssetMap, AssetMapEntry, Environment}; @@ -1297,8 +1297,8 @@ impl StacksChainState { // block from getting relayed in the first place if let clarity_error::Parse(ref parse_error) = &other_error { match *parse_error.err { - ParseErrors::ExpressionStackDepthTooDeep - | ParseErrors::VaryExpressionStackDepthTooDeep => { + ParseErrorKind::ExpressionStackDepthTooDeep + | ParseErrorKind::VaryExpressionStackDepthTooDeep => { info!("Transaction {} is problematic and should have prevented this block from being relayed", tx.txid()); return Err(Error::ClarityError(other_error)); } diff --git a/stackslib/src/chainstate/stacks/miner.rs b/stackslib/src/chainstate/stacks/miner.rs index a6837e5c4f..816abddfd5 100644 --- a/stackslib/src/chainstate/stacks/miner.rs +++ b/stackslib/src/chainstate/stacks/miner.rs @@ -22,7 +22,7 @@ use std::sync::{Arc, Mutex}; use std::thread::ThreadId; use std::time::Instant; -use clarity::vm::ast::errors::ParseErrors; +use clarity::vm::ast::errors::ParseErrorKind; use clarity::vm::ast::ASTRules; use clarity::vm::database::BurnStateDB; use clarity::vm::errors::Error as InterpreterError; @@ -660,8 +660,8 @@ impl TransactionResult { if let clarity_error::Parse(ref parse_err) = error { info!("Parse error: {}", parse_err; "txid" => %tx.txid()); match *parse_err.err { - ParseErrors::ExpressionStackDepthTooDeep - | ParseErrors::VaryExpressionStackDepthTooDeep => { + ParseErrorKind::ExpressionStackDepthTooDeep + | ParseErrorKind::VaryExpressionStackDepthTooDeep => { info!("Problematic transaction failed AST depth check"; "txid" => %tx.txid()); return (true, Error::ClarityError(error)); } diff --git a/stackslib/src/net/relay.rs b/stackslib/src/net/relay.rs index 8a8364190b..a5618d19b5 100644 --- a/stackslib/src/net/relay.rs +++ b/stackslib/src/net/relay.rs @@ -17,7 +17,7 @@ use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::mem; -use clarity::vm::ast::errors::ParseErrors; +use clarity::vm::ast::errors::ParseErrorKind; use clarity::vm::ast::{ast_check_size, ASTRules}; use clarity::vm::types::{QualifiedContractIdentifier, StacksAddressExtensions}; use clarity::vm::ClarityVersion; @@ -1845,8 +1845,8 @@ impl Relayer { match ast_res { Ok(_) => {} Err(parse_error) => match *parse_error.err { - ParseErrors::ExpressionStackDepthTooDeep - | ParseErrors::VaryExpressionStackDepthTooDeep => { + ParseErrorKind::ExpressionStackDepthTooDeep + | ParseErrorKind::VaryExpressionStackDepthTooDeep => { // don't include this block info!("Transaction {} is problematic and will not be included, relayed, or built upon", &tx.txid()); return Err(Error::ClarityError(parse_error.into())); From 6d4560ff50e3cb453b465cd861aed51bd5928af7 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 10:32:42 -0700 Subject: [PATCH 08/34] Add comment descriptions to ParseErrorKind and its variants Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/ast.rs | 71 ++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/clarity-types/src/errors/ast.rs b/clarity-types/src/errors/ast.rs index 506bc84a8f..75460a49fc 100644 --- a/clarity-types/src/errors/ast.rs +++ b/clarity-types/src/errors/ast.rs @@ -25,74 +25,135 @@ use crate::token::Token; pub type ParseResult = Result; #[derive(Debug, PartialEq)] +/// Errors encountered during the lexical and syntactic analysis of Clarity source code +/// when constructing the abstract syntax tree (AST). pub enum ParseErrorKind { - // Cost errors + // Cost-related errors + /// Arithmetic overflow in cost computation during AST construction, exceeding the maximum threshold. CostOverflow, + /// Cumulative parsing cost exceeds the allocated budget, indicating budget depletion rather than an overflow. CostBalanceExceeded(ExecutionCost, ExecutionCost), + /// Memory usage during AST construction exceeds the allocated memory budget. MemoryBalanceExceeded(u64, u64), + /// Failure in the cost-tracking mechanism due to an unexpected condition or invalid state. CostComputationFailed(String), + /// Parsing time exceeds the allowed budget, halting AST construction to ensure responsiveness. ExecutionTimeExpired, + // Structural errors + /// Number of expressions exceeds the maximum allowed limit. TooManyExpressions, + /// Nesting depth of expressions exceeds the allowed stack depth limit. ExpressionStackDepthTooDeep, + /// Nesting depth of expressions exceeds the allowed stack depth limit. VaryExpressionStackDepthTooDeep, + + // Semantic errors + /// Failed to parse a string into an integer literal. FailedParsingIntValue(String), + /// Circular reference detected in interdependent function definitions. CircularReference(Vec), + /// Variable name is already in use within the same scope. NameAlreadyUsed(String), + /// Attempt to store a trait reference, which is prohibited to ensure type safety and deterministic execution. TraitReferenceNotAllowed, + /// Invalid or malformed signature in a `(use-trait ...)` expression. ImportTraitBadSignature, + /// Invalid or malformed signature in a `(define-trait ...)` expression. DefineTraitBadSignature, + /// Invalid or malformed signature in a `(impl-trait ...)` expression. ImplTraitBadSignature, + /// Referenced trait does not exist or cannot be found. TraitReferenceUnknown(String), - // V1 errors + // V1 Errors + /// Failed to capture an expected substring or value during pattern matching in lexical analysis. FailedCapturingInput, + /// Expected a whitespace or a close parentheses but found an unexpected token or character. SeparatorExpected(String), + /// Expected a whitespace after a colon, but found an unexpected token. SeparatorExpectedAfterColon(String), + /// Input program exceeds the maximum allowed number of lines. ProgramTooLarge, + /// Variable name contains invalid characters or violates naming rules. IllegalVariableName(String), + /// Failed to parse a string into a buffer literal. FailedParsingBuffer(String), + /// Failed to parse a string into a hexadecimal value, with the input string and error details. FailedParsingHexValue(String, String), + /// Failed to parse a string into a principal literal (e.g., invalid principal format). FailedParsingPrincipal(String), + /// Failed to parse a string into a valid field literal. FailedParsingField(String), + /// Failed to parse the remaining input after processing a construct, leaving invalid or unexpected tokens. FailedParsingRemainder(String), + /// Unexpected closing parenthesis encountered in the input. ClosingParenthesisUnexpected, + /// Expected a closing parenthesis but found another token or end of input. ClosingParenthesisExpected, + /// Unexpected closing brace for a tuple literal encountered in the input. ClosingTupleLiteralUnexpected, + /// Expected a closing brace for a tuple literal but it was missing. ClosingTupleLiteralExpected, + /// Expected a colon in a tuple literal at the specified position, but it was missing. TupleColonExpected(usize), + /// Expected a comma in a tuple literal at the specified position, but it was missing. TupleCommaExpected(usize), + /// Expected a tuple item (e.g., key-value pair) at the specified position, but it was missing or invalid. TupleItemExpected(usize), + /// Unexpected comma separator encountered outside a valid list or tuple context. CommaSeparatorUnexpected, + /// Unexpected colon separator encountered. ColonSeparatorUnexpected, + /// Input contains invalid or disallowed characters. InvalidCharactersDetected, + /// Invalid escape sequence in a string literal (e.g., incorrect use of `\`). InvalidEscaping, // V2 Errors + /// Lexical analysis failed due to an underlying lexer error. Lexer(LexerError), + /// Contract name exceeds the maximum allowed length. ContractNameTooLong(String), + /// Expected a specific closing token (e.g., parenthesis or brace) but found another token. ExpectedClosing(Token), + /// Expected a contract identifier (e.g., `.contract-name`) but found an invalid or missing token. ExpectedContractIdentifier, + /// Expected a trait identifier (e.g., `.trait-name`) but found an invalid or missing token. ExpectedTraitIdentifier, + /// Expected whitespace to separate tokens but found an unexpected token or character. ExpectedWhitespace, + /// Failed to parse a string into an unsigned integer literal. FailedParsingUIntValue(String), + /// Trait name contains invalid characters or violates naming rules. IllegalTraitName(String), + /// Invalid principal literal format, preventing parsing into a valid principal. InvalidPrincipalLiteral, + /// Invalid buffer literal format, preventing parsing into a valid buffer. InvalidBuffer, + /// Name (e.g., variable or function) exceeds the maximum allowed length. NameTooLong(String), + /// Encountered an unexpected token during parsing. UnexpectedToken(Token), + /// Expected a colon in a tuple literal (version 2 syntax) but it was missing. TupleColonExpectedv2, + /// Expected a comma in a tuple literal (version 2 syntax) but it was missing. TupleCommaExpectedv2, + /// Expected a value in a tuple literal but it was missing or invalid. TupleValueExpected, + /// Clarity name (e.g., variable, function, or trait) contains invalid characters or violates naming rules. IllegalClarityName(String), + /// ASCII string literal contains invalid characters or violates format rules. IllegalASCIIString(String), + /// Contract name contains invalid characters or violates naming rules. IllegalContractName(String), + // Notes + /// Indicates a token mismatch, used for internal parser diagnostics to match a specific token. NoteToMatchThis(Token), - /// Should be an unreachable error + /// Unreachable error indicating an unexpected parser failure; should never occur in valid execution. UnexpectedParserFailure, - - /// Should be an unreachable failure which invalidates the transaction + /// Unreachable failure indicating an invalid transaction due to an unexpected interpreter error. InterpreterFailure, } From ad651d045a37c32e598fba45e76ad3f846879f11 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 10:38:21 -0700 Subject: [PATCH 09/34] Rename ShortReturnType to EarlyReturnError Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/mod.rs | 22 +++++++++++----------- clarity/src/vm/errors.rs | 4 ++-- clarity/src/vm/functions/mod.rs | 6 +++--- clarity/src/vm/functions/options.rs | 12 ++++++------ clarity/src/vm/tests/datamaps.rs | 4 ++-- clarity/src/vm/tests/simple_apply_eval.rs | 14 ++++++++------ 6 files changed, 32 insertions(+), 30 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 58b42b8a99..95b4b40286 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -46,7 +46,7 @@ pub enum Error { Unchecked(CheckErrors), Interpreter(InterpreterError), Runtime(RuntimeErrorType, Option), - ShortReturn(ShortReturnType), + ShortReturn(EarlyReturnError), } /// InterpreterErrors are errors that *should never* occur. @@ -104,7 +104,7 @@ pub enum RuntimeErrorType { } #[derive(Debug, PartialEq)] -pub enum ShortReturnType { +pub enum EarlyReturnError { ExpectedValue(Box), AssertionFailed(Box), } @@ -208,8 +208,8 @@ impl From<(CheckErrors, &SymbolicExpression)> for Error { } } -impl From for Error { - fn from(err: ShortReturnType) -> Self { +impl From for Error { + fn from(err: EarlyReturnError) -> Self { Error::ShortReturn(err) } } @@ -225,11 +225,11 @@ impl From for () { fn from(_err: Error) -> Self {} } -impl From for Value { - fn from(val: ShortReturnType) -> Self { +impl From for Value { + fn from(val: EarlyReturnError) -> Self { match val { - ShortReturnType::ExpectedValue(v) => *v, - ShortReturnType::AssertionFailed(v) => *v, + EarlyReturnError::ExpectedValue(v) => *v, + EarlyReturnError::AssertionFailed(v) => *v, } } } @@ -241,15 +241,15 @@ mod test { #[test] fn equality() { assert_eq!( - Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))), - Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))) + Error::ShortReturn(EarlyReturnError::ExpectedValue(Box::new(Value::Bool(true)))), + Error::ShortReturn(EarlyReturnError::ExpectedValue(Box::new(Value::Bool(true)))) ); assert_eq!( Error::Interpreter(InterpreterError::InterpreterError("".to_string())), Error::Interpreter(InterpreterError::InterpreterError("".to_string())) ); assert!( - Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))) + Error::ShortReturn(EarlyReturnError::ExpectedValue(Box::new(Value::Bool(true)))) != Error::Interpreter(InterpreterError::InterpreterError("".to_string())) ); } diff --git a/clarity/src/vm/errors.rs b/clarity/src/vm/errors.rs index 764ac466e5..1fec7b51c5 100644 --- a/clarity/src/vm/errors.rs +++ b/clarity/src/vm/errors.rs @@ -15,8 +15,8 @@ // along with this program. If not, see . pub use clarity_types::errors::{ - Error, IncomparableError, InterpreterError, InterpreterResult, RuntimeErrorType, - ShortReturnType, + EarlyReturnError, Error, IncomparableError, InterpreterError, InterpreterResult, + RuntimeErrorType, }; pub use crate::vm::analysis::errors::{ diff --git a/clarity/src/vm/functions/mod.rs b/clarity/src/vm/functions/mod.rs index f458c282e6..b0fd12de86 100644 --- a/clarity/src/vm/functions/mod.rs +++ b/clarity/src/vm/functions/mod.rs @@ -20,8 +20,8 @@ use crate::vm::callables::{cost_input_sized_vararg, CallableType, NativeHandle}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{constants as cost_constants, runtime_cost, CostTracker, MemoryConsumer}; use crate::vm::errors::{ - check_argument_count, check_arguments_at_least, CheckErrors, Error, - InterpreterResult as Result, ShortReturnType, SyntaxBindingError, SyntaxBindingErrorType, + check_argument_count, check_arguments_at_least, CheckErrors, EarlyReturnError, Error, + InterpreterResult as Result, SyntaxBindingError, SyntaxBindingErrorType, }; pub use crate::vm::functions::assets::stx_transfer_consolidated; use crate::vm::representations::{ClarityName, SymbolicExpression, SymbolicExpressionType}; @@ -667,7 +667,7 @@ fn special_asserts( Ok(conditional) } else { let thrown = eval(&args[1], env, context)?; - Err(ShortReturnType::AssertionFailed(Box::new(thrown)).into()) + Err(EarlyReturnError::AssertionFailed(Box::new(thrown)).into()) } } _ => Err(CheckErrors::TypeValueError( diff --git a/clarity/src/vm/functions/options.rs b/clarity/src/vm/functions/options.rs index c47dae91cc..5d8cac1ed8 100644 --- a/clarity/src/vm/functions/options.rs +++ b/clarity/src/vm/functions/options.rs @@ -18,8 +18,8 @@ use crate::vm::contexts::{Environment, LocalContext}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostTracker, MemoryConsumer}; use crate::vm::errors::{ - check_arguments_at_least, CheckErrors, InterpreterError, InterpreterResult as Result, - RuntimeErrorType, ShortReturnType, + check_arguments_at_least, CheckErrors, EarlyReturnError, InterpreterError, + InterpreterResult as Result, RuntimeErrorType, }; use crate::vm::types::{CallableData, OptionalData, ResponseData, TypeSignature, Value}; use crate::vm::Value::CallableContract; @@ -66,7 +66,7 @@ pub fn native_unwrap(input: Value) -> Result { pub fn native_unwrap_or_ret(input: Value, thrown: Value) -> Result { inner_unwrap(input).and_then(|opt_value| match opt_value { Some(v) => Ok(v), - None => Err(ShortReturnType::ExpectedValue(Box::new(thrown)).into()), + None => Err(EarlyReturnError::ExpectedValue(Box::new(thrown)).into()), }) } @@ -80,7 +80,7 @@ pub fn native_unwrap_err(input: Value) -> Result { pub fn native_unwrap_err_or_ret(input: Value, thrown: Value) -> Result { inner_unwrap_err(input).and_then(|opt_value| match opt_value { Some(v) => Ok(v), - None => Err(ShortReturnType::ExpectedValue(Box::new(thrown)).into()), + None => Err(EarlyReturnError::ExpectedValue(Box::new(thrown)).into()), }) } @@ -88,7 +88,7 @@ pub fn native_try_ret(input: Value) -> Result { match input { Value::Optional(data) => match data.data { Some(data) => Ok(*data), - None => Err(ShortReturnType::ExpectedValue(Box::new(Value::none())).into()), + None => Err(EarlyReturnError::ExpectedValue(Box::new(Value::none())).into()), }, Value::Response(data) => { if data.committed { @@ -99,7 +99,7 @@ pub fn native_try_ret(input: Value) -> Result { "BUG: Failed to construct new response type from old response type".into(), ) })?; - Err(ShortReturnType::ExpectedValue(Box::new(short_return_val)).into()) + Err(EarlyReturnError::ExpectedValue(Box::new(short_return_val)).into()) } } _ => Err(CheckErrors::ExpectedOptionalOrResponseValue(Box::new(input)).into()), diff --git a/clarity/src/vm/tests/datamaps.rs b/clarity/src/vm/tests/datamaps.rs index 83fef9ab76..931142d92e 100644 --- a/clarity/src/vm/tests/datamaps.rs +++ b/clarity/src/vm/tests/datamaps.rs @@ -16,7 +16,7 @@ use crate::vm::types::{TupleData, Value}; #[cfg(test)] use crate::vm::{ - errors::{CheckErrors, ShortReturnType, SyntaxBindingError}, + errors::{CheckErrors, EarlyReturnError, SyntaxBindingError}, types::{ListData, SequenceData, TupleTypeSignature, TypeSignature}, }; use crate::vm::{execute, ClarityName, Error}; @@ -296,7 +296,7 @@ fn test_set_response_variable() { "#; let contract_src = contract_src.to_string(); assert_eq!( - Err(ShortReturnType::ExpectedValue(Box::new(Value::Int(5))).into()), + Err(EarlyReturnError::ExpectedValue(Box::new(Value::Int(5))).into()), execute(&contract_src) ); } diff --git a/clarity/src/vm/tests/simple_apply_eval.rs b/clarity/src/vm/tests/simple_apply_eval.rs index 53558e3548..5b79e67da1 100644 --- a/clarity/src/vm/tests/simple_apply_eval.rs +++ b/clarity/src/vm/tests/simple_apply_eval.rs @@ -31,7 +31,7 @@ use crate::vm::callables::DefinedFunction; use crate::vm::contexts::OwnedEnvironment; use crate::vm::costs::LimitedCostTracker; use crate::vm::database::MemoryBackingStore; -use crate::vm::errors::{CheckErrors, Error, RuntimeErrorType, ShortReturnType}; +use crate::vm::errors::{CheckErrors, EarlyReturnError, Error, RuntimeErrorType}; use crate::vm::tests::{execute, test_clarity_versions}; use crate::vm::types::signatures::*; use crate::vm::types::{ @@ -1431,7 +1431,7 @@ fn test_option_destructs() { .into(), ), Ok(Value::Int(3)), - Err(ShortReturnType::ExpectedValue(Box::new(Value::Int(2))).into()), + Err(EarlyReturnError::ExpectedValue(Box::new(Value::Int(2))).into()), Ok(Value::Int(3)), Ok(Value::Int(3)), Ok(Value::Int(3)), @@ -1444,9 +1444,11 @@ fn test_option_destructs() { Ok(Value::Int(8)), Err(CheckErrors::BadMatchInput(Box::new(TypeSignature::IntType)).into()), Err(CheckErrors::BadMatchInput(Box::new(TypeSignature::IntType)).into()), - Err(ShortReturnType::ExpectedValue(Box::new(Value::error(Value::UInt(1)).unwrap())).into()), + Err( + EarlyReturnError::ExpectedValue(Box::new(Value::error(Value::UInt(1)).unwrap())).into(), + ), Ok(Value::Int(3)), - Err(ShortReturnType::ExpectedValue(Box::new(Value::none())).into()), + Err(EarlyReturnError::ExpectedValue(Box::new(Value::none())).into()), Ok(Value::Bool(true)), Err(CheckErrors::IncorrectArgumentCount(1, 2).into()), Err(CheckErrors::ExpectedOptionalOrResponseValue(Box::new(Value::Int(1))).into()), @@ -1675,10 +1677,10 @@ fn test_asserts_short_circuit() { ]; let expectations: &[Error] = &[ - Error::ShortReturn(ShortReturnType::AssertionFailed(Box::new( + Error::ShortReturn(EarlyReturnError::AssertionFailed(Box::new( Value::error(Value::Int(0)).unwrap(), ))), - Error::ShortReturn(ShortReturnType::AssertionFailed(Box::new( + Error::ShortReturn(EarlyReturnError::AssertionFailed(Box::new( Value::error(Value::Int(1)).unwrap(), ))), ]; From 7b14874a657c34fbbb47297fcac6addddd446dfe Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 10:39:29 -0700 Subject: [PATCH 10/34] Rename ShortReturn variant to EarlyReturn Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/mod.rs | 12 ++++++------ clarity/src/vm/callables.rs | 2 +- clarity/src/vm/tests/simple_apply_eval.rs | 4 ++-- stackslib/src/chainstate/stacks/db/transactions.rs | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 95b4b40286..74b9574d25 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -46,7 +46,7 @@ pub enum Error { Unchecked(CheckErrors), Interpreter(InterpreterError), Runtime(RuntimeErrorType, Option), - ShortReturn(EarlyReturnError), + EarlyReturn(EarlyReturnError), } /// InterpreterErrors are errors that *should never* occur. @@ -122,7 +122,7 @@ impl PartialEq for Error { match (self, other) { (Error::Runtime(x, _), Error::Runtime(y, _)) => x == y, (Error::Unchecked(x), Error::Unchecked(y)) => x == y, - (Error::ShortReturn(x), Error::ShortReturn(y)) => x == y, + (Error::EarlyReturn(x), Error::EarlyReturn(y)) => x == y, (Error::Interpreter(x), Error::Interpreter(y)) => x == y, _ => false, } @@ -210,7 +210,7 @@ impl From<(CheckErrors, &SymbolicExpression)> for Error { impl From for Error { fn from(err: EarlyReturnError) -> Self { - Error::ShortReturn(err) + Error::EarlyReturn(err) } } @@ -241,15 +241,15 @@ mod test { #[test] fn equality() { assert_eq!( - Error::ShortReturn(EarlyReturnError::ExpectedValue(Box::new(Value::Bool(true)))), - Error::ShortReturn(EarlyReturnError::ExpectedValue(Box::new(Value::Bool(true)))) + Error::EarlyReturn(EarlyReturnError::ExpectedValue(Box::new(Value::Bool(true)))), + Error::EarlyReturn(EarlyReturnError::ExpectedValue(Box::new(Value::Bool(true)))) ); assert_eq!( Error::Interpreter(InterpreterError::InterpreterError("".to_string())), Error::Interpreter(InterpreterError::InterpreterError("".to_string())) ); assert!( - Error::ShortReturn(EarlyReturnError::ExpectedValue(Box::new(Value::Bool(true)))) + Error::EarlyReturn(EarlyReturnError::ExpectedValue(Box::new(Value::Bool(true)))) != Error::Interpreter(InterpreterError::InterpreterError("".to_string())) ); } diff --git a/clarity/src/vm/callables.rs b/clarity/src/vm/callables.rs index b697b3a095..afe1f9a479 100644 --- a/clarity/src/vm/callables.rs +++ b/clarity/src/vm/callables.rs @@ -294,7 +294,7 @@ impl DefinedFunction { match result { Ok(r) => Ok(r), Err(e) => match e { - Error::ShortReturn(v) => Ok(v.into()), + Error::EarlyReturn(v) => Ok(v.into()), _ => Err(e), }, } diff --git a/clarity/src/vm/tests/simple_apply_eval.rs b/clarity/src/vm/tests/simple_apply_eval.rs index 5b79e67da1..8293954765 100644 --- a/clarity/src/vm/tests/simple_apply_eval.rs +++ b/clarity/src/vm/tests/simple_apply_eval.rs @@ -1677,10 +1677,10 @@ fn test_asserts_short_circuit() { ]; let expectations: &[Error] = &[ - Error::ShortReturn(EarlyReturnError::AssertionFailed(Box::new( + Error::EarlyReturn(EarlyReturnError::AssertionFailed(Box::new( Value::error(Value::Int(0)).unwrap(), ))), - Error::ShortReturn(EarlyReturnError::AssertionFailed(Box::new( + Error::EarlyReturn(EarlyReturnError::AssertionFailed(Box::new( Value::error(Value::Int(1)).unwrap(), ))), ]; diff --git a/stackslib/src/chainstate/stacks/db/transactions.rs b/stackslib/src/chainstate/stacks/db/transactions.rs index 2deee7b642..ff6c441007 100644 --- a/stackslib/src/chainstate/stacks/db/transactions.rs +++ b/stackslib/src/chainstate/stacks/db/transactions.rs @@ -382,7 +382,7 @@ pub fn handle_clarity_runtime_error(error: clarity_error) -> ClarityRuntimeTxErr err_type: "runtime error", } } - clarity_error::Interpreter(InterpreterError::ShortReturn(_)) => { + clarity_error::Interpreter(InterpreterError::EarlyReturn(_)) => { ClarityRuntimeTxError::Acceptable { error, err_type: "short return/panic", From f063b241431b73f83ff69b80698e46c662bf7df6 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 10:58:26 -0700 Subject: [PATCH 11/34] Add descriptions to EarlyReturnError Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/mod.rs | 17 ++++++++++++----- clarity/src/vm/functions/options.rs | 8 ++++---- clarity/src/vm/tests/datamaps.rs | 2 +- clarity/src/vm/tests/simple_apply_eval.rs | 8 +++----- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 74b9574d25..8ed190cd1c 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -104,8 +104,15 @@ pub enum RuntimeErrorType { } #[derive(Debug, PartialEq)] +/// Errors triggered during Clarity contract evaluation that cause early termination. +/// These errors halt evaluation and fail the transaction. pub enum EarlyReturnError { - ExpectedValue(Box), + /// Failed to unwrap an `Optional` (`none`) or `Response` (`err` or `ok`) Clarity value. + /// The `Box` holds the original or thrown value. Triggered by `try!`, `unwrap-or`, or + /// `unwrap-err-or`. + UnwrapFailed(Box), + /// An 'asserts!' expression evaluated to false. + /// The `Box` holds the value provided as the second argument to `asserts!`. AssertionFailed(Box), } @@ -228,7 +235,7 @@ impl From for () { impl From for Value { fn from(val: EarlyReturnError) -> Self { match val { - EarlyReturnError::ExpectedValue(v) => *v, + EarlyReturnError::UnwrapFailed(v) => *v, EarlyReturnError::AssertionFailed(v) => *v, } } @@ -241,15 +248,15 @@ mod test { #[test] fn equality() { assert_eq!( - Error::EarlyReturn(EarlyReturnError::ExpectedValue(Box::new(Value::Bool(true)))), - Error::EarlyReturn(EarlyReturnError::ExpectedValue(Box::new(Value::Bool(true)))) + Error::EarlyReturn(EarlyReturnError::UnwrapFailed(Box::new(Value::Bool(true)))), + Error::EarlyReturn(EarlyReturnError::UnwrapFailed(Box::new(Value::Bool(true)))) ); assert_eq!( Error::Interpreter(InterpreterError::InterpreterError("".to_string())), Error::Interpreter(InterpreterError::InterpreterError("".to_string())) ); assert!( - Error::EarlyReturn(EarlyReturnError::ExpectedValue(Box::new(Value::Bool(true)))) + Error::EarlyReturn(EarlyReturnError::UnwrapFailed(Box::new(Value::Bool(true)))) != Error::Interpreter(InterpreterError::InterpreterError("".to_string())) ); } diff --git a/clarity/src/vm/functions/options.rs b/clarity/src/vm/functions/options.rs index 5d8cac1ed8..b8150edd08 100644 --- a/clarity/src/vm/functions/options.rs +++ b/clarity/src/vm/functions/options.rs @@ -66,7 +66,7 @@ pub fn native_unwrap(input: Value) -> Result { pub fn native_unwrap_or_ret(input: Value, thrown: Value) -> Result { inner_unwrap(input).and_then(|opt_value| match opt_value { Some(v) => Ok(v), - None => Err(EarlyReturnError::ExpectedValue(Box::new(thrown)).into()), + None => Err(EarlyReturnError::UnwrapFailed(Box::new(thrown)).into()), }) } @@ -80,7 +80,7 @@ pub fn native_unwrap_err(input: Value) -> Result { pub fn native_unwrap_err_or_ret(input: Value, thrown: Value) -> Result { inner_unwrap_err(input).and_then(|opt_value| match opt_value { Some(v) => Ok(v), - None => Err(EarlyReturnError::ExpectedValue(Box::new(thrown)).into()), + None => Err(EarlyReturnError::UnwrapFailed(Box::new(thrown)).into()), }) } @@ -88,7 +88,7 @@ pub fn native_try_ret(input: Value) -> Result { match input { Value::Optional(data) => match data.data { Some(data) => Ok(*data), - None => Err(EarlyReturnError::ExpectedValue(Box::new(Value::none())).into()), + None => Err(EarlyReturnError::UnwrapFailed(Box::new(Value::none())).into()), }, Value::Response(data) => { if data.committed { @@ -99,7 +99,7 @@ pub fn native_try_ret(input: Value) -> Result { "BUG: Failed to construct new response type from old response type".into(), ) })?; - Err(EarlyReturnError::ExpectedValue(Box::new(short_return_val)).into()) + Err(EarlyReturnError::UnwrapFailed(Box::new(short_return_val)).into()) } } _ => Err(CheckErrors::ExpectedOptionalOrResponseValue(Box::new(input)).into()), diff --git a/clarity/src/vm/tests/datamaps.rs b/clarity/src/vm/tests/datamaps.rs index 931142d92e..94143e17f3 100644 --- a/clarity/src/vm/tests/datamaps.rs +++ b/clarity/src/vm/tests/datamaps.rs @@ -296,7 +296,7 @@ fn test_set_response_variable() { "#; let contract_src = contract_src.to_string(); assert_eq!( - Err(EarlyReturnError::ExpectedValue(Box::new(Value::Int(5))).into()), + Err(EarlyReturnError::UnwrapFailed(Box::new(Value::Int(5))).into()), execute(&contract_src) ); } diff --git a/clarity/src/vm/tests/simple_apply_eval.rs b/clarity/src/vm/tests/simple_apply_eval.rs index 8293954765..44f4f09f1f 100644 --- a/clarity/src/vm/tests/simple_apply_eval.rs +++ b/clarity/src/vm/tests/simple_apply_eval.rs @@ -1431,7 +1431,7 @@ fn test_option_destructs() { .into(), ), Ok(Value::Int(3)), - Err(EarlyReturnError::ExpectedValue(Box::new(Value::Int(2))).into()), + Err(EarlyReturnError::UnwrapFailed(Box::new(Value::Int(2))).into()), Ok(Value::Int(3)), Ok(Value::Int(3)), Ok(Value::Int(3)), @@ -1444,11 +1444,9 @@ fn test_option_destructs() { Ok(Value::Int(8)), Err(CheckErrors::BadMatchInput(Box::new(TypeSignature::IntType)).into()), Err(CheckErrors::BadMatchInput(Box::new(TypeSignature::IntType)).into()), - Err( - EarlyReturnError::ExpectedValue(Box::new(Value::error(Value::UInt(1)).unwrap())).into(), - ), + Err(EarlyReturnError::UnwrapFailed(Box::new(Value::error(Value::UInt(1)).unwrap())).into()), Ok(Value::Int(3)), - Err(EarlyReturnError::ExpectedValue(Box::new(Value::none())).into()), + Err(EarlyReturnError::UnwrapFailed(Box::new(Value::none())).into()), Ok(Value::Bool(true)), Err(CheckErrors::IncorrectArgumentCount(1, 2).into()), Err(CheckErrors::ExpectedOptionalOrResponseValue(Box::new(Value::Int(1))).into()), From d2a8832868792fa008b8b728f8729bd348bb2d7c Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 11:09:17 -0700 Subject: [PATCH 12/34] Rename CheckErrors to CheckErrorKind Signed-off-by: Jacinta Ferrant --- CONTRIBUTING.md | 2 +- clarity-types/src/errors/analysis.rs | 306 ++++----- clarity-types/src/errors/mod.rs | 14 +- clarity-types/src/representations.rs | 4 +- clarity-types/src/tests/types/mod.rs | 24 +- .../src/tests/types/serialization.rs | 4 +- clarity-types/src/tests/types/signatures.rs | 8 +- clarity-types/src/types/mod.rs | 74 ++- clarity-types/src/types/serialization.rs | 36 +- clarity-types/src/types/signatures.rs | 229 +++---- clarity/fuzz/fuzz_targets/fuzz_sanitize.rs | 14 +- .../fuzz/fuzz_targets/fuzz_value_sanitize.rs | 8 +- clarity/src/vm/analysis/analysis_db.rs | 42 +- .../src/vm/analysis/arithmetic_checker/mod.rs | 4 +- .../contract_interface_builder/mod.rs | 8 +- clarity/src/vm/analysis/errors.rs | 2 +- clarity/src/vm/analysis/mod.rs | 10 +- .../src/vm/analysis/read_only_checker/mod.rs | 32 +- .../vm/analysis/read_only_checker/tests.rs | 14 +- clarity/src/vm/analysis/trait_checker/mod.rs | 6 +- .../src/vm/analysis/trait_checker/tests.rs | 48 +- .../src/vm/analysis/type_checker/contexts.rs | 8 +- clarity/src/vm/analysis/type_checker/mod.rs | 6 +- .../analysis/type_checker/v2_05/contexts.rs | 4 +- .../src/vm/analysis/type_checker/v2_05/mod.rs | 96 +-- .../type_checker/v2_05/natives/assets.rs | 38 +- .../type_checker/v2_05/natives/maps.rs | 22 +- .../type_checker/v2_05/natives/mod.rs | 92 +-- .../type_checker/v2_05/natives/options.rs | 62 +- .../type_checker/v2_05/natives/sequences.rs | 58 +- .../type_checker/v2_05/tests/assets.rs | 80 +-- .../type_checker/v2_05/tests/contracts.rs | 22 +- .../analysis/type_checker/v2_05/tests/mod.rs | 316 ++++----- .../vm/analysis/type_checker/v2_1/contexts.rs | 8 +- .../src/vm/analysis/type_checker/v2_1/mod.rs | 139 ++-- .../type_checker/v2_1/natives/assets.rs | 40 +- .../type_checker/v2_1/natives/maps.rs | 22 +- .../analysis/type_checker/v2_1/natives/mod.rs | 168 ++--- .../type_checker/v2_1/natives/options.rs | 61 +- .../type_checker/v2_1/natives/sequences.rs | 66 +- .../type_checker/v2_1/tests/assets.rs | 80 +-- .../type_checker/v2_1/tests/contracts.rs | 128 ++-- .../analysis/type_checker/v2_1/tests/mod.rs | 606 +++++++++--------- clarity/src/vm/analysis/types.rs | 8 +- clarity/src/vm/callables.rs | 22 +- clarity/src/vm/clarity.rs | 20 +- clarity/src/vm/contexts.rs | 16 +- clarity/src/vm/costs/mod.rs | 5 +- clarity/src/vm/database/clarity_db.rs | 32 +- clarity/src/vm/database/sqlite.rs | 4 +- clarity/src/vm/errors.rs | 2 +- clarity/src/vm/functions/arithmetic.rs | 40 +- clarity/src/vm/functions/assets.rs | 106 +-- clarity/src/vm/functions/boolean.rs | 4 +- clarity/src/vm/functions/conversions.rs | 16 +- clarity/src/vm/functions/crypto.rs | 32 +- clarity/src/vm/functions/database.rs | 163 ++--- clarity/src/vm/functions/define.rs | 40 +- clarity/src/vm/functions/mod.rs | 20 +- clarity/src/vm/functions/options.rs | 40 +- clarity/src/vm/functions/principals.rs | 27 +- clarity/src/vm/functions/sequences.rs | 51 +- clarity/src/vm/functions/tuples.rs | 12 +- clarity/src/vm/mod.rs | 14 +- clarity/src/vm/tests/assets.rs | 8 +- clarity/src/vm/tests/contracts.rs | 18 +- clarity/src/vm/tests/conversions.rs | 42 +- clarity/src/vm/tests/datamaps.rs | 34 +- clarity/src/vm/tests/defines.rs | 102 +-- clarity/src/vm/tests/principals.rs | 20 +- clarity/src/vm/tests/sequences.rs | 85 +-- clarity/src/vm/tests/simple_apply_eval.rs | 168 ++--- clarity/src/vm/tests/traits.rs | 14 +- clarity/src/vm/tests/variables.rs | 116 ++-- clarity/src/vm/types/mod.rs | 12 +- clarity/src/vm/types/signatures.rs | 121 ++-- .../chainstate/stacks/boot/contract_tests.rs | 9 +- stackslib/src/chainstate/stacks/boot/mod.rs | 4 +- stackslib/src/chainstate/stacks/db/blocks.rs | 2 +- .../src/chainstate/stacks/db/contracts.rs | 6 +- .../src/chainstate/stacks/db/transactions.rs | 6 +- stackslib/src/clarity_vm/clarity.rs | 6 +- .../src/clarity_vm/tests/analysis_costs.rs | 4 +- stackslib/src/clarity_vm/tests/contracts.rs | 22 +- stackslib/src/clarity_vm/tests/forking.rs | 4 +- stackslib/src/net/api/callreadonly.rs | 4 +- stackslib/src/net/api/fastcallreadonly.rs | 6 +- stackslib/src/net/tests/mod.rs | 2 +- 88 files changed, 2331 insertions(+), 2169 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 613e8c973e..60ebf8bda8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -498,7 +498,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { /// /// # Errors /// - /// - Returns CheckErrors::WriteAttemptedInReadOnly if there is a read-only + /// - Returns CheckErrorKind::WriteAttemptedInReadOnly if there is a read-only /// violation, i.e. if some function marked read-only attempts to modify /// the chainstate. pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), CheckError> diff --git a/clarity-types/src/errors/analysis.rs b/clarity-types/src/errors/analysis.rs index 09e4e5f056..2a1a0b7c75 100644 --- a/clarity-types/src/errors/analysis.rs +++ b/clarity-types/src/errors/analysis.rs @@ -136,14 +136,14 @@ impl SyntaxBindingError { } } -impl From for CheckErrors { +impl From for CheckErrorKind { fn from(e: SyntaxBindingError) -> Self { Self::BadSyntaxBinding(e) } } #[derive(Debug, PartialEq)] -pub enum CheckErrors { +pub enum CheckErrorKind { // cost checker errors CostOverflow, CostBalanceExceeded(ExecutionCost, ExecutionCost), @@ -160,8 +160,8 @@ pub enum CheckErrors { Expects(String), // match errors - BadMatchOptionSyntax(Box), - BadMatchResponseSyntax(Box), + BadMatchOptionSyntax(Box), + BadMatchResponseSyntax(Box), BadMatchInput(Box), // list typing errors @@ -311,24 +311,24 @@ pub enum CheckErrors { #[derive(Debug, PartialEq)] pub struct CheckError { - pub err: Box, + pub err: Box, pub expressions: Option>, pub diagnostic: Diagnostic, } -impl CheckErrors { +impl CheckErrorKind { /// Does this check error indicate that the transaction should be /// rejected? pub fn rejectable(&self) -> bool { matches!( self, - CheckErrors::SupertypeTooLarge | CheckErrors::Expects(_) + CheckErrorKind::SupertypeTooLarge | CheckErrorKind::Expects(_) ) } } impl CheckError { - pub fn new(err: CheckErrors) -> CheckError { + pub fn new(err: CheckErrorKind) -> CheckError { let diagnostic = Diagnostic::err(&err); CheckError { err: Box::new(err), @@ -351,7 +351,7 @@ impl CheckError { self.expressions.replace(exprs.to_vec()); } - pub fn with_expression(err: CheckErrors, expr: &SymbolicExpression) -> Self { + pub fn with_expression(err: CheckErrorKind, expr: &SymbolicExpression) -> Self { let mut r = Self::new(err); r.set_expression(expr); r @@ -360,25 +360,25 @@ impl CheckError { impl From<(SyntaxBindingError, &SymbolicExpression)> for CheckError { fn from(e: (SyntaxBindingError, &SymbolicExpression)) -> Self { - Self::with_expression(CheckErrors::BadSyntaxBinding(e.0), e.1) + Self::with_expression(CheckErrorKind::BadSyntaxBinding(e.0), e.1) } } -impl From<(CheckErrors, &SymbolicExpression)> for CheckError { - fn from(e: (CheckErrors, &SymbolicExpression)) -> Self { +impl From<(CheckErrorKind, &SymbolicExpression)> for CheckError { + fn from(e: (CheckErrorKind, &SymbolicExpression)) -> Self { let mut ce = Self::new(e.0); ce.set_expression(e.1); ce } } -impl From<(CheckErrors, &SymbolicExpression)> for CheckErrors { - fn from(e: (CheckErrors, &SymbolicExpression)) -> Self { +impl From<(CheckErrorKind, &SymbolicExpression)> for CheckErrorKind { + fn from(e: (CheckErrorKind, &SymbolicExpression)) -> Self { e.0 } } -impl fmt::Display for CheckErrors { +impl fmt::Display for CheckErrorKind { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{self:?}") } @@ -398,25 +398,25 @@ impl fmt::Display for CheckError { impl From for CheckError { fn from(err: CostErrors) -> Self { - CheckError::from(CheckErrors::from(err)) + CheckError::from(CheckErrorKind::from(err)) } } -impl From for CheckErrors { +impl From for CheckErrorKind { fn from(err: CostErrors) -> Self { match err { - CostErrors::CostOverflow => CheckErrors::CostOverflow, - CostErrors::CostBalanceExceeded(a, b) => CheckErrors::CostBalanceExceeded(a, b), - CostErrors::MemoryBalanceExceeded(a, b) => CheckErrors::MemoryBalanceExceeded(a, b), - CostErrors::CostComputationFailed(s) => CheckErrors::CostComputationFailed(s), + CostErrors::CostOverflow => CheckErrorKind::CostOverflow, + CostErrors::CostBalanceExceeded(a, b) => CheckErrorKind::CostBalanceExceeded(a, b), + CostErrors::MemoryBalanceExceeded(a, b) => CheckErrorKind::MemoryBalanceExceeded(a, b), + CostErrors::CostComputationFailed(s) => CheckErrorKind::CostComputationFailed(s), CostErrors::CostContractLoadFailure => { - CheckErrors::CostComputationFailed("Failed to load cost contract".into()) + CheckErrorKind::CostComputationFailed("Failed to load cost contract".into()) } CostErrors::InterpreterFailure => { - CheckErrors::Expects("Unexpected interpreter failure in cost computation".into()) + CheckErrorKind::Expects("Unexpected interpreter failure in cost computation".into()) } - CostErrors::Expect(s) => CheckErrors::Expects(s), - CostErrors::ExecutionTimeExpired => CheckErrors::ExecutionTimeExpired, + CostErrors::Expect(s) => CheckErrorKind::Expects(s), + CostErrors::ExecutionTimeExpired => CheckErrorKind::ExecutionTimeExpired, } } } @@ -427,44 +427,50 @@ impl error::Error for CheckError { } } -impl error::Error for CheckErrors { +impl error::Error for CheckErrorKind { fn source(&self) -> Option<&(dyn error::Error + 'static)> { None } } -impl From for CheckError { - fn from(err: CheckErrors) -> Self { +impl From for CheckError { + fn from(err: CheckErrorKind) -> Self { CheckError::new(err) } } #[cfg(any(test, feature = "testing"))] -impl From for String { - fn from(o: CheckErrors) -> Self { +impl From for String { + fn from(o: CheckErrorKind) -> Self { o.to_string() } } -pub fn check_argument_count(expected: usize, args: &[T]) -> Result<(), CheckErrors> { +pub fn check_argument_count(expected: usize, args: &[T]) -> Result<(), CheckErrorKind> { if args.len() != expected { - Err(CheckErrors::IncorrectArgumentCount(expected, args.len())) + Err(CheckErrorKind::IncorrectArgumentCount(expected, args.len())) } else { Ok(()) } } -pub fn check_arguments_at_least(expected: usize, args: &[T]) -> Result<(), CheckErrors> { +pub fn check_arguments_at_least(expected: usize, args: &[T]) -> Result<(), CheckErrorKind> { if args.len() < expected { - Err(CheckErrors::RequiresAtLeastArguments(expected, args.len())) + Err(CheckErrorKind::RequiresAtLeastArguments( + expected, + args.len(), + )) } else { Ok(()) } } -pub fn check_arguments_at_most(expected: usize, args: &[T]) -> Result<(), CheckErrors> { +pub fn check_arguments_at_most(expected: usize, args: &[T]) -> Result<(), CheckErrorKind> { if args.len() > expected { - Err(CheckErrors::RequiresAtMostArguments(expected, args.len())) + Err(CheckErrorKind::RequiresAtMostArguments( + expected, + args.len(), + )) } else { Ok(()) } @@ -485,139 +491,139 @@ fn formatted_expected_types(expected_types: &[TypeSignature]) -> String { expected_types_joined } -impl DiagnosableError for CheckErrors { +impl DiagnosableError for CheckErrorKind { fn message(&self) -> String { match &self { - CheckErrors::SupertypeTooLarge => "supertype of two types is too large".into(), - CheckErrors::Expects(s) => format!("unexpected interpreter behavior: {s}"), - CheckErrors::BadMatchOptionSyntax(source) => + CheckErrorKind::SupertypeTooLarge => "supertype of two types is too large".into(), + CheckErrorKind::Expects(s) => format!("unexpected interpreter behavior: {s}"), + CheckErrorKind::BadMatchOptionSyntax(source) => format!("match on a optional type uses the following syntax: (match input some-name if-some-expression if-none-expression). Caused by: {}", source.message()), - CheckErrors::BadMatchResponseSyntax(source) => + CheckErrorKind::BadMatchResponseSyntax(source) => format!("match on a result type uses the following syntax: (match input ok-name if-ok-expression err-name if-err-expression). Caused by: {}", source.message()), - CheckErrors::BadMatchInput(t) => + CheckErrorKind::BadMatchInput(t) => format!("match requires an input of either a response or optional, found input: '{t}'"), - CheckErrors::CostOverflow => "contract execution cost overflowed cost counter".into(), - CheckErrors::CostBalanceExceeded(a, b) => format!("contract execution cost exceeded budget: {a:?} > {b:?}"), - CheckErrors::MemoryBalanceExceeded(a, b) => format!("contract execution cost exceeded memory budget: {a:?} > {b:?}"), - CheckErrors::InvalidTypeDescription => "supplied type description is invalid".into(), - CheckErrors::EmptyTuplesNotAllowed => "tuple types may not be empty".into(), - CheckErrors::UnknownTypeName(name) => format!("failed to parse type: '{name}'"), - CheckErrors::ValueTooLarge => "created a type which was greater than maximum allowed value size".into(), - CheckErrors::ValueOutOfBounds => "created a type which value size was out of defined bounds".into(), - CheckErrors::TypeSignatureTooDeep => "created a type which was deeper than maximum allowed type depth".into(), - CheckErrors::ExpectedName => "expected a name argument to this function".into(), - CheckErrors::ListTypesMustMatch => "expecting elements of same type in a list".into(), - CheckErrors::ConstructedListTooLarge => "reached limit of elements in a sequence".into(), - CheckErrors::TypeError(expected_type, found_type) => format!("expecting expression of type '{expected_type}', found '{found_type}'"), - CheckErrors::TypeValueError(expected_type, found_value) => format!("expecting expression of type '{expected_type}', found '{found_value}'"), - CheckErrors::UnionTypeError(expected_types, found_type) => format!("expecting expression of type {}, found '{}'", formatted_expected_types(expected_types), found_type), - CheckErrors::UnionTypeValueError(expected_types, found_type) => format!("expecting expression of type {}, found '{}'", formatted_expected_types(expected_types), found_type), - CheckErrors::ExpectedOptionalType(found_type) => format!("expecting expression of type 'optional', found '{found_type}'"), - CheckErrors::ExpectedOptionalOrResponseType(found_type) => format!("expecting expression of type 'optional' or 'response', found '{found_type}'"), - CheckErrors::ExpectedOptionalOrResponseValue(found_value) => format!("expecting expression of type 'optional' or 'response', found '{found_value}'"), - CheckErrors::ExpectedResponseType(found_type) => format!("expecting expression of type 'response', found '{found_type}'"), - CheckErrors::ExpectedOptionalValue(found_value) => format!("expecting expression of type 'optional', found '{found_value}'"), - CheckErrors::ExpectedResponseValue(found_value) => format!("expecting expression of type 'response', found '{found_value}'"), - CheckErrors::ExpectedContractPrincipalValue(found_value) => format!("expecting contract principal value, found '{found_value}'"), - CheckErrors::CouldNotDetermineResponseOkType => "attempted to obtain 'ok' value from response, but 'ok' type is indeterminate".into(), - CheckErrors::CouldNotDetermineResponseErrType => "attempted to obtain 'err' value from response, but 'err' type is indeterminate".into(), - CheckErrors::CouldNotDetermineMatchTypes => "attempted to match on an (optional) or (response) type where either the some, ok, or err type is indeterminate. you may wish to use unwrap-panic or unwrap-err-panic instead.".into(), - CheckErrors::CouldNotDetermineType => "type of expression cannot be determined".into(), - CheckErrors::BadTupleFieldName => "invalid tuple field name".into(), - CheckErrors::ExpectedTuple(type_signature) => format!("expecting tuple, found '{type_signature}'"), - CheckErrors::NoSuchTupleField(field_name, tuple_signature) => format!("cannot find field '{field_name}' in tuple '{tuple_signature}'"), - CheckErrors::BadTupleConstruction(message) => format!("invalid tuple syntax: {message}"), - CheckErrors::NoSuchDataVariable(var_name) => format!("use of unresolved persisted variable '{var_name}'"), - CheckErrors::BadTransferSTXArguments => "STX transfer expects an int amount, from principal, to principal".into(), - CheckErrors::BadTransferFTArguments => "transfer expects an int amount, from principal, to principal".into(), - CheckErrors::BadTransferNFTArguments => "transfer expects an asset, from principal, to principal".into(), - CheckErrors::BadMintFTArguments => "mint expects a uint amount and from principal".into(), - CheckErrors::BadBurnFTArguments => "burn expects a uint amount and from principal".into(), - CheckErrors::BadMapName => "invalid map name".into(), - CheckErrors::NoSuchMap(map_name) => format!("use of unresolved map '{map_name}'"), - CheckErrors::DefineFunctionBadSignature => "invalid function definition".into(), - CheckErrors::BadFunctionName => "invalid function name".into(), - CheckErrors::BadMapTypeDefinition => "invalid map definition".into(), - CheckErrors::PublicFunctionMustReturnResponse(found_type) => format!("public functions must return an expression of type 'response', found '{found_type}'"), - CheckErrors::DefineVariableBadSignature => "invalid variable definition".into(), - CheckErrors::ReturnTypesMustMatch(type_1, type_2) => format!("detected two execution paths, returning two different expression types (got '{type_1}' and '{type_2}')"), - CheckErrors::NoSuchContract(contract_identifier) => format!("use of unresolved contract '{contract_identifier}'"), - CheckErrors::NoSuchPublicFunction(contract_identifier, function_name) => format!("contract '{contract_identifier}' has no public function '{function_name}'"), - CheckErrors::PublicFunctionNotReadOnly(contract_identifier, function_name) => format!("function '{contract_identifier}' in '{function_name}' is not read-only"), - CheckErrors::ContractAlreadyExists(contract_identifier) => format!("contract name '{contract_identifier}' conflicts with existing contract"), - CheckErrors::ContractCallExpectName => "missing contract name for call".into(), - CheckErrors::ExpectedCallableType(found_type) => format!("expected a callable contract, found {found_type}"), - CheckErrors::NoSuchBlockInfoProperty(property_name) => format!("use of block unknown property '{property_name}'"), - CheckErrors::NoSuchBurnBlockInfoProperty(property_name) => format!("use of burn block unknown property '{property_name}'"), - CheckErrors::NoSuchStacksBlockInfoProperty(property_name) => format!("use of unknown stacks block property '{property_name}'"), - CheckErrors::NoSuchTenureInfoProperty(property_name) => format!("use of unknown tenure property '{property_name}'"), - CheckErrors::GetBlockInfoExpectPropertyName => "missing property name for block info introspection".into(), - CheckErrors::GetBurnBlockInfoExpectPropertyName => "missing property name for burn block info introspection".into(), - CheckErrors::GetStacksBlockInfoExpectPropertyName => "missing property name for stacks block info introspection".into(), - CheckErrors::GetTenureInfoExpectPropertyName => "missing property name for tenure info introspection".into(), - CheckErrors::NameAlreadyUsed(name) => format!("defining '{name}' conflicts with previous value"), - CheckErrors::ReservedWord(name) => format!("{name} is a reserved word"), - CheckErrors::NonFunctionApplication => "expecting expression of type function".into(), - CheckErrors::ExpectedListApplication => "expecting expression of type list".into(), - CheckErrors::ExpectedSequence(found_type) => format!("expecting expression of type 'list', 'buff', 'string-ascii' or 'string-utf8' - found '{found_type}'"), - CheckErrors::MaxLengthOverflow => format!("expecting a value <= {}", u32::MAX), - CheckErrors::BadLetSyntax => "invalid syntax of 'let'".into(), - CheckErrors::CircularReference(references) => format!("detected circular reference: ({})", references.join(", ")), - CheckErrors::BadSyntaxBinding(binding_error) => format!("invalid syntax binding: {}", &binding_error.message()), - CheckErrors::MaxContextDepthReached => "reached depth limit".into(), - CheckErrors::UndefinedVariable(var_name) => format!("use of unresolved variable '{var_name}'"), - CheckErrors::UndefinedFunction(var_name) => format!("use of unresolved function '{var_name}'"), - CheckErrors::RequiresAtLeastArguments(expected, found) => format!("expecting >= {expected} arguments, got {found}"), - CheckErrors::RequiresAtMostArguments(expected, found) => format!("expecting < {expected} arguments, got {found}"), - CheckErrors::IncorrectArgumentCount(expected_count, found_count) => format!("expecting {expected_count} arguments, got {found_count}"), - CheckErrors::IfArmsMustMatch(type_1, type_2) => format!("expression types returned by the arms of 'if' must match (got '{type_1}' and '{type_2}')"), - CheckErrors::MatchArmsMustMatch(type_1, type_2) => format!("expression types returned by the arms of 'match' must match (got '{type_1}' and '{type_2}')"), - CheckErrors::DefaultTypesMustMatch(type_1, type_2) => format!("expression types passed in 'default-to' must match (got '{type_1}' and '{type_2}')"), - CheckErrors::IllegalOrUnknownFunctionApplication(function_name) => format!("use of illegal / unresolved function '{function_name}"), - CheckErrors::UnknownFunction(function_name) => format!("use of unresolved function '{function_name}'"), - CheckErrors::TraitBasedContractCallInReadOnly => "use of trait based contract calls are not allowed in read-only context".into(), - CheckErrors::WriteAttemptedInReadOnly => "expecting read-only statements, detected a writing operation".into(), - CheckErrors::AtBlockClosureMustBeReadOnly => "(at-block ...) closures expect read-only statements, but detected a writing operation".into(), - CheckErrors::BadTokenName => "expecting an token name as an argument".into(), - CheckErrors::DefineNFTBadSignature => "(define-asset ...) expects an asset name and an asset identifier type signature as arguments".into(), - CheckErrors::NoSuchNFT(asset_name) => format!("tried to use asset function with a undefined asset ('{asset_name}')"), - CheckErrors::NoSuchFT(asset_name) => format!("tried to use token function with a undefined token ('{asset_name}')"), - CheckErrors::NoSuchTrait(contract_name, trait_name) => format!("use of unresolved trait {contract_name}.{trait_name}"), - CheckErrors::TraitReferenceUnknown(trait_name) => format!("use of undeclared trait <{trait_name}>"), - CheckErrors::TraitMethodUnknown(trait_name, func_name) => format!("method '{func_name}' unspecified in trait <{trait_name}>"), - CheckErrors::BadTraitImplementation(trait_name, func_name) => format!("invalid signature for method '{func_name}' regarding trait's specification <{trait_name}>"), - CheckErrors::ExpectedTraitIdentifier => "expecting expression of type trait identifier".into(), - CheckErrors::UnexpectedTraitOrFieldReference => "unexpected use of trait reference or field".into(), - CheckErrors::DefineTraitBadSignature => "invalid trait definition".into(), - CheckErrors::DefineTraitDuplicateMethod(method_name) => format!("duplicate method name '{method_name}' in trait definition"), - CheckErrors::TraitReferenceNotAllowed => "trait references can not be stored".into(), - CheckErrors::ContractOfExpectsTrait => "trait reference expected".into(), - CheckErrors::IncompatibleTrait(expected_trait, actual_trait) => format!("trait '{actual_trait}' is not a compatible with expected trait, '{expected_trait}'"), - CheckErrors::InvalidCharactersDetected => "invalid characters detected".into(), - CheckErrors::InvalidUTF8Encoding => "invalid UTF8 encoding".into(), - CheckErrors::InvalidSecp65k1Signature => "invalid seckp256k1 signature".into(), - CheckErrors::TypeAlreadyAnnotatedFailure | CheckErrors::CheckerImplementationFailure => { + CheckErrorKind::CostOverflow => "contract execution cost overflowed cost counter".into(), + CheckErrorKind::CostBalanceExceeded(a, b) => format!("contract execution cost exceeded budget: {a:?} > {b:?}"), + CheckErrorKind::MemoryBalanceExceeded(a, b) => format!("contract execution cost exceeded memory budget: {a:?} > {b:?}"), + CheckErrorKind::InvalidTypeDescription => "supplied type description is invalid".into(), + CheckErrorKind::EmptyTuplesNotAllowed => "tuple types may not be empty".into(), + CheckErrorKind::UnknownTypeName(name) => format!("failed to parse type: '{name}'"), + CheckErrorKind::ValueTooLarge => "created a type which was greater than maximum allowed value size".into(), + CheckErrorKind::ValueOutOfBounds => "created a type which value size was out of defined bounds".into(), + CheckErrorKind::TypeSignatureTooDeep => "created a type which was deeper than maximum allowed type depth".into(), + CheckErrorKind::ExpectedName => "expected a name argument to this function".into(), + CheckErrorKind::ListTypesMustMatch => "expecting elements of same type in a list".into(), + CheckErrorKind::ConstructedListTooLarge => "reached limit of elements in a sequence".into(), + CheckErrorKind::TypeError(expected_type, found_type) => format!("expecting expression of type '{expected_type}', found '{found_type}'"), + CheckErrorKind::TypeValueError(expected_type, found_value) => format!("expecting expression of type '{expected_type}', found '{found_value}'"), + CheckErrorKind::UnionTypeError(expected_types, found_type) => format!("expecting expression of type {}, found '{}'", formatted_expected_types(expected_types), found_type), + CheckErrorKind::UnionTypeValueError(expected_types, found_type) => format!("expecting expression of type {}, found '{}'", formatted_expected_types(expected_types), found_type), + CheckErrorKind::ExpectedOptionalType(found_type) => format!("expecting expression of type 'optional', found '{found_type}'"), + CheckErrorKind::ExpectedOptionalOrResponseType(found_type) => format!("expecting expression of type 'optional' or 'response', found '{found_type}'"), + CheckErrorKind::ExpectedOptionalOrResponseValue(found_value) => format!("expecting expression of type 'optional' or 'response', found '{found_value}'"), + CheckErrorKind::ExpectedResponseType(found_type) => format!("expecting expression of type 'response', found '{found_type}'"), + CheckErrorKind::ExpectedOptionalValue(found_value) => format!("expecting expression of type 'optional', found '{found_value}'"), + CheckErrorKind::ExpectedResponseValue(found_value) => format!("expecting expression of type 'response', found '{found_value}'"), + CheckErrorKind::ExpectedContractPrincipalValue(found_value) => format!("expecting contract principal value, found '{found_value}'"), + CheckErrorKind::CouldNotDetermineResponseOkType => "attempted to obtain 'ok' value from response, but 'ok' type is indeterminate".into(), + CheckErrorKind::CouldNotDetermineResponseErrType => "attempted to obtain 'err' value from response, but 'err' type is indeterminate".into(), + CheckErrorKind::CouldNotDetermineMatchTypes => "attempted to match on an (optional) or (response) type where either the some, ok, or err type is indeterminate. you may wish to use unwrap-panic or unwrap-err-panic instead.".into(), + CheckErrorKind::CouldNotDetermineType => "type of expression cannot be determined".into(), + CheckErrorKind::BadTupleFieldName => "invalid tuple field name".into(), + CheckErrorKind::ExpectedTuple(type_signature) => format!("expecting tuple, found '{type_signature}'"), + CheckErrorKind::NoSuchTupleField(field_name, tuple_signature) => format!("cannot find field '{field_name}' in tuple '{tuple_signature}'"), + CheckErrorKind::BadTupleConstruction(message) => format!("invalid tuple syntax: {message}"), + CheckErrorKind::NoSuchDataVariable(var_name) => format!("use of unresolved persisted variable '{var_name}'"), + CheckErrorKind::BadTransferSTXArguments => "STX transfer expects an int amount, from principal, to principal".into(), + CheckErrorKind::BadTransferFTArguments => "transfer expects an int amount, from principal, to principal".into(), + CheckErrorKind::BadTransferNFTArguments => "transfer expects an asset, from principal, to principal".into(), + CheckErrorKind::BadMintFTArguments => "mint expects a uint amount and from principal".into(), + CheckErrorKind::BadBurnFTArguments => "burn expects a uint amount and from principal".into(), + CheckErrorKind::BadMapName => "invalid map name".into(), + CheckErrorKind::NoSuchMap(map_name) => format!("use of unresolved map '{map_name}'"), + CheckErrorKind::DefineFunctionBadSignature => "invalid function definition".into(), + CheckErrorKind::BadFunctionName => "invalid function name".into(), + CheckErrorKind::BadMapTypeDefinition => "invalid map definition".into(), + CheckErrorKind::PublicFunctionMustReturnResponse(found_type) => format!("public functions must return an expression of type 'response', found '{found_type}'"), + CheckErrorKind::DefineVariableBadSignature => "invalid variable definition".into(), + CheckErrorKind::ReturnTypesMustMatch(type_1, type_2) => format!("detected two execution paths, returning two different expression types (got '{type_1}' and '{type_2}')"), + CheckErrorKind::NoSuchContract(contract_identifier) => format!("use of unresolved contract '{contract_identifier}'"), + CheckErrorKind::NoSuchPublicFunction(contract_identifier, function_name) => format!("contract '{contract_identifier}' has no public function '{function_name}'"), + CheckErrorKind::PublicFunctionNotReadOnly(contract_identifier, function_name) => format!("function '{contract_identifier}' in '{function_name}' is not read-only"), + CheckErrorKind::ContractAlreadyExists(contract_identifier) => format!("contract name '{contract_identifier}' conflicts with existing contract"), + CheckErrorKind::ContractCallExpectName => "missing contract name for call".into(), + CheckErrorKind::ExpectedCallableType(found_type) => format!("expected a callable contract, found {found_type}"), + CheckErrorKind::NoSuchBlockInfoProperty(property_name) => format!("use of block unknown property '{property_name}'"), + CheckErrorKind::NoSuchBurnBlockInfoProperty(property_name) => format!("use of burn block unknown property '{property_name}'"), + CheckErrorKind::NoSuchStacksBlockInfoProperty(property_name) => format!("use of unknown stacks block property '{property_name}'"), + CheckErrorKind::NoSuchTenureInfoProperty(property_name) => format!("use of unknown tenure property '{property_name}'"), + CheckErrorKind::GetBlockInfoExpectPropertyName => "missing property name for block info introspection".into(), + CheckErrorKind::GetBurnBlockInfoExpectPropertyName => "missing property name for burn block info introspection".into(), + CheckErrorKind::GetStacksBlockInfoExpectPropertyName => "missing property name for stacks block info introspection".into(), + CheckErrorKind::GetTenureInfoExpectPropertyName => "missing property name for tenure info introspection".into(), + CheckErrorKind::NameAlreadyUsed(name) => format!("defining '{name}' conflicts with previous value"), + CheckErrorKind::ReservedWord(name) => format!("{name} is a reserved word"), + CheckErrorKind::NonFunctionApplication => "expecting expression of type function".into(), + CheckErrorKind::ExpectedListApplication => "expecting expression of type list".into(), + CheckErrorKind::ExpectedSequence(found_type) => format!("expecting expression of type 'list', 'buff', 'string-ascii' or 'string-utf8' - found '{found_type}'"), + CheckErrorKind::MaxLengthOverflow => format!("expecting a value <= {}", u32::MAX), + CheckErrorKind::BadLetSyntax => "invalid syntax of 'let'".into(), + CheckErrorKind::CircularReference(references) => format!("detected circular reference: ({})", references.join(", ")), + CheckErrorKind::BadSyntaxBinding(binding_error) => format!("invalid syntax binding: {}", &binding_error.message()), + CheckErrorKind::MaxContextDepthReached => "reached depth limit".into(), + CheckErrorKind::UndefinedVariable(var_name) => format!("use of unresolved variable '{var_name}'"), + CheckErrorKind::UndefinedFunction(var_name) => format!("use of unresolved function '{var_name}'"), + CheckErrorKind::RequiresAtLeastArguments(expected, found) => format!("expecting >= {expected} arguments, got {found}"), + CheckErrorKind::RequiresAtMostArguments(expected, found) => format!("expecting < {expected} arguments, got {found}"), + CheckErrorKind::IncorrectArgumentCount(expected_count, found_count) => format!("expecting {expected_count} arguments, got {found_count}"), + CheckErrorKind::IfArmsMustMatch(type_1, type_2) => format!("expression types returned by the arms of 'if' must match (got '{type_1}' and '{type_2}')"), + CheckErrorKind::MatchArmsMustMatch(type_1, type_2) => format!("expression types returned by the arms of 'match' must match (got '{type_1}' and '{type_2}')"), + CheckErrorKind::DefaultTypesMustMatch(type_1, type_2) => format!("expression types passed in 'default-to' must match (got '{type_1}' and '{type_2}')"), + CheckErrorKind::IllegalOrUnknownFunctionApplication(function_name) => format!("use of illegal / unresolved function '{function_name}"), + CheckErrorKind::UnknownFunction(function_name) => format!("use of unresolved function '{function_name}'"), + CheckErrorKind::TraitBasedContractCallInReadOnly => "use of trait based contract calls are not allowed in read-only context".into(), + CheckErrorKind::WriteAttemptedInReadOnly => "expecting read-only statements, detected a writing operation".into(), + CheckErrorKind::AtBlockClosureMustBeReadOnly => "(at-block ...) closures expect read-only statements, but detected a writing operation".into(), + CheckErrorKind::BadTokenName => "expecting an token name as an argument".into(), + CheckErrorKind::DefineNFTBadSignature => "(define-asset ...) expects an asset name and an asset identifier type signature as arguments".into(), + CheckErrorKind::NoSuchNFT(asset_name) => format!("tried to use asset function with a undefined asset ('{asset_name}')"), + CheckErrorKind::NoSuchFT(asset_name) => format!("tried to use token function with a undefined token ('{asset_name}')"), + CheckErrorKind::NoSuchTrait(contract_name, trait_name) => format!("use of unresolved trait {contract_name}.{trait_name}"), + CheckErrorKind::TraitReferenceUnknown(trait_name) => format!("use of undeclared trait <{trait_name}>"), + CheckErrorKind::TraitMethodUnknown(trait_name, func_name) => format!("method '{func_name}' unspecified in trait <{trait_name}>"), + CheckErrorKind::BadTraitImplementation(trait_name, func_name) => format!("invalid signature for method '{func_name}' regarding trait's specification <{trait_name}>"), + CheckErrorKind::ExpectedTraitIdentifier => "expecting expression of type trait identifier".into(), + CheckErrorKind::UnexpectedTraitOrFieldReference => "unexpected use of trait reference or field".into(), + CheckErrorKind::DefineTraitBadSignature => "invalid trait definition".into(), + CheckErrorKind::DefineTraitDuplicateMethod(method_name) => format!("duplicate method name '{method_name}' in trait definition"), + CheckErrorKind::TraitReferenceNotAllowed => "trait references can not be stored".into(), + CheckErrorKind::ContractOfExpectsTrait => "trait reference expected".into(), + CheckErrorKind::IncompatibleTrait(expected_trait, actual_trait) => format!("trait '{actual_trait}' is not a compatible with expected trait, '{expected_trait}'"), + CheckErrorKind::InvalidCharactersDetected => "invalid characters detected".into(), + CheckErrorKind::InvalidUTF8Encoding => "invalid UTF8 encoding".into(), + CheckErrorKind::InvalidSecp65k1Signature => "invalid seckp256k1 signature".into(), + CheckErrorKind::TypeAlreadyAnnotatedFailure | CheckErrorKind::CheckerImplementationFailure => { "internal error - please file an issue on https://github.com/stacks-network/stacks-blockchain".into() }, - CheckErrors::UncheckedIntermediaryResponses => "intermediary responses in consecutive statements must be checked".into(), - CheckErrors::CostComputationFailed(s) => format!("contract cost computation failed: {s}"), - CheckErrors::CouldNotDetermineSerializationType => "could not determine the input type for the serialization function".into(), - CheckErrors::ExecutionTimeExpired => "execution time expired".into(), + CheckErrorKind::UncheckedIntermediaryResponses => "intermediary responses in consecutive statements must be checked".into(), + CheckErrorKind::CostComputationFailed(s) => format!("contract cost computation failed: {s}"), + CheckErrorKind::CouldNotDetermineSerializationType => "could not determine the input type for the serialization function".into(), + CheckErrorKind::ExecutionTimeExpired => "execution time expired".into(), } } fn suggestion(&self) -> Option { match &self { - CheckErrors::BadLetSyntax => Some( + CheckErrorKind::BadLetSyntax => Some( "'let' syntax example: (let ((supply 1000) (ttl 60)) )".into(), ), - CheckErrors::TraitReferenceUnknown(_) => Some( + CheckErrorKind::TraitReferenceUnknown(_) => Some( "traits should be either defined, with define-trait, or imported, with use-trait." .into(), ), - CheckErrors::NoSuchBlockInfoProperty(_) => Some( + CheckErrorKind::NoSuchBlockInfoProperty(_) => Some( "properties available: time, header-hash, burnchain-header-hash, vrf-seed".into(), ), _ => None, diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 58b42b8a99..a8be99328d 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -20,7 +20,7 @@ pub mod lexer; use std::{error, fmt}; -pub use analysis::{CheckError, CheckErrors}; +pub use analysis::{CheckError, CheckErrorKind}; pub use ast::{ParseError, ParseErrors, ParseResult}; pub use cost::CostErrors; pub use lexer::LexerError; @@ -43,7 +43,7 @@ pub enum Error { /// UncheckedErrors are errors that *should* be caught by the /// TypeChecker and other check passes. Test executions may /// trigger these errors. - Unchecked(CheckErrors), + Unchecked(CheckErrorKind), Interpreter(InterpreterError), Runtime(RuntimeErrorType, Option), ShortReturn(ShortReturnType), @@ -185,7 +185,7 @@ impl From for Error { CostErrors::Expect(s) => Error::from(InterpreterError::Expect(format!( "Interpreter failure during cost calculation: {s}" ))), - other_err => Error::from(CheckErrors::from(other_err)), + other_err => Error::from(CheckErrorKind::from(other_err)), } } } @@ -196,14 +196,14 @@ impl From for Error { } } -impl From for Error { - fn from(err: CheckErrors) -> Self { +impl From for Error { + fn from(err: CheckErrorKind) -> Self { Error::Unchecked(err) } } -impl From<(CheckErrors, &SymbolicExpression)> for Error { - fn from(err: (CheckErrors, &SymbolicExpression)) -> Self { +impl From<(CheckErrorKind, &SymbolicExpression)> for Error { + fn from(err: (CheckErrorKind, &SymbolicExpression)) -> Self { Error::Unchecked(err.0) } } diff --git a/clarity-types/src/representations.rs b/clarity-types/src/representations.rs index e941e9b7ec..2a8cf9c29b 100644 --- a/clarity-types/src/representations.rs +++ b/clarity-types/src/representations.rs @@ -623,14 +623,14 @@ impl SymbolicExpression { } /// Encode this SymbolicExpression as a String suitable for logging an error (such as in - /// CheckErrors). The `developer-mode` feature includes the `span`. + /// CheckErrorKind). The `developer-mode` feature includes the `span`. #[cfg(feature = "developer-mode")] pub fn as_error_string(&self) -> String { format!("{} at {:?}", &self.expr, &self.span) } /// Encode this SymbolicExpression as a String suitable for logging an error (such as in - /// CheckErrors). + /// CheckErrorKind). #[cfg(not(feature = "developer-mode"))] pub fn as_error_string(&self) -> String { format!("{}", &self.expr) diff --git a/clarity-types/src/tests/types/mod.rs b/clarity-types/src/tests/types/mod.rs index 8c8d861c7c..819395c9b6 100644 --- a/clarity-types/src/tests/types/mod.rs +++ b/clarity-types/src/tests/types/mod.rs @@ -19,7 +19,7 @@ use rstest::rstest; use stacks_common::types::StacksEpochId; use crate::Error; -use crate::errors::{CheckErrors, InterpreterError, RuntimeErrorType}; +use crate::errors::{CheckErrorKind, InterpreterError, RuntimeErrorType}; use crate::types::{ ASCIIData, BuffData, CharType, ListTypeData, MAX_VALUE_SIZE, PrincipalData, QualifiedContractIdentifier, SequenceData, SequencedValue as _, StandardPrincipalData, @@ -38,12 +38,12 @@ fn test_constructors() { ); assert_eq!( ListTypeData::new_list(TypeSignature::IntType, MAX_VALUE_SIZE), - Err(CheckErrors::ValueTooLarge) + Err(CheckErrorKind::ValueTooLarge) ); assert_eq!( Value::buff_from(vec![0; (MAX_VALUE_SIZE + 1) as usize]), - Err(CheckErrors::ValueTooLarge.into()) + Err(CheckErrorKind::ValueTooLarge.into()) ); // Test that wrappers (okay, error, some) @@ -52,17 +52,17 @@ fn test_constructors() { // isn't causing the error). assert_eq!( Value::okay(Value::buff_from(vec![0; (MAX_VALUE_SIZE) as usize]).unwrap()), - Err(CheckErrors::ValueTooLarge.into()) + Err(CheckErrorKind::ValueTooLarge.into()) ); assert_eq!( Value::error(Value::buff_from(vec![0; (MAX_VALUE_SIZE) as usize]).unwrap()), - Err(CheckErrors::ValueTooLarge.into()) + Err(CheckErrorKind::ValueTooLarge.into()) ); assert_eq!( Value::some(Value::buff_from(vec![0; (MAX_VALUE_SIZE) as usize]).unwrap()), - Err(CheckErrors::ValueTooLarge.into()) + Err(CheckErrorKind::ValueTooLarge.into()) ); // Test that the depth limit is correctly enforced: @@ -86,24 +86,24 @@ fn test_constructors() { let inner_value = cons().unwrap(); assert_eq!( TupleData::from_data(vec![("a".into(), inner_value.clone())]), - Err(CheckErrors::TypeSignatureTooDeep.into()) + Err(CheckErrorKind::TypeSignatureTooDeep.into()) ); assert_eq!( Value::list_from(vec![inner_value.clone()]), - Err(CheckErrors::TypeSignatureTooDeep.into()) + Err(CheckErrorKind::TypeSignatureTooDeep.into()) ); assert_eq!( Value::okay(inner_value.clone()), - Err(CheckErrors::TypeSignatureTooDeep.into()) + Err(CheckErrorKind::TypeSignatureTooDeep.into()) ); assert_eq!( Value::error(inner_value.clone()), - Err(CheckErrors::TypeSignatureTooDeep.into()) + Err(CheckErrorKind::TypeSignatureTooDeep.into()) ); assert_eq!( Value::some(inner_value), - Err(CheckErrors::TypeSignatureTooDeep.into()) + Err(CheckErrorKind::TypeSignatureTooDeep.into()) ); if std::env::var("CIRCLE_TESTING") == Ok("1".to_string()) { @@ -115,7 +115,7 @@ fn test_constructors() { if (u32::MAX as usize) < usize::MAX { assert_eq!( Value::buff_from(vec![0; (u32::MAX as usize) + 10]), - Err(CheckErrors::ValueTooLarge.into()) + Err(CheckErrorKind::ValueTooLarge.into()) ); } } diff --git a/clarity-types/src/tests/types/serialization.rs b/clarity-types/src/tests/types/serialization.rs index 679befd351..2349b937c9 100644 --- a/clarity-types/src/tests/types/serialization.rs +++ b/clarity-types/src/tests/types/serialization.rs @@ -15,7 +15,7 @@ use std::io::Write; use crate::Error; -use crate::errors::{CheckErrors, InterpreterError}; +use crate::errors::{CheckErrorKind, InterpreterError}; use crate::types::serialization::SerializationError; use crate::types::{ ASCIIData, CharType, MAX_VALUE_SIZE, PrincipalData, QualifiedContractIdentifier, SequenceData, @@ -394,7 +394,7 @@ fn try_deser_large_tuple() { fn try_overflow_stack() { let input = "08080808080808080808070707080807080808080808080708080808080708080707080707080807080808080808080708080808080708080707080708070807080808080808080708080808080708080708080808080808080807070807080808080808070808070707080807070808070808080808070808070708070807080808080808080707080708070807080708080808080808070808080808070808070808080808080808080707080708080808080807080807070708080707080807080808080807080807070807080708080808080808070708070808080808080708080707070808070708080807080807070708"; assert_eq!( - Err(CheckErrors::TypeSignatureTooDeep.into()), + Err(CheckErrorKind::TypeSignatureTooDeep.into()), Value::try_deserialize_hex_untyped(input) ); } diff --git a/clarity-types/src/tests/types/signatures.rs b/clarity-types/src/tests/types/signatures.rs index bb8fa5231a..9776877835 100644 --- a/clarity-types/src/tests/types/signatures.rs +++ b/clarity-types/src/tests/types/signatures.rs @@ -14,7 +14,7 @@ // along with this program. If not, see . use std::collections::HashSet; -use crate::errors::CheckErrors; +use crate::errors::CheckErrorKind; use crate::types::TypeSignature::{BoolType, IntType, ListUnionType, UIntType}; use crate::types::signatures::{CallableSubtype, TypeSignature}; use crate::types::{ @@ -518,11 +518,11 @@ fn test_least_supertype() { for pair in bad_pairs { matches!( TypeSignature::least_supertype_v2_1(&pair.0, &pair.1).unwrap_err(), - CheckErrors::TypeError(..) + CheckErrorKind::TypeError(..) ); matches!( TypeSignature::least_supertype_v2_1(&pair.1, &pair.0).unwrap_err(), - CheckErrors::TypeError(..) + CheckErrorKind::TypeError(..) ); } } @@ -531,7 +531,7 @@ fn test_least_supertype() { fn test_type_signature_bound_string_ascii_type_returns_check_errors() { let err = TypeSignature::bound_string_ascii_type(MAX_VALUE_SIZE + 1).unwrap_err(); assert_eq!( - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: Max Clarity Value Size is no longer realizable in ASCII Type".to_string() ), err diff --git a/clarity-types/src/types/mod.rs b/clarity-types/src/types/mod.rs index c28dc0c275..6b5bab1b82 100644 --- a/clarity-types/src/types/mod.rs +++ b/clarity-types/src/types/mod.rs @@ -37,7 +37,9 @@ pub use self::signatures::{ ListTypeData, SequenceSubtype, StringSubtype, StringUTF8Length, TupleTypeSignature, TypeSignature, }; -use crate::errors::{CheckErrors, InterpreterError, InterpreterResult as Result, RuntimeErrorType}; +use crate::errors::{ + CheckErrorKind, InterpreterError, InterpreterResult as Result, RuntimeErrorType, +}; use crate::representations::{ClarityName, ContractName, SymbolicExpression}; // use crate::vm::ClarityVersion; @@ -403,7 +405,7 @@ impl SequenceData { } } if index >= seq_length { - return Err(CheckErrors::ValueOutOfBounds.into()); + return Err(CheckErrorKind::ValueOutOfBounds.into()); } let new_seq_data = match (self, element) { @@ -414,7 +416,7 @@ impl SequenceData { (SequenceData::List(mut data), elem) => { let entry_type = data.type_signature.get_list_item_type(); if !entry_type.admits(epoch, &elem)? { - return Err(CheckErrors::ListTypesMustMatch.into()); + return Err(CheckErrorKind::ListTypesMustMatch.into()); } data.data[index] = elem; SequenceData::List(data) @@ -433,7 +435,7 @@ impl SequenceData { data.data[index] = elem.data.swap_remove(0); SequenceData::String(CharType::UTF8(data)) } - _ => return Err(CheckErrors::ListTypesMustMatch.into()), + _ => return Err(CheckErrorKind::ListTypesMustMatch.into()), }; Value::some(Value::Sequence(new_seq_data)) @@ -454,7 +456,7 @@ impl SequenceData { Ok(None) } } else { - Err(CheckErrors::TypeValueError( + Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::min_buffer()?), Box::new(to_find), ) @@ -483,7 +485,7 @@ impl SequenceData { Ok(None) } } else { - Err(CheckErrors::TypeValueError( + Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::min_string_ascii()?), Box::new(to_find), ) @@ -504,7 +506,7 @@ impl SequenceData { Ok(None) } } else { - Err(CheckErrors::TypeValueError( + Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::min_string_utf8()?), Box::new(to_find), ) @@ -691,7 +693,7 @@ impl fmt::Display for UTF8Data { } pub trait SequencedValue { - fn type_signature(&self) -> std::result::Result; + fn type_signature(&self) -> std::result::Result; fn items(&self) -> &Vec; @@ -716,7 +718,7 @@ impl SequencedValue for ListData { self.data.drain(..).collect() } - fn type_signature(&self) -> std::result::Result { + fn type_signature(&self) -> std::result::Result { Ok(TypeSignature::SequenceType(SequenceSubtype::ListType( self.type_signature.clone(), ))) @@ -736,9 +738,9 @@ impl SequencedValue for BuffData { self.data.drain(..).collect() } - fn type_signature(&self) -> std::result::Result { + fn type_signature(&self) -> std::result::Result { let buff_length = BufferLength::try_from(self.data.len()).map_err(|_| { - CheckErrors::Expects("ERROR: Too large of a buffer successfully constructed.".into()) + CheckErrorKind::Expects("ERROR: Too large of a buffer successfully constructed.".into()) })?; Ok(TypeSignature::SequenceType(SequenceSubtype::BufferType( buff_length, @@ -759,9 +761,9 @@ impl SequencedValue for ASCIIData { self.data.drain(..).collect() } - fn type_signature(&self) -> std::result::Result { + fn type_signature(&self) -> std::result::Result { let buff_length = BufferLength::try_from(self.data.len()).map_err(|_| { - CheckErrors::Expects("ERROR: Too large of a buffer successfully constructed.".into()) + CheckErrorKind::Expects("ERROR: Too large of a buffer successfully constructed.".into()) })?; Ok(TypeSignature::SequenceType(SequenceSubtype::StringType( StringSubtype::ASCII(buff_length), @@ -785,9 +787,9 @@ impl SequencedValue> for UTF8Data { self.data.drain(..).collect() } - fn type_signature(&self) -> std::result::Result { + fn type_signature(&self) -> std::result::Result { let str_len = StringUTF8Length::try_from(self.data.len()).map_err(|_| { - CheckErrors::Expects("ERROR: Too large of a buffer successfully constructed.".into()) + CheckErrorKind::Expects("ERROR: Too large of a buffer successfully constructed.".into()) })?; Ok(TypeSignature::SequenceType(SequenceSubtype::StringType( StringSubtype::UTF8(str_len), @@ -803,19 +805,19 @@ impl SequencedValue> for UTF8Data { } impl OptionalData { - pub fn type_signature(&self) -> std::result::Result { + pub fn type_signature(&self) -> std::result::Result { let type_result = match self.data { Some(ref v) => TypeSignature::new_option(TypeSignature::type_of(v)?), None => TypeSignature::new_option(TypeSignature::NoType), }; type_result.map_err(|_| { - CheckErrors::Expects("Should not have constructed too large of a type.".into()) + CheckErrorKind::Expects("Should not have constructed too large of a type.".into()) }) } } impl ResponseData { - pub fn type_signature(&self) -> std::result::Result { + pub fn type_signature(&self) -> std::result::Result { let type_result = match self.committed { true => TypeSignature::new_response( TypeSignature::type_of(&self.data)?, @@ -827,7 +829,7 @@ impl ResponseData { ), }; type_result.map_err(|_| { - CheckErrors::Expects("Should not have constructed too large of a type.".into()) + CheckErrorKind::Expects("Should not have constructed too large of a type.".into()) }) } } @@ -849,9 +851,9 @@ pub const NONE: Value = Value::Optional(OptionalData { data: None }); impl Value { pub fn some(data: Value) -> Result { if data.size()? + WRAPPER_VALUE_SIZE > MAX_VALUE_SIZE { - Err(CheckErrors::ValueTooLarge.into()) + Err(CheckErrorKind::ValueTooLarge.into()) } else if data.depth()? + 1 > MAX_TYPE_DEPTH { - Err(CheckErrors::TypeSignatureTooDeep.into()) + Err(CheckErrorKind::TypeSignatureTooDeep.into()) } else { Ok(Value::Optional(OptionalData { data: Some(Box::new(data)), @@ -886,9 +888,9 @@ impl Value { pub fn okay(data: Value) -> Result { if data.size()? + WRAPPER_VALUE_SIZE > MAX_VALUE_SIZE { - Err(CheckErrors::ValueTooLarge.into()) + Err(CheckErrorKind::ValueTooLarge.into()) } else if data.depth()? + 1 > MAX_TYPE_DEPTH { - Err(CheckErrors::TypeSignatureTooDeep.into()) + Err(CheckErrorKind::TypeSignatureTooDeep.into()) } else { Ok(Value::Response(ResponseData { committed: true, @@ -899,9 +901,9 @@ impl Value { pub fn error(data: Value) -> Result { if data.size()? + WRAPPER_VALUE_SIZE > MAX_VALUE_SIZE { - Err(CheckErrors::ValueTooLarge.into()) + Err(CheckErrorKind::ValueTooLarge.into()) } else if data.depth()? + 1 > MAX_TYPE_DEPTH { - Err(CheckErrors::TypeSignatureTooDeep.into()) + Err(CheckErrorKind::TypeSignatureTooDeep.into()) } else { Ok(Value::Response(ResponseData { committed: false, @@ -977,7 +979,7 @@ impl Value { .map(|(value, _did_sanitize)| value) }) .collect(); - let list_data = list_data_opt.ok_or_else(|| CheckErrors::ListTypesMustMatch)?; + let list_data = list_data_opt.ok_or_else(|| CheckErrorKind::ListTypesMustMatch)?; Ok(Value::Sequence(SequenceData::List(ListData { data: list_data, type_signature: type_sig, @@ -985,7 +987,7 @@ impl Value { } /// # Errors - /// - CheckErrors::ValueTooLarge if `buff_data` is too large. + /// - CheckErrorKind::ValueTooLarge if `buff_data` is too large. pub fn buff_from(buff_data: Vec) -> Result { // check the buffer size BufferLength::try_from(buff_data.len())?; @@ -1005,7 +1007,7 @@ impl Value { for b in bytes.iter() { if !b.is_ascii_alphanumeric() && !b.is_ascii_punctuation() && !b.is_ascii_whitespace() { - return Err(CheckErrors::InvalidCharactersDetected.into()); + return Err(CheckErrorKind::InvalidCharactersDetected.into()); } } // construct the string @@ -1028,8 +1030,8 @@ impl Value { let scalar_value = window[matched.start()..matched.end()].to_string(); let unicode_char = { let u = u32::from_str_radix(&scalar_value, 16) - .map_err(|_| CheckErrors::InvalidUTF8Encoding)?; - let c = char::from_u32(u).ok_or_else(|| CheckErrors::InvalidUTF8Encoding)?; + .map_err(|_| CheckErrorKind::InvalidUTF8Encoding)?; + let c = char::from_u32(u).ok_or_else(|| CheckErrorKind::InvalidUTF8Encoding)?; let mut encoded_char: Vec = vec![0; c.len_utf8()]; c.encode_utf8(&mut encoded_char[..]); encoded_char @@ -1056,7 +1058,7 @@ impl Value { pub fn string_utf8_from_bytes(bytes: Vec) -> Result { let validated_utf8_str = match str::from_utf8(&bytes) { Ok(string) => string, - _ => return Err(CheckErrors::InvalidCharactersDetected.into()), + _ => return Err(CheckErrorKind::InvalidCharactersDetected.into()), }; let data = validated_utf8_str .chars() @@ -1269,7 +1271,7 @@ impl ListData { let max_len = self.type_signature.get_max_len() + other_seq.type_signature.get_max_len(); for item in other_seq.data.into_iter() { let (item, _) = Value::sanitize_value(epoch, &entry_type, item) - .ok_or_else(|| CheckErrors::ListTypesMustMatch)?; + .ok_or_else(|| CheckErrorKind::ListTypesMustMatch)?; self.data.push(item); } @@ -1556,7 +1558,9 @@ impl TupleData { let entry = type_map.entry(name.clone()); match entry { Entry::Vacant(e) => e.insert(type_info), - Entry::Occupied(_) => return Err(CheckErrors::NameAlreadyUsed(name.into()).into()), + Entry::Occupied(_) => { + return Err(CheckErrorKind::NameAlreadyUsed(name.into()).into()); + } }; data_map.insert(name, value); } @@ -1586,13 +1590,13 @@ impl TupleData { pub fn get(&self, name: &str) -> Result<&Value> { self.data_map.get(name).ok_or_else(|| { - CheckErrors::NoSuchTupleField(name.to_string(), self.type_signature.clone()).into() + CheckErrorKind::NoSuchTupleField(name.to_string(), self.type_signature.clone()).into() }) } pub fn get_owned(mut self, name: &str) -> Result { self.data_map.remove(name).ok_or_else(|| { - CheckErrors::NoSuchTupleField(name.to_string(), self.type_signature.clone()).into() + CheckErrorKind::NoSuchTupleField(name.to_string(), self.type_signature.clone()).into() }) } diff --git a/clarity-types/src/types/serialization.rs b/clarity-types/src/types/serialization.rs index 2179efd824..d0e5ff5972 100644 --- a/clarity-types/src/types/serialization.rs +++ b/clarity-types/src/types/serialization.rs @@ -23,7 +23,7 @@ use stacks_common::util::hash::{hex_bytes, to_hex}; use stacks_common::util::retry::BoundReader; use super::{ListTypeData, TupleTypeSignature}; -use crate::errors::{CheckErrors, IncomparableError, InterpreterError}; +use crate::errors::{CheckErrorKind, IncomparableError, InterpreterError}; use crate::representations::{ClarityName, ContractName, MAX_STRING_LEN}; use crate::types::{ BOUND_VALUE_SERIALIZATION_BYTES, BufferLength, CallableData, CharType, MAX_TYPE_DEPTH, @@ -40,7 +40,7 @@ use crate::types::{ #[derive(Debug, PartialEq)] pub enum SerializationError { IOError(IncomparableError), - BadTypeError(CheckErrors), + BadTypeError(CheckErrorKind), DeserializationError(String), DeserializeExpected(Box), LeftoverBytesInDeserialization, @@ -122,8 +122,8 @@ impl From<&str> for SerializationError { } } -impl From for SerializationError { - fn from(e: CheckErrors) -> Self { +impl From for SerializationError { + fn from(e: CheckErrorKind) -> Self { SerializationError::BadTypeError(e) } } @@ -394,7 +394,7 @@ impl TypeSignature { /// size of a `(buff 1024*1024)` is `1+1024*1024` because of the /// type prefix byte. However, that is 1 byte larger than the maximum /// buffer size in Clarity. - pub fn max_serialized_size(&self) -> Result { + pub fn max_serialized_size(&self) -> Result { let type_prefix_size = 1; let max_output_size = match self { @@ -405,7 +405,7 @@ impl TypeSignature { // `some` or similar with `result` types). So, when // serializing an object with a `NoType`, the other // branch should always be used. - return Err(CheckErrors::CouldNotDetermineSerializationType); + return Err(CheckErrorKind::CouldNotDetermineSerializationType); } TypeSignature::IntType => 16, TypeSignature::UIntType => 16, @@ -417,14 +417,14 @@ impl TypeSignature { .get_max_len() .checked_mul(list_type.get_list_item_type().max_serialized_size()?) .and_then(|x| x.checked_add(list_length_encode)) - .ok_or_else(|| CheckErrors::ValueTooLarge)? + .ok_or_else(|| CheckErrorKind::ValueTooLarge)? } TypeSignature::SequenceType(SequenceSubtype::BufferType(buff_length)) => { // u32 length as big-endian bytes let buff_length_encode = 4; u32::from(buff_length) .checked_add(buff_length_encode) - .ok_or_else(|| CheckErrors::ValueTooLarge)? + .ok_or_else(|| CheckErrorKind::ValueTooLarge)? } TypeSignature::SequenceType(SequenceSubtype::StringType(StringSubtype::ASCII( length, @@ -434,7 +434,7 @@ impl TypeSignature { // ascii is 1-byte per character u32::from(length) .checked_add(str_length_encode) - .ok_or_else(|| CheckErrors::ValueTooLarge)? + .ok_or_else(|| CheckErrorKind::ValueTooLarge)? } TypeSignature::SequenceType(SequenceSubtype::StringType(StringSubtype::UTF8( length, @@ -445,7 +445,7 @@ impl TypeSignature { u32::from(length) .checked_mul(4) .and_then(|x| x.checked_add(str_length_encode)) - .ok_or_else(|| CheckErrors::ValueTooLarge)? + .ok_or_else(|| CheckErrorKind::ValueTooLarge)? } TypeSignature::PrincipalType | TypeSignature::CallableType(_) @@ -468,7 +468,7 @@ impl TypeSignature { .checked_add(1) // length of key-name .and_then(|x| x.checked_add(key.len() as u32)) // ClarityName is ascii-only, so 1 byte per length .and_then(|x| x.checked_add(value_size)) - .ok_or_else(|| CheckErrors::ValueTooLarge)?; + .ok_or_else(|| CheckErrorKind::ValueTooLarge)?; } total_size } @@ -477,7 +477,7 @@ impl TypeSignature { Ok(size) => size, // if NoType, then this is just serializing a none // value, which is only the type prefix - Err(CheckErrors::CouldNotDetermineSerializationType) => 0, + Err(CheckErrorKind::CouldNotDetermineSerializationType) => 0, Err(e) => return Err(e), } } @@ -485,17 +485,17 @@ impl TypeSignature { let (ok_type, err_type) = response_types.as_ref(); let (ok_type_max_size, no_ok_type) = match ok_type.max_serialized_size() { Ok(size) => (size, false), - Err(CheckErrors::CouldNotDetermineSerializationType) => (0, true), + Err(CheckErrorKind::CouldNotDetermineSerializationType) => (0, true), Err(e) => return Err(e), }; let err_type_max_size = match err_type.max_serialized_size() { Ok(size) => size, - Err(CheckErrors::CouldNotDetermineSerializationType) => { + Err(CheckErrorKind::CouldNotDetermineSerializationType) => { if no_ok_type { // if both the ok type and the error type are NoType, // throw a CheckError. This should not be possible, but the check // is done out of caution. - return Err(CheckErrors::CouldNotDetermineSerializationType); + return Err(CheckErrorKind::CouldNotDetermineSerializationType); } else { 0 } @@ -505,13 +505,13 @@ impl TypeSignature { cmp::max(ok_type_max_size, err_type_max_size) } TypeSignature::ListUnionType(_) => { - return Err(CheckErrors::CouldNotDetermineSerializationType); + return Err(CheckErrorKind::CouldNotDetermineSerializationType); } }; max_output_size .checked_add(type_prefix_size) - .ok_or_else(|| CheckErrors::ValueTooLarge) + .ok_or_else(|| CheckErrorKind::ValueTooLarge) } } @@ -583,7 +583,7 @@ impl Value { UNSANITIZED_DEPTH_CHECK }; if stack.len() > depth_check { - return Err(CheckErrors::TypeSignatureTooDeep.into()); + return Err(CheckErrorKind::TypeSignatureTooDeep.into()); } #[allow(clippy::expect_used)] diff --git a/clarity-types/src/types/signatures.rs b/clarity-types/src/types/signatures.rs index a8e49b92f9..3fd0ee57cb 100644 --- a/clarity-types/src/types/signatures.rs +++ b/clarity-types/src/types/signatures.rs @@ -23,7 +23,7 @@ use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; use stacks_common::types::StacksEpochId; -use crate::errors::CheckErrors; +use crate::errors::CheckErrorKind; use crate::representations::{CONTRACT_MAX_NAME_LENGTH, ClarityName, ContractName}; use crate::types::{ CharType, MAX_TYPE_DEPTH, MAX_VALUE_SIZE, PrincipalData, QualifiedContractIdentifier, @@ -150,7 +150,7 @@ pub enum SequenceSubtype { } impl SequenceSubtype { - pub fn unit_type(&self) -> Result { + pub fn unit_type(&self) -> Result { match &self { SequenceSubtype::ListType(list_data) => Ok(list_data.clone().destruct().0), SequenceSubtype::BufferType(_) => TypeSignature::min_buffer(), @@ -296,10 +296,10 @@ impl From for u32 { } impl TryFrom for BufferLength { - type Error = CheckErrors; - fn try_from(data: u32) -> Result { + type Error = CheckErrorKind; + fn try_from(data: u32) -> Result { if data > MAX_VALUE_SIZE { - Err(CheckErrors::ValueTooLarge) + Err(CheckErrorKind::ValueTooLarge) } else { Ok(BufferLength(data)) } @@ -307,10 +307,10 @@ impl TryFrom for BufferLength { } impl TryFrom for BufferLength { - type Error = CheckErrors; - fn try_from(data: usize) -> Result { + type Error = CheckErrorKind; + fn try_from(data: usize) -> Result { if data > (MAX_VALUE_SIZE as usize) { - Err(CheckErrors::ValueTooLarge) + Err(CheckErrorKind::ValueTooLarge) } else { Ok(BufferLength(data as u32)) } @@ -318,12 +318,12 @@ impl TryFrom for BufferLength { } impl TryFrom for BufferLength { - type Error = CheckErrors; - fn try_from(data: i128) -> Result { + type Error = CheckErrorKind; + fn try_from(data: i128) -> Result { if data > (MAX_VALUE_SIZE as i128) { - Err(CheckErrors::ValueTooLarge) + Err(CheckErrorKind::ValueTooLarge) } else if data < 0 { - Err(CheckErrors::ValueOutOfBounds) + Err(CheckErrorKind::ValueOutOfBounds) } else { Ok(BufferLength(data as u32)) } @@ -343,13 +343,13 @@ impl From for u32 { } impl TryFrom for StringUTF8Length { - type Error = CheckErrors; - fn try_from(data: u32) -> Result { + type Error = CheckErrorKind; + fn try_from(data: u32) -> Result { let len = data .checked_mul(4) - .ok_or_else(|| CheckErrors::ValueTooLarge)?; + .ok_or_else(|| CheckErrorKind::ValueTooLarge)?; if len > MAX_VALUE_SIZE { - Err(CheckErrors::ValueTooLarge) + Err(CheckErrorKind::ValueTooLarge) } else { Ok(StringUTF8Length(data)) } @@ -357,13 +357,13 @@ impl TryFrom for StringUTF8Length { } impl TryFrom for StringUTF8Length { - type Error = CheckErrors; - fn try_from(data: usize) -> Result { + type Error = CheckErrorKind; + fn try_from(data: usize) -> Result { let len = data .checked_mul(4) - .ok_or_else(|| CheckErrors::ValueTooLarge)?; + .ok_or_else(|| CheckErrorKind::ValueTooLarge)?; if len > (MAX_VALUE_SIZE as usize) { - Err(CheckErrors::ValueTooLarge) + Err(CheckErrorKind::ValueTooLarge) } else { Ok(StringUTF8Length(data as u32)) } @@ -371,15 +371,15 @@ impl TryFrom for StringUTF8Length { } impl TryFrom for StringUTF8Length { - type Error = CheckErrors; - fn try_from(data: i128) -> Result { + type Error = CheckErrorKind; + fn try_from(data: i128) -> Result { let len = data .checked_mul(4) - .ok_or_else(|| CheckErrors::ValueTooLarge)?; + .ok_or_else(|| CheckErrorKind::ValueTooLarge)?; if len > (MAX_VALUE_SIZE as i128) { - Err(CheckErrors::ValueTooLarge) + Err(CheckErrorKind::ValueTooLarge) } else if data < 0 { - Err(CheckErrors::ValueOutOfBounds) + Err(CheckErrorKind::ValueOutOfBounds) } else { Ok(StringUTF8Length(data as u32)) } @@ -387,10 +387,13 @@ impl TryFrom for StringUTF8Length { } impl ListTypeData { - pub fn new_list(entry_type: TypeSignature, max_len: u32) -> Result { + pub fn new_list( + entry_type: TypeSignature, + max_len: u32, + ) -> Result { let would_be_depth = 1 + entry_type.depth(); if would_be_depth > MAX_TYPE_DEPTH { - return Err(CheckErrors::TypeSignatureTooDeep); + return Err(CheckErrorKind::TypeSignatureTooDeep); } let list_data = ListTypeData { @@ -399,9 +402,9 @@ impl ListTypeData { }; let would_be_size = list_data .inner_size()? - .ok_or_else(|| CheckErrors::ValueTooLarge)?; + .ok_or_else(|| CheckErrorKind::ValueTooLarge)?; if would_be_size > MAX_VALUE_SIZE { - Err(CheckErrors::ValueTooLarge) + Err(CheckErrorKind::ValueTooLarge) } else { Ok(list_data) } @@ -429,13 +432,13 @@ impl ListTypeData { } impl TypeSignature { - pub fn new_option(inner_type: TypeSignature) -> Result { + pub fn new_option(inner_type: TypeSignature) -> Result { let new_size = WRAPPER_VALUE_SIZE + inner_type.size()?; let new_depth = 1 + inner_type.depth(); if new_size > MAX_VALUE_SIZE { - Err(CheckErrors::ValueTooLarge) + Err(CheckErrorKind::ValueTooLarge) } else if new_depth > MAX_TYPE_DEPTH { - Err(CheckErrors::TypeSignatureTooDeep) + Err(CheckErrorKind::TypeSignatureTooDeep) } else { Ok(OptionalType(Box::new(inner_type))) } @@ -444,27 +447,27 @@ impl TypeSignature { pub fn new_response( ok_type: TypeSignature, err_type: TypeSignature, - ) -> Result { + ) -> Result { let new_size = WRAPPER_VALUE_SIZE + cmp::max(ok_type.size()?, err_type.size()?); let new_depth = 1 + cmp::max(ok_type.depth(), err_type.depth()); if new_size > MAX_VALUE_SIZE { - Err(CheckErrors::ValueTooLarge) + Err(CheckErrorKind::ValueTooLarge) } else if new_depth > MAX_TYPE_DEPTH { - Err(CheckErrors::TypeSignatureTooDeep) + Err(CheckErrorKind::TypeSignatureTooDeep) } else { Ok(ResponseType(Box::new((ok_type, err_type)))) } } - pub fn new_string_ascii(len: usize) -> Result { + pub fn new_string_ascii(len: usize) -> Result { let len = BufferLength::try_from(len)?; Ok(TypeSignature::SequenceType(SequenceSubtype::StringType( StringSubtype::ASCII(len), ))) } - pub fn new_string_utf8(len: usize) -> Result { + pub fn new_string_utf8(len: usize) -> Result { let len = StringUTF8Length::try_from(len)?; Ok(TypeSignature::SequenceType(SequenceSubtype::StringType( StringSubtype::UTF8(len), @@ -479,7 +482,7 @@ impl TypeSignature { &TypeSignature::NoType == self } - pub fn admits(&self, epoch: &StacksEpochId, x: &Value) -> Result { + pub fn admits(&self, epoch: &StacksEpochId, x: &Value) -> Result { let x_type = TypeSignature::type_of(x)?; self.admits_type(epoch, &x_type) } @@ -488,7 +491,7 @@ impl TypeSignature { &self, epoch: &StacksEpochId, other: &TypeSignature, - ) -> Result { + ) -> Result { match epoch { StacksEpochId::Epoch20 | StacksEpochId::Epoch2_05 => self.admits_type_v2_0(other), StacksEpochId::Epoch21 @@ -500,11 +503,13 @@ impl TypeSignature { | StacksEpochId::Epoch31 | StacksEpochId::Epoch32 | StacksEpochId::Epoch33 => self.admits_type_v2_1(other), - StacksEpochId::Epoch10 => Err(CheckErrors::Expects("epoch 1.0 not supported".into())), + StacksEpochId::Epoch10 => { + Err(CheckErrorKind::Expects("epoch 1.0 not supported".into())) + } } } - pub fn admits_type_v2_0(&self, other: &TypeSignature) -> Result { + pub fn admits_type_v2_0(&self, other: &TypeSignature) -> Result { match self { SequenceType(SequenceSubtype::ListType(my_list_type)) => { if let SequenceType(SequenceSubtype::ListType(other_list_type)) = other { @@ -586,18 +591,18 @@ impl TypeSignature { Ok(false) } } - NoType => Err(CheckErrors::CouldNotDetermineType), - CallableType(_) => Err(CheckErrors::Expects( + NoType => Err(CheckErrorKind::CouldNotDetermineType), + CallableType(_) => Err(CheckErrorKind::Expects( "CallableType should not be used in epoch v2.0".into(), )), - ListUnionType(_) => Err(CheckErrors::Expects( + ListUnionType(_) => Err(CheckErrorKind::Expects( "ListUnionType should not be used in epoch v2.0".into(), )), _ => Ok(other == self), } } - fn admits_type_v2_1(&self, other: &TypeSignature) -> Result { + fn admits_type_v2_1(&self, other: &TypeSignature) -> Result { let other = match other.concretize() { Ok(other) => other, Err(_) => { @@ -686,7 +691,7 @@ impl TypeSignature { Ok(false) } } - NoType => Err(CheckErrors::CouldNotDetermineType), + NoType => Err(CheckErrorKind::CouldNotDetermineType), _ => Ok(&other == self), } } @@ -743,7 +748,7 @@ impl TypeSignature { /// Concretize the type. The input to this method may include /// `ListUnionType` and the `CallableType` variant for a `principal. /// This method turns these "temporary" types into actual types. - pub fn concretize(&self) -> Result { + pub fn concretize(&self) -> Result { match self { ListUnionType(types) => { let mut is_trait = None; @@ -752,7 +757,7 @@ impl TypeSignature { match partial { CallableSubtype::Principal(_) => { if is_trait.is_some() { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(TypeSignature::CallableType(partial.clone())), Box::new(TypeSignature::PrincipalType), )); @@ -762,7 +767,7 @@ impl TypeSignature { } CallableSubtype::Trait(t) => { if is_principal { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::CallableType(partial.clone())), )); @@ -785,12 +790,12 @@ impl TypeSignature { } impl TryFrom> for TupleTypeSignature { - type Error = CheckErrors; + type Error = CheckErrorKind; fn try_from( type_data: Vec<(ClarityName, TypeSignature)>, - ) -> Result { + ) -> Result { if type_data.is_empty() { - return Err(CheckErrors::EmptyTuplesNotAllowed); + return Err(CheckErrorKind::EmptyTuplesNotAllowed); } let mut type_map = BTreeMap::new(); @@ -798,7 +803,7 @@ impl TryFrom> for TupleTypeSignature { if let Entry::Vacant(e) = type_map.entry(name.clone()) { e.insert(type_info); } else { - return Err(CheckErrors::NameAlreadyUsed(name.into())); + return Err(CheckErrorKind::NameAlreadyUsed(name.into())); } } TupleTypeSignature::try_from(type_map) @@ -806,25 +811,25 @@ impl TryFrom> for TupleTypeSignature { } impl TryFrom> for TupleTypeSignature { - type Error = CheckErrors; + type Error = CheckErrorKind; fn try_from( type_map: BTreeMap, - ) -> Result { + ) -> Result { if type_map.is_empty() { - return Err(CheckErrors::EmptyTuplesNotAllowed); + return Err(CheckErrorKind::EmptyTuplesNotAllowed); } for child_sig in type_map.values() { if (1 + child_sig.depth()) > MAX_TYPE_DEPTH { - return Err(CheckErrors::TypeSignatureTooDeep); + return Err(CheckErrorKind::TypeSignatureTooDeep); } } let type_map = Arc::new(type_map.into_iter().collect()); let result = TupleTypeSignature { type_map }; let would_be_size = result .inner_size()? - .ok_or_else(|| CheckErrors::ValueTooLarge)?; + .ok_or_else(|| CheckErrorKind::ValueTooLarge)?; if would_be_size > MAX_VALUE_SIZE { - Err(CheckErrors::ValueTooLarge) + Err(CheckErrorKind::ValueTooLarge) } else { Ok(result) } @@ -854,7 +859,7 @@ impl TupleTypeSignature { &self, epoch: &StacksEpochId, other: &TupleTypeSignature, - ) -> Result { + ) -> Result { if self.type_map.len() != other.type_map.len() { return Ok(false); } @@ -878,78 +883,78 @@ impl TupleTypeSignature { } impl TypeSignature { - pub fn empty_buffer() -> Result { + pub fn empty_buffer() -> Result { Ok(SequenceType(SequenceSubtype::BufferType( 0_u32.try_into().map_err(|_| { - CheckErrors::Expects("FAIL: Empty clarity value size is not realizable".into()) + CheckErrorKind::Expects("FAIL: Empty clarity value size is not realizable".into()) })?, ))) } - pub fn min_buffer() -> Result { + pub fn min_buffer() -> Result { Ok(SequenceType(SequenceSubtype::BufferType( 1_u32.try_into().map_err(|_| { - CheckErrors::Expects("FAIL: Min clarity value size is not realizable".into()) + CheckErrorKind::Expects("FAIL: Min clarity value size is not realizable".into()) })?, ))) } - pub fn min_string_ascii() -> Result { + pub fn min_string_ascii() -> Result { Ok(SequenceType(SequenceSubtype::StringType( StringSubtype::ASCII(1_u32.try_into().map_err(|_| { - CheckErrors::Expects("FAIL: Min clarity value size is not realizable".into()) + CheckErrorKind::Expects("FAIL: Min clarity value size is not realizable".into()) })?), ))) } - pub fn min_string_utf8() -> Result { + pub fn min_string_utf8() -> Result { Ok(SequenceType(SequenceSubtype::StringType( StringSubtype::UTF8(1_u32.try_into().map_err(|_| { - CheckErrors::Expects("FAIL: Min clarity value size is not realizable".into()) + CheckErrorKind::Expects("FAIL: Min clarity value size is not realizable".into()) })?), ))) } - pub fn max_string_ascii() -> Result { + pub fn max_string_ascii() -> Result { Ok(SequenceType(SequenceSubtype::StringType( StringSubtype::ASCII(BufferLength::try_from(MAX_VALUE_SIZE).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: Max Clarity Value Size is no longer realizable in ASCII Type".into(), ) })?), ))) } - pub fn max_string_utf8() -> Result { + pub fn max_string_utf8() -> Result { Ok(SequenceType(SequenceSubtype::StringType( StringSubtype::UTF8(StringUTF8Length::try_from(MAX_VALUE_SIZE / 4).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: Max Clarity Value Size is no longer realizable in UTF8 Type".into(), ) })?), ))) } - pub fn max_buffer() -> Result { + pub fn max_buffer() -> Result { Ok(SequenceType(SequenceSubtype::BufferType( BufferLength::try_from(MAX_VALUE_SIZE).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: Max Clarity Value Size is no longer realizable in Buffer Type".into(), ) })?, ))) } - pub fn contract_name_string_ascii_type() -> Result { + pub fn contract_name_string_ascii_type() -> Result { TypeSignature::bound_string_ascii_type(CONTRACT_MAX_NAME_LENGTH.try_into().map_err( - |_| CheckErrors::Expects("FAIL: contract name max length exceeds u32 space".into()), + |_| CheckErrorKind::Expects("FAIL: contract name max length exceeds u32 space".into()), )?) } - pub fn bound_string_ascii_type(max_len: u32) -> Result { + pub fn bound_string_ascii_type(max_len: u32) -> Result { Ok(SequenceType(SequenceSubtype::StringType( StringSubtype::ASCII(BufferLength::try_from(max_len).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: Max Clarity Value Size is no longer realizable in ASCII Type".into(), ) })?), @@ -961,7 +966,7 @@ impl TypeSignature { epoch: &StacksEpochId, a: &TypeSignature, b: &TypeSignature, - ) -> Result { + ) -> Result { if a.is_no_type() { Ok(b.clone()) } else if b.is_no_type() { @@ -1012,7 +1017,7 @@ impl TypeSignature { epoch: &StacksEpochId, a: &TypeSignature, b: &TypeSignature, - ) -> Result { + ) -> Result { match epoch { StacksEpochId::Epoch20 | StacksEpochId::Epoch2_05 => Self::least_supertype_v2_0(a, b), StacksEpochId::Epoch21 @@ -1024,14 +1029,16 @@ impl TypeSignature { | StacksEpochId::Epoch31 | StacksEpochId::Epoch32 | StacksEpochId::Epoch33 => Self::least_supertype_v2_1(a, b), - StacksEpochId::Epoch10 => Err(CheckErrors::Expects("epoch 1.0 not supported".into())), + StacksEpochId::Epoch10 => { + Err(CheckErrorKind::Expects("epoch 1.0 not supported".into())) + } } } pub fn least_supertype_v2_0( a: &TypeSignature, b: &TypeSignature, - ) -> Result { + ) -> Result { match (a, b) { ( TupleType(TupleTypeSignature { type_map: types_a }), @@ -1039,7 +1046,7 @@ impl TypeSignature { ) => { let mut type_map_out = BTreeMap::new(); for (name, entry_a) in types_a.iter() { - let entry_b = types_b.get(name).ok_or(CheckErrors::TypeError( + let entry_b = types_b.get(name).ok_or(CheckErrorKind::TypeError( Box::new(a.clone()), Box::new(b.clone()), ))?; @@ -1048,7 +1055,7 @@ impl TypeSignature { } Ok(TupleTypeSignature::try_from(type_map_out) .map(|x| x.into()) - .map_err(|_| CheckErrors::SupertypeTooLarge)?) + .map_err(|_| CheckErrorKind::SupertypeTooLarge)?) } ( SequenceType(SequenceSubtype::ListType(ListTypeData { @@ -1069,7 +1076,7 @@ impl TypeSignature { }; let max_len = cmp::max(len_a, len_b); Ok(Self::list_of(entry_type, *max_len) - .map_err(|_| CheckErrors::SupertypeTooLarge)?) + .map_err(|_| CheckErrorKind::SupertypeTooLarge)?) } (ResponseType(resp_a), ResponseType(resp_b)) => { let ok_type = @@ -1128,7 +1135,7 @@ impl TypeSignature { if x == y { Ok(x.clone()) } else { - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(a.clone()), Box::new(b.clone()), )) @@ -1140,7 +1147,7 @@ impl TypeSignature { pub fn least_supertype_v2_1( a: &TypeSignature, b: &TypeSignature, - ) -> Result { + ) -> Result { match (a, b) { ( TupleType(TupleTypeSignature { type_map: types_a }), @@ -1148,7 +1155,7 @@ impl TypeSignature { ) => { let mut type_map_out = BTreeMap::new(); for (name, entry_a) in types_a.iter() { - let entry_b = types_b.get(name).ok_or(CheckErrors::TypeError( + let entry_b = types_b.get(name).ok_or(CheckErrorKind::TypeError( Box::new(a.clone()), Box::new(b.clone()), ))?; @@ -1157,7 +1164,7 @@ impl TypeSignature { } Ok(TupleTypeSignature::try_from(type_map_out) .map(|x| x.into()) - .map_err(|_| CheckErrors::SupertypeTooLarge)?) + .map_err(|_| CheckErrorKind::SupertypeTooLarge)?) } ( SequenceType(SequenceSubtype::ListType(ListTypeData { @@ -1178,7 +1185,7 @@ impl TypeSignature { }; let max_len = cmp::max(len_a, len_b); Ok(Self::list_of(entry_type, *max_len) - .map_err(|_| CheckErrors::SupertypeTooLarge)?) + .map_err(|_| CheckErrorKind::SupertypeTooLarge)?) } (ResponseType(resp_a), ResponseType(resp_b)) => { let ok_type = @@ -1259,7 +1266,7 @@ impl TypeSignature { if all_principals { Ok(PrincipalType) } else { - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(a.clone()), Box::new(b.clone()), )) @@ -1272,7 +1279,7 @@ impl TypeSignature { if x == y { Ok(x.clone()) } else { - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(a.clone()), Box::new(b.clone()), )) @@ -1281,7 +1288,10 @@ impl TypeSignature { } } - pub fn list_of(item_type: TypeSignature, max_len: u32) -> Result { + pub fn list_of( + item_type: TypeSignature, + max_len: u32, + ) -> Result { ListTypeData::new_list(item_type, max_len).map(|x| x.into()) } @@ -1292,7 +1302,7 @@ impl TypeSignature { } } - pub fn type_of(x: &Value) -> Result { + pub fn type_of(x: &Value) -> Result { let out = match x { Value::Principal(_) => PrincipalType, Value::Int(_v) => IntType, @@ -1321,7 +1331,7 @@ impl TypeSignature { Ok(out) } - pub fn literal_type_of(x: &Value) -> Result { + pub fn literal_type_of(x: &Value) -> Result { match x { Value::Principal(PrincipalData::Contract(contract_id)) => Ok(CallableType( CallableSubtype::Principal(contract_id.clone()), @@ -1331,19 +1341,19 @@ impl TypeSignature { } // Checks if resulting type signature is of valid size. - pub fn construct_parent_list_type(args: &[Value]) -> Result { - let children_types: Result, CheckErrors> = + pub fn construct_parent_list_type(args: &[Value]) -> Result { + let children_types: Result, CheckErrorKind> = args.iter().map(TypeSignature::type_of).collect(); TypeSignature::parent_list_type(&children_types?) } - pub fn parent_list_type(children: &[TypeSignature]) -> Result { + pub fn parent_list_type(children: &[TypeSignature]) -> Result { if let Some((first, rest)) = children.split_first() { let mut current_entry_type = first.clone(); for next_entry in rest.iter() { current_entry_type = Self::least_supertype_v2_1(¤t_entry_type, next_entry)?; } - let len = u32::try_from(children.len()).map_err(|_| CheckErrors::ValueTooLarge)?; + let len = u32::try_from(children.len()).map_err(|_| CheckErrorKind::ValueTooLarge)?; ListTypeData::new_list(current_entry_type, len) } else { Ok(TypeSignature::empty_list()) @@ -1383,16 +1393,16 @@ impl TypeSignature { } } - pub fn size(&self) -> Result { + pub fn size(&self) -> Result { self.inner_size()?.ok_or_else(|| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: .size() overflowed on too large of a type. construction should have failed!" .into(), ) }) } - fn inner_size(&self) -> Result, CheckErrors> { + fn inner_size(&self) -> Result, CheckErrorKind> { let out = match self { // NoType's may be asked for their size at runtime -- // legal constructions like `(ok 1)` have NoType parts (if they have unknown error variant types). @@ -1425,9 +1435,9 @@ impl TypeSignature { Ok(out) } - pub fn type_size(&self) -> Result { + pub fn type_size(&self) -> Result { self.inner_type_size() - .ok_or_else(|| CheckErrors::ValueTooLarge) + .ok_or_else(|| CheckErrorKind::ValueTooLarge) } /// Returns the size of the _type signature_ @@ -1457,7 +1467,7 @@ impl TypeSignature { impl ListTypeData { /// List Size: type_signature_size + max_len * entry_type.size() - fn inner_size(&self) -> Result, CheckErrors> { + fn inner_size(&self) -> Result, CheckErrorKind> { let total_size = self .entry_type .size()? @@ -1506,9 +1516,10 @@ impl TupleTypeSignature { } } - pub fn size(&self) -> Result { - self.inner_size()? - .ok_or_else(|| CheckErrors::Expects("size() overflowed on a constructed type.".into())) + pub fn size(&self) -> Result { + self.inner_size()?.ok_or_else(|| { + CheckErrorKind::Expects("size() overflowed on a constructed type.".into()) + }) } fn max_depth(&self) -> u8 { @@ -1522,7 +1533,7 @@ impl TupleTypeSignature { /// Tuple Size: /// size( btreemap ) + type_size /// size( btreemap ) = 2*map.len() + sum(names) + sum(values) - fn inner_size(&self) -> Result, CheckErrors> { + fn inner_size(&self) -> Result, CheckErrorKind> { let Some(mut total_size) = u32::try_from(self.type_map.len()) .ok() .and_then(|x| x.checked_mul(2)) diff --git a/clarity/fuzz/fuzz_targets/fuzz_sanitize.rs b/clarity/fuzz/fuzz_targets/fuzz_sanitize.rs index a4fd207c57..7b509750ab 100644 --- a/clarity/fuzz/fuzz_targets/fuzz_sanitize.rs +++ b/clarity/fuzz/fuzz_targets/fuzz_sanitize.rs @@ -29,7 +29,7 @@ use clarity::vm::ClarityName; use clarity::vm::representations::ContractName; use clarity::vm::types::serialization::SerializationError; use stacks_common::types::StacksEpochId; -use clarity::vm::analysis::CheckErrors; +use clarity::vm::analysis::CheckErrorKind; use clarity::vm::types::StringSubtype; use libfuzzer_sys::arbitrary; @@ -131,9 +131,9 @@ impl arbitrary::Arbitrary<'_> for FuzzClarityValue { } } -pub fn strict_admits(me: &TypeSignature, x: &ClarityValue) -> Result { +pub fn strict_admits(me: &TypeSignature, x: &ClarityValue) -> Result { match me { - TypeSignature::NoType => Err(CheckErrors::CouldNotDetermineType), + TypeSignature::NoType => Err(CheckErrorKind::CouldNotDetermineType), TypeSignature::IntType => match x { ClarityValue::Int(_) => Ok(true), _ => Ok(false), @@ -238,7 +238,7 @@ pub fn strict_admits(me: &TypeSignature, x: &ClarityValue) -> Result Err(CheckErrors::TraitReferenceNotAllowed), + TypeSignature::TraitReferenceType(_) => Err(CheckErrorKind::TraitReferenceNotAllowed), } } @@ -274,7 +274,7 @@ fn fuzz_sanitize(input: ClarityValue) { deserialize_unsanitized.unwrap_err(); } else { let deser_value = match deserialize_unsanitized { - Err(SerializationError::BadTypeError(CheckErrors::TypeSignatureTooDeep)) => { + Err(SerializationError::BadTypeError(CheckErrorKind::TypeSignatureTooDeep)) => { // pre-2.4, deserializer could error on types deeper than a deserialization limit of 16. // with sanitization enabled (a 2.4-gated feature), these serializations are readable. ClarityValue::deserialize_read( @@ -294,7 +294,7 @@ fn fuzz_sanitize(input: ClarityValue) { true ) { Ok(x) => x, - Err(SerializationError::BadTypeError(CheckErrors::TypeSignatureTooDeep)) => { + Err(SerializationError::BadTypeError(CheckErrorKind::TypeSignatureTooDeep)) => { assert!(!did_strict_admit, "Unsanitized inputs may fail to deserialize, but they must have needed sanitization"); // check that the sanitized value *is* readable let serialized = sanitized_value.serialize_to_vec().expect("serialize sanitized"); @@ -303,7 +303,7 @@ fn fuzz_sanitize(input: ClarityValue) { Some(&computed_type), false ) { - Err(SerializationError::BadTypeError(CheckErrors::TypeSignatureTooDeep)) => { + Err(SerializationError::BadTypeError(CheckErrorKind::TypeSignatureTooDeep)) => { // pre-2.4, deserializer could error on legal types deeper than a deserialization limit of 16. // with sanitization enabled (a 2.4-gated feature), these serializations are readable. ClarityValue::deserialize_read( diff --git a/clarity/fuzz/fuzz_targets/fuzz_value_sanitize.rs b/clarity/fuzz/fuzz_targets/fuzz_value_sanitize.rs index 39def41c64..52c983daec 100644 --- a/clarity/fuzz/fuzz_targets/fuzz_value_sanitize.rs +++ b/clarity/fuzz/fuzz_targets/fuzz_value_sanitize.rs @@ -19,7 +19,7 @@ #![no_main] use arbitrary::Arbitrary; -use clarity::vm::analysis::CheckErrors; +use clarity::vm::analysis::CheckErrorKind; use clarity::vm::representations::ContractName; use clarity::vm::types::signatures::SequenceSubtype; use clarity::vm::types::{ @@ -131,9 +131,9 @@ impl arbitrary::Arbitrary<'_> for FuzzClarityValue { } } -pub fn strict_admits(me: &TypeSignature, x: &ClarityValue) -> Result { +pub fn strict_admits(me: &TypeSignature, x: &ClarityValue) -> Result { match me { - TypeSignature::NoType => Err(CheckErrors::CouldNotDetermineType), + TypeSignature::NoType => Err(CheckErrorKind::CouldNotDetermineType), TypeSignature::IntType => match x { ClarityValue::Int(_) => Ok(true), _ => Ok(false), @@ -251,7 +251,7 @@ pub fn strict_admits(me: &TypeSignature, x: &ClarityValue) -> Result Err(CheckErrors::TraitReferenceNotAllowed), + | TypeSignature::TraitReferenceType(_) => Err(CheckErrorKind::TraitReferenceNotAllowed), } } diff --git a/clarity/src/vm/analysis/analysis_db.rs b/clarity/src/vm/analysis/analysis_db.rs index 390d3e9dbe..9930581b54 100644 --- a/clarity/src/vm/analysis/analysis_db.rs +++ b/clarity/src/vm/analysis/analysis_db.rs @@ -20,7 +20,7 @@ use clarity_types::representations::ClarityName; use clarity_types::types::{QualifiedContractIdentifier, TraitIdentifier}; use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::{CheckError, CheckErrors}; +use crate::vm::analysis::errors::{CheckError, CheckErrorKind}; use crate::vm::analysis::type_checker::ContractAnalysis; use crate::vm::database::{ ClarityBackingStore, ClarityDeserializable, ClaritySerializable, RollbackWrapper, @@ -46,16 +46,16 @@ impl<'a> AnalysisDatabase<'a> { pub fn execute(&mut self, f: F) -> Result where F: FnOnce(&mut Self) -> Result, - E: From, + E: From, { self.begin(); let result = f(self).or_else(|e| { self.roll_back() - .map_err(|e| CheckErrors::Expects(format!("{e:?}")))?; + .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")))?; Err(e) })?; self.commit() - .map_err(|e| CheckErrors::Expects(format!("{e:?}")))?; + .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")))?; Ok(result) } @@ -66,13 +66,13 @@ impl<'a> AnalysisDatabase<'a> { pub fn commit(&mut self) -> Result<(), CheckError> { self.store .commit() - .map_err(|e| CheckErrors::Expects(format!("{e:?}")).into()) + .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")).into()) } pub fn roll_back(&mut self) -> Result<(), CheckError> { self.store .rollback() - .map_err(|e| CheckErrors::Expects(format!("{e:?}")).into()) + .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")).into()) } pub fn storage_key() -> &'static str { @@ -108,7 +108,7 @@ impl<'a> AnalysisDatabase<'a> { .flatten() .map(|x| { ContractAnalysis::deserialize(&x).map_err(|_| { - CheckErrors::Expects("Bad data deserialized from DB".into()).into() + CheckErrorKind::Expects("Bad data deserialized from DB".into()).into() }) }) .transpose() @@ -128,7 +128,7 @@ impl<'a> AnalysisDatabase<'a> { .flatten() .map(|x| { ContractAnalysis::deserialize(&x) - .map_err(|_| CheckErrors::Expects("Bad data deserialized from DB".into())) + .map_err(|_| CheckErrorKind::Expects("Bad data deserialized from DB".into())) }) .transpose()? .map(|mut x| { @@ -144,12 +144,14 @@ impl<'a> AnalysisDatabase<'a> { ) -> Result<(), CheckError> { let key = AnalysisDatabase::storage_key(); if self.store.has_metadata_entry(contract_identifier, key) { - return Err(CheckErrors::ContractAlreadyExists(contract_identifier.to_string()).into()); + return Err( + CheckErrorKind::ContractAlreadyExists(contract_identifier.to_string()).into(), + ); } self.store .insert_metadata(contract_identifier, key, &contract.serialize()) - .map_err(|e| CheckErrors::Expects(format!("{e:?}")))?; + .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")))?; Ok(()) } @@ -163,7 +165,9 @@ impl<'a> AnalysisDatabase<'a> { // charges based on the function type size. let contract = self .load_contract_non_canonical(contract_identifier)? - .ok_or(CheckErrors::NoSuchContract(contract_identifier.to_string()))?; + .ok_or(CheckErrorKind::NoSuchContract( + contract_identifier.to_string(), + ))?; Ok(contract.clarity_version) } @@ -179,7 +183,9 @@ impl<'a> AnalysisDatabase<'a> { // charges based on the function type size. let contract = self .load_contract_non_canonical(contract_identifier)? - .ok_or(CheckErrors::NoSuchContract(contract_identifier.to_string()))?; + .ok_or(CheckErrorKind::NoSuchContract( + contract_identifier.to_string(), + ))?; Ok(contract .get_public_function_type(function_name) .map(|x| x.canonicalize(epoch))) @@ -197,7 +203,9 @@ impl<'a> AnalysisDatabase<'a> { // charges based on the function type size. let contract = self .load_contract_non_canonical(contract_identifier)? - .ok_or(CheckErrors::NoSuchContract(contract_identifier.to_string()))?; + .ok_or(CheckErrorKind::NoSuchContract( + contract_identifier.to_string(), + ))?; Ok(contract .get_read_only_function_type(function_name) .map(|x| x.canonicalize(epoch))) @@ -215,7 +223,9 @@ impl<'a> AnalysisDatabase<'a> { // charges based on the function type size. let contract = self .load_contract_non_canonical(contract_identifier)? - .ok_or(CheckErrors::NoSuchContract(contract_identifier.to_string()))?; + .ok_or(CheckErrorKind::NoSuchContract( + contract_identifier.to_string(), + ))?; Ok(contract.get_defined_trait(trait_name).map(|trait_map| { trait_map .iter() @@ -230,7 +240,9 @@ impl<'a> AnalysisDatabase<'a> { ) -> Result, CheckError> { let contract = self .load_contract_non_canonical(contract_identifier)? - .ok_or(CheckErrors::NoSuchContract(contract_identifier.to_string()))?; + .ok_or(CheckErrorKind::NoSuchContract( + contract_identifier.to_string(), + ))?; Ok(contract.implemented_traits) } diff --git a/clarity/src/vm/analysis/arithmetic_checker/mod.rs b/clarity/src/vm/analysis/arithmetic_checker/mod.rs index 83be68ab23..fa8323d6a5 100644 --- a/clarity/src/vm/analysis/arithmetic_checker/mod.rs +++ b/clarity/src/vm/analysis/arithmetic_checker/mod.rs @@ -16,7 +16,9 @@ use clarity_types::representations::ClarityName; -pub use super::errors::{check_argument_count, check_arguments_at_least, CheckError, CheckErrors}; +pub use super::errors::{ + check_argument_count, check_arguments_at_least, CheckError, CheckErrorKind, +}; use crate::vm::analysis::types::ContractAnalysis; use crate::vm::functions::define::{DefineFunctions, DefineFunctionsParsed}; use crate::vm::functions::NativeFunctions; diff --git a/clarity/src/vm/analysis/contract_interface_builder/mod.rs b/clarity/src/vm/analysis/contract_interface_builder/mod.rs index 26c71f695b..3a03578aa0 100644 --- a/clarity/src/vm/analysis/contract_interface_builder/mod.rs +++ b/clarity/src/vm/analysis/contract_interface_builder/mod.rs @@ -24,7 +24,7 @@ use crate::vm::types::signatures::CallableSubtype; use crate::vm::types::{ FixedFunction, FunctionArg, FunctionType, TupleTypeSignature, TypeSignature, }; -use crate::vm::{CheckErrors, ClarityName, ClarityVersion}; +use crate::vm::{CheckErrorKind, ClarityName, ClarityVersion}; pub fn build_contract_interface( contract_analysis: &ContractAnalysis, @@ -278,7 +278,7 @@ impl ContractInterfaceFunction { FunctionType::Fixed(FixedFunction { returns, .. }) => { ContractInterfaceAtomType::from_type_signature(returns) } - _ => return Err(CheckErrors::Expects( + _ => return Err(CheckErrorKind::Expects( "Contract functions should only have fixed function return types!" .into(), ) @@ -290,7 +290,7 @@ impl ContractInterfaceFunction { ContractInterfaceFunctionArg::from_function_args(args) } _ => { - return Err(CheckErrors::Expects( + return Err(CheckErrorKind::Expects( "Contract functions should only have fixed function arguments!" .into(), ) @@ -402,7 +402,7 @@ impl ContractInterface { pub fn serialize(&self) -> Result { serde_json::to_string(self).map_err(|_| { - CheckErrors::Expects("Failed to serialize contract interface".into()).into() + CheckErrorKind::Expects("Failed to serialize contract interface".into()).into() }) } } diff --git a/clarity/src/vm/analysis/errors.rs b/clarity/src/vm/analysis/errors.rs index f7ce7072f3..0ee01d0e57 100644 --- a/clarity/src/vm/analysis/errors.rs +++ b/clarity/src/vm/analysis/errors.rs @@ -16,5 +16,5 @@ pub use clarity_types::errors::analysis::{ check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckError, - CheckErrors, SyntaxBindingError, SyntaxBindingErrorType, + CheckErrorKind, SyntaxBindingError, SyntaxBindingErrorType, }; diff --git a/clarity/src/vm/analysis/mod.rs b/clarity/src/vm/analysis/mod.rs index 404f468609..2ab179c038 100644 --- a/clarity/src/vm/analysis/mod.rs +++ b/clarity/src/vm/analysis/mod.rs @@ -28,7 +28,7 @@ use stacks_common::types::StacksEpochId; pub use self::analysis_db::AnalysisDatabase; use self::arithmetic_checker::ArithmeticOnlyChecker; use self::contract_interface_builder::build_contract_interface; -pub use self::errors::{CheckError, CheckErrors}; +pub use self::errors::{CheckError, CheckErrorKind}; use self::read_only_checker::ReadOnlyChecker; use self::trait_checker::TraitChecker; use self::type_checker::v2_05::TypeChecker as TypeChecker2_05; @@ -62,7 +62,7 @@ pub fn mem_type_check( epoch, ASTRules::PrecheckSize, ) - .map_err(|_| CheckErrors::Expects("Failed to build AST".into()))? + .map_err(|_| CheckErrorKind::Expects("Failed to build AST".into()))? .expressions; let mut marf = MemoryBackingStore::new(); @@ -83,11 +83,11 @@ pub fn mem_type_check( let first_type = x .type_map .as_ref() - .ok_or_else(|| CheckErrors::Expects("Should be non-empty".into()))? + .ok_or_else(|| CheckErrorKind::Expects("Should be non-empty".into()))? .get_type_expected( x.expressions .last() - .ok_or_else(|| CheckErrors::Expects("Should be non-empty".into()))?, + .ok_or_else(|| CheckErrorKind::Expects("Should be non-empty".into()))?, ) .cloned(); Ok((first_type, x)) @@ -158,7 +158,7 @@ pub fn run_analysis( TypeChecker2_1::run_pass(&epoch, &mut contract_analysis, db, build_type_map) } StacksEpochId::Epoch10 => { - return Err(CheckErrors::Expects( + return Err(CheckErrorKind::Expects( "Epoch 1.0 is not a valid epoch for analysis".into(), ) .into()) diff --git a/clarity/src/vm/analysis/read_only_checker/mod.rs b/clarity/src/vm/analysis/read_only_checker/mod.rs index 21b2bbd8f7..273aba52c0 100644 --- a/clarity/src/vm/analysis/read_only_checker/mod.rs +++ b/clarity/src/vm/analysis/read_only_checker/mod.rs @@ -21,7 +21,7 @@ use clarity_types::types::{PrincipalData, Value}; use stacks_common::types::StacksEpochId; pub use super::errors::{ - check_argument_count, check_arguments_at_least, CheckError, CheckErrors, SyntaxBindingError, + check_argument_count, check_arguments_at_least, CheckError, CheckErrorKind, SyntaxBindingError, }; use super::AnalysisDatabase; use crate::vm::analysis::types::{AnalysisPass, ContractAnalysis}; @@ -81,7 +81,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { /// Returns successfully iff this function is read-only correct. /// /// # Errors - /// - `CheckErrors::WriteAttemptedInReadOnly` + /// - `CheckErrorKind::WriteAttemptedInReadOnly` /// - Contract parsing errors pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), CheckError> { // Iterate over all the top-level statements in a contract. @@ -105,7 +105,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { /// Returns successfully iff this function is read-only correct. /// /// # Errors - /// - CheckErrors::WriteAttemptedInReadOnly + /// - CheckErrorKind::WriteAttemptedInReadOnly /// - Contract parsing errors fn check_top_level_expression( &mut self, @@ -135,7 +135,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { let (function_name, is_read_only) = self.check_define_function(signature, body)?; if !is_read_only { - return Err(CheckErrors::WriteAttemptedInReadOnly.into()); + return Err(CheckErrorKind::WriteAttemptedInReadOnly.into()); } else { self.defined_functions.insert(function_name, is_read_only); } @@ -171,9 +171,9 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { ) -> Result<(ClarityName, bool), CheckError> { let function_name = signature .first() - .ok_or(CheckErrors::DefineFunctionBadSignature)? + .ok_or(CheckErrorKind::DefineFunctionBadSignature)? .match_atom() - .ok_or(CheckErrors::BadFunctionName)?; + .ok_or(CheckErrorKind::BadFunctionName)?; let is_read_only = self.check_read_only(body)?; @@ -203,7 +203,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { ReadOnlyFunction { signature, body } => { let (f_name, is_read_only) = self.check_define_function(signature, body)?; if !is_read_only { - return Err(CheckErrors::WriteAttemptedInReadOnly.into()); + return Err(CheckErrorKind::WriteAttemptedInReadOnly.into()); } else { self.defined_functions.insert(f_name, is_read_only); } @@ -310,7 +310,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { let is_block_arg_read_only = self.check_read_only(&args[0])?; let closure_read_only = self.check_read_only(&args[1])?; if !closure_read_only { - return Err(CheckErrors::AtBlockClosureMustBeReadOnly.into()); + return Err(CheckErrorKind::AtBlockClosureMustBeReadOnly.into()); } Ok(is_block_arg_read_only) } @@ -327,7 +327,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { Let => { check_arguments_at_least(2, args)?; - let binding_list = args[0].match_list().ok_or(CheckErrors::BadLetSyntax)?; + let binding_list = args[0].match_list().ok_or(CheckErrorKind::BadLetSyntax)?; for (i, pair) in binding_list.iter().enumerate() { let pair_expression = pair.match_list().ok_or_else(|| { @@ -402,7 +402,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { let function_name = args[1] .match_atom() - .ok_or(CheckErrors::ContractCallExpectName)?; + .ok_or(CheckErrorKind::ContractCallExpectName)?; let is_function_read_only = match &args[0].expr { SymbolicExpressionType::LiteralValue(Value::Principal( @@ -421,7 +421,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { // As such dynamic dispatch is currently forbidden. false } - _ => return Err(CheckError::new(CheckErrors::ContractCallExpectName)), + _ => return Err(CheckError::new(CheckErrorKind::ContractCallExpectName)), }; self.check_each_expression_is_read_only(&args[2..]) @@ -437,20 +437,20 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { /// Returns `true` iff the function application is read-only. /// /// # Errors - /// - `CheckErrors::NonFunctionApplication` if there is no first expression, or if the first + /// - `CheckErrorKind::NonFunctionApplication` if there is no first expression, or if the first /// expression is not a `ClarityName`. - /// - `CheckErrors::UnknownFunction` if the first expression does not name a known function. + /// - `CheckErrorKind::UnknownFunction` if the first expression does not name a known function. fn check_expression_application_is_read_only( &mut self, expressions: &[SymbolicExpression], ) -> Result { let (function_name, args) = expressions .split_first() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; let function_name = function_name .match_atom() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; if let Some(mut result) = self.try_check_native_function_is_read_only(function_name, args) { if let Err(ref mut check_err) = result { @@ -461,7 +461,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { let is_function_read_only = *self .defined_functions .get(function_name) - .ok_or(CheckErrors::UnknownFunction(function_name.to_string()))?; + .ok_or(CheckErrorKind::UnknownFunction(function_name.to_string()))?; self.check_each_expression_is_read_only(args) .map(|args_read_only| args_read_only && is_function_read_only) } diff --git a/clarity/src/vm/analysis/read_only_checker/tests.rs b/clarity/src/vm/analysis/read_only_checker/tests.rs index 585bea62cd..5b985b7b2f 100644 --- a/clarity/src/vm/analysis/read_only_checker/tests.rs +++ b/clarity/src/vm/analysis/read_only_checker/tests.rs @@ -21,7 +21,7 @@ use rstest_reuse::{self, *}; use stacks_common::types::StacksEpochId; use crate::vm::analysis::type_checker::v2_1::tests::mem_type_check; -use crate::vm::analysis::{type_check, CheckErrors}; +use crate::vm::analysis::{type_check, CheckErrorKind}; use crate::vm::ast::parse; use crate::vm::database::MemoryBackingStore; use crate::vm::tests::test_clarity_versions; @@ -34,11 +34,11 @@ fn test_argument_count_violations() { ( "(define-private (foo-bar) (at-block))", - CheckErrors::IncorrectArgumentCount(2, 0), + CheckErrorKind::IncorrectArgumentCount(2, 0), ), ( "(define-private (foo-bar) (map-get?))", - CheckErrors::IncorrectArgumentCount(2, 0), + CheckErrorKind::IncorrectArgumentCount(2, 0), ), ]; @@ -72,7 +72,7 @@ fn test_at_block_violations() { for contract in examples.iter() { let err = mem_type_check(contract).unwrap_err(); eprintln!("{err}"); - assert_eq!(*err.err, CheckErrors::AtBlockClosureMustBeReadOnly) + assert_eq!(*err.err, CheckErrorKind::AtBlockClosureMustBeReadOnly) } } @@ -163,7 +163,7 @@ fn test_simple_read_only_violations() { for contract in bad_contracts.iter() { let err = mem_type_check(contract).unwrap_err(); - assert_eq!(*err.err, CheckErrors::WriteAttemptedInReadOnly) + assert_eq!(*err.err, CheckErrorKind::WriteAttemptedInReadOnly) } } @@ -180,7 +180,7 @@ fn test_nested_writing_closure() { for contract in bad_contracts.iter() { let err = mem_type_check(contract).unwrap_err(); - assert_eq!(*err.err, CheckErrors::AtBlockClosureMustBeReadOnly) + assert_eq!(*err.err, CheckErrorKind::AtBlockClosureMustBeReadOnly) } } @@ -231,7 +231,7 @@ fn test_contract_call_read_only_violations( ) }) .unwrap_err(); - assert_eq!(*err.err, CheckErrors::WriteAttemptedInReadOnly); + assert_eq!(*err.err, CheckErrorKind::WriteAttemptedInReadOnly); db.execute(|db| { type_check( diff --git a/clarity/src/vm/analysis/trait_checker/mod.rs b/clarity/src/vm/analysis/trait_checker/mod.rs index 491fe81c24..0986b8ed1e 100644 --- a/clarity/src/vm/analysis/trait_checker/mod.rs +++ b/clarity/src/vm/analysis/trait_checker/mod.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::{CheckError, CheckErrors}; +use crate::vm::analysis::errors::{CheckError, CheckErrorKind}; use crate::vm::analysis::types::{AnalysisPass, ContractAnalysis}; use crate::vm::analysis::AnalysisDatabase; @@ -49,13 +49,13 @@ impl TraitChecker { let trait_name = trait_identifier.name.to_string(); let contract_defining_trait = analysis_db .load_contract(&trait_identifier.contract_identifier, &self.epoch)? - .ok_or(CheckErrors::TraitReferenceUnknown( + .ok_or(CheckErrorKind::TraitReferenceUnknown( trait_identifier.name.to_string(), ))?; let trait_definition = contract_defining_trait .get_defined_trait(&trait_name) - .ok_or(CheckErrors::TraitReferenceUnknown( + .ok_or(CheckErrorKind::TraitReferenceUnknown( trait_identifier.name.to_string(), ))?; diff --git a/clarity/src/vm/analysis/trait_checker/tests.rs b/clarity/src/vm/analysis/trait_checker/tests.rs index 305781f959..e93f073858 100644 --- a/clarity/src/vm/analysis/trait_checker/tests.rs +++ b/clarity/src/vm/analysis/trait_checker/tests.rs @@ -20,7 +20,7 @@ use rstest::rstest; use rstest_reuse::{self, *}; use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::CheckErrors; +use crate::vm::analysis::errors::CheckErrorKind; use crate::vm::analysis::{type_check, CheckError}; use crate::vm::ast::errors::ParseErrors; use crate::vm::ast::{build_ast, parse}; @@ -98,7 +98,7 @@ fn test_incomplete_impl_trait_1(#[case] version: ClarityVersion, #[case] epoch: }) .unwrap_err(); match *err.err { - CheckErrors::BadTraitImplementation(_, _) => {} + CheckErrorKind::BadTraitImplementation(_, _) => {} _ => panic!("{err:?}"), } } @@ -125,7 +125,7 @@ fn test_incomplete_impl_trait_2(#[case] version: ClarityVersion, #[case] epoch: }) .unwrap_err(); match *err.err { - CheckErrors::BadTraitImplementation(_, _) => {} + CheckErrorKind::BadTraitImplementation(_, _) => {} _ => panic!("{err:?}"), } } @@ -149,7 +149,7 @@ fn test_impl_trait_arg_admission_1(#[case] version: ClarityVersion, #[case] epoc }) .unwrap_err(); match *err.err { - CheckErrors::BadTraitImplementation(_, _) => {} + CheckErrorKind::BadTraitImplementation(_, _) => {} _ => panic!("{err:?}"), } } @@ -289,7 +289,7 @@ fn test_get_trait_reference_from_tuple( }) .unwrap_err(); match *err.err { - CheckErrors::ContractCallExpectName => {} + CheckErrorKind::ContractCallExpectName => {} _ => panic!("{err:?}"), } } @@ -332,7 +332,7 @@ fn test_dynamic_dispatch_by_defining_and_impl_trait( }) .unwrap_err(); match *err.err { - CheckErrors::TraitReferenceUnknown(_) => {} + CheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err:?}"), } } @@ -434,7 +434,7 @@ fn test_cycle_in_traits_2_contracts(#[case] version: ClarityVersion, #[case] epo }) .unwrap_err(); match *err.err { - CheckErrors::NoSuchContract(_) => {} + CheckErrorKind::NoSuchContract(_) => {} _ => panic!("{err:?}"), } } @@ -487,7 +487,7 @@ fn test_dynamic_dispatch_unknown_method( }) .unwrap_err(); match *err.err { - CheckErrors::TraitMethodUnknown(_, _) => {} + CheckErrorKind::TraitMethodUnknown(_, _) => {} _ => panic!("{err:?}"), } } @@ -812,7 +812,7 @@ fn test_dynamic_dispatch_importing_non_existant_trait( }) .unwrap_err(); match *err.err { - CheckErrors::TraitReferenceUnknown(_) => {} + CheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err:?}"), } } @@ -1099,13 +1099,13 @@ fn test_dynamic_dispatch_including_wrong_nested_trait( .unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, actual) if epoch < StacksEpochId::Epoch21 => { + CheckErrorKind::TypeError(expected, actual) if epoch < StacksEpochId::Epoch21 => { match (&*expected, &*actual) { (TypeSignature::TraitReferenceType(_), TypeSignature::TraitReferenceType(_)) => {} _ => panic!("unexpected TypeSignature: {expected:?} {actual:?}"), } } - CheckErrors::TypeError(expected, actual) + CheckErrorKind::TypeError(expected, actual) if epoch >= StacksEpochId::Epoch21 && version < ClarityVersion::Clarity2 => { match (&*expected, &*actual) { @@ -1113,7 +1113,7 @@ fn test_dynamic_dispatch_including_wrong_nested_trait( _ => panic!("unexpected TypeSignature: {expected:?} {actual:?}"), } } - CheckErrors::TraitReferenceUnknown(name) => assert_eq!(name.as_str(), "trait-a"), + CheckErrorKind::TraitReferenceUnknown(name) => assert_eq!(name.as_str(), "trait-a"), _ => panic!("{err:?}"), } } @@ -1167,7 +1167,7 @@ fn test_dynamic_dispatch_mismatched_args( }) .unwrap_err(); match *err.err { - CheckErrors::TypeError(_, _) => {} + CheckErrorKind::TypeError(_, _) => {} _ => panic!("{err:?}"), } } @@ -1221,7 +1221,7 @@ fn test_dynamic_dispatch_mismatched_returns( }) .unwrap_err(); match *err.err { - CheckErrors::BadTraitImplementation(_, _) => {} + CheckErrorKind::BadTraitImplementation(_, _) => {} _ => panic!("{err:?}"), } } @@ -1257,7 +1257,7 @@ fn test_bad_call_with_trait(#[case] version: ClarityVersion, #[case] epoch: Stac }) .unwrap_err(); match *err.err { - CheckErrors::TypeError(_, _) => {} + CheckErrorKind::TypeError(_, _) => {} _ => panic!("{err:?}"), } } @@ -1466,7 +1466,7 @@ fn test_dynamic_dispatch_pass_bound_principal_as_trait_in_user_defined_functions match result { Err(err) if version == ClarityVersion::Clarity1 => { match *err.err { - CheckErrors::TypeError(_, _) => {} + CheckErrorKind::TypeError(_, _) => {} _ => panic!("{err:?}"), }; } @@ -1560,7 +1560,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_principal.err { - CheckErrors::TraitReferenceUnknown(_) => {} + CheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_principal:?}"), } let err_int = db @@ -1570,7 +1570,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_int.err { - CheckErrors::TraitReferenceUnknown(_) => {} + CheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_int:?}"), } let err_uint = db @@ -1580,7 +1580,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_uint.err { - CheckErrors::TraitReferenceUnknown(_) => {} + CheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_uint:?}"), } let err_bool = db @@ -1590,7 +1590,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_bool.err { - CheckErrors::TraitReferenceUnknown(_) => {} + CheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_bool:?}"), } let err_list = db @@ -1600,7 +1600,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_list.err { - CheckErrors::TraitReferenceUnknown(_) => {} + CheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_list:?}"), } let err_buff = db @@ -1610,7 +1610,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_buff.err { - CheckErrors::TraitReferenceUnknown(_) => {} + CheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_buff:?}"), } let err_tuple = db @@ -1620,7 +1620,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_tuple.err { - CheckErrors::TraitReferenceUnknown(_) => {} + CheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_tuple:?}"), } } @@ -1819,7 +1819,7 @@ fn test_trait_contract_not_found(#[case] version: ClarityVersion, #[case] epoch: ) }) { Err(CheckError { err, .. }) if version < ClarityVersion::Clarity2 => match *err { - CheckErrors::NoSuchContract(contract) => { + CheckErrorKind::NoSuchContract(contract) => { assert!(contract.ends_with(".trait-contract")) } _ => panic!("{version}: unexpected NoSuchContract error"), diff --git a/clarity/src/vm/analysis/type_checker/contexts.rs b/clarity/src/vm/analysis/type_checker/contexts.rs index ddc34d8b8b..5eb210657c 100644 --- a/clarity/src/vm/analysis/type_checker/contexts.rs +++ b/clarity/src/vm/analysis/type_checker/contexts.rs @@ -18,7 +18,7 @@ use std::collections::{HashMap, HashSet}; use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::{CheckError, CheckErrors}; +use crate::vm::analysis::errors::{CheckError, CheckErrorKind}; use crate::vm::types::signatures::CallableSubtype; use crate::vm::types::{TraitIdentifier, TypeSignature}; use crate::vm::{ClarityName, ClarityVersion, SymbolicExpression, MAX_CONTEXT_DEPTH}; @@ -68,14 +68,14 @@ impl TypeMap { match self.map { TypeMapDataType::Map(ref mut map) => { if map.insert(expr.id, type_sig).is_some() { - Err(CheckError::new(CheckErrors::TypeAlreadyAnnotatedFailure)) + Err(CheckError::new(CheckErrorKind::TypeAlreadyAnnotatedFailure)) } else { Ok(()) } } TypeMapDataType::Set(ref mut map) => { if !map.insert(expr.id) { - Err(CheckError::new(CheckErrors::TypeAlreadyAnnotatedFailure)) + Err(CheckError::new(CheckErrorKind::TypeAlreadyAnnotatedFailure)) } else { Ok(()) } @@ -105,7 +105,7 @@ impl TypingContext<'_> { pub fn extend(&self) -> Result, CheckError> { if self.depth >= MAX_CONTEXT_DEPTH { - Err(CheckError::new(CheckErrors::MaxContextDepthReached)) + Err(CheckError::new(CheckErrorKind::MaxContextDepthReached)) } else { Ok(TypingContext { epoch: self.epoch, diff --git a/clarity/src/vm/analysis/type_checker/mod.rs b/clarity/src/vm/analysis/type_checker/mod.rs index d33c7c87e6..b893830792 100644 --- a/clarity/src/vm/analysis/type_checker/mod.rs +++ b/clarity/src/vm/analysis/type_checker/mod.rs @@ -20,7 +20,7 @@ pub mod v2_1; use stacks_common::types::StacksEpochId; -use super::errors::{CheckError, CheckErrors}; +use super::errors::{CheckError, CheckErrorKind}; pub use super::types::{AnalysisPass, ContractAnalysis}; use super::AnalysisDatabase; use crate::vm::costs::CostTracker; @@ -49,7 +49,7 @@ impl FunctionType { | StacksEpochId::Epoch32 | StacksEpochId::Epoch33 => self.check_args_2_1(accounting, args, clarity_version), StacksEpochId::Epoch10 => { - Err(CheckErrors::Expects("Epoch10 is not supported".into()).into()) + Err(CheckErrorKind::Expects("Epoch10 is not supported".into()).into()) } } } @@ -77,7 +77,7 @@ impl FunctionType { self.check_args_by_allowing_trait_cast_2_1(db, clarity_version, func_args) } StacksEpochId::Epoch10 => { - Err(CheckErrors::Expects("Epoch10 is not supported".into()).into()) + Err(CheckErrorKind::Expects("Epoch10 is not supported".into()).into()) } } } diff --git a/clarity/src/vm/analysis/type_checker/v2_05/contexts.rs b/clarity/src/vm/analysis/type_checker/v2_05/contexts.rs index d89baac36e..a889304ee6 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/contexts.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/contexts.rs @@ -16,7 +16,7 @@ use std::collections::{BTreeMap, HashMap, HashSet}; -use crate::vm::analysis::errors::{CheckError, CheckErrors}; +use crate::vm::analysis::errors::{CheckError, CheckErrorKind}; use crate::vm::analysis::types::ContractAnalysis; use crate::vm::representations::ClarityName; use crate::vm::types::signatures::FunctionSignature; @@ -67,7 +67,7 @@ impl ContractContext { || self.traits.contains_key(name) || self.map_types.contains_key(name) { - Err(CheckError::new(CheckErrors::NameAlreadyUsed( + Err(CheckError::new(CheckErrorKind::NameAlreadyUsed( name.to_string(), ))) } else { diff --git a/clarity/src/vm/analysis/type_checker/v2_05/mod.rs b/clarity/src/vm/analysis/type_checker/v2_05/mod.rs index 31cf5140dd..7ebb0cb9d0 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/mod.rs @@ -27,7 +27,8 @@ pub use self::natives::{SimpleNativeFunction, TypedNativeFunction}; use super::contexts::{TypeMap, TypingContext}; use super::ContractAnalysis; pub use crate::vm::analysis::errors::{ - check_argument_count, check_arguments_at_least, CheckError, CheckErrors, SyntaxBindingErrorType, + check_argument_count, check_arguments_at_least, CheckError, CheckErrorKind, + SyntaxBindingErrorType, }; use crate::vm::analysis::AnalysisDatabase; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -146,7 +147,7 @@ impl FunctionType { for found_type in args.iter() { analysis_typecheck_cost(accounting, expected_type, found_type)?; if !expected_type.admits_type(&StacksEpochId::Epoch2_05, found_type)? { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(found_type.clone()), ) @@ -164,7 +165,7 @@ impl FunctionType { { analysis_typecheck_cost(accounting, expected_type, found_type)?; if !expected_type.admits_type(&StacksEpochId::Epoch2_05, found_type)? { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(found_type.clone()), ) @@ -183,7 +184,7 @@ impl FunctionType { } } Err( - CheckErrors::UnionTypeError(arg_types.clone(), Box::new(found_type.clone())) + CheckErrorKind::UnionTypeError(arg_types.clone(), Box::new(found_type.clone())) .into(), ) } @@ -198,12 +199,12 @@ impl FunctionType { } let (first, rest) = args .split_first() - .ok_or(CheckErrors::RequiresAtLeastArguments(1, args.len()))?; + .ok_or(CheckErrorKind::RequiresAtLeastArguments(1, args.len()))?; analysis_typecheck_cost(accounting, &TypeSignature::IntType, first)?; let return_type = match first { TypeSignature::IntType => Ok(TypeSignature::IntType), TypeSignature::UIntType => Ok(TypeSignature::UIntType), - _ => Err(CheckErrors::UnionTypeError( + _ => Err(CheckErrorKind::UnionTypeError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(first.clone()), )), @@ -211,7 +212,7 @@ impl FunctionType { for found_type in rest.iter() { analysis_typecheck_cost(accounting, &TypeSignature::IntType, found_type)?; if found_type != &return_type { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(return_type), Box::new(found_type.clone()), ) @@ -227,7 +228,7 @@ impl FunctionType { analysis_typecheck_cost(accounting, &TypeSignature::IntType, second)?; if first != &TypeSignature::IntType && first != &TypeSignature::UIntType { - return Err(CheckErrors::UnionTypeError( + return Err(CheckErrorKind::UnionTypeError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(first.clone()), ) @@ -235,7 +236,7 @@ impl FunctionType { } if first != second { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(first.clone()), Box::new(second.clone()), ) @@ -244,9 +245,10 @@ impl FunctionType { Ok(TypeSignature::BoolType) } - FunctionType::Binary(_, _, _) => { - Err(CheckErrors::Expects("Binary type should not be reached in 2.05".into()).into()) - } + FunctionType::Binary(_, _, _) => Err(CheckErrorKind::Expects( + "Binary type should not be reached in 2.05".into(), + ) + .into()), } } @@ -257,7 +259,7 @@ impl FunctionType { ) -> Result { let (expected_args, returns) = match self { FunctionType::Fixed(FixedFunction { args, returns }) => (args, returns), - _ => return Err(CheckErrors::Expects("Unexpected function type".into()).into()), + _ => return Err(CheckErrorKind::Expects("Unexpected function type".into()).into()), }; check_argument_count(expected_args.len(), func_args)?; @@ -269,7 +271,7 @@ impl FunctionType { ) => { let contract_to_check = db .load_contract(contract, &StacksEpochId::Epoch2_05)? - .ok_or_else(|| CheckErrors::NoSuchContract(contract.name.to_string()))?; + .ok_or_else(|| CheckErrorKind::NoSuchContract(contract.name.to_string()))?; let trait_definition = db .get_defined_trait( &trait_id.contract_identifier, @@ -277,9 +279,9 @@ impl FunctionType { &StacksEpochId::Epoch2_05, ) .map_err(|_| { - CheckErrors::NoSuchContract(trait_id.contract_identifier.to_string()) + CheckErrorKind::NoSuchContract(trait_id.contract_identifier.to_string()) })? - .ok_or(CheckErrors::NoSuchContract( + .ok_or(CheckErrorKind::NoSuchContract( trait_id.contract_identifier.to_string(), ))?; contract_to_check.check_trait_compliance( @@ -291,7 +293,7 @@ impl FunctionType { (expected_type, value) => { if !expected_type.admits(&StacksEpochId::Epoch2_05, value)? { let actual_type = TypeSignature::type_of(value)?; - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type), ) @@ -325,13 +327,13 @@ fn type_reserved_variable(variable_name: &str) -> Result, BlockHeight => TypeSignature::UIntType, BurnBlockHeight => TypeSignature::UIntType, NativeNone => TypeSignature::new_option(no_type()) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, NativeTrue => TypeSignature::BoolType, NativeFalse => TypeSignature::BoolType, TotalLiquidMicroSTX => TypeSignature::UIntType, Regtest => TypeSignature::BoolType, TxSponsor | Mainnet | ChainId | StacksBlockHeight | TenureHeight | BlockTime | CurrentContract => { - return Err(CheckErrors::Expects( + return Err(CheckErrorKind::Expects( "tx-sponsor, mainnet, chain-id, stacks-block-height, tenure-height, block-time, and current-contract should not reach here in 2.05".into(), ) .into()) @@ -388,7 +390,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &return_type, ) .map_err(|_| { - CheckErrors::ReturnTypesMustMatch( + CheckErrorKind::ReturnTypesMustMatch( Box::new(expected_type), Box::new(return_type), ) @@ -419,7 +421,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { } Err(e) => Err(e), })? - .ok_or_else(|| CheckErrors::Expects("Expected a depth result".into()))?; + .ok_or_else(|| CheckErrorKind::Expects("Expected a depth result".into()))?; } runtime_cost(ClarityCostFunction::AnalysisStorage, self, size)?; @@ -458,7 +460,9 @@ impl<'a, 'b> TypeChecker<'a, 'b> { let contract_to_check = self .db .load_contract(contract_identifier, &StacksEpochId::Epoch2_05)? - .ok_or(CheckErrors::NoSuchContract(contract_identifier.to_string()))?; + .ok_or(CheckErrorKind::NoSuchContract( + contract_identifier.to_string(), + ))?; let contract_defining_trait = self .db @@ -466,13 +470,13 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &trait_identifier.contract_identifier, &StacksEpochId::Epoch2_05, )? - .ok_or(CheckErrors::NoSuchContract( + .ok_or(CheckErrorKind::NoSuchContract( trait_identifier.contract_identifier.to_string(), ))?; let trait_definition = contract_defining_trait .get_defined_trait(&trait_identifier.name) - .ok_or(CheckErrors::NoSuchTrait( + .ok_or(CheckErrorKind::NoSuchTrait( trait_identifier.contract_identifier.to_string(), trait_identifier.name.to_string(), ))?; @@ -490,7 +494,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { if !expected_type.admits_type(&StacksEpochId::Epoch2_05, &actual_type)? { let mut err: CheckError = - CheckErrors::TypeError(Box::new(expected_type.clone()), Box::new(actual_type)) + CheckErrorKind::TypeError(Box::new(expected_type.clone()), Box::new(actual_type)) .into(); err.set_expression(expr); Err(err) @@ -525,13 +529,13 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result { let mut types_returned = self.type_check_all(args, context)?; - let last_return = types_returned - .pop() - .ok_or(CheckError::new(CheckErrors::CheckerImplementationFailure))?; + let last_return = types_returned.pop().ok_or(CheckError::new( + CheckErrorKind::CheckerImplementationFailure, + ))?; for type_return in types_returned.iter() { if type_return.is_response_type() { - return Err(CheckErrors::UncheckedIntermediaryResponses.into()); + return Err(CheckErrorKind::UncheckedIntermediaryResponses.into()); } } Ok(last_return) @@ -574,10 +578,10 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result<(ClarityName, FixedFunction), CheckError> { let (function_name, args) = signature .split_first() - .ok_or(CheckErrors::RequiresAtLeastArguments(1, 0))?; + .ok_or(CheckErrorKind::RequiresAtLeastArguments(1, 0))?; let function_name = function_name .match_atom() - .ok_or(CheckErrors::BadFunctionName)?; + .ok_or(CheckErrorKind::BadFunctionName)?; let args = parse_name_type_pairs::<(), CheckError>( StacksEpochId::Epoch2_05, args, @@ -586,7 +590,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { )?; if self.function_return_tracker.is_some() { - return Err(CheckErrors::Expects( + return Err(CheckErrorKind::Expects( "Interpreter error: Previous function define left dirty typecheck state.".into(), ) .into()); @@ -628,7 +632,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &return_type, ) .map_err(|_| { - CheckErrors::ReturnTypesMustMatch( + CheckErrorKind::ReturnTypesMustMatch( Box::new(expected.clone()), Box::new(return_type), ) @@ -667,10 +671,10 @@ impl<'a, 'b> TypeChecker<'a, 'b> { // should we set the type of the subexpressions of the signature to no-type as well? let key_type = TypeSignature::parse_type_repr(StacksEpochId::Epoch2_05, key_type, &mut ()) - .map_err(|_| CheckErrors::BadMapTypeDefinition)?; + .map_err(|_| CheckErrorKind::BadMapTypeDefinition)?; let value_type = TypeSignature::parse_type_repr(StacksEpochId::Epoch2_05, value_type, &mut ()) - .map_err(|_| CheckErrors::BadMapTypeDefinition)?; + .map_err(|_| CheckErrorKind::BadMapTypeDefinition)?; Ok((map_name.clone(), (key_type, value_type))) } @@ -702,19 +706,19 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result { let (function_name, args) = expression .split_first() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; self.type_map.set_type(function_name, no_type())?; let function_name = function_name .match_atom() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; if let Some(type_result) = self.try_native_function_check(function_name, args, context) { type_result } else { let function = match self.get_function_type(function_name) { Some(FunctionType::Fixed(function)) => Ok(function), - _ => Err(CheckErrors::UnknownFunction(function_name.to_string())), + _ => Err(CheckErrorKind::UnknownFunction(function_name.to_string())), }?; for (expected_type, found_type) in function.args.iter().map(|x| &x.signature).zip(args) @@ -744,7 +748,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { // be undefined. This early error prevents a cost function error // due to `context.depth` being 0. if context.depth == 0 { - return Err(CheckErrors::UndefinedVariable(name.to_string()).into()); + return Err(CheckErrorKind::UndefinedVariable(name.to_string()).into()); } runtime_cost( @@ -756,7 +760,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { if let Some(type_result) = context.lookup_variable_type(name) { Ok(type_result.clone()) } else { - Err(CheckErrors::UndefinedVariable(name.to_string()).into()) + Err(CheckErrorKind::UndefinedVariable(name.to_string()).into()) } } } @@ -771,7 +775,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { Atom(ref name) => self.lookup_variable(name, context)?, List(ref expression) => self.type_check_function_application(expression, context)?, TraitReference(_, _) | Field(_) => { - return Err(CheckErrors::UnexpectedTraitOrFieldReference.into()); + return Err(CheckErrorKind::UnexpectedTraitOrFieldReference.into()); } }; @@ -803,7 +807,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result<(ClarityName, TypeSignature), CheckError> { let expected_type = TypeSignature::parse_type_repr::<()>(StacksEpochId::Epoch2_05, var_type, &mut ()) - .map_err(|_e| CheckErrors::DefineVariableBadSignature)?; + .map_err(|_e| CheckErrorKind::DefineVariableBadSignature)?; self.type_check_expects(initial, context, &expected_type)?; @@ -831,7 +835,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result<(ClarityName, TypeSignature), CheckError> { let asset_type = TypeSignature::parse_type_repr::<()>(StacksEpochId::Epoch2_05, nft_type, &mut ()) - .map_err(|_| CheckErrors::DefineNFTBadSignature)?; + .map_err(|_| CheckErrorKind::DefineNFTBadSignature)?; Ok((asset_name.clone(), asset_type)) } @@ -895,7 +899,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { .add_public_function_type(f_name, FunctionType::Fixed(f_type))?; return Ok(Some(())); } else { - return Err(CheckErrors::PublicFunctionMustReturnResponse(Box::new( + return Err(CheckErrorKind::PublicFunctionMustReturnResponse(Box::new( f_type.returns, )) .into()); @@ -1002,7 +1006,9 @@ impl<'a, 'b> TypeChecker<'a, 'b> { None => { // still had to do a db read, even if it didn't exist! runtime_cost(ClarityCostFunction::AnalysisUseTraitEntry, self, 1)?; - return Err(CheckErrors::TraitReferenceUnknown(name.to_string()).into()); + return Err( + CheckErrorKind::TraitReferenceUnknown(name.to_string()).into() + ); } } } diff --git a/clarity/src/vm/analysis/type_checker/v2_05/natives/assets.rs b/clarity/src/vm/analysis/type_checker/v2_05/natives/assets.rs index 13f967e6af..bb737034cf 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/natives/assets.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/natives/assets.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . use super::{TypeChecker, TypingContext}; -use crate::vm::analysis::errors::{check_argument_count, CheckError, CheckErrors}; +use crate::vm::analysis::errors::{check_argument_count, CheckError, CheckErrorKind}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::representations::SymbolicExpression; @@ -28,13 +28,13 @@ pub fn check_special_get_owner( ) -> Result { check_argument_count(2, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_asset_type = checker .contract_context .get_nft_type(asset_name) .cloned() - .ok_or_else(|| CheckErrors::NoSuchNFT(asset_name.to_string()))?; + .ok_or_else(|| CheckErrorKind::NoSuchNFT(asset_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -56,10 +56,10 @@ pub fn check_special_get_balance( ) -> Result { check_argument_count(2, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; if !checker.contract_context.ft_exists(asset_name) { - return Err(CheckErrors::NoSuchFT(asset_name.to_string()).into()); + return Err(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } runtime_cost(ClarityCostFunction::AnalysisTypeLookup, checker, 1)?; @@ -77,13 +77,13 @@ pub fn check_special_mint_asset( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; let expected_asset_type = checker .contract_context .get_nft_type(asset_name) - .ok_or(CheckErrors::NoSuchNFT(asset_name.to_string()))? + .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))? .clone(); // this clone shouldn't be strictly necessary, but to use `type_check_expects` with this, it would have to be. runtime_cost( @@ -108,7 +108,7 @@ pub fn check_special_mint_token( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_amount: TypeSignature = TypeSignature::UIntType; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; @@ -119,7 +119,7 @@ pub fn check_special_mint_token( checker.type_check_expects(&args[2], context, &expected_owner_type)?; if !checker.contract_context.ft_exists(asset_name) { - return Err(CheckErrors::NoSuchFT(asset_name.to_string()).into()); + return Err(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } Ok(TypeSignature::ResponseType(Box::new(( @@ -135,13 +135,13 @@ pub fn check_special_transfer_asset( ) -> Result { check_argument_count(4, args)?; - let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; let expected_asset_type = checker .contract_context .get_nft_type(token_name) - .ok_or(CheckErrors::NoSuchNFT(token_name.to_string()))? + .ok_or(CheckErrorKind::NoSuchNFT(token_name.to_string()))? .clone(); runtime_cost( @@ -167,7 +167,7 @@ pub fn check_special_transfer_token( ) -> Result { check_argument_count(4, args)?; - let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_amount: TypeSignature = TypeSignature::UIntType; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; @@ -179,7 +179,7 @@ pub fn check_special_transfer_token( checker.type_check_expects(&args[3], context, &expected_owner_type)?; // recipient if !checker.contract_context.ft_exists(token_name) { - return Err(CheckErrors::NoSuchFT(token_name.to_string()).into()); + return Err(CheckErrorKind::NoSuchFT(token_name.to_string()).into()); } Ok(TypeSignature::ResponseType(Box::new(( @@ -195,10 +195,10 @@ pub fn check_special_get_token_supply( ) -> Result { check_argument_count(1, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; if !checker.contract_context.ft_exists(asset_name) { - return Err(CheckErrors::NoSuchFT(asset_name.to_string()).into()); + return Err(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } runtime_cost(ClarityCostFunction::AnalysisTypeLookup, checker, 1)?; @@ -213,13 +213,13 @@ pub fn check_special_burn_asset( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; let expected_asset_type = checker .contract_context .get_nft_type(asset_name) - .ok_or(CheckErrors::NoSuchNFT(asset_name.to_string()))? + .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))? .clone(); // this clone shouldn't be strictly necessary, but to use `type_check_expects` with this, it would have to be. runtime_cost( @@ -244,7 +244,7 @@ pub fn check_special_burn_token( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_amount: TypeSignature = TypeSignature::UIntType; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; @@ -255,7 +255,7 @@ pub fn check_special_burn_token( checker.type_check_expects(&args[2], context, &expected_owner_type)?; if !checker.contract_context.ft_exists(asset_name) { - return Err(CheckErrors::NoSuchFT(asset_name.to_string()).into()); + return Err(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } Ok(TypeSignature::ResponseType(Box::new(( diff --git a/clarity/src/vm/analysis/type_checker/v2_05/natives/maps.rs b/clarity/src/vm/analysis/type_checker/v2_05/natives/maps.rs index ccbf880e17..b1f31b12fd 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/natives/maps.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/natives/maps.rs @@ -17,7 +17,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::analysis::type_checker::v2_05::{ - check_arguments_at_least, CheckError, CheckErrors, TypeChecker, TypingContext, + check_arguments_at_least, CheckError, CheckErrorKind, TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost}; @@ -31,14 +31,14 @@ pub fn check_special_fetch_entry( ) -> Result { check_arguments_at_least(2, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; let key_type = checker.type_check(&args[1], context)?; let (expected_key_type, value_type) = checker .contract_context .get_map_type(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -55,7 +55,7 @@ pub fn check_special_fetch_entry( let option_type = TypeSignature::new_option(value_type.clone())?; if !expected_key_type.admits_type(&StacksEpochId::Epoch2_05, &key_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(CheckError::new(CheckErrorKind::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) @@ -71,14 +71,14 @@ pub fn check_special_delete_entry( ) -> Result { check_arguments_at_least(2, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; let key_type = checker.type_check(&args[1], context)?; let (expected_key_type, _) = checker .contract_context .get_map_type(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -88,7 +88,7 @@ pub fn check_special_delete_entry( analysis_typecheck_cost(&mut checker.cost_track, expected_key_type, &key_type)?; if !expected_key_type.admits_type(&StacksEpochId::Epoch2_05, &key_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(CheckError::new(CheckErrorKind::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) @@ -104,7 +104,7 @@ fn check_set_or_insert_entry( ) -> Result { check_arguments_at_least(3, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; let key_type = checker.type_check(&args[1], context)?; let value_type = checker.type_check(&args[2], context)?; @@ -112,7 +112,7 @@ fn check_set_or_insert_entry( let (expected_key_type, expected_value_type) = checker .contract_context .get_map_type(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -129,12 +129,12 @@ fn check_set_or_insert_entry( analysis_typecheck_cost(&mut checker.cost_track, expected_value_type, &value_type)?; if !expected_key_type.admits_type(&StacksEpochId::Epoch2_05, &key_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(CheckError::new(CheckErrorKind::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) } else if !expected_value_type.admits_type(&StacksEpochId::Epoch2_05, &value_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(CheckError::new(CheckErrorKind::TypeError( Box::new(expected_value_type.clone()), Box::new(value_type), ))) diff --git a/clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs b/clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs index 08297f7440..ae1aeffca2 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs @@ -17,7 +17,7 @@ use stacks_common::types::StacksEpochId; use super::{check_argument_count, check_arguments_at_least, no_type, TypeChecker, TypingContext}; -use crate::vm::analysis::errors::{CheckError, CheckErrors, SyntaxBindingErrorType}; +use crate::vm::analysis::errors::{CheckError, CheckErrorKind, SyntaxBindingErrorType}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost}; use crate::vm::diagnostic::DiagnosableError; @@ -117,7 +117,7 @@ fn inner_handle_tuple_get( let return_type = tuple_type_sig .field_type(field_to_get) - .ok_or(CheckError::new(CheckErrors::NoSuchTupleField( + .ok_or(CheckError::new(CheckErrorKind::NoSuchTupleField( field_to_get.to_string(), tuple_type_sig.clone(), )))? @@ -132,7 +132,9 @@ fn check_special_get( ) -> Result { check_argument_count(2, args)?; - let field_to_get = args[0].match_atom().ok_or(CheckErrors::BadTupleFieldName)?; + let field_to_get = args[0] + .match_atom() + .ok_or(CheckErrorKind::BadTupleFieldName)?; let argument_type = checker.type_check(&args[1], context)?; @@ -144,10 +146,10 @@ fn check_special_get( let option_type = TypeSignature::new_option(inner_type)?; Ok(option_type) } else { - Err(CheckErrors::ExpectedTuple(value_type_sig).into()) + Err(CheckErrorKind::ExpectedTuple(value_type_sig).into()) } } else { - Err(CheckErrors::ExpectedTuple(Box::new(argument_type)).into()) + Err(CheckErrorKind::ExpectedTuple(Box::new(argument_type)).into()) } } @@ -161,13 +163,13 @@ fn check_special_merge( let res = checker.type_check(&args[0], context)?; let mut base = match res { TypeSignature::TupleType(tuple_sig) => Ok(tuple_sig), - _ => Err(CheckErrors::ExpectedTuple(Box::new(res.clone()))), + _ => Err(CheckErrorKind::ExpectedTuple(Box::new(res.clone()))), }?; let res = checker.type_check(&args[1], context)?; let mut update = match res { TypeSignature::TupleType(tuple_sig) => Ok(tuple_sig), - _ => Err(CheckErrors::ExpectedTuple(Box::new(res.clone()))), + _ => Err(CheckErrorKind::ExpectedTuple(Box::new(res.clone()))), }?; runtime_cost( ClarityCostFunction::AnalysisCheckTupleMerge, @@ -208,7 +210,7 @@ pub fn check_special_tuple_cons( )?; let tuple_signature = TupleTypeSignature::try_from(tuple_type_data) - .map_err(|e| CheckErrors::BadTupleConstruction(e.message()))?; + .map_err(|e| CheckErrorKind::BadTupleConstruction(e.message()))?; Ok(TypeSignature::TupleType(tuple_signature)) } @@ -222,7 +224,7 @@ fn check_special_let( let binding_list = args[0] .match_list() - .ok_or(CheckError::new(CheckErrors::BadLetSyntax))?; + .ok_or(CheckError::new(CheckErrorKind::BadLetSyntax))?; let mut out_context = context.extend()?; @@ -234,7 +236,7 @@ fn check_special_let( |var_name, var_sexp| { checker.contract_context.check_name_used(var_name)?; if out_context.lookup_variable_type(var_name).is_some() { - return Err(CheckError::new(CheckErrors::NameAlreadyUsed( + return Err(CheckError::new(CheckErrorKind::NameAlreadyUsed( var_name.to_string(), ))); } @@ -265,12 +267,12 @@ fn check_special_fetch_var( let var_name = args[0] .match_atom() - .ok_or(CheckError::new(CheckErrors::BadMapName))?; + .ok_or(CheckError::new(CheckErrorKind::BadMapName))?; let value_type = checker .contract_context .get_persisted_variable_type(var_name) - .ok_or(CheckError::new(CheckErrors::NoSuchDataVariable( + .ok_or(CheckError::new(CheckErrorKind::NoSuchDataVariable( var_name.to_string(), )))?; @@ -290,14 +292,14 @@ fn check_special_set_var( ) -> Result { check_arguments_at_least(2, args)?; - let var_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; + let var_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; let value_type = checker.type_check(&args[1], context)?; let expected_value_type = checker .contract_context .get_persisted_variable_type(var_name) - .ok_or(CheckErrors::NoSuchDataVariable(var_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchDataVariable(var_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -307,7 +309,7 @@ fn check_special_set_var( analysis_typecheck_cost(&mut checker.cost_track, &value_type, expected_value_type)?; if !expected_value_type.admits_type(&StacksEpochId::Epoch2_05, &value_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(CheckError::new(CheckErrorKind::TypeError( Box::new(expected_value_type.clone()), Box::new(value_type), ))) @@ -329,7 +331,7 @@ fn check_special_equals( for x_type in arg_types.into_iter() { analysis_typecheck_cost(checker, &x_type, &arg_type)?; arg_type = TypeSignature::least_supertype(&StacksEpochId::Epoch2_05, &x_type, &arg_type) - .map_err(|_| CheckErrors::TypeError(Box::new(x_type), Box::new(arg_type)))?; + .map_err(|_| CheckErrorKind::TypeError(Box::new(x_type), Box::new(arg_type)))?; } Ok(TypeSignature::BoolType) @@ -352,7 +354,7 @@ fn check_special_if( analysis_typecheck_cost(checker, expr1, expr2)?; TypeSignature::least_supertype(&StacksEpochId::Epoch2_05, expr1, expr2).map_err(|_| { - CheckErrors::IfArmsMustMatch(Box::new(expr1.clone()), Box::new(expr2.clone())).into() + CheckErrorKind::IfArmsMustMatch(Box::new(expr1.clone()), Box::new(expr2.clone())).into() }) } @@ -365,7 +367,7 @@ fn check_contract_call( let func_name = args[1] .match_atom() - .ok_or(CheckError::new(CheckErrors::ContractCallExpectName))?; + .ok_or(CheckError::new(CheckErrorKind::ContractCallExpectName))?; checker.type_map.set_type(&args[1], no_type())?; let expected_sig = match &args[0].expr { @@ -389,7 +391,7 @@ fn check_contract_call( { Ok(function) } else { - Err(CheckError::new(CheckErrors::NoSuchPublicFunction( + Err(CheckError::new(CheckErrorKind::NoSuchPublicFunction( contract_identifier.to_string(), func_name.to_string(), ))) @@ -412,7 +414,7 @@ fn check_contract_call( Some(trait_id) => trait_id, _ => { return Err( - CheckErrors::TraitReferenceUnknown(trait_instance.to_string()).into(), + CheckErrorKind::TraitReferenceUnknown(trait_instance.to_string()).into(), ); } }; @@ -420,12 +422,12 @@ fn check_contract_call( runtime_cost(ClarityCostFunction::AnalysisLookupFunction, checker, 0)?; let trait_signature = checker.contract_context.get_trait(&trait_id.name).ok_or( - CheckErrors::TraitReferenceUnknown(trait_id.name.to_string()), + CheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()), )?; let func_signature = trait_signature .get(func_name) - .ok_or(CheckErrors::TraitMethodUnknown( + .ok_or(CheckErrorKind::TraitMethodUnknown( trait_id.name.to_string(), func_name.to_string(), ))?; @@ -438,7 +440,7 @@ fn check_contract_call( func_signature.clone() } - _ => return Err(CheckError::new(CheckErrors::ContractCallExpectName)), + _ => return Err(CheckError::new(CheckErrorKind::ContractCallExpectName)), }; check_argument_count(expected_sig.args.len(), &args[2..])?; @@ -458,12 +460,12 @@ fn check_contract_of( let trait_instance = match &args[0].expr { SymbolicExpressionType::Atom(trait_instance) => trait_instance, - _ => return Err(CheckError::new(CheckErrors::ContractOfExpectsTrait)), + _ => return Err(CheckError::new(CheckErrorKind::ContractOfExpectsTrait)), }; let trait_id = match context.lookup_trait_reference_type(trait_instance) { Some(trait_id) => trait_id, - _ => return Err(CheckErrors::TraitReferenceUnknown(trait_instance.to_string()).into()), + _ => return Err(CheckErrorKind::TraitReferenceUnknown(trait_instance.to_string()).into()), }; runtime_cost(ClarityCostFunction::ContractOf, checker, 1)?; @@ -471,7 +473,7 @@ fn check_contract_of( checker .contract_context .get_trait(&trait_id.name) - .ok_or_else(|| CheckErrors::TraitReferenceUnknown(trait_id.name.to_string()))?; + .ok_or_else(|| CheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()))?; Ok(TypeSignature::PrincipalType) } @@ -485,7 +487,7 @@ fn check_principal_of( checker.type_check_expects(&args[0], context, &BUFF_33)?; Ok( TypeSignature::new_response(TypeSignature::PrincipalType, TypeSignature::UIntType) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, ) } @@ -499,7 +501,7 @@ fn check_secp256k1_recover( checker.type_check_expects(&args[1], context, &BUFF_65)?; Ok( TypeSignature::new_response(BUFF_33.clone(), TypeSignature::UIntType) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, ) } @@ -522,15 +524,15 @@ fn check_get_block_info( ) -> Result { check_arguments_at_least(2, args)?; - let block_info_prop_str = args[0] - .match_atom() - .ok_or(CheckError::new(CheckErrors::GetBlockInfoExpectPropertyName))?; + let block_info_prop_str = args[0].match_atom().ok_or(CheckError::new( + CheckErrorKind::GetBlockInfoExpectPropertyName, + ))?; let block_info_prop = BlockInfoProperty::lookup_by_name_at_version( block_info_prop_str, &ClarityVersion::Clarity1, ) - .ok_or(CheckError::new(CheckErrors::NoSuchBlockInfoProperty( + .ok_or(CheckError::new(CheckErrorKind::NoSuchBlockInfoProperty( block_info_prop_str.to_string(), )))?; @@ -557,7 +559,7 @@ impl TypedNativeFunction { pub fn type_native_function( function: &NativeFunctions, - ) -> Result { + ) -> Result { use self::TypedNativeFunction::{Simple, Special}; use crate::vm::functions::NativeFunctions::*; let out = match function { @@ -579,7 +581,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::IntType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -590,7 +592,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::UIntType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -601,7 +603,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::BoolType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -654,7 +656,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("owner".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -666,7 +668,7 @@ impl TypedNativeFunction { FunctionArg::new( TypeSignature::UIntType, ClarityName::try_from("amount".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -674,7 +676,7 @@ impl TypedNativeFunction { FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("sender".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -682,7 +684,7 @@ impl TypedNativeFunction { FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("recipient".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -692,14 +694,14 @@ impl TypedNativeFunction { TypeSignature::BoolType, TypeSignature::UIntType, ) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, }))), StxBurn => Simple(SimpleNativeFunction(FunctionType::Fixed(FixedFunction { args: vec![ FunctionArg::new( TypeSignature::UIntType, ClarityName::try_from("amount".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -707,7 +709,7 @@ impl TypedNativeFunction { FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("sender".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -717,7 +719,7 @@ impl TypedNativeFunction { TypeSignature::BoolType, TypeSignature::UIntType, ) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, }))), GetTokenBalance => Special(SpecialNativeFunction(&assets::check_special_get_balance)), GetAssetOwner => Special(SpecialNativeFunction(&assets::check_special_get_owner)), @@ -783,7 +785,7 @@ impl TypedNativeFunction { | StxGetAccount | BitwiseAnd | BitwiseOr | BitwiseNot | BitwiseLShift | BitwiseRShift | BitwiseXor2 | Slice | ToConsensusBuff | FromConsensusBuff | ReplaceAt | GetStacksBlockInfo | GetTenureInfo | ContractHash | ToAscii => { - return Err(CheckErrors::Expects( + return Err(CheckErrorKind::Expects( "Clarity 2+ keywords should not show up in 2.05".into(), )); } diff --git a/clarity/src/vm/analysis/type_checker/v2_05/natives/options.rs b/clarity/src/vm/analysis/type_checker/v2_05/natives/options.rs index 1cf9b301a7..a8e5fb0bc5 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/natives/options.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/natives/options.rs @@ -19,8 +19,8 @@ use clarity_types::types::TypeSignature; use stacks_common::types::StacksEpochId; use crate::vm::analysis::type_checker::v2_05::{ - check_argument_count, check_arguments_at_least, no_type, CheckError, CheckErrors, TypeChecker, - TypingContext, + check_argument_count, check_arguments_at_least, no_type, CheckError, CheckErrorKind, + TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost}; @@ -82,7 +82,7 @@ pub fn check_special_is_response( if let TypeSignature::ResponseType(_types) = input { Ok(TypeSignature::BoolType) } else { - Err(CheckErrors::ExpectedResponseType(Box::new(input)).into()) + Err(CheckErrorKind::ExpectedResponseType(Box::new(input)).into()) } } @@ -100,7 +100,7 @@ pub fn check_special_is_optional( if let TypeSignature::OptionalType(_type) = input { Ok(TypeSignature::BoolType) } else { - Err(CheckErrors::ExpectedOptionalType(Box::new(input)).into()) + Err(CheckErrorKind::ExpectedOptionalType(Box::new(input)).into()) } } @@ -120,11 +120,11 @@ pub fn check_special_default_to( let contained_type = *input_type; TypeSignature::least_supertype(&StacksEpochId::Epoch2_05, &default, &contained_type) .map_err(|_| { - CheckErrors::DefaultTypesMustMatch(Box::new(default), Box::new(contained_type)) + CheckErrorKind::DefaultTypesMustMatch(Box::new(default), Box::new(contained_type)) .into() }) } else { - Err(CheckErrors::ExpectedOptionalType(Box::new(input)).into()) + Err(CheckErrorKind::ExpectedOptionalType(Box::new(input)).into()) } } @@ -152,7 +152,7 @@ fn inner_unwrap( match input { TypeSignature::OptionalType(input_type) => { if input_type.is_no_type() { - Err(CheckErrors::CouldNotDetermineResponseOkType.into()) + Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) } else { Ok(*input_type) } @@ -160,12 +160,12 @@ fn inner_unwrap( TypeSignature::ResponseType(response_type) => { let ok_type = response_type.0; if ok_type.is_no_type() { - Err(CheckErrors::CouldNotDetermineResponseOkType.into()) + Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) } else { Ok(ok_type) } } - _ => Err(CheckErrors::ExpectedOptionalOrResponseType(Box::new(input)).into()), + _ => Err(CheckErrorKind::ExpectedOptionalOrResponseType(Box::new(input)).into()), } } @@ -178,12 +178,12 @@ fn inner_unwrap_err( if let TypeSignature::ResponseType(response_type) = input { let err_type = response_type.1; if err_type.is_no_type() { - Err(CheckErrors::CouldNotDetermineResponseErrType.into()) + Err(CheckErrorKind::CouldNotDetermineResponseErrType.into()) } else { Ok(err_type) } } else { - Err(CheckErrors::ExpectedResponseType(Box::new(input)).into()) + Err(CheckErrorKind::ExpectedResponseType(Box::new(input)).into()) } } @@ -231,7 +231,7 @@ pub fn check_special_try_ret( match input { TypeSignature::OptionalType(input_type) => { if input_type.is_no_type() { - Err(CheckErrors::CouldNotDetermineResponseOkType.into()) + Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) } else { checker.track_return_type(TypeSignature::new_option(TypeSignature::NoType)?)?; Ok(*input_type) @@ -240,9 +240,9 @@ pub fn check_special_try_ret( TypeSignature::ResponseType(response_type) => { let (ok_type, err_type) = *response_type; if ok_type.is_no_type() { - Err(CheckErrors::CouldNotDetermineResponseOkType.into()) + Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) } else if err_type.is_no_type() { - Err(CheckErrors::CouldNotDetermineResponseErrType.into()) + Err(CheckErrorKind::CouldNotDetermineResponseErrType.into()) } else { checker.track_return_type(TypeSignature::new_response( TypeSignature::NoType, @@ -251,7 +251,7 @@ pub fn check_special_try_ret( Ok(ok_type) } } - _ => Err(CheckErrors::ExpectedOptionalOrResponseType(Box::new(input)).into()), + _ => Err(CheckErrorKind::ExpectedOptionalOrResponseType(Box::new(input)).into()), } } @@ -297,7 +297,7 @@ fn eval_with_new_binding( checker.contract_context.check_name_used(&bind_name)?; if inner_context.lookup_variable_type(&bind_name).is_some() { - return Err(CheckErrors::NameAlreadyUsed(bind_name.into()).into()); + return Err(CheckErrorKind::NameAlreadyUsed(bind_name.into()).into()); } inner_context.variable_types.insert(bind_name, bind_type); @@ -312,20 +312,22 @@ fn check_special_match_opt( context: &TypingContext, ) -> Result { if args.len() != 3 { - Err(CheckErrors::BadMatchOptionSyntax(Box::new( - CheckErrors::IncorrectArgumentCount(4, args.len() + 1), + Err(CheckErrorKind::BadMatchOptionSyntax(Box::new( + CheckErrorKind::IncorrectArgumentCount(4, args.len() + 1), )))?; } let bind_name = args[0] .match_atom() - .ok_or_else(|| CheckErrors::BadMatchOptionSyntax(Box::new(CheckErrors::ExpectedName)))? + .ok_or_else(|| { + CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::ExpectedName)) + })? .clone(); let some_branch = &args[1]; let none_branch = &args[2]; if option_type.is_no_type() { - return Err(CheckErrors::CouldNotDetermineMatchTypes.into()); + return Err(CheckErrorKind::CouldNotDetermineMatchTypes.into()); } let some_branch_type = @@ -340,7 +342,7 @@ fn check_special_match_opt( &none_branch_type, ) .map_err(|_| { - CheckErrors::MatchArmsMustMatch(Box::new(some_branch_type), Box::new(none_branch_type)) + CheckErrorKind::MatchArmsMustMatch(Box::new(some_branch_type), Box::new(none_branch_type)) .into() }) } @@ -352,26 +354,30 @@ fn check_special_match_resp( context: &TypingContext, ) -> Result { if args.len() != 4 { - Err(CheckErrors::BadMatchResponseSyntax(Box::new( - CheckErrors::IncorrectArgumentCount(5, args.len() + 1), + Err(CheckErrorKind::BadMatchResponseSyntax(Box::new( + CheckErrorKind::IncorrectArgumentCount(5, args.len() + 1), )))?; } let ok_bind_name = args[0] .match_atom() - .ok_or_else(|| CheckErrors::BadMatchResponseSyntax(Box::new(CheckErrors::ExpectedName)))? + .ok_or_else(|| { + CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)) + })? .clone(); let ok_branch = &args[1]; let err_bind_name = args[2] .match_atom() - .ok_or_else(|| CheckErrors::BadMatchResponseSyntax(Box::new(CheckErrors::ExpectedName)))? + .ok_or_else(|| { + CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)) + })? .clone(); let err_branch = &args[3]; let (ok_type, err_type) = resp_type; if ok_type.is_no_type() || err_type.is_no_type() { - return Err(CheckErrors::CouldNotDetermineMatchTypes.into()); + return Err(CheckErrorKind::CouldNotDetermineMatchTypes.into()); } let ok_branch_type = eval_with_new_binding(ok_branch, ok_bind_name, ok_type, checker, context)?; @@ -382,7 +388,7 @@ fn check_special_match_resp( TypeSignature::least_supertype(&StacksEpochId::Epoch2_05, &ok_branch_type, &err_branch_type) .map_err(|_| { - CheckErrors::MatchArmsMustMatch(Box::new(ok_branch_type), Box::new(err_branch_type)) + CheckErrorKind::MatchArmsMustMatch(Box::new(ok_branch_type), Box::new(err_branch_type)) .into() }) } @@ -403,6 +409,6 @@ pub fn check_special_match( TypeSignature::ResponseType(resp_type) => { check_special_match_resp(*resp_type, checker, &args[1..], context) } - _ => Err(CheckErrors::BadMatchInput(Box::new(input)).into()), + _ => Err(CheckErrorKind::BadMatchInput(Box::new(input)).into()), } } diff --git a/clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs b/clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs index 00904bfe49..a86325a7d8 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs @@ -18,7 +18,7 @@ use stacks_common::types::StacksEpochId; use super::{SimpleNativeFunction, TypedNativeFunction}; use crate::vm::analysis::type_checker::v2_05::{ - check_argument_count, check_arguments_at_least, CheckError, CheckErrors, TypeChecker, + check_argument_count, check_arguments_at_least, CheckError, CheckErrorKind, TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -44,11 +44,14 @@ fn get_simple_native_or_user_define( { Ok(function_type) } else { - Err(CheckErrors::IllegalOrUnknownFunctionApplication(function_name.to_string()).into()) + Err( + CheckErrorKind::IllegalOrUnknownFunctionApplication(function_name.to_string()) + .into(), + ) } } else { checker.get_function_type(function_name).ok_or( - CheckErrors::IllegalOrUnknownFunctionApplication(function_name.to_string()).into(), + CheckErrorKind::IllegalOrUnknownFunctionApplication(function_name.to_string()).into(), ) } } @@ -62,7 +65,7 @@ pub fn check_special_map( let function_name = args[0] .match_atom() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; // we will only lookup native or defined functions here. // you _cannot_ map a special function. let function_type = get_simple_native_or_user_define(function_name, checker)?; @@ -98,7 +101,7 @@ pub fn check_special_map( // However that could lead to confusions when combining certain types: // ex: (map concat (list "hello " "hi ") "world") would fail, because // strings are handled as sequences. - return Err(CheckErrors::ExpectedSequence(Box::new(argument_type)).into()); + return Err(CheckErrorKind::ExpectedSequence(Box::new(argument_type)).into()); } }; func_args.push(entry_type); @@ -107,7 +110,7 @@ pub fn check_special_map( let mapped_type = function_type.check_args(checker, &func_args, context.epoch, context.clarity_version)?; TypeSignature::list_of(mapped_type, min_args) - .map_err(|_| CheckErrors::ConstructedListTooLarge.into()) + .map_err(|_| CheckErrorKind::ConstructedListTooLarge.into()) } pub fn check_special_filter( @@ -119,7 +122,7 @@ pub fn check_special_filter( let function_name = args[0] .match_atom() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; // we will only lookup native or defined functions here. // you _cannot_ map a special function. let function_type = get_simple_native_or_user_define(function_name, checker)?; @@ -130,7 +133,7 @@ pub fn check_special_filter( { let input_type = match argument_type { TypeSignature::SequenceType(ref sequence_type) => Ok(sequence_type.unit_type()?), - _ => Err(CheckErrors::ExpectedSequence(Box::new( + _ => Err(CheckErrorKind::ExpectedSequence(Box::new( argument_type.clone(), ))), }?; @@ -143,7 +146,7 @@ pub fn check_special_filter( )?; if TypeSignature::BoolType != filter_type { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(TypeSignature::BoolType), Box::new(filter_type), ) @@ -163,7 +166,7 @@ pub fn check_special_fold( let function_name = args[0] .match_atom() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; // we will only lookup native or defined functions here. // you _cannot_ fold a special function. let function_type = get_simple_native_or_user_define(function_name, checker)?; @@ -173,7 +176,7 @@ pub fn check_special_fold( let input_type = match argument_type { TypeSignature::SequenceType(sequence_type) => Ok(sequence_type.unit_type()?), - _ => Err(CheckErrors::ExpectedSequence(Box::new(argument_type))), + _ => Err(CheckErrorKind::ExpectedSequence(Box::new(argument_type))), }?; let initial_value_type = checker.type_check(&args[2], context)?; @@ -231,29 +234,29 @@ pub fn check_special_concat( )?; let new_len = lhs_max_len .checked_add(rhs_max_len) - .ok_or(CheckErrors::MaxLengthOverflow)?; + .ok_or(CheckErrorKind::MaxLengthOverflow)?; TypeSignature::list_of(list_entry_type, new_len)? } (BufferType(lhs_len), BufferType(rhs_len)) => { let size: u32 = u32::from(lhs_len) .checked_add(u32::from(rhs_len)) - .ok_or(CheckErrors::MaxLengthOverflow)?; + .ok_or(CheckErrorKind::MaxLengthOverflow)?; TypeSignature::SequenceType(BufferType(size.try_into()?)) } (StringType(ASCII(lhs_len)), StringType(ASCII(rhs_len))) => { let size: u32 = u32::from(lhs_len) .checked_add(u32::from(rhs_len)) - .ok_or(CheckErrors::MaxLengthOverflow)?; + .ok_or(CheckErrorKind::MaxLengthOverflow)?; TypeSignature::SequenceType(StringType(ASCII(size.try_into()?))) } (StringType(UTF8(lhs_len)), StringType(UTF8(rhs_len))) => { let size: u32 = u32::from(lhs_len) .checked_add(u32::from(rhs_len)) - .ok_or(CheckErrors::MaxLengthOverflow)?; + .ok_or(CheckErrorKind::MaxLengthOverflow)?; TypeSignature::SequenceType(StringType(UTF8(size.try_into()?))) } (_, _) => { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(lhs_type.clone()), Box::new(rhs_type.clone()), ) @@ -261,7 +264,7 @@ pub fn check_special_concat( } } } - _ => return Err(CheckErrors::ExpectedSequence(Box::new(lhs_type.clone())).into()), + _ => return Err(CheckErrorKind::ExpectedSequence(Box::new(lhs_type.clone())).into()), }; Ok(res) } @@ -290,11 +293,11 @@ pub fn check_special_append( )?; let new_len = lhs_max_len .checked_add(1) - .ok_or(CheckErrors::MaxLengthOverflow)?; + .ok_or(CheckErrorKind::MaxLengthOverflow)?; let return_type = TypeSignature::list_of(list_entry_type, new_len)?; Ok(return_type) } - _ => Err(CheckErrors::ExpectedListApplication.into()), + _ => Err(CheckErrorKind::ExpectedListApplication.into()), } } @@ -309,7 +312,7 @@ pub fn check_special_as_max_len( SymbolicExpressionType::LiteralValue(Value::UInt(expected_len)) => expected_len, _ => { let expected_len_type = checker.type_check(&args[1], context)?; - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(expected_len_type), ) @@ -325,7 +328,8 @@ pub fn check_special_as_max_len( .type_map .set_type(&args[1], TypeSignature::UIntType)?; - let expected_len = u32::try_from(expected_len).map_err(|_e| CheckErrors::MaxLengthOverflow)?; + let expected_len = + u32::try_from(expected_len).map_err(|_e| CheckErrorKind::MaxLengthOverflow)?; let sequence = checker.type_check(&args[0], context)?; runtime_cost(ClarityCostFunction::AnalysisIterableFunc, checker, 0)?; @@ -351,7 +355,7 @@ pub fn check_special_as_max_len( StringUTF8Length::try_from(expected_len)?, )))), )), - _ => Err(CheckErrors::ExpectedSequence(Box::new(sequence)).into()), + _ => Err(CheckErrorKind::ExpectedSequence(Box::new(sequence)).into()), } } @@ -367,7 +371,7 @@ pub fn check_special_len( match collection_type { TypeSignature::SequenceType(_) => Ok(()), - _ => Err(CheckErrors::ExpectedSequence(Box::new(collection_type))), + _ => Err(CheckErrorKind::ExpectedSequence(Box::new(collection_type))), }?; Ok(TypeSignature::UIntType) @@ -396,16 +400,16 @@ pub fn check_special_element_at( TypeSignature::SequenceType(StringType(ASCII(_))) => Ok(TypeSignature::OptionalType( Box::new(TypeSignature::SequenceType(StringType(ASCII( BufferLength::try_from(1u32) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, )))), )), TypeSignature::SequenceType(StringType(UTF8(_))) => Ok(TypeSignature::OptionalType( Box::new(TypeSignature::SequenceType(StringType(UTF8( StringUTF8Length::try_from(1u32) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, )))), )), - _ => Err(CheckErrors::ExpectedSequence(Box::new(collection_type)).into()), + _ => Err(CheckErrorKind::ExpectedSequence(Box::new(collection_type)).into()), } } @@ -421,7 +425,7 @@ pub fn check_special_index_of( let expected_input_type = match list_type { TypeSignature::SequenceType(ref sequence_type) => Ok(sequence_type.unit_type()?), - _ => Err(CheckErrors::ExpectedSequence(Box::new(list_type))), + _ => Err(CheckErrorKind::ExpectedSequence(Box::new(list_type))), }?; checker.type_check_expects(&args[1], context, &expected_input_type)?; diff --git a/clarity/src/vm/analysis/type_checker/v2_05/tests/assets.rs b/clarity/src/vm/analysis/type_checker/v2_05/tests/assets.rs index 75dbc4928f..39e52b274d 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/tests/assets.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/tests/assets.rs @@ -16,7 +16,7 @@ use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::CheckErrors; +use crate::vm::analysis::errors::CheckErrorKind; use crate::vm::ast::parse; use crate::vm::database::MemoryBackingStore; use crate::vm::tooling::mem_type_check; @@ -193,108 +193,108 @@ fn test_bad_asset_usage() { ]; let expected = [ - CheckErrors::NoSuchFT("stackoos".to_string()), - CheckErrors::BadTokenName, - CheckErrors::BadTokenName, - CheckErrors::TypeError( + CheckErrorKind::NoSuchFT("stackoos".to_string()), + CheckErrorKind::BadTokenName, + CheckErrorKind::BadTokenName, + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::IntType), ), - CheckErrors::BadTokenName, - CheckErrors::NoSuchNFT("stackoos".to_string()), - CheckErrors::TypeError( + CheckErrorKind::BadTokenName, + CheckErrorKind::NoSuchNFT("stackoos".to_string()), + CheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(string_ascii_type(15)), ), - CheckErrors::BadTokenName, - CheckErrors::NoSuchNFT("stackoos".to_string()), - CheckErrors::TypeError( + CheckErrorKind::BadTokenName, + CheckErrorKind::NoSuchNFT("stackoos".to_string()), + CheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(string_ascii_type(15)), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::NoSuchFT("stackoos".to_string()), - CheckErrors::BadTokenName, - CheckErrors::TypeError( + CheckErrorKind::NoSuchFT("stackoos".to_string()), + CheckErrorKind::BadTokenName, + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::BoolType), ), - CheckErrors::BadTokenName, - CheckErrors::NoSuchNFT("stackoos".to_string()), - CheckErrors::TypeError( + CheckErrorKind::BadTokenName, + CheckErrorKind::NoSuchNFT("stackoos".to_string()), + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrors::BadTokenName, - CheckErrors::TypeError( + CheckErrorKind::BadTokenName, + CheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::NoSuchFT("stackoos".to_string()), - CheckErrors::BadTokenName, - CheckErrors::TypeError( + CheckErrorKind::NoSuchFT("stackoos".to_string()), + CheckErrorKind::BadTokenName, + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::BoolType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::BoolType), ), - CheckErrors::DefineNFTBadSignature, - CheckErrors::TypeError( + CheckErrorKind::DefineNFTBadSignature, + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrors::NoSuchFT("stackoos".to_string()), - CheckErrors::NoSuchFT("stackoos".to_string()), - CheckErrors::TypeError( + CheckErrorKind::NoSuchFT("stackoos".to_string()), + CheckErrorKind::NoSuchFT("stackoos".to_string()), + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::IntType), ), diff --git a/clarity/src/vm/analysis/type_checker/v2_05/tests/contracts.rs b/clarity/src/vm/analysis/type_checker/v2_05/tests/contracts.rs index 6d37d06837..6b6c513727 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/tests/contracts.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/tests/contracts.rs @@ -19,7 +19,7 @@ use stacks_common::types::StacksEpochId; use {assert_json_diff, serde_json}; use crate::vm::analysis::contract_interface_builder::build_contract_interface; -use crate::vm::analysis::errors::CheckErrors; +use crate::vm::analysis::errors::CheckErrorKind; use crate::vm::analysis::{mem_type_check, type_check}; use crate::vm::ast::parse; use crate::vm::database::MemoryBackingStore; @@ -492,7 +492,7 @@ fn test_names_tokens_contracts_bad() { ) }) .unwrap_err(); - assert!(matches!(*err.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*err.err, CheckErrorKind::TypeError(_, _))); } #[test] @@ -534,7 +534,7 @@ fn test_bad_map_usage() { for contract in tests.iter() { let err = mem_type_check(contract, ClarityVersion::Clarity1, StacksEpochId::Epoch2_05) .unwrap_err(); - assert!(matches!(*err.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*err.err, CheckErrorKind::TypeError(_, _))); } assert!(matches!( @@ -545,7 +545,7 @@ fn test_bad_map_usage() { ) .unwrap_err() .err, - CheckErrors::UnionTypeError(_, _) + CheckErrorKind::UnionTypeError(_, _) )); } @@ -663,7 +663,10 @@ fn test_expects() { ) .unwrap_err(); eprintln!("unmatched_return_types returned check error: {err}"); - assert!(matches!(*err.err, CheckErrors::ReturnTypesMustMatch(_, _))); + assert!(matches!( + *err.err, + CheckErrorKind::ReturnTypesMustMatch(_, _) + )); } let err = mem_type_check( @@ -673,7 +676,10 @@ fn test_expects() { ) .unwrap_err(); eprintln!("bad_default_types returned check error: {err}"); - assert!(matches!(*err.err, CheckErrors::DefaultTypesMustMatch(_, _))); + assert!(matches!( + *err.err, + CheckErrorKind::DefaultTypesMustMatch(_, _) + )); let err = mem_type_check( notype_response_type, @@ -684,7 +690,7 @@ fn test_expects() { eprintln!("notype_response_type returned check error: {err}"); assert!(matches!( *err.err, - CheckErrors::CouldNotDetermineResponseErrType + CheckErrorKind::CouldNotDetermineResponseErrType )); let err = mem_type_check( @@ -696,6 +702,6 @@ fn test_expects() { eprintln!("notype_response_type_2 returned check error: {err}"); assert!(matches!( *err.err, - CheckErrors::CouldNotDetermineResponseOkType + CheckErrorKind::CouldNotDetermineResponseOkType )); } diff --git a/clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs b/clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs index 99fd0191ce..72e9545b96 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs @@ -16,7 +16,7 @@ use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::{CheckError, CheckErrors, SyntaxBindingError}; +use crate::vm::analysis::errors::{CheckError, CheckErrorKind, SyntaxBindingError}; use crate::vm::analysis::mem_type_check; use crate::vm::ast::build_ast; use crate::vm::ast::errors::ParseErrors; @@ -70,10 +70,10 @@ fn test_get_block_info() { "(get-block-info? time)", ]; let bad_expected = [ - CheckErrors::NoSuchBlockInfoProperty("none".to_string()), - CheckErrors::TypeError(Box::new(UIntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::RequiresAtLeastArguments(2, 1), + CheckErrorKind::NoSuchBlockInfoProperty("none".to_string()), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::RequiresAtLeastArguments(2, 1), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -114,10 +114,10 @@ fn test_define_trait() { "(define-trait)", ]; let bad_expected = [ - CheckErrors::InvalidTypeDescription, - CheckErrors::DefineTraitBadSignature, - CheckErrors::DefineTraitBadSignature, - CheckErrors::InvalidTypeDescription, + CheckErrorKind::InvalidTypeDescription, + CheckErrorKind::DefineTraitBadSignature, + CheckErrorKind::DefineTraitBadSignature, + CheckErrorKind::InvalidTypeDescription, ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -217,16 +217,16 @@ fn test_stx_ops() { "(stx-get-balance 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR)" ]; let bad_expected = [ - CheckErrors::IncorrectArgumentCount(3, 2), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::TypeError(Box::new(PrincipalType), Box::new(UIntType)), - CheckErrors::TypeError(Box::new(PrincipalType), Box::new(BoolType)), - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::TypeError(Box::new(PrincipalType), Box::new(BoolType)), - CheckErrors::IncorrectArgumentCount(2, 3), - CheckErrors::TypeError(Box::new(PrincipalType), Box::new(BoolType)), - CheckErrors::IncorrectArgumentCount(1, 2), + CheckErrorKind::IncorrectArgumentCount(3, 2), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(UIntType)), + CheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + CheckErrorKind::IncorrectArgumentCount(2, 3), + CheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + CheckErrorKind::IncorrectArgumentCount(1, 2), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -292,7 +292,7 @@ fn test_destructuring_opts() { let bad = [ ( "(unwrap-err! (some 2) 2)", - CheckErrors::ExpectedResponseType(Box::new(TypeSignature::from_string( + CheckErrorKind::ExpectedResponseType(Box::new(TypeSignature::from_string( "(optional int)", ClarityVersion::Clarity1, StacksEpochId::Epoch2_05, @@ -300,88 +300,90 @@ fn test_destructuring_opts() { ), ( "(unwrap! (err 3) 2)", - CheckErrors::CouldNotDetermineResponseOkType, + CheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(unwrap-err-panic (ok 3))", - CheckErrors::CouldNotDetermineResponseErrType, + CheckErrorKind::CouldNotDetermineResponseErrType, ), ( "(unwrap-panic none)", - CheckErrors::CouldNotDetermineResponseOkType, + CheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(define-private (foo) (if (> 1 0) none none)) (unwrap-panic (foo))", - CheckErrors::CouldNotDetermineResponseOkType, + CheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(unwrap-panic (err 3))", - CheckErrors::CouldNotDetermineResponseOkType, + CheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(match none inner-value (/ 1 0) (+ 1 8))", - CheckErrors::CouldNotDetermineMatchTypes, + CheckErrorKind::CouldNotDetermineMatchTypes, ), ( "(match (ok 1) ok-val (/ ok-val 0) err-val (+ err-val 7))", - CheckErrors::CouldNotDetermineMatchTypes, + CheckErrorKind::CouldNotDetermineMatchTypes, ), ( "(match (err 1) ok-val (/ ok-val 0) err-val (+ err-val 7))", - CheckErrors::CouldNotDetermineMatchTypes, + CheckErrorKind::CouldNotDetermineMatchTypes, ), ( "(define-private (foo) (if (> 1 0) (ok 1) (err u8))) (match (foo) ok-val (+ 1 ok-val) err-val (/ err-val u0))", - CheckErrors::MatchArmsMustMatch( + CheckErrorKind::MatchArmsMustMatch( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), ), ( "(match (some 1) inner-value (+ 1 inner-value) (> 1 28))", - CheckErrors::MatchArmsMustMatch( + CheckErrorKind::MatchArmsMustMatch( Box::new(TypeSignature::IntType), Box::new(TypeSignature::BoolType), ), ), ( "(match (some 1) inner-value (+ 1 inner-value))", - CheckErrors::BadMatchOptionSyntax(Box::new(CheckErrors::IncorrectArgumentCount(4, 3))), + CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::IncorrectArgumentCount( + 4, 3, + ))), ), ( "(match (ok 1) inner-value (+ 1 inner-value))", - CheckErrors::BadMatchResponseSyntax(Box::new(CheckErrors::IncorrectArgumentCount( - 5, 3, - ))), + CheckErrorKind::BadMatchResponseSyntax(Box::new( + CheckErrorKind::IncorrectArgumentCount(5, 3), + )), ), ( "(match (ok 1) 1 (+ 1 1) err-val (+ 2 err-val))", - CheckErrors::BadMatchResponseSyntax(Box::new(CheckErrors::ExpectedName)), + CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)), ), ( "(match (ok 1) ok-val (+ 1 1) (+ 3 4) (+ 2 err-val))", - CheckErrors::BadMatchResponseSyntax(Box::new(CheckErrors::ExpectedName)), + CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)), ), ( "(match (some 1) 2 (+ 1 1) (+ 3 4))", - CheckErrors::BadMatchOptionSyntax(Box::new(CheckErrors::ExpectedName)), + CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::ExpectedName)), ), - ("(match)", CheckErrors::RequiresAtLeastArguments(1, 0)), + ("(match)", CheckErrorKind::RequiresAtLeastArguments(1, 0)), ( "(match 1 ok-val (/ ok-val 0) err-val (+ err-val 7))", - CheckErrors::BadMatchInput(Box::new(TypeSignature::IntType)), + CheckErrorKind::BadMatchInput(Box::new(TypeSignature::IntType)), ), ( "(default-to 3 5)", - CheckErrors::ExpectedOptionalType(Box::new(TypeSignature::IntType)), + CheckErrorKind::ExpectedOptionalType(Box::new(TypeSignature::IntType)), ), ( "(define-private (foo (x int)) (match (some 3) x (+ x 2) 5))", - CheckErrors::NameAlreadyUsed("x".to_string()), + CheckErrorKind::NameAlreadyUsed("x".to_string()), ), ( "(define-private (t1 (x uint)) (if (> x u1) (ok x) (err false))) @@ -389,7 +391,7 @@ fn test_destructuring_opts() { (if (> x u4) (err u3) (ok (+ u2 (try! (t1 x))))))", - CheckErrors::ReturnTypesMustMatch( + CheckErrorKind::ReturnTypesMustMatch( Box::new( TypeSignature::new_response(TypeSignature::NoType, TypeSignature::BoolType) .unwrap(), @@ -404,7 +406,7 @@ fn test_destructuring_opts() { "(define-private (t1 (x uint)) (if (> x u1) (ok x) (err false))) (define-private (t2 (x uint)) (> u2 (try! (t1 x))))", - CheckErrors::ReturnTypesMustMatch( + CheckErrorKind::ReturnTypesMustMatch( Box::new( TypeSignature::new_response(TypeSignature::NoType, TypeSignature::BoolType) .unwrap(), @@ -414,18 +416,24 @@ fn test_destructuring_opts() { ), ( "(try! (ok 3))", - CheckErrors::CouldNotDetermineResponseErrType, + CheckErrorKind::CouldNotDetermineResponseErrType, + ), + ( + "(try! none)", + CheckErrorKind::CouldNotDetermineResponseOkType, ), - ("(try! none)", CheckErrors::CouldNotDetermineResponseOkType), ( "(try! (err 3))", - CheckErrors::CouldNotDetermineResponseOkType, + CheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(try! 3)", - CheckErrors::ExpectedOptionalOrResponseType(Box::new(TypeSignature::IntType)), + CheckErrorKind::ExpectedOptionalOrResponseType(Box::new(TypeSignature::IntType)), + ), + ( + "(try! (ok 3) 4)", + CheckErrorKind::IncorrectArgumentCount(1, 2), ), - ("(try! (ok 3) 4)", CheckErrors::IncorrectArgumentCount(1, 2)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -452,11 +460,11 @@ fn test_at_block() { let bad = [ ( "(at-block (sha512 u0) u1)", - CheckErrors::TypeError(Box::new(BUFF_32.clone()), Box::new(BUFF_64.clone())), + CheckErrorKind::TypeError(Box::new(BUFF_32.clone()), Box::new(BUFF_64.clone())), ), ( "(at-block (sha256 u0) u1 u2)", - CheckErrors::IncorrectArgumentCount(2, 3), + CheckErrorKind::IncorrectArgumentCount(2, 3), ), ]; @@ -497,7 +505,7 @@ fn test_trait_reference_unknown() { fn test_unexpected_use_of_field_or_trait_reference() { let bad = [( "(+ 1 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR.contract.field)", - CheckErrors::UnexpectedTraitOrFieldReference, + CheckErrorKind::UnexpectedTraitOrFieldReference, )]; for (bad_test, expected) in bad.iter() { @@ -522,12 +530,12 @@ fn test_simple_arithmetic_checks() { "(and (or true false) (+ 1 2 3))", ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::RequiresAtLeastArguments(1, 0), - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::UndefinedVariable("x".to_string()), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::RequiresAtLeastArguments(1, 0), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::UndefinedVariable("x".to_string()), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -588,14 +596,14 @@ fn test_simple_hash_checks() { for bad_test in bad_types.iter() { assert!(matches!( *type_check_helper(bad_test).unwrap_err().err, - CheckErrors::UnionTypeError(_, _) + CheckErrorKind::UnionTypeError(_, _) )); } for bad_test in invalid_args.iter() { assert!(matches!( *type_check_helper(bad_test).unwrap_err().err, - CheckErrors::IncorrectArgumentCount(_, _) + CheckErrorKind::IncorrectArgumentCount(_, _) )); } } @@ -618,10 +626,10 @@ fn test_simple_ifs() { ]; let bad_expected = [ - CheckErrors::IfArmsMustMatch(Box::new(BoolType), Box::new(IntType)), - CheckErrors::IfArmsMustMatch(Box::new(ascii_type(1)), Box::new(BoolType)), - CheckErrors::IncorrectArgumentCount(3, 0), - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IfArmsMustMatch(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IfArmsMustMatch(Box::new(ascii_type(1)), Box::new(BoolType)), + CheckErrorKind::IncorrectArgumentCount(3, 0), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -654,9 +662,9 @@ fn test_simple_lets() { ]; let bad_expected = [ - CheckErrors::BadSyntaxBinding(SyntaxBindingError::let_binding_invalid_length(0)), - CheckErrors::BadSyntaxBinding(SyntaxBindingError::let_binding_not_atom(0)), - CheckErrors::TypeError( + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_invalid_length(0)), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_not_atom(0)), + CheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), @@ -711,26 +719,26 @@ fn test_index_of() { ]; let bad_expected = [ - CheckErrors::ExpectedSequence(Box::new(TypeSignature::IntType)), - CheckErrors::TypeError( + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), + CheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::min_buffer().unwrap()), Box::new(TypeSignature::min_string_ascii().unwrap()), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::min_string_utf8().unwrap()), Box::new(TypeSignature::min_string_ascii().unwrap()), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::min_string_ascii().unwrap()), Box::new(TypeSignature::min_string_utf8().unwrap()), ), - CheckErrors::CouldNotDetermineType, - CheckErrors::CouldNotDetermineType, - CheckErrors::CouldNotDetermineType, + CheckErrorKind::CouldNotDetermineType, + CheckErrorKind::CouldNotDetermineType, + CheckErrorKind::CouldNotDetermineType, ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -759,11 +767,11 @@ fn test_element_at() { let bad = ["(element-at (list 1 2 3 4 5) 100)", "(element-at 3 u100)"]; let bad_expected = [ - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrors::ExpectedSequence(Box::new(TypeSignature::IntType)), + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -795,12 +803,12 @@ fn test_eqs() { ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrors::TypeError( + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::TypeError( Box::new(TypeSignature::list_of(IntType, 1).unwrap()), Box::new(IntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::from_string( "(optional bool)", ClarityVersion::Clarity1, @@ -842,9 +850,9 @@ fn test_asserts() { ]; let bad_expected = [ - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(2, 3), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(2, 3), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -908,23 +916,23 @@ fn test_lists() { "(map + (list 1 2 3 4 5) (list true true true true true))", ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(BoolType), Box::new(buff_type(20))), - CheckErrors::TypeError(Box::new(BoolType), Box::new(buff_type(20))), - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(2, 3), - CheckErrors::UnknownFunction("ynot".to_string()), - CheckErrors::IllegalOrUnknownFunctionApplication("if".to_string()), - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), - CheckErrors::ExpectedSequence(Box::new(UIntType)), - CheckErrors::ExpectedSequence(Box::new(IntType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(buff_type(20))), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(buff_type(20))), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(2, 3), + CheckErrorKind::UnknownFunction("ynot".to_string()), + CheckErrorKind::IllegalOrUnknownFunctionApplication("if".to_string()), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), + CheckErrorKind::ExpectedSequence(Box::new(UIntType)), + CheckErrorKind::ExpectedSequence(Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -965,20 +973,20 @@ fn test_buff() { "(len 1)", ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(BoolType), Box::new(buff_type(20))), - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(2, 3), - CheckErrors::UnknownFunction("ynot".to_string()), - CheckErrors::IllegalOrUnknownFunctionApplication("if".to_string()), - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), - CheckErrors::ExpectedSequence(Box::new(UIntType)), - CheckErrors::ExpectedSequence(Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(buff_type(20))), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(2, 3), + CheckErrorKind::UnknownFunction("ynot".to_string()), + CheckErrorKind::IllegalOrUnknownFunctionApplication("if".to_string()), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), + CheckErrorKind::ExpectedSequence(Box::new(UIntType)), + CheckErrorKind::ExpectedSequence(Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1053,9 +1061,9 @@ fn test_native_as_max_len() { "(as-max-len? 0x01 u1048577)", ]; let bad_expected = [ - CheckErrors::ValueTooLarge, - CheckErrors::ValueTooLarge, - CheckErrors::ValueTooLarge, + CheckErrorKind::ValueTooLarge, + CheckErrorKind::ValueTooLarge, + CheckErrorKind::ValueTooLarge, ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { assert_eq!(*expected, *type_check_helper(bad_test).unwrap_err().err); @@ -1099,9 +1107,9 @@ fn test_native_append() { ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(IntType), Box::new(UIntType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(2, 1), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(2, 1), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { assert_eq!(*expected, *type_check_helper(bad_test).unwrap_err().err); @@ -1127,9 +1135,9 @@ fn test_native_concat() { ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(IntType), Box::new(UIntType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(2, 1), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(2, 1), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { assert_eq!(*expected, *type_check_helper(bad_test).unwrap_err().err); @@ -1225,8 +1233,8 @@ fn test_tuples() { ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1256,7 +1264,7 @@ fn test_empty_tuple_should_fail() { ) .unwrap_err() .err, - CheckErrors::EmptyTuplesNotAllowed + CheckErrorKind::EmptyTuplesNotAllowed ); } @@ -1352,9 +1360,9 @@ fn test_simple_uints() { let bad = ["(> u1 1)", "(to-uint true)", "(to-int false)"]; let bad_expected = [ - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(BoolType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1415,7 +1423,7 @@ fn test_response_inference() { ]; let bad_expected = [ - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::from_string( "(response bool int)", ClarityVersion::Clarity1, @@ -1423,8 +1431,8 @@ fn test_response_inference() { )), Box::new(BoolType), ), - CheckErrors::ReturnTypesMustMatch(Box::new(IntType), Box::new(BoolType)), - CheckErrors::CouldNotDetermineResponseOkType, + CheckErrorKind::ReturnTypesMustMatch(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::CouldNotDetermineResponseOkType, ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1562,7 +1570,7 @@ fn test_options() { .unwrap_err() .err { - CheckErrors::TypeError(t1, t2) => { + CheckErrorKind::TypeError(t1, t2) => { *t1 == TypeSignature::from_string( "(optional bool)", ClarityVersion::Clarity1, @@ -1714,7 +1722,7 @@ fn test_missing_value_on_declaration_should_fail() { .unwrap_err(); assert!(matches!( *res.err, - CheckErrors::IncorrectArgumentCount(_, _) + CheckErrorKind::IncorrectArgumentCount(_, _) )); } @@ -1730,7 +1738,7 @@ fn test_mismatching_type_on_declaration_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); } #[test] @@ -1751,7 +1759,7 @@ fn test_mismatching_type_on_update_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); } #[test] @@ -1768,7 +1776,7 @@ fn test_direct_access_to_persisted_var_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::UndefinedVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); } #[test] @@ -1788,7 +1796,7 @@ fn test_data_var_shadowed_by_let_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NameAlreadyUsed(_))); + assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -1806,7 +1814,7 @@ fn test_mutating_unknown_data_var_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NoSuchDataVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::NoSuchDataVariable(_))); } #[test] @@ -1822,7 +1830,7 @@ fn test_accessing_unknown_data_var_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NoSuchDataVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::NoSuchDataVariable(_))); } #[test] @@ -1838,7 +1846,7 @@ fn test_let_shadowed_by_let_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NameAlreadyUsed(_))); + assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -1855,7 +1863,7 @@ fn test_let_shadowed_by_nested_let_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NameAlreadyUsed(_))); + assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -1873,7 +1881,7 @@ fn test_define_constant_shadowed_by_let_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NameAlreadyUsed(_))); + assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -1890,7 +1898,7 @@ fn test_define_constant_shadowed_by_argument_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NameAlreadyUsed(_))); + assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -2112,7 +2120,7 @@ fn test_fetch_entry_mismatching_type_signatures() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); } } @@ -2132,7 +2140,7 @@ fn test_fetch_entry_unbound_variables() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::UndefinedVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); } } @@ -2184,7 +2192,7 @@ fn test_insert_entry_mismatching_type_signatures() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); } } @@ -2207,7 +2215,7 @@ fn test_insert_entry_unbound_variables() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::UndefinedVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); } } @@ -2257,7 +2265,7 @@ fn test_delete_entry_mismatching_type_signatures() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); } } @@ -2277,7 +2285,7 @@ fn test_delete_entry_unbound_variables() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::UndefinedVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); } } @@ -2331,7 +2339,7 @@ fn test_set_entry_mismatching_type_signatures() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); } } @@ -2354,7 +2362,7 @@ fn test_set_entry_unbound_variables() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrors::UndefinedVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); } } @@ -2489,7 +2497,7 @@ fn test_buff_negative_len() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert_eq!(*res.err, CheckErrors::ValueOutOfBounds); + assert_eq!(*res.err, CheckErrorKind::ValueOutOfBounds); } #[test] @@ -2503,7 +2511,7 @@ fn test_string_ascii_negative_len() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert_eq!(*res.err, CheckErrors::ValueOutOfBounds); + assert_eq!(*res.err, CheckErrorKind::ValueOutOfBounds); } #[test] @@ -2517,5 +2525,5 @@ fn test_string_utf8_negative_len() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert_eq!(*res.err, CheckErrors::ValueOutOfBounds); + assert_eq!(*res.err, CheckErrorKind::ValueOutOfBounds); } diff --git a/clarity/src/vm/analysis/type_checker/v2_1/contexts.rs b/clarity/src/vm/analysis/type_checker/v2_1/contexts.rs index 2d068554c3..7d6cc27d1a 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/contexts.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/contexts.rs @@ -16,7 +16,7 @@ use std::collections::{BTreeMap, HashMap, HashSet}; -use crate::vm::analysis::errors::{CheckError, CheckErrors}; +use crate::vm::analysis::errors::{CheckError, CheckErrorKind}; use crate::vm::analysis::type_checker::is_reserved_word; use crate::vm::analysis::types::ContractAnalysis; use crate::vm::representations::ClarityName; @@ -171,7 +171,9 @@ impl ContractContext { pub fn check_name_used(&self, name: &str) -> Result<(), CheckError> { if is_reserved_word(name, self.clarity_version) { - return Err(CheckError::new(CheckErrors::ReservedWord(name.to_string()))); + return Err(CheckError::new(CheckErrorKind::ReservedWord( + name.to_string(), + ))); } if self.variable_types.contains_key(name) @@ -183,7 +185,7 @@ impl ContractContext { || self.traits.is_name_used(name) || self.map_types.contains_key(name) { - Err(CheckError::new(CheckErrors::NameAlreadyUsed( + Err(CheckError::new(CheckErrorKind::NameAlreadyUsed( name.to_string(), ))) } else { diff --git a/clarity/src/vm/analysis/type_checker/v2_1/mod.rs b/clarity/src/vm/analysis/type_checker/v2_1/mod.rs index 131186958c..9e1a03d663 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/mod.rs @@ -27,7 +27,7 @@ use super::contexts::{TypeMap, TypingContext}; use super::ContractAnalysis; pub use crate::vm::analysis::errors::{ check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckError, - CheckErrors, SyntaxBindingErrorType, + CheckErrorKind, SyntaxBindingErrorType, }; use crate::vm::analysis::AnalysisDatabase; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -161,9 +161,9 @@ pub fn compute_typecheck_cost( ) } -pub fn check_argument_len(expected: usize, args_len: usize) -> Result<(), CheckErrors> { +pub fn check_argument_len(expected: usize, args_len: usize) -> Result<(), CheckErrorKind> { if args_len != expected { - Err(CheckErrors::IncorrectArgumentCount(expected, args_len)) + Err(CheckErrorKind::IncorrectArgumentCount(expected, args_len)) } else { Ok(()) } @@ -192,7 +192,7 @@ impl FunctionType { if !admitted { return ( cost, - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(arg_type.clone()), ) @@ -211,7 +211,7 @@ impl FunctionType { let return_type = match arg_type { TypeSignature::IntType => Ok(Some(TypeSignature::IntType)), TypeSignature::UIntType => Ok(Some(TypeSignature::UIntType)), - _ => Err(CheckErrors::UnionTypeError( + _ => Err(CheckErrorKind::UnionTypeError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(arg_type.clone()), ) @@ -220,10 +220,10 @@ impl FunctionType { (cost, return_type) } else { let return_type = accumulated_type - .ok_or_else(|| CheckErrors::Expects("Failed to set accumulated type for arg indices >= 1 in variadic arithmetic".into()).into()); + .ok_or_else(|| CheckErrorKind::Expects("Failed to set accumulated type for arg indices >= 1 in variadic arithmetic".into()).into()); let check_result = return_type.and_then(|return_type| { if arg_type != return_type { - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(return_type.clone()), Box::new(arg_type.clone()), ) @@ -246,7 +246,10 @@ impl FunctionType { // note: argument count will be wrong? return ( None, - Err(CheckErrors::IncorrectArgumentCount(arg_types.len(), arg_index).into()), + Err( + CheckErrorKind::IncorrectArgumentCount(arg_types.len(), arg_index) + .into(), + ), ); } (None, Ok(None)) @@ -259,7 +262,7 @@ impl FunctionType { if arg_index >= 1 { return ( None, - Err(CheckErrors::IncorrectArgumentCount(1, arg_index).into()), + Err(CheckErrorKind::IncorrectArgumentCount(1, arg_index).into()), ); } (None, Ok(None)) @@ -270,7 +273,7 @@ impl FunctionType { if arg_index >= 2 { return ( None, - Err(CheckErrors::IncorrectArgumentCount(2, arg_index).into()), + Err(CheckErrorKind::IncorrectArgumentCount(2, arg_index).into()), ); } (None, Ok(None)) @@ -290,7 +293,7 @@ impl FunctionType { for found_type in args.iter() { analysis_typecheck_cost(accounting, expected_type, found_type)?; if !expected_type.admits_type(&StacksEpochId::Epoch21, found_type)? { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(found_type.clone()), ) @@ -308,7 +311,7 @@ impl FunctionType { { analysis_typecheck_cost(accounting, expected_type, found_type)?; if !expected_type.admits_type(&StacksEpochId::Epoch21, found_type)? { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(found_type.clone()), ) @@ -327,7 +330,7 @@ impl FunctionType { } } Err( - CheckErrors::UnionTypeError(arg_types.clone(), Box::new(found_type.clone())) + CheckErrorKind::UnionTypeError(arg_types.clone(), Box::new(found_type.clone())) .into(), ) } @@ -356,12 +359,12 @@ impl FunctionType { } let (first, rest) = args .split_first() - .ok_or(CheckErrors::RequiresAtLeastArguments(1, args.len()))?; + .ok_or(CheckErrorKind::RequiresAtLeastArguments(1, args.len()))?; analysis_typecheck_cost(accounting, &TypeSignature::IntType, first)?; let return_type = match first { TypeSignature::IntType => Ok(TypeSignature::IntType), TypeSignature::UIntType => Ok(TypeSignature::UIntType), - _ => Err(CheckErrors::UnionTypeError( + _ => Err(CheckErrorKind::UnionTypeError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(first.clone()), )), @@ -369,7 +372,7 @@ impl FunctionType { for found_type in rest.iter() { analysis_typecheck_cost(accounting, &TypeSignature::IntType, found_type)?; if found_type != &return_type { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(return_type.clone()), Box::new(found_type.clone()), ) @@ -403,7 +406,7 @@ impl FunctionType { }; if !first_type_supported { - return Err(CheckErrors::UnionTypeError( + return Err(CheckErrorKind::UnionTypeError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -445,7 +448,7 @@ impl FunctionType { }; if !pair_of_types_matches { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(first.clone()), Box::new(second.clone()), ) @@ -490,7 +493,7 @@ impl FunctionType { depth: u8, ) -> Result { if depth > MAX_TYPE_DEPTH { - return Err(CheckErrors::TypeSignatureTooDeep.into()); + return Err(CheckErrorKind::TypeSignatureTooDeep.into()); } Ok(match value { @@ -560,7 +563,7 @@ impl FunctionType { ) -> Result { let (expected_args, returns) = match self { FunctionType::Fixed(FixedFunction { args, returns }) => (args, returns), - _ => return Err(CheckErrors::Expects("Unexpected function type".into()).into()), + _ => return Err(CheckErrorKind::Expects("Unexpected function type".into()).into()), }; check_argument_count(expected_args.len(), func_args)?; @@ -574,7 +577,7 @@ impl FunctionType { let contract_to_check = db .load_contract(contract, &StacksEpochId::Epoch21)? .ok_or_else(|| { - CheckErrors::NoSuchContract(contract.name.to_string()) + CheckErrorKind::NoSuchContract(contract.name.to_string()) })?; let trait_definition = db .get_defined_trait( @@ -582,8 +585,8 @@ impl FunctionType { &trait_id.name, &StacksEpochId::Epoch21, ) - .map_err(|_| CheckErrors::Expects("Failed to get trait".into()))? - .ok_or(CheckErrors::NoSuchContract( + .map_err(|_| CheckErrorKind::Expects("Failed to get trait".into()))? + .ok_or(CheckErrorKind::NoSuchContract( trait_id.contract_identifier.to_string(), ))?; contract_to_check.check_trait_compliance( @@ -595,7 +598,7 @@ impl FunctionType { (expected_type, value) => { if !expected_type.admits(&StacksEpochId::Epoch21, value)? { let actual_type = TypeSignature::type_of(value)?; - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -634,7 +637,7 @@ fn check_function_arg_signature( FunctionArgSignature::Single(expected_type) => { analysis_typecheck_cost(cost_tracker, expected_type, actual_type)?; if !expected_type.admits_type(&StacksEpochId::Epoch21, actual_type)? { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -651,7 +654,7 @@ fn check_function_arg_signature( } } if !admitted { - return Err(CheckErrors::UnionTypeError( + return Err(CheckErrorKind::UnionTypeError( expected_types.clone(), Box::new(actual_type.clone()), ) @@ -732,14 +735,14 @@ pub fn clarity2_trait_check_trait_compliance( func, tracker, ) { - return Err(CheckErrors::IncompatibleTrait( + return Err(CheckErrorKind::IncompatibleTrait( Box::new(expected_trait_identifier.clone()), Box::new(actual_trait_identifier.clone()), ) .into()); } } else { - return Err(CheckErrors::IncompatibleTrait( + return Err(CheckErrorKind::IncompatibleTrait( Box::new(expected_trait_identifier.clone()), Box::new(actual_trait_identifier.clone()), ) @@ -760,7 +763,7 @@ fn clarity2_inner_type_check_type( tracker: &mut T, ) -> Result { if depth > MAX_TYPE_DEPTH { - return Err(CheckErrors::TypeSignatureTooDeep.into()); + return Err(CheckErrorKind::TypeSignatureTooDeep.into()); } // Recurse into values to check embedded traits properly @@ -813,7 +816,7 @@ fn clarity2_inner_type_check_type( tracker, )?; } else { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -825,7 +828,7 @@ fn clarity2_inner_type_check_type( TypeSignature::TupleType(expected_tuple_type), ) => { if expected_tuple_type.get_type_map().len() != atom_tuple_type.get_type_map().len() { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -845,7 +848,7 @@ fn clarity2_inner_type_check_type( )?; } None => { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -891,7 +894,9 @@ fn clarity2_inner_type_check_type( } None => { runtime_cost(ClarityCostFunction::AnalysisFetchContractEntry, tracker, 1)?; - return Err(CheckErrors::NoSuchContract(contract_identifier.to_string()).into()); + return Err( + CheckErrorKind::NoSuchContract(contract_identifier.to_string()).into(), + ); } }; let expected_trait = @@ -921,7 +926,7 @@ fn clarity2_inner_type_check_type( (TypeSignature::NoType, _) => (), (_, _) => { if !expected_type.admits_type(&StacksEpochId::Epoch21, actual_type)? { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -943,7 +948,7 @@ fn clarity2_lookup_trait( if contract_context.is_contract(&trait_id.contract_identifier) { return Ok(contract_context .get_trait(trait_id) - .ok_or(CheckErrors::NoSuchTrait( + .ok_or(CheckErrorKind::NoSuchTrait( trait_id.contract_identifier.to_string(), trait_id.name.to_string(), ))? @@ -970,7 +975,7 @@ fn clarity2_lookup_trait( } Ok(None) => { runtime_cost(ClarityCostFunction::AnalysisUseTraitEntry, tracker, 1)?; - Err(CheckErrors::NoSuchTrait( + Err(CheckErrorKind::NoSuchTrait( trait_id.contract_identifier.to_string(), trait_id.name.to_string(), ) @@ -1008,14 +1013,14 @@ fn type_reserved_variable( let var_type = match variable { TxSender => TypeSignature::PrincipalType, TxSponsor => TypeSignature::new_option(TypeSignature::PrincipalType) - .map_err(|_| CheckErrors::Expects("Bad construction".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad construction".into()))?, ContractCaller => TypeSignature::PrincipalType, BlockHeight => TypeSignature::UIntType, StacksBlockHeight => TypeSignature::UIntType, TenureHeight => TypeSignature::UIntType, BurnBlockHeight => TypeSignature::UIntType, NativeNone => TypeSignature::new_option(no_type()) - .map_err(|_| CheckErrors::Expects("Bad construction".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad construction".into()))?, NativeTrue => TypeSignature::BoolType, NativeFalse => TypeSignature::BoolType, TotalLiquidMicroSTX => TypeSignature::UIntType, @@ -1081,7 +1086,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &return_type, ) .map_err(|_| { - CheckErrors::ReturnTypesMustMatch( + CheckErrorKind::ReturnTypesMustMatch( Box::new(expected_type), Box::new(return_type), ) @@ -1112,7 +1117,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { } Err(e) => Err(e), })? - .ok_or_else(|| CheckErrors::Expects("Expected a depth result".into()))?; + .ok_or_else(|| CheckErrorKind::Expects("Expected a depth result".into()))?; } runtime_cost(ClarityCostFunction::AnalysisStorage, self, size)?; @@ -1187,7 +1192,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { let type_return = self.type_check(&args[ix], context)?; if ix + 1 < args.len() { if type_return.is_response_type() { - return_failure = Err(CheckErrors::UncheckedIntermediaryResponses); + return_failure = Err(CheckErrorKind::UncheckedIntermediaryResponses); } } else { last_return = Some(type_return); @@ -1195,7 +1200,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { } let last_return = last_return - .ok_or_else(|| CheckError::new(CheckErrors::CheckerImplementationFailure))?; + .ok_or_else(|| CheckError::new(CheckErrorKind::CheckerImplementationFailure))?; return_failure?; Ok(last_return) @@ -1258,9 +1263,9 @@ impl<'a, 'b> TypeChecker<'a, 'b> { } } if let Err(mut check_error) = check_result { - if let CheckErrors::IncorrectArgumentCount(expected, _actual) = *check_error.err { + if let CheckErrorKind::IncorrectArgumentCount(expected, _actual) = *check_error.err { check_error.err = - Box::new(CheckErrors::IncorrectArgumentCount(expected, args.len())); + Box::new(CheckErrorKind::IncorrectArgumentCount(expected, args.len())); check_error.diagnostic = Diagnostic::err(check_error.err.as_ref()); } // accumulate the checking costs @@ -1290,10 +1295,10 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result<(ClarityName, FixedFunction), CheckError> { let (function_name, args) = signature .split_first() - .ok_or(CheckErrors::RequiresAtLeastArguments(1, 0))?; + .ok_or(CheckErrorKind::RequiresAtLeastArguments(1, 0))?; let function_name = function_name .match_atom() - .ok_or(CheckErrors::BadFunctionName)?; + .ok_or(CheckErrorKind::BadFunctionName)?; let args = parse_name_type_pairs::<(), CheckError>( StacksEpochId::Epoch21, args, @@ -1302,7 +1307,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { )?; if self.function_return_tracker.is_some() { - return Err(CheckErrors::Expects( + return Err(CheckErrorKind::Expects( "Interpreter error: Previous function define left dirty typecheck state.".into(), ) .into()); @@ -1358,7 +1363,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &return_type, ) .map_err(|_| { - CheckErrors::ReturnTypesMustMatch( + CheckErrorKind::ReturnTypesMustMatch( Box::new(expected.clone()), Box::new(return_type), ) @@ -1398,10 +1403,10 @@ impl<'a, 'b> TypeChecker<'a, 'b> { // should we set the type of the subexpressions of the signature to no-type as well? let key_type = TypeSignature::parse_type_repr(StacksEpochId::Epoch21, key_type, &mut ()) - .map_err(|_| CheckErrors::BadMapTypeDefinition)?; + .map_err(|_| CheckErrorKind::BadMapTypeDefinition)?; let value_type = TypeSignature::parse_type_repr(StacksEpochId::Epoch21, value_type, &mut ()) - .map_err(|_| CheckErrors::BadMapTypeDefinition)?; + .map_err(|_| CheckErrorKind::BadMapTypeDefinition)?; Ok((map_name.clone(), (key_type, value_type))) } @@ -1433,19 +1438,19 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result { let (function_name, args) = expression .split_first() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; self.type_map.set_type(function_name, no_type())?; let function_name = function_name .match_atom() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; if let Some(type_result) = self.try_native_function_check(function_name, args, context) { type_result } else { let function = match self.get_function_type(function_name) { Some(FunctionType::Fixed(function)) => Ok(function), - _ => Err(CheckErrors::UnknownFunction(function_name.to_string())), + _ => Err(CheckErrorKind::UnknownFunction(function_name.to_string())), }?; for (expected_type, found_type) in function.args.iter().map(|x| &x.signature).zip(args) @@ -1477,7 +1482,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { // be undefined. This early error prevents a cost function error // due to `context.depth` being 0. if context.depth == 0 { - return Err(CheckErrors::UndefinedVariable(name.to_string()).into()); + return Err(CheckErrorKind::UndefinedVariable(name.to_string()).into()); } runtime_cost( @@ -1489,7 +1494,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { if let Some(type_result) = context.lookup_variable_type(name) { Ok(type_result.clone()) } else { - Err(CheckErrors::UndefinedVariable(name.to_string()).into()) + Err(CheckErrorKind::UndefinedVariable(name.to_string()).into()) } } } @@ -1508,7 +1513,9 @@ impl<'a, 'b> TypeChecker<'a, 'b> { let contract_to_check = self .db .load_contract(contract_identifier, &StacksEpochId::Epoch21)? - .ok_or(CheckErrors::NoSuchContract(contract_identifier.to_string()))?; + .ok_or(CheckErrorKind::NoSuchContract( + contract_identifier.to_string(), + ))?; let contract_defining_trait = self .db @@ -1516,13 +1523,13 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &trait_identifier.contract_identifier, &StacksEpochId::Epoch21, )? - .ok_or(CheckErrors::NoSuchContract( + .ok_or(CheckErrorKind::NoSuchContract( trait_identifier.contract_identifier.to_string(), ))?; let trait_definition = contract_defining_trait .get_defined_trait(&trait_identifier.name) - .ok_or(CheckErrors::NoSuchTrait( + .ok_or(CheckErrorKind::NoSuchTrait( trait_identifier.contract_identifier.to_string(), trait_identifier.name.to_string(), ))?; @@ -1539,7 +1546,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { analysis_typecheck_cost(self, expected_type, &actual_type)?; if !expected_type.admits_type(&StacksEpochId::Epoch21, &actual_type)? { - let mut err: CheckError = CheckErrors::TypeError( + let mut err: CheckError = CheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -1563,7 +1570,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { Atom(ref name) => self.lookup_variable(name, context)?, List(ref expression) => self.type_check_function_application(expression, context)?, TraitReference(_, _) | Field(_) => { - return Err(CheckErrors::UnexpectedTraitOrFieldReference.into()); + return Err(CheckErrorKind::UnexpectedTraitOrFieldReference.into()); } }; @@ -1601,7 +1608,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { Atom(ref name) => self.lookup_variable(name, context)?, List(ref expression) => self.type_check_function_application(expression, context)?, TraitReference(_, _) | Field(_) => { - return Err(CheckErrors::UnexpectedTraitOrFieldReference.into()); + return Err(CheckErrorKind::UnexpectedTraitOrFieldReference.into()); } }; @@ -1633,7 +1640,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result<(ClarityName, TypeSignature), CheckError> { let expected_type = TypeSignature::parse_type_repr::<()>(StacksEpochId::Epoch21, var_type, &mut ()) - .map_err(|_e| CheckErrors::DefineVariableBadSignature)?; + .map_err(|_e| CheckErrorKind::DefineVariableBadSignature)?; self.type_check_expects(initial, context, &expected_type)?; @@ -1661,7 +1668,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result<(ClarityName, TypeSignature), CheckError> { let asset_type = TypeSignature::parse_type_repr::<()>(StacksEpochId::Epoch21, nft_type, &mut ()) - .map_err(|_| CheckErrors::DefineNFTBadSignature)?; + .map_err(|_| CheckErrorKind::DefineNFTBadSignature)?; Ok((asset_name.clone(), asset_type)) } @@ -1736,7 +1743,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { .add_public_function_type(f_name, FunctionType::Fixed(f_type))?; return Ok(Some(())); } else { - return Err(CheckErrors::PublicFunctionMustReturnResponse(Box::new( + return Err(CheckErrorKind::PublicFunctionMustReturnResponse(Box::new( f_type.returns, )) .into()); @@ -1879,7 +1886,9 @@ impl<'a, 'b> TypeChecker<'a, 'b> { None => { // still had to do a db read, even if it didn't exist! runtime_cost(ClarityCostFunction::AnalysisUseTraitEntry, self, 1)?; - return Err(CheckErrors::TraitReferenceUnknown(name.to_string()).into()); + return Err( + CheckErrorKind::TraitReferenceUnknown(name.to_string()).into() + ); } } } diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/assets.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/assets.rs index fbd2e251c4..c473df3c85 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/assets.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/assets.rs @@ -17,7 +17,7 @@ use stacks_common::consts::TOKEN_TRANSFER_MEMO_LENGTH; use super::{TypeChecker, TypingContext}; -use crate::vm::analysis::errors::{check_argument_count, CheckError, CheckErrors}; +use crate::vm::analysis::errors::{check_argument_count, CheckError, CheckErrorKind}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::representations::SymbolicExpression; @@ -30,13 +30,13 @@ pub fn check_special_get_owner( ) -> Result { check_argument_count(2, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_asset_type = checker .contract_context .get_nft_type(asset_name) .cloned() - .ok_or_else(|| CheckErrors::NoSuchNFT(asset_name.to_string()))?; + .ok_or_else(|| CheckErrorKind::NoSuchNFT(asset_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -58,10 +58,10 @@ pub fn check_special_get_balance( ) -> Result { check_argument_count(2, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; if !checker.contract_context.ft_exists(asset_name) { - return Err(CheckErrors::NoSuchFT(asset_name.to_string()).into()); + return Err(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } runtime_cost(ClarityCostFunction::AnalysisTypeLookup, checker, 1)?; @@ -79,13 +79,13 @@ pub fn check_special_mint_asset( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; let expected_asset_type = checker .contract_context .get_nft_type(asset_name) - .ok_or(CheckErrors::NoSuchNFT(asset_name.to_string()))? + .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))? .clone(); // this clone shouldn't be strictly necessary, but to use `type_check_expects` with this, it would have to be. runtime_cost( @@ -110,7 +110,7 @@ pub fn check_special_mint_token( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_amount: TypeSignature = TypeSignature::UIntType; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; @@ -121,7 +121,7 @@ pub fn check_special_mint_token( checker.type_check_expects(&args[2], context, &expected_owner_type)?; if !checker.contract_context.ft_exists(asset_name) { - return Err(CheckErrors::NoSuchFT(asset_name.to_string()).into()); + return Err(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } Ok(TypeSignature::ResponseType(Box::new(( @@ -137,13 +137,13 @@ pub fn check_special_transfer_asset( ) -> Result { check_argument_count(4, args)?; - let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; let expected_asset_type = checker .contract_context .get_nft_type(token_name) - .ok_or(CheckErrors::NoSuchNFT(token_name.to_string()))? + .ok_or(CheckErrorKind::NoSuchNFT(token_name.to_string()))? .clone(); runtime_cost( @@ -169,7 +169,7 @@ pub fn check_special_transfer_token( ) -> Result { check_argument_count(4, args)?; - let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_amount: TypeSignature = TypeSignature::UIntType; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; @@ -181,7 +181,7 @@ pub fn check_special_transfer_token( checker.type_check_expects(&args[3], context, &expected_owner_type)?; // recipient if !checker.contract_context.ft_exists(token_name) { - return Err(CheckErrors::NoSuchFT(token_name.to_string()).into()); + return Err(CheckErrorKind::NoSuchFT(token_name.to_string()).into()); } Ok(TypeSignature::ResponseType(Box::new(( @@ -225,7 +225,7 @@ pub fn check_special_stx_transfer_memo( let to_type: TypeSignature = TypeSignature::PrincipalType; let memo_type: TypeSignature = TypeSignature::SequenceType(SequenceSubtype::BufferType( BufferLength::try_from(TOKEN_TRANSFER_MEMO_LENGTH as u32) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, )); runtime_cost(ClarityCostFunction::AnalysisTypeLookup, checker, 0)?; @@ -248,10 +248,10 @@ pub fn check_special_get_token_supply( ) -> Result { check_argument_count(1, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; if !checker.contract_context.ft_exists(asset_name) { - return Err(CheckErrors::NoSuchFT(asset_name.to_string()).into()); + return Err(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } runtime_cost(ClarityCostFunction::AnalysisTypeLookup, checker, 1)?; @@ -266,13 +266,13 @@ pub fn check_special_burn_asset( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; let expected_asset_type = checker .contract_context .get_nft_type(asset_name) - .ok_or(CheckErrors::NoSuchNFT(asset_name.to_string()))? + .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))? .clone(); // this clone shouldn't be strictly necessary, but to use `type_check_expects` with this, it would have to be. runtime_cost( @@ -297,7 +297,7 @@ pub fn check_special_burn_token( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let expected_amount: TypeSignature = TypeSignature::UIntType; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; @@ -308,7 +308,7 @@ pub fn check_special_burn_token( checker.type_check_expects(&args[2], context, &expected_owner_type)?; if !checker.contract_context.ft_exists(asset_name) { - return Err(CheckErrors::NoSuchFT(asset_name.to_string()).into()); + return Err(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } Ok(TypeSignature::ResponseType(Box::new(( diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/maps.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/maps.rs index 2dbc240798..4c9d7c3801 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/maps.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/maps.rs @@ -17,7 +17,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::analysis::type_checker::v2_1::{ - check_arguments_at_least, CheckError, CheckErrors, TypeChecker, TypingContext, + check_arguments_at_least, CheckError, CheckErrorKind, TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost}; @@ -31,14 +31,14 @@ pub fn check_special_fetch_entry( ) -> Result { check_arguments_at_least(2, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; let key_type = checker.type_check(&args[1], context)?; let (expected_key_type, value_type) = checker .contract_context .get_map_type(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -55,7 +55,7 @@ pub fn check_special_fetch_entry( let option_type = TypeSignature::new_option(value_type.clone())?; if !expected_key_type.admits_type(&StacksEpochId::Epoch21, &key_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(CheckError::new(CheckErrorKind::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) @@ -71,14 +71,14 @@ pub fn check_special_delete_entry( ) -> Result { check_arguments_at_least(2, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; let key_type = checker.type_check(&args[1], context)?; let (expected_key_type, _) = checker .contract_context .get_map_type(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -88,7 +88,7 @@ pub fn check_special_delete_entry( analysis_typecheck_cost(&mut checker.cost_track, expected_key_type, &key_type)?; if !expected_key_type.admits_type(&StacksEpochId::Epoch21, &key_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(CheckError::new(CheckErrorKind::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) @@ -104,7 +104,7 @@ fn check_set_or_insert_entry( ) -> Result { check_arguments_at_least(3, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; let key_type = checker.type_check(&args[1], context)?; let value_type = checker.type_check(&args[2], context)?; @@ -112,7 +112,7 @@ fn check_set_or_insert_entry( let (expected_key_type, expected_value_type) = checker .contract_context .get_map_type(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -129,12 +129,12 @@ fn check_set_or_insert_entry( analysis_typecheck_cost(&mut checker.cost_track, expected_value_type, &value_type)?; if !expected_key_type.admits_type(&StacksEpochId::Epoch21, &key_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(CheckError::new(CheckErrorKind::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) } else if !expected_value_type.admits_type(&StacksEpochId::Epoch21, &value_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(CheckError::new(CheckErrorKind::TypeError( Box::new(expected_value_type.clone()), Box::new(value_type), ))) diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/mod.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/mod.rs index 161e6a5689..97d9de1d1f 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/mod.rs @@ -20,7 +20,7 @@ use super::{ check_argument_count, check_arguments_at_least, check_arguments_at_most, compute_typecheck_cost, no_type, TypeChecker, TypingContext, }; -use crate::vm::analysis::errors::{CheckError, CheckErrors, SyntaxBindingErrorType}; +use crate::vm::analysis::errors::{CheckError, CheckErrorKind, SyntaxBindingErrorType}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost, CostErrors, CostTracker}; use crate::vm::diagnostic::DiagnosableError; @@ -77,7 +77,7 @@ fn check_special_list_cons( ClarityCostFunction::AnalysisListItemsCheck, &[ty_size.into()], ) - .map_err(CheckErrors::from) + .map_err(CheckErrorKind::from) }); costs.push(cost); @@ -98,7 +98,7 @@ fn check_special_list_cons( checker.add_cost(cost?)?; } if entries_size.is_none() { - return Err(CheckErrors::ValueTooLarge.into()); + return Err(CheckErrorKind::ValueTooLarge.into()); } let typed_args = result; TypeSignature::parent_list_type(&typed_args) @@ -157,7 +157,7 @@ fn inner_handle_tuple_get( let return_type = tuple_type_sig .field_type(field_to_get) - .ok_or(CheckError::new(CheckErrors::NoSuchTupleField( + .ok_or(CheckError::new(CheckErrorKind::NoSuchTupleField( field_to_get.to_string(), tuple_type_sig.clone(), )))? @@ -172,7 +172,9 @@ fn check_special_get( ) -> Result { check_argument_count(2, args)?; - let field_to_get = args[0].match_atom().ok_or(CheckErrors::BadTupleFieldName)?; + let field_to_get = args[0] + .match_atom() + .ok_or(CheckErrorKind::BadTupleFieldName)?; let argument_type = checker.type_check(&args[1], context)?; @@ -184,10 +186,10 @@ fn check_special_get( let option_type = TypeSignature::new_option(inner_type)?; Ok(option_type) } else { - Err(CheckErrors::ExpectedTuple(value_type_sig).into()) + Err(CheckErrorKind::ExpectedTuple(value_type_sig).into()) } } else { - Err(CheckErrors::ExpectedTuple(Box::new(argument_type)).into()) + Err(CheckErrorKind::ExpectedTuple(Box::new(argument_type)).into()) } } @@ -201,13 +203,13 @@ fn check_special_merge( let res = checker.type_check(&args[0], context)?; let mut base = match res { TypeSignature::TupleType(tuple_sig) => Ok(tuple_sig), - _ => Err(CheckErrors::ExpectedTuple(Box::new(res.clone()))), + _ => Err(CheckErrorKind::ExpectedTuple(Box::new(res.clone()))), }?; let res = checker.type_check(&args[1], context)?; let mut update = match res { TypeSignature::TupleType(tuple_sig) => Ok(tuple_sig), - _ => Err(CheckErrors::ExpectedTuple(Box::new(res.clone()))), + _ => Err(CheckErrorKind::ExpectedTuple(Box::new(res.clone()))), }?; runtime_cost( ClarityCostFunction::AnalysisCheckTupleMerge, @@ -255,7 +257,7 @@ pub fn check_special_tuple_cons( .saturating_add(var_type.size()?); tuple_type_data.push((var_name.clone(), var_type)); } else { - cons_error = Err(CheckErrors::BadTupleConstruction(format!( + cons_error = Err(CheckErrorKind::BadTupleConstruction(format!( "type size of {type_size} bytes exceeds maximum of {MAX_VALUE_SIZE} bytes" ))); } @@ -266,7 +268,7 @@ pub fn check_special_tuple_cons( cons_error?; let tuple_signature = TupleTypeSignature::try_from(tuple_type_data) - .map_err(|e| CheckErrors::BadTupleConstruction(e.message()))?; + .map_err(|e| CheckErrorKind::BadTupleConstruction(e.message()))?; Ok(TypeSignature::TupleType(tuple_signature)) } @@ -281,7 +283,7 @@ fn check_special_let( let binding_list = args[0] .match_list() - .ok_or(CheckError::new(CheckErrors::BadLetSyntax))?; + .ok_or(CheckError::new(CheckErrorKind::BadLetSyntax))?; let mut out_context = context.extend()?; @@ -294,7 +296,7 @@ fn check_special_let( |var_name, var_sexp| { checker.contract_context.check_name_used(var_name)?; if out_context.lookup_variable_type(var_name).is_some() { - return Err(CheckError::new(CheckErrors::NameAlreadyUsed( + return Err(CheckError::new(CheckErrorKind::NameAlreadyUsed( var_name.to_string(), ))); } @@ -336,12 +338,12 @@ fn check_special_fetch_var( let var_name = args[0] .match_atom() - .ok_or(CheckError::new(CheckErrors::BadMapName))?; + .ok_or(CheckError::new(CheckErrorKind::BadMapName))?; let value_type = checker .contract_context .get_persisted_variable_type(var_name) - .ok_or(CheckError::new(CheckErrors::NoSuchDataVariable( + .ok_or(CheckError::new(CheckErrorKind::NoSuchDataVariable( var_name.to_string(), )))?; @@ -361,14 +363,14 @@ fn check_special_set_var( ) -> Result { check_arguments_at_least(2, args)?; - let var_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; + let var_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; let value_type = checker.type_check(&args[1], context)?; let expected_value_type = checker .contract_context .get_persisted_variable_type(var_name) - .ok_or(CheckErrors::NoSuchDataVariable(var_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchDataVariable(var_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -378,7 +380,7 @@ fn check_special_set_var( analysis_typecheck_cost(&mut checker.cost_track, &value_type, expected_value_type)?; if !expected_value_type.admits_type(&StacksEpochId::Epoch21, &value_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(CheckError::new(CheckErrorKind::TypeError( Box::new(expected_value_type.clone()), Box::new(value_type), ))) @@ -407,7 +409,7 @@ fn check_special_equals( costs.push(cost); arg_type = Some( TypeSignature::least_supertype(&StacksEpochId::Epoch21, &x_type, &cur_type) - .map_err(|_| CheckErrors::TypeError(Box::new(x_type), Box::new(cur_type))), + .map_err(|_| CheckErrorKind::TypeError(Box::new(x_type), Box::new(cur_type))), ); } } @@ -418,7 +420,7 @@ fn check_special_equals( // check if there was a least supertype failure. arg_type.ok_or_else(|| { - CheckErrors::Expects("Arg type should be set because arguments checked for >= 1".into()) + CheckErrorKind::Expects("Arg type should be set because arguments checked for >= 1".into()) })??; Ok(TypeSignature::BoolType) @@ -443,7 +445,7 @@ fn check_special_if( TypeSignature::least_supertype(&StacksEpochId::Epoch21, expr1, expr2) .and_then(|t| t.concretize()) .map_err(|_| { - CheckErrors::IfArmsMustMatch(Box::new(expr1.clone()), Box::new(expr2.clone())).into() + CheckErrorKind::IfArmsMustMatch(Box::new(expr1.clone()), Box::new(expr2.clone())).into() }) } @@ -456,7 +458,7 @@ fn check_contract_call( let func_name = args[1] .match_atom() - .ok_or(CheckError::new(CheckErrors::ContractCallExpectName))?; + .ok_or(CheckError::new(CheckErrorKind::ContractCallExpectName))?; checker.type_map.set_type(&args[1], no_type())?; let expected_sig = match &args[0].expr { @@ -480,7 +482,7 @@ fn check_contract_call( { Ok(function) } else { - Err(CheckError::new(CheckErrors::NoSuchPublicFunction( + Err(CheckError::new(CheckErrorKind::NoSuchPublicFunction( contract_identifier.to_string(), func_name.to_string(), ))) @@ -503,21 +505,22 @@ fn check_contract_call( let trait_id = match context.lookup_trait_reference_type(trait_instance) { Some(trait_id) => trait_id, _ => { - return Err( - CheckErrors::TraitReferenceUnknown(trait_instance.to_string()).into(), - ); + return Err(CheckErrorKind::TraitReferenceUnknown( + trait_instance.to_string(), + ) + .into()); } }; runtime_cost(ClarityCostFunction::AnalysisLookupFunction, checker, 0)?; let trait_signature = checker.contract_context.get_trait(trait_id).ok_or( - CheckErrors::TraitReferenceUnknown(trait_id.name.to_string()), + CheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()), )?; let func_signature = trait_signature .get(func_name) - .ok_or(CheckErrors::TraitMethodUnknown( + .ok_or(CheckErrorKind::TraitMethodUnknown( trait_id.name.to_string(), func_name.to_string(), ))?; @@ -554,7 +557,7 @@ fn check_contract_call( { Ok(function) } else { - Err(CheckError::new(CheckErrors::NoSuchPublicFunction( + Err(CheckError::new(CheckErrorKind::NoSuchPublicFunction( contract_identifier.to_string(), func_name.to_string(), ))) @@ -573,16 +576,17 @@ fn check_contract_call( } Some(var_type) => { // Any other typed constant is an error - return Err( - CheckErrors::ExpectedCallableType(Box::new(var_type.clone())).into(), - ); + return Err(CheckErrorKind::ExpectedCallableType(Box::new( + var_type.clone(), + )) + .into()); } _ => { // Dynamic dispatch let trait_id = match context.lookup_trait_reference_type(trait_instance) { Some(trait_id) => trait_id, _ => { - return Err(CheckErrors::TraitReferenceUnknown( + return Err(CheckErrorKind::TraitReferenceUnknown( trait_instance.to_string(), ) .into()); @@ -592,10 +596,10 @@ fn check_contract_call( runtime_cost(ClarityCostFunction::AnalysisLookupFunction, checker, 0)?; let trait_signature = checker.contract_context.get_trait(trait_id).ok_or( - CheckErrors::TraitReferenceUnknown(trait_id.name.to_string()), + CheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()), )?; let func_signature = trait_signature.get(func_name).ok_or( - CheckErrors::TraitMethodUnknown( + CheckErrorKind::TraitMethodUnknown( trait_id.name.to_string(), func_name.to_string(), ), @@ -612,7 +616,7 @@ fn check_contract_call( } } } - _ => return Err(CheckError::new(CheckErrors::ContractCallExpectName)), + _ => return Err(CheckError::new(CheckErrorKind::ContractCallExpectName)), }; check_argument_count(expected_sig.args.len(), &args[2..])?; @@ -632,12 +636,12 @@ fn check_contract_of( let trait_instance = match &args[0].expr { SymbolicExpressionType::Atom(trait_instance) => trait_instance, - _ => return Err(CheckError::new(CheckErrors::ContractOfExpectsTrait)), + _ => return Err(CheckError::new(CheckErrorKind::ContractOfExpectsTrait)), }; let trait_id = match context.lookup_trait_reference_type(trait_instance) { Some(trait_id) => trait_id, - _ => return Err(CheckErrors::TraitReferenceUnknown(trait_instance.to_string()).into()), + _ => return Err(CheckErrorKind::TraitReferenceUnknown(trait_instance.to_string()).into()), }; runtime_cost(ClarityCostFunction::ContractOf, checker, 1)?; @@ -645,7 +649,7 @@ fn check_contract_of( checker .contract_context .get_trait(trait_id) - .ok_or_else(|| CheckErrors::TraitReferenceUnknown(trait_id.name.to_string()))?; + .ok_or_else(|| CheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()))?; Ok(TypeSignature::PrincipalType) } @@ -659,7 +663,7 @@ fn check_principal_of( checker.type_check_expects(&args[0], context, &BUFF_33)?; Ok( TypeSignature::new_response(TypeSignature::PrincipalType, TypeSignature::UIntType) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, ) } @@ -691,13 +695,13 @@ fn check_principal_construct( ("error_code".into(), TypeSignature::UIntType), ( "value".into(), - TypeSignature::new_option(TypeSignature::PrincipalType).map_err(|_| CheckErrors::Expects("FATAL: failed to create (optional principal) type signature".into()))?, + TypeSignature::new_option(TypeSignature::PrincipalType).map_err(|_| CheckErrorKind::Expects("FATAL: failed to create (optional principal) type signature".into()))?, ), ]) - .map_err(|_| CheckErrors::Expects("FAIL: PrincipalConstruct failed to initialize type signature".into()))? + .map_err(|_| CheckErrorKind::Expects("FAIL: PrincipalConstruct failed to initialize type signature".into()))? .into() ) - .map_err(|_| CheckErrors::Expects("FATAL: failed to create `(response principal { error_code: uint, principal: (optional principal) })` type signature".into()))? + .map_err(|_| CheckErrorKind::Expects("FATAL: failed to create `(response principal { error_code: uint, principal: (optional principal) })` type signature".into()))? ) } @@ -711,7 +715,7 @@ fn check_secp256k1_recover( checker.type_check_expects(&args[1], context, &BUFF_65)?; Ok( TypeSignature::new_response(BUFF_33.clone(), TypeSignature::UIntType) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, ) } @@ -734,13 +738,13 @@ fn check_get_block_info( ) -> Result { check_arguments_at_least(2, args)?; - let block_info_prop_str = args[0] - .match_atom() - .ok_or(CheckError::new(CheckErrors::GetBlockInfoExpectPropertyName))?; + let block_info_prop_str = args[0].match_atom().ok_or(CheckError::new( + CheckErrorKind::GetBlockInfoExpectPropertyName, + ))?; let block_info_prop = BlockInfoProperty::lookup_by_name_at_version(block_info_prop_str, &checker.clarity_version) - .ok_or(CheckError::new(CheckErrors::NoSuchBlockInfoProperty( + .ok_or(CheckError::new(CheckErrorKind::NoSuchBlockInfoProperty( block_info_prop_str.to_string(), )))?; @@ -750,8 +754,8 @@ fn check_get_block_info( } // # Errors -// - `CheckErrors::GetBurnBlockInfoExpectPropertyName` when `args[0]` is not a valid `ClarityName`. -// - `CheckErrors::NoSuchBlockInfoProperty` when `args[0]` does not name a `BurnBlockInfoProperty`. +// - `CheckErrorKind::GetBurnBlockInfoExpectPropertyName` when `args[0]` is not a valid `ClarityName`. +// - `CheckErrorKind::NoSuchBlockInfoProperty` when `args[0]` does not name a `BurnBlockInfoProperty`. fn check_get_burn_block_info( checker: &mut TypeChecker, args: &[SymbolicExpression], @@ -760,20 +764,20 @@ fn check_get_burn_block_info( check_argument_count(2, args)?; let block_info_prop_str = args[0].match_atom().ok_or(CheckError::new( - CheckErrors::GetBurnBlockInfoExpectPropertyName, + CheckErrorKind::GetBurnBlockInfoExpectPropertyName, ))?; let block_info_prop = BurnBlockInfoProperty::lookup_by_name(block_info_prop_str).ok_or(CheckError::new( - CheckErrors::NoSuchBlockInfoProperty(block_info_prop_str.to_string()), + CheckErrorKind::NoSuchBlockInfoProperty(block_info_prop_str.to_string()), ))?; checker.type_check_expects(&args[1], context, &TypeSignature::UIntType)?; Ok(TypeSignature::new_option( - block_info_prop - .type_result() - .map_err(|_| CheckErrors::Expects("FAILED to type valid burn info property".into()))?, + block_info_prop.type_result().map_err(|_| { + CheckErrorKind::Expects("FAILED to type valid burn info property".into()) + })?, )?) } @@ -785,12 +789,12 @@ fn check_get_stacks_block_info( check_argument_count(2, args)?; let block_info_prop_str = args[0].match_atom().ok_or(CheckError::new( - CheckErrors::GetStacksBlockInfoExpectPropertyName, + CheckErrorKind::GetStacksBlockInfoExpectPropertyName, ))?; let block_info_prop = StacksBlockInfoProperty::lookup_by_name(block_info_prop_str).ok_or(CheckError::new( - CheckErrors::NoSuchStacksBlockInfoProperty(block_info_prop_str.to_string()), + CheckErrorKind::NoSuchStacksBlockInfoProperty(block_info_prop_str.to_string()), ))?; checker.type_check_expects(&args[1], context, &TypeSignature::UIntType)?; @@ -806,12 +810,12 @@ fn check_get_tenure_info( check_argument_count(2, args)?; let block_info_prop_str = args[0].match_atom().ok_or(CheckError::new( - CheckErrors::GetTenureInfoExpectPropertyName, + CheckErrorKind::GetTenureInfoExpectPropertyName, ))?; let block_info_prop = TenureInfoProperty::lookup_by_name(block_info_prop_str).ok_or(CheckError::new( - CheckErrors::NoSuchTenureInfoProperty(block_info_prop_str.to_string()), + CheckErrorKind::NoSuchTenureInfoProperty(block_info_prop_str.to_string()), ))?; checker.type_check_expects(&args[1], context, &TypeSignature::UIntType)?; @@ -841,7 +845,7 @@ impl TypedNativeFunction { pub fn type_native_function( function: &NativeFunctions, - ) -> Result { + ) -> Result { use self::TypedNativeFunction::{Simple, Special}; use crate::vm::functions::NativeFunctions::*; let out = match function { @@ -870,7 +874,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::IntType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -881,7 +885,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::UIntType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -892,7 +896,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -904,10 +908,10 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::SequenceType(SequenceSubtype::BufferType( BufferLength::try_from(16_u32) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, )), ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -920,10 +924,10 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::SequenceType(SequenceSubtype::BufferType( BufferLength::try_from(16_u32) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, )), ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -959,7 +963,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::BoolType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1012,7 +1016,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("owner".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1024,7 +1028,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("principal".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1032,7 +1036,7 @@ impl TypedNativeFunction { returns: { /// The return type of `principal-destruct` is a Response, in which the success /// and error types are the same. - fn parse_principal_basic_type() -> Result { + fn parse_principal_basic_type() -> Result { TupleTypeSignature::try_from(vec![ ("version".into(), BUFF_1.clone()), ("hash-bytes".into(), BUFF_20.clone()), @@ -1041,11 +1045,11 @@ impl TypedNativeFunction { TypeSignature::new_option( TypeSignature::contract_name_string_ascii_type()?, ) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, ), ]) .map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: PrincipalDestruct failed to initialize type signature" .into(), ) @@ -1061,7 +1065,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("owner".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1072,7 +1076,7 @@ impl TypedNativeFunction { ("unlock-height".into(), TypeSignature::UIntType), ]) .map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: StxGetAccount failed to initialize type signature".into(), ) })? @@ -1083,7 +1087,7 @@ impl TypedNativeFunction { FunctionArg::new( TypeSignature::UIntType, ClarityName::try_from("amount".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1091,7 +1095,7 @@ impl TypedNativeFunction { FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("sender".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1101,7 +1105,7 @@ impl TypedNativeFunction { TypeSignature::BoolType, TypeSignature::UIntType, ) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, }))), StxTransfer => Special(SpecialNativeFunction(&assets::check_special_stx_transfer)), StxTransferMemo => Special(SpecialNativeFunction( @@ -1184,13 +1188,13 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("contract".to_owned()).map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, )], returns: TypeSignature::new_response(BUFF_32.clone(), TypeSignature::UIntType) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, }))), ToAscii => Simple(SimpleNativeFunction(FunctionType::UnionArgs( vec![ @@ -1206,7 +1210,9 @@ impl TypedNativeFunction { TypeSignature::UIntType, ) .map_err(|_| { - CheckErrors::Expects("FATAL: Legal Clarity response type marked invalid".into()) + CheckErrorKind::Expects( + "FATAL: Legal Clarity response type marked invalid".into(), + ) })?, ))), }; diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/options.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/options.rs index 56d145298a..d5c7e098c7 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/options.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/options.rs @@ -19,7 +19,8 @@ use clarity_types::types::TypeSignature; use stacks_common::types::StacksEpochId; use super::{ - check_argument_count, check_arguments_at_least, no_type, CheckError, CheckErrors, TypeChecker, + check_argument_count, check_arguments_at_least, no_type, CheckError, CheckErrorKind, + TypeChecker, }; use crate::vm::analysis::type_checker::contexts::TypingContext; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -82,7 +83,7 @@ pub fn check_special_is_response( if let TypeSignature::ResponseType(_types) = input { Ok(TypeSignature::BoolType) } else { - Err(CheckErrors::ExpectedResponseType(Box::new(input.clone())).into()) + Err(CheckErrorKind::ExpectedResponseType(Box::new(input.clone())).into()) } } @@ -100,7 +101,7 @@ pub fn check_special_is_optional( if let TypeSignature::OptionalType(_type) = input { Ok(TypeSignature::BoolType) } else { - Err(CheckErrors::ExpectedOptionalType(Box::new(input.clone())).into()) + Err(CheckErrorKind::ExpectedOptionalType(Box::new(input.clone())).into()) } } @@ -120,12 +121,12 @@ pub fn check_special_default_to( let contained_type = *input_type; TypeSignature::least_supertype(&StacksEpochId::Epoch21, &default, &contained_type).map_err( |_| { - CheckErrors::DefaultTypesMustMatch(Box::new(default), Box::new(contained_type)) + CheckErrorKind::DefaultTypesMustMatch(Box::new(default), Box::new(contained_type)) .into() }, ) } else { - Err(CheckErrors::ExpectedOptionalType(Box::new(input)).into()) + Err(CheckErrorKind::ExpectedOptionalType(Box::new(input)).into()) } } @@ -153,7 +154,7 @@ fn inner_unwrap( match input { TypeSignature::OptionalType(input_type) => { if input_type.is_no_type() { - Err(CheckErrors::CouldNotDetermineResponseOkType.into()) + Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) } else { Ok(*input_type) } @@ -161,12 +162,12 @@ fn inner_unwrap( TypeSignature::ResponseType(response_type) => { let ok_type = response_type.0; if ok_type.is_no_type() { - Err(CheckErrors::CouldNotDetermineResponseOkType.into()) + Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) } else { Ok(ok_type) } } - _ => Err(CheckErrors::ExpectedOptionalOrResponseType(Box::new(input)).into()), + _ => Err(CheckErrorKind::ExpectedOptionalOrResponseType(Box::new(input)).into()), } } @@ -179,12 +180,12 @@ fn inner_unwrap_err( if let TypeSignature::ResponseType(response_type) = input { let err_type = response_type.1; if err_type.is_no_type() { - Err(CheckErrors::CouldNotDetermineResponseErrType.into()) + Err(CheckErrorKind::CouldNotDetermineResponseErrType.into()) } else { Ok(err_type) } } else { - Err(CheckErrors::ExpectedResponseType(Box::new(input)).into()) + Err(CheckErrorKind::ExpectedResponseType(Box::new(input)).into()) } } @@ -232,7 +233,7 @@ pub fn check_special_try_ret( match input { TypeSignature::OptionalType(input_type) => { if input_type.is_no_type() { - Err(CheckErrors::CouldNotDetermineResponseOkType.into()) + Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) } else { checker.track_return_type(TypeSignature::new_option(TypeSignature::NoType)?)?; Ok(*input_type) @@ -241,9 +242,9 @@ pub fn check_special_try_ret( TypeSignature::ResponseType(response_type) => { let (ok_type, err_type) = *response_type; if ok_type.is_no_type() { - Err(CheckErrors::CouldNotDetermineResponseOkType.into()) + Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) } else if err_type.is_no_type() { - Err(CheckErrors::CouldNotDetermineResponseErrType.into()) + Err(CheckErrorKind::CouldNotDetermineResponseErrType.into()) } else { checker.track_return_type(TypeSignature::new_response( TypeSignature::NoType, @@ -252,7 +253,7 @@ pub fn check_special_try_ret( Ok(ok_type) } } - _ => Err(CheckErrors::ExpectedOptionalOrResponseType(Box::new(input)).into()), + _ => Err(CheckErrorKind::ExpectedOptionalOrResponseType(Box::new(input)).into()), } } @@ -305,7 +306,7 @@ fn eval_with_new_binding( checker.contract_context.check_name_used(&bind_name)?; if inner_context.lookup_variable_type(&bind_name).is_some() { - return Err(CheckErrors::NameAlreadyUsed(bind_name.into()).into()); + return Err(CheckErrorKind::NameAlreadyUsed(bind_name.into()).into()); } inner_context.add_variable_type(bind_name, bind_type, checker.clarity_version); @@ -324,20 +325,22 @@ fn check_special_match_opt( context: &TypingContext, ) -> Result { if args.len() != 3 { - Err(CheckErrors::BadMatchOptionSyntax(Box::new( - CheckErrors::IncorrectArgumentCount(4, args.len() + 1), + Err(CheckErrorKind::BadMatchOptionSyntax(Box::new( + CheckErrorKind::IncorrectArgumentCount(4, args.len() + 1), )))?; } let bind_name = args[0] .match_atom() - .ok_or_else(|| CheckErrors::BadMatchOptionSyntax(Box::new(CheckErrors::ExpectedName)))? + .ok_or_else(|| { + CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::ExpectedName)) + })? .clone(); let some_branch = &args[1]; let none_branch = &args[2]; if option_type.is_no_type() { - return Err(CheckErrors::CouldNotDetermineMatchTypes.into()); + return Err(CheckErrorKind::CouldNotDetermineMatchTypes.into()); } let some_branch_type = @@ -352,7 +355,7 @@ fn check_special_match_opt( &none_branch_type, ) .map_err(|_| { - CheckErrors::MatchArmsMustMatch(Box::new(some_branch_type), Box::new(none_branch_type)) + CheckErrorKind::MatchArmsMustMatch(Box::new(some_branch_type), Box::new(none_branch_type)) .into() }) } @@ -364,26 +367,30 @@ fn check_special_match_resp( context: &TypingContext, ) -> Result { if args.len() != 4 { - Err(CheckErrors::BadMatchResponseSyntax(Box::new( - CheckErrors::IncorrectArgumentCount(5, args.len() + 1), + Err(CheckErrorKind::BadMatchResponseSyntax(Box::new( + CheckErrorKind::IncorrectArgumentCount(5, args.len() + 1), )))?; } let ok_bind_name = args[0] .match_atom() - .ok_or_else(|| CheckErrors::BadMatchResponseSyntax(Box::new(CheckErrors::ExpectedName)))? + .ok_or_else(|| { + CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)) + })? .clone(); let ok_branch = &args[1]; let err_bind_name = args[2] .match_atom() - .ok_or_else(|| CheckErrors::BadMatchResponseSyntax(Box::new(CheckErrors::ExpectedName)))? + .ok_or_else(|| { + CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)) + })? .clone(); let err_branch = &args[3]; let (ok_type, err_type) = resp_type; if ok_type.is_no_type() || err_type.is_no_type() { - return Err(CheckErrors::CouldNotDetermineMatchTypes.into()); + return Err(CheckErrorKind::CouldNotDetermineMatchTypes.into()); } let ok_branch_type = eval_with_new_binding(ok_branch, ok_bind_name, ok_type, checker, context)?; @@ -394,7 +401,7 @@ fn check_special_match_resp( TypeSignature::least_supertype(&StacksEpochId::Epoch21, &ok_branch_type, &err_branch_type) .map_err(|_| { - CheckErrors::MatchArmsMustMatch(Box::new(ok_branch_type), Box::new(err_branch_type)) + CheckErrorKind::MatchArmsMustMatch(Box::new(ok_branch_type), Box::new(err_branch_type)) .into() }) } @@ -415,6 +422,6 @@ pub fn check_special_match( TypeSignature::ResponseType(resp_type) => { check_special_match_resp(*resp_type, checker, &args[1..], context) } - _ => Err(CheckErrors::BadMatchInput(Box::new(input)).into()), + _ => Err(CheckErrorKind::BadMatchInput(Box::new(input)).into()), } } diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/sequences.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/sequences.rs index 92143b80b0..93c13fb04e 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/sequences.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/sequences.rs @@ -18,7 +18,7 @@ use stacks_common::types::StacksEpochId; use super::{SimpleNativeFunction, TypedNativeFunction}; use crate::vm::analysis::type_checker::v2_1::{ - check_argument_count, check_arguments_at_least, CheckError, CheckErrors, TypeChecker, + check_argument_count, check_arguments_at_least, CheckError, CheckErrorKind, TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -44,11 +44,14 @@ fn get_simple_native_or_user_define( { Ok(function_type) } else { - Err(CheckErrors::IllegalOrUnknownFunctionApplication(function_name.to_string()).into()) + Err( + CheckErrorKind::IllegalOrUnknownFunctionApplication(function_name.to_string()) + .into(), + ) } } else { checker.get_function_type(function_name).ok_or( - CheckErrors::IllegalOrUnknownFunctionApplication(function_name.to_string()).into(), + CheckErrorKind::IllegalOrUnknownFunctionApplication(function_name.to_string()).into(), ) } } @@ -62,7 +65,7 @@ pub fn check_special_map( let function_name = args[0] .match_atom() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; // we will only lookup native or defined functions here. // you _cannot_ map a special function. let function_type = get_simple_native_or_user_define(function_name, checker)?; @@ -104,7 +107,7 @@ pub fn check_special_map( // However that could lead to confusions when combining certain types: // ex: (map concat (list "hello " "hi ") "world") would fail, because // strings are handled as sequences. - return Err(CheckErrors::ExpectedSequence(Box::new(argument_type)).into()); + return Err(CheckErrorKind::ExpectedSequence(Box::new(argument_type)).into()); } }; @@ -134,8 +137,8 @@ pub fn check_special_map( } if let Err(mut check_error) = check_result { - if let CheckErrors::IncorrectArgumentCount(expected, _actual) = *check_error.err { - check_error.err = Box::new(CheckErrors::IncorrectArgumentCount( + if let CheckErrorKind::IncorrectArgumentCount(expected, _actual) = *check_error.err { + check_error.err = Box::new(CheckErrorKind::IncorrectArgumentCount( expected, args.len().saturating_sub(1), )); @@ -156,7 +159,7 @@ pub fn check_special_map( context.clarity_version, )?; TypeSignature::list_of(mapped_type, min_args) - .map_err(|_| CheckErrors::ConstructedListTooLarge.into()) + .map_err(|_| CheckErrorKind::ConstructedListTooLarge.into()) } pub fn check_special_filter( @@ -168,7 +171,7 @@ pub fn check_special_filter( let function_name = args[0] .match_atom() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; // we will only lookup native or defined functions here. // you _cannot_ map a special function. let function_type = get_simple_native_or_user_define(function_name, checker)?; @@ -179,7 +182,7 @@ pub fn check_special_filter( { let input_type = match argument_type { TypeSignature::SequenceType(ref sequence_type) => Ok(sequence_type.unit_type()?), - _ => Err(CheckErrors::ExpectedSequence(Box::new( + _ => Err(CheckErrorKind::ExpectedSequence(Box::new( argument_type.clone(), ))), }?; @@ -192,7 +195,7 @@ pub fn check_special_filter( )?; if TypeSignature::BoolType != filter_type { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(TypeSignature::BoolType), Box::new(filter_type), ) @@ -212,7 +215,7 @@ pub fn check_special_fold( let function_name = args[0] .match_atom() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; // we will only lookup native or defined functions here. // you _cannot_ fold a special function. let function_type = get_simple_native_or_user_define(function_name, checker)?; @@ -222,7 +225,7 @@ pub fn check_special_fold( let input_type = match argument_type { TypeSignature::SequenceType(sequence_type) => Ok(sequence_type.unit_type()?), - _ => Err(CheckErrors::ExpectedSequence(Box::new(argument_type))), + _ => Err(CheckErrorKind::ExpectedSequence(Box::new(argument_type))), }?; let initial_value_type = checker.type_check(&args[2], context)?; @@ -280,29 +283,29 @@ pub fn check_special_concat( )?; let new_len = lhs_max_len .checked_add(rhs_max_len) - .ok_or(CheckErrors::MaxLengthOverflow)?; + .ok_or(CheckErrorKind::MaxLengthOverflow)?; TypeSignature::list_of(list_entry_type, new_len)? } (BufferType(lhs_len), BufferType(rhs_len)) => { let size: u32 = u32::from(lhs_len) .checked_add(u32::from(rhs_len)) - .ok_or(CheckErrors::MaxLengthOverflow)?; + .ok_or(CheckErrorKind::MaxLengthOverflow)?; TypeSignature::SequenceType(BufferType(size.try_into()?)) } (StringType(ASCII(lhs_len)), StringType(ASCII(rhs_len))) => { let size: u32 = u32::from(lhs_len) .checked_add(u32::from(rhs_len)) - .ok_or(CheckErrors::MaxLengthOverflow)?; + .ok_or(CheckErrorKind::MaxLengthOverflow)?; TypeSignature::SequenceType(StringType(ASCII(size.try_into()?))) } (StringType(UTF8(lhs_len)), StringType(UTF8(rhs_len))) => { let size: u32 = u32::from(lhs_len) .checked_add(u32::from(rhs_len)) - .ok_or(CheckErrors::MaxLengthOverflow)?; + .ok_or(CheckErrorKind::MaxLengthOverflow)?; TypeSignature::SequenceType(StringType(UTF8(size.try_into()?))) } (_, _) => { - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(lhs_type.clone()), Box::new(rhs_type.clone()), ) @@ -310,7 +313,7 @@ pub fn check_special_concat( } } } - _ => return Err(CheckErrors::ExpectedSequence(Box::new(lhs_type.clone())).into()), + _ => return Err(CheckErrorKind::ExpectedSequence(Box::new(lhs_type.clone())).into()), }; Ok(res) } @@ -339,11 +342,11 @@ pub fn check_special_append( )?; let new_len = lhs_max_len .checked_add(1) - .ok_or(CheckErrors::MaxLengthOverflow)?; + .ok_or(CheckErrorKind::MaxLengthOverflow)?; let return_type = TypeSignature::list_of(list_entry_type, new_len)?; Ok(return_type) } - _ => Err(CheckErrors::ExpectedListApplication.into()), + _ => Err(CheckErrorKind::ExpectedListApplication.into()), } } @@ -358,7 +361,7 @@ pub fn check_special_as_max_len( SymbolicExpressionType::LiteralValue(Value::UInt(expected_len)) => expected_len, _ => { let expected_len_type = checker.type_check(&args[1], context)?; - return Err(CheckErrors::TypeError( + return Err(CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(expected_len_type), ) @@ -374,7 +377,8 @@ pub fn check_special_as_max_len( .type_map .set_type(&args[1], TypeSignature::UIntType)?; - let expected_len = u32::try_from(expected_len).map_err(|_e| CheckErrors::MaxLengthOverflow)?; + let expected_len = + u32::try_from(expected_len).map_err(|_e| CheckErrorKind::MaxLengthOverflow)?; let sequence = checker.type_check(&args[0], context)?; runtime_cost(ClarityCostFunction::AnalysisIterableFunc, checker, 0)?; @@ -400,7 +404,7 @@ pub fn check_special_as_max_len( StringUTF8Length::try_from(expected_len)?, )))), )), - _ => Err(CheckErrors::ExpectedSequence(Box::new(sequence)).into()), + _ => Err(CheckErrorKind::ExpectedSequence(Box::new(sequence)).into()), } } @@ -416,7 +420,7 @@ pub fn check_special_len( match collection_type { TypeSignature::SequenceType(_) => Ok(()), - _ => Err(CheckErrors::ExpectedSequence(Box::new(collection_type))), + _ => Err(CheckErrorKind::ExpectedSequence(Box::new(collection_type))), }?; Ok(TypeSignature::UIntType) @@ -445,16 +449,16 @@ pub fn check_special_element_at( TypeSignature::SequenceType(StringType(ASCII(_))) => Ok(TypeSignature::OptionalType( Box::new(TypeSignature::SequenceType(StringType(ASCII( BufferLength::try_from(1u32) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, )))), )), TypeSignature::SequenceType(StringType(UTF8(_))) => Ok(TypeSignature::OptionalType( Box::new(TypeSignature::SequenceType(StringType(UTF8( StringUTF8Length::try_from(1u32) - .map_err(|_| CheckErrors::Expects("Bad constructor".into()))?, + .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, )))), )), - _ => Err(CheckErrors::ExpectedSequence(Box::new(collection_type)).into()), + _ => Err(CheckErrorKind::ExpectedSequence(Box::new(collection_type)).into()), } } @@ -470,7 +474,7 @@ pub fn check_special_index_of( let expected_input_type = match list_type { TypeSignature::SequenceType(ref sequence_type) => Ok(sequence_type.unit_type()?), - _ => Err(CheckErrors::ExpectedSequence(Box::new(list_type))), + _ => Err(CheckErrorKind::ExpectedSequence(Box::new(list_type))), }?; checker.type_check_expects(&args[1], context, &expected_input_type)?; @@ -493,7 +497,7 @@ pub fn check_special_slice( TypeSignature::SequenceType(seq) => { TypeSignature::new_option(TypeSignature::SequenceType(seq))? } - _ => return Err(CheckErrors::ExpectedSequence(Box::new(seq_type)).into()), + _ => return Err(CheckErrorKind::ExpectedSequence(Box::new(seq_type)).into()), }; // Check left position argument @@ -517,7 +521,7 @@ pub fn check_special_replace_at( let input_type = checker.type_check(&args[0], context)?; let seq_type = match &input_type { TypeSignature::SequenceType(seq) => seq, - _ => return Err(CheckErrors::ExpectedSequence(Box::new(input_type)).into()), + _ => return Err(CheckErrorKind::ExpectedSequence(Box::new(input_type)).into()), }; let unit_seq = seq_type.unit_type()?; // Check index argument diff --git a/clarity/src/vm/analysis/type_checker/v2_1/tests/assets.rs b/clarity/src/vm/analysis/type_checker/v2_1/tests/assets.rs index a25a43a3cc..cd2c5620c0 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/tests/assets.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/tests/assets.rs @@ -21,7 +21,7 @@ use rstest_reuse::{self, *}; use stacks_common::types::StacksEpochId; use super::contracts::type_check; -use crate::vm::analysis::errors::CheckErrors; +use crate::vm::analysis::errors::CheckErrorKind; use crate::vm::ast::parse; use crate::vm::database::MemoryBackingStore; use crate::vm::tests::test_clarity_versions; @@ -173,108 +173,108 @@ fn test_bad_asset_usage() { ]; let expected = [ - CheckErrors::NoSuchFT("stackoos".to_string()), - CheckErrors::BadTokenName, - CheckErrors::BadTokenName, - CheckErrors::TypeError( + CheckErrorKind::NoSuchFT("stackoos".to_string()), + CheckErrorKind::BadTokenName, + CheckErrorKind::BadTokenName, + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::IntType), ), - CheckErrors::BadTokenName, - CheckErrors::NoSuchNFT("stackoos".to_string()), - CheckErrors::TypeError( + CheckErrorKind::BadTokenName, + CheckErrorKind::NoSuchNFT("stackoos".to_string()), + CheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(string_ascii_type(15)), ), - CheckErrors::BadTokenName, - CheckErrors::NoSuchNFT("stackoos".to_string()), - CheckErrors::TypeError( + CheckErrorKind::BadTokenName, + CheckErrorKind::NoSuchNFT("stackoos".to_string()), + CheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(string_ascii_type(15)), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::NoSuchFT("stackoos".to_string()), - CheckErrors::BadTokenName, - CheckErrors::TypeError( + CheckErrorKind::NoSuchFT("stackoos".to_string()), + CheckErrorKind::BadTokenName, + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::BoolType), ), - CheckErrors::BadTokenName, - CheckErrors::NoSuchNFT("stackoos".to_string()), - CheckErrors::TypeError( + CheckErrorKind::BadTokenName, + CheckErrorKind::NoSuchNFT("stackoos".to_string()), + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrors::BadTokenName, - CheckErrors::TypeError( + CheckErrorKind::BadTokenName, + CheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::NoSuchFT("stackoos".to_string()), - CheckErrors::BadTokenName, - CheckErrors::TypeError( + CheckErrorKind::NoSuchFT("stackoos".to_string()), + CheckErrorKind::BadTokenName, + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::BoolType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::BoolType), ), - CheckErrors::DefineNFTBadSignature, - CheckErrors::TypeError( + CheckErrorKind::DefineNFTBadSignature, + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrors::NoSuchFT("stackoos".to_string()), - CheckErrors::NoSuchFT("stackoos".to_string()), - CheckErrors::TypeError( + CheckErrorKind::NoSuchFT("stackoos".to_string()), + CheckErrorKind::NoSuchFT("stackoos".to_string()), + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::IntType), ), diff --git a/clarity/src/vm/analysis/type_checker/v2_1/tests/contracts.rs b/clarity/src/vm/analysis/type_checker/v2_1/tests/contracts.rs index 82dd67ce0e..b474e391e4 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/tests/contracts.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/tests/contracts.rs @@ -21,7 +21,7 @@ use serde_json; use stacks_common::types::StacksEpochId; use crate::vm::analysis::contract_interface_builder::build_contract_interface; -use crate::vm::analysis::errors::CheckErrors; +use crate::vm::analysis::errors::CheckErrorKind; use crate::vm::analysis::type_checker::v2_1::tests::mem_type_check; use crate::vm::analysis::{ mem_type_check as mem_run_analysis, run_analysis, AnalysisDatabase, CheckError, @@ -494,7 +494,7 @@ fn test_names_tokens_contracts_bad(#[case] version: ClarityVersion, #[case] epoc let err = db .execute(|db| type_check(&names_contract_id, &mut names_contract, db, true)) .unwrap_err(); - assert!(matches!(*err.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*err.err, CheckErrorKind::TypeError(_, _))); } #[test] @@ -535,12 +535,12 @@ fn test_bad_map_usage() { for contract in tests.iter() { let err = mem_type_check(contract).unwrap_err(); - assert!(matches!(*err.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*err.err, CheckErrorKind::TypeError(_, _))); } assert!(matches!( *mem_type_check(unhandled_option).unwrap_err().err, - CheckErrors::UnionTypeError(_, _) + CheckErrorKind::UnionTypeError(_, _) )); } @@ -627,25 +627,31 @@ fn test_expects() { for unmatched_return_types in bad_return_types_tests.iter() { let err = mem_type_check(unmatched_return_types).unwrap_err(); eprintln!("unmatched_return_types returned check error: {err}"); - assert!(matches!(*err.err, CheckErrors::ReturnTypesMustMatch(_, _))); + assert!(matches!( + *err.err, + CheckErrorKind::ReturnTypesMustMatch(_, _) + )); } let err = mem_type_check(bad_default_type).unwrap_err(); eprintln!("bad_default_types returned check error: {err}"); - assert!(matches!(*err.err, CheckErrors::DefaultTypesMustMatch(_, _))); + assert!(matches!( + *err.err, + CheckErrorKind::DefaultTypesMustMatch(_, _) + )); let err = mem_type_check(notype_response_type).unwrap_err(); eprintln!("notype_response_type returned check error: {err}"); assert!(matches!( *err.err, - CheckErrors::CouldNotDetermineResponseErrType + CheckErrorKind::CouldNotDetermineResponseErrType )); let err = mem_type_check(notype_response_type_2).unwrap_err(); eprintln!("notype_response_type_2 returned check error: {err}"); assert!(matches!( *err.err, - CheckErrors::CouldNotDetermineResponseOkType + CheckErrorKind::CouldNotDetermineResponseOkType )); } @@ -681,7 +687,7 @@ fn test_trait_to_compatible_trait() { mem_type_check(trait_to_compatible_trait).unwrap(); let err = mem_type_check_v1(trait_to_compatible_trait).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, found) => match (&*expected, &*found) { + CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -708,7 +714,7 @@ fn test_bad_principal_to_trait() { let err = mem_type_check(bad_principal_to_trait).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, found) => match (&*expected, &*found) { + CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::PrincipalType, @@ -721,7 +727,7 @@ fn test_bad_principal_to_trait() { }; let err = mem_type_check_v1(bad_principal_to_trait).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, found) => match (&*expected, &*found) { + CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::PrincipalType, @@ -750,7 +756,7 @@ fn test_bad_other_trait() { let err = mem_type_check(bad_other_trait).unwrap_err(); match *err.err { - CheckErrors::IncompatibleTrait(expected, actual) => { + CheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-2"); assert_eq!(actual.name.as_str(), "trait-1"); } @@ -758,7 +764,7 @@ fn test_bad_other_trait() { }; let err = mem_type_check_v1(bad_other_trait).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, actual) => match (&*expected, &*actual) { + CheckErrorKind::TypeError(expected, actual) => match (&*expected, &*actual) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -791,7 +797,7 @@ fn test_embedded_trait() { mem_type_check(embedded_trait).unwrap(); let err = mem_type_check_v1(embedded_trait).unwrap_err(); match *err.err { - CheckErrors::TraitReferenceUnknown(name) => { + CheckErrorKind::TraitReferenceUnknown(name) => { assert_eq!(name.as_str(), "contract"); } _ => panic!("Unexpected error: {err:?}"), @@ -821,7 +827,7 @@ fn test_embedded_trait_compatible() { mem_type_check(embedded_trait_compatible).unwrap(); let err = mem_type_check_v1(embedded_trait_compatible).unwrap_err(); match *err.err { - CheckErrors::TraitReferenceUnknown(name) => { + CheckErrorKind::TraitReferenceUnknown(name) => { assert_eq!(name.as_str(), "contract"); } _ => panic!("Unexpected error: {err:?}"), @@ -854,7 +860,7 @@ fn test_bad_embedded_trait() { let err = mem_type_check(bad_embedded_trait).unwrap_err(); match *err.err { - CheckErrors::IncompatibleTrait(expected, actual) => { + CheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-12"); assert_eq!(actual.name.as_str(), "trait-1"); } @@ -862,7 +868,7 @@ fn test_bad_embedded_trait() { }; let err = mem_type_check_v1(bad_embedded_trait).unwrap_err(); match *err.err { - CheckErrors::TraitReferenceUnknown(name) => { + CheckErrorKind::TraitReferenceUnknown(name) => { assert_eq!(name.as_str(), "contract"); } _ => panic!("Unexpected error: {err:?}"), @@ -884,7 +890,7 @@ fn test_let_trait() { mem_type_check(let_trait).unwrap(); let err = mem_type_check_v1(let_trait).unwrap_err(); match *err.err { - CheckErrors::TraitReferenceUnknown(name) => { + CheckErrorKind::TraitReferenceUnknown(name) => { assert_eq!(name.as_str(), "t1"); } _ => panic!("Unexpected error: {err:?}"), @@ -910,7 +916,7 @@ fn test_let3_trait() { mem_type_check(let3_trait).unwrap(); let err = mem_type_check_v1(let3_trait).unwrap_err(); match *err.err { - CheckErrors::TraitReferenceUnknown(name) => { + CheckErrorKind::TraitReferenceUnknown(name) => { assert_eq!(name.as_str(), "t3"); } _ => panic!("Unexpected error: {err:?}"), @@ -965,7 +971,7 @@ fn test_let3_compound_trait_call() { mem_type_check(let3_compound_trait_call).unwrap(); let err = mem_type_check_v1(let3_compound_trait_call).unwrap_err(); match *err.err { - CheckErrors::TraitReferenceUnknown(name) => { + CheckErrorKind::TraitReferenceUnknown(name) => { assert_eq!(name.as_str(), "t4"); } _ => panic!("Unexpected error: {err:?}"), @@ -989,7 +995,7 @@ fn test_trait_args_differ() { let err = mem_type_check(trait_args_differ).unwrap_err(); match *err.err { - CheckErrors::IncompatibleTrait(expected, actual) => { + CheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-2"); assert_eq!(actual.name.as_str(), "trait-1"); } @@ -997,7 +1003,7 @@ fn test_trait_args_differ() { }; let err = mem_type_check_v1(trait_args_differ).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, found) => match (&*expected, &*found) { + CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1027,7 +1033,7 @@ fn test_trait_arg_counts_differ1() { let err = mem_type_check(trait_to_compatible_trait).unwrap_err(); match *err.err { - CheckErrors::IncompatibleTrait(expected, found) => { + CheckErrorKind::IncompatibleTrait(expected, found) => { assert_eq!(expected.name.as_str(), "trait-2"); assert_eq!(found.name.as_str(), "trait-1"); } @@ -1035,7 +1041,7 @@ fn test_trait_arg_counts_differ1() { }; let err = mem_type_check_v1(trait_to_compatible_trait).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, found) => match (&*expected, &*found) { + CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1065,7 +1071,7 @@ fn test_trait_arg_counts_differ2() { let err = mem_type_check(trait_to_compatible_trait).unwrap_err(); match *err.err { - CheckErrors::IncompatibleTrait(expected, found) => { + CheckErrorKind::IncompatibleTrait(expected, found) => { assert_eq!(expected.name.as_str(), "trait-2"); assert_eq!(found.name.as_str(), "trait-1"); } @@ -1073,7 +1079,7 @@ fn test_trait_arg_counts_differ2() { }; let err = mem_type_check_v1(trait_to_compatible_trait).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, found) => match (&*expected, &*found) { + CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1103,7 +1109,7 @@ fn test_trait_ret_ty_differ() { let err = mem_type_check(trait_ret_ty_differ).unwrap_err(); match *err.err { - CheckErrors::IncompatibleTrait(expected, actual) => { + CheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-2"); assert_eq!(actual.name.as_str(), "trait-1"); } @@ -1111,7 +1117,7 @@ fn test_trait_ret_ty_differ() { }; let err = mem_type_check_v1(trait_ret_ty_differ).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, found) => match (&*expected, &*found) { + CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1149,7 +1155,7 @@ fn test_trait_with_compatible_trait_arg() { mem_type_check(trait_with_compatible_trait_arg).unwrap(); let err = mem_type_check_v1(trait_with_compatible_trait_arg).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, found) => match (&*expected, &*found) { + CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1186,7 +1192,7 @@ fn test_trait_with_bad_trait_arg() { let err = mem_type_check(trait_with_bad_trait_arg).unwrap_err(); match *err.err { - CheckErrors::IncompatibleTrait(expected, actual) => { + CheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-b"); assert_eq!(actual.name.as_str(), "trait-a"); } @@ -1194,7 +1200,7 @@ fn test_trait_with_bad_trait_arg() { }; let err = mem_type_check_v1(trait_with_bad_trait_arg).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, found) => match (&*expected, &*found) { + CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1232,7 +1238,7 @@ fn test_trait_with_superset_trait_arg() { let err = mem_type_check(trait_with_superset_trait_arg).unwrap_err(); match *err.err { - CheckErrors::IncompatibleTrait(expected, actual) => { + CheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-b"); assert_eq!(actual.name.as_str(), "trait-a"); } @@ -1242,7 +1248,7 @@ fn test_trait_with_superset_trait_arg() { let err = mem_type_check_v1(trait_with_superset_trait_arg).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, found) => match (&*expected, &*found) { + CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1281,7 +1287,7 @@ fn test_trait_with_subset_trait_arg() { mem_type_check(trait_with_subset_trait_arg).unwrap(); let err = mem_type_check_v1(trait_with_subset_trait_arg).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, found) => match (&*expected, &*found) { + CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1305,7 +1311,7 @@ fn test_trait_with_duplicate_method() { let err = mem_type_check(trait_with_duplicate_method).unwrap_err(); match *err.err { - CheckErrors::DefineTraitDuplicateMethod(method_name) => { + CheckErrorKind::DefineTraitDuplicateMethod(method_name) => { assert_eq!(method_name.as_str(), "foo"); } _ => panic!("Unexpected error: {err:?}"), @@ -1334,7 +1340,7 @@ fn test_trait_to_subtrait_and_back() { let err = mem_type_check(trait_to_subtrait_and_back).unwrap_err(); match *err.err { - CheckErrors::IncompatibleTrait(expected, actual) => { + CheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-2"); assert_eq!(actual.name.as_str(), "trait-1"); } @@ -1342,7 +1348,7 @@ fn test_trait_to_subtrait_and_back() { }; let err = mem_type_check_v1(trait_to_subtrait_and_back).unwrap_err(); match *err.err { - CheckErrors::TypeError(expected, found) => match (&*expected, &*found) { + CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1389,7 +1395,7 @@ fn test_if_branches_with_incompatible_trait_types() { )"; let err = mem_type_check(if_branches_with_incompatible_trait_types).unwrap_err(); match *err.err { - CheckErrors::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { + CheckErrorKind::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { ( TypeSignature::CallableType(CallableSubtype::Trait(trait1)), TypeSignature::CallableType(CallableSubtype::Trait(trait2)), @@ -1403,7 +1409,7 @@ fn test_if_branches_with_incompatible_trait_types() { }; let err = mem_type_check_v1(if_branches_with_incompatible_trait_types).unwrap_err(); match *err.err { - CheckErrors::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { + CheckErrorKind::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { ( TypeSignature::CallableType(CallableSubtype::Trait(trait1)), TypeSignature::CallableType(CallableSubtype::Trait(trait2)), @@ -1435,7 +1441,7 @@ fn test_if_branches_with_compatible_trait_types() { let err = mem_type_check(if_branches_with_compatible_trait_types).unwrap_err(); match *err.err { - CheckErrors::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { + CheckErrorKind::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { ( TypeSignature::CallableType(CallableSubtype::Trait(trait1)), TypeSignature::CallableType(CallableSubtype::Trait(trait2)), @@ -1449,7 +1455,7 @@ fn test_if_branches_with_compatible_trait_types() { }; let err = mem_type_check_v1(if_branches_with_compatible_trait_types).unwrap_err(); match *err.err { - CheckErrors::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { + CheckErrorKind::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { ( TypeSignature::CallableType(CallableSubtype::Trait(trait1)), TypeSignature::CallableType(CallableSubtype::Trait(trait2)), @@ -1508,7 +1514,7 @@ fn test_traits_multi_contract(#[case] version: ClarityVersion) { match result { Ok(_) if version >= ClarityVersion::Clarity2 => (), Err(CheckError { err, .. }) if version < ClarityVersion::Clarity2 => match *err { - CheckErrors::TraitMethodUnknown(trait_name, function) => { + CheckErrorKind::TraitMethodUnknown(trait_name, function) => { assert_eq!(trait_name.as_str(), "a"); assert_eq!(function.as_str(), "do-it"); } @@ -3388,7 +3394,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? 123)", "int type", - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::IntType), )), @@ -3396,7 +3402,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? u123)", "uint type", - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), )), @@ -3404,7 +3410,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? true)", "bool type", - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::BoolType), )), @@ -3412,7 +3418,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? 0x1234)", "buffer type", - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::SequenceType(SequenceSubtype::BufferType( BufferLength::try_from(2u32).unwrap(), @@ -3422,7 +3428,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? \"60 percent of the time, it works every time\")", "ascii string", - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::SequenceType(SequenceSubtype::StringType( StringSubtype::ASCII(BufferLength::try_from(43u32).unwrap()), @@ -3432,7 +3438,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? u\"I am serious, and don't call me Shirley.\")", "utf8 string", - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::SequenceType(SequenceSubtype::StringType( StringSubtype::UTF8(StringUTF8Length::try_from(40u32).unwrap()), @@ -3442,7 +3448,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? (list 1 2 3))", "list type", - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::SequenceType(SequenceSubtype::ListType( ListTypeData::new_list(TypeSignature::IntType, 3).unwrap(), @@ -3452,7 +3458,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? { a: 1, b: u2 })", "tuple type", - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::TupleType( vec![ @@ -3467,7 +3473,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? (some u789))", "optional type", - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::new_option(TypeSignature::UIntType).unwrap()), )), @@ -3475,7 +3481,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? (ok true))", "response type", - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new( TypeSignature::new_response(TypeSignature::BoolType, TypeSignature::NoType) @@ -3492,7 +3498,9 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc let expected = if version >= ClarityVersion::Clarity4 { clarity4_expected } else { - &Err(CheckErrors::UnknownFunction("contract-hash?".to_string())) + &Err(CheckErrorKind::UnknownFunction( + "contract-hash?".to_string(), + )) }; assert_eq!(&actual, expected, "Failed for test case: {description}"); @@ -3548,7 +3556,7 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ( &format!("(to-ascii? 0x{})", "ff".repeat(524285)), "oversized buffer type", - Err(CheckErrors::UnionTypeError( + Err(CheckErrorKind::UnionTypeError( to_ascii_expected_types.clone(), Box::new(TypeSignature::SequenceType(SequenceSubtype::BufferType( BufferLength::try_from(524285u32).unwrap(), @@ -3563,7 +3571,7 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ( "(to-ascii? \"60 percent of the time, it works every time\")", "ascii string", - Err(CheckErrors::UnionTypeError( + Err(CheckErrorKind::UnionTypeError( to_ascii_expected_types.clone(), Box::new(TypeSignature::SequenceType(SequenceSubtype::StringType( StringSubtype::ASCII(BufferLength::try_from(43u32).unwrap()), @@ -3573,7 +3581,7 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ( "(to-ascii? (list 1 2 3))", "list type", - Err(CheckErrors::UnionTypeError( + Err(CheckErrorKind::UnionTypeError( to_ascii_expected_types.clone(), Box::new(TypeSignature::SequenceType(SequenceSubtype::ListType( ListTypeData::new_list(TypeSignature::IntType, 3).unwrap(), @@ -3583,7 +3591,7 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ( "(to-ascii? { a: 1, b: u2 })", "tuple type", - Err(CheckErrors::UnionTypeError( + Err(CheckErrorKind::UnionTypeError( to_ascii_expected_types.clone(), Box::new(TypeSignature::TupleType( vec![ @@ -3598,7 +3606,7 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ( "(to-ascii? (some u789))", "optional type", - Err(CheckErrors::UnionTypeError( + Err(CheckErrorKind::UnionTypeError( to_ascii_expected_types.clone(), Box::new(TypeSignature::new_option(TypeSignature::UIntType).unwrap()), )), @@ -3606,7 +3614,7 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ( "(to-ascii? (ok true))", "response type", - Err(CheckErrors::UnionTypeError( + Err(CheckErrorKind::UnionTypeError( to_ascii_expected_types.clone(), Box::new( TypeSignature::new_response(TypeSignature::BoolType, TypeSignature::NoType) @@ -3623,7 +3631,7 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) let expected = if version >= ClarityVersion::Clarity4 { clarity4_expected } else { - &Err(CheckErrors::UnknownFunction("to-ascii?".to_string())) + &Err(CheckErrorKind::UnknownFunction("to-ascii?".to_string())) }; assert_eq!(&actual, expected, "Failed for test case: {description}"); diff --git a/clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs b/clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs index ac978b277b..7b839d72bf 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs @@ -20,7 +20,7 @@ use rstest::rstest; use rstest_reuse::{self, *}; use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::{CheckError, CheckErrors, SyntaxBindingError}; +use crate::vm::analysis::errors::{CheckError, CheckErrorKind, SyntaxBindingError}; use crate::vm::analysis::mem_type_check as mem_run_analysis; use crate::vm::analysis::types::ContractAnalysis; use crate::vm::ast::build_ast; @@ -87,26 +87,26 @@ fn test_from_consensus_buff() { let bad = [ ( "(from-consensus-buff?)", - CheckErrors::IncorrectArgumentCount(2, 0), + CheckErrorKind::IncorrectArgumentCount(2, 0), ), ( "(from-consensus-buff? 0x00 0x00 0x00)", - CheckErrors::IncorrectArgumentCount(2, 3), + CheckErrorKind::IncorrectArgumentCount(2, 3), ), ( "(from-consensus-buff? 0x00 0x00)", - CheckErrors::InvalidTypeDescription, + CheckErrorKind::InvalidTypeDescription, ), ( "(from-consensus-buff? int u6)", - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::max_buffer().unwrap()), Box::new(TypeSignature::UIntType), ), ), ( "(from-consensus-buff? (buff 1048576) 0x00)", - CheckErrors::ValueTooLarge, + CheckErrorKind::ValueTooLarge, ), ]; @@ -183,26 +183,26 @@ fn test_to_consensus_buff() { let bad = [ ( "(to-consensus-buff?)", - CheckErrors::IncorrectArgumentCount(1, 0), + CheckErrorKind::IncorrectArgumentCount(1, 0), ), ( "(to-consensus-buff? 0x00 0x00)", - CheckErrors::IncorrectArgumentCount(1, 2), + CheckErrorKind::IncorrectArgumentCount(1, 2), ), ( "(define-private (my-func (x (buff 1048576))) (to-consensus-buff? x))", - CheckErrors::ValueTooLarge, + CheckErrorKind::ValueTooLarge, ), ( "(define-private (my-func (x (buff 1048570))) (to-consensus-buff? x))", - CheckErrors::ValueTooLarge, + CheckErrorKind::ValueTooLarge, ), ( "(define-private (my-func (x (buff 1048567))) (to-consensus-buff? x))", - CheckErrors::ValueTooLarge, + CheckErrorKind::ValueTooLarge, ), ]; @@ -261,10 +261,10 @@ fn test_get_block_info() { "(get-block-info? time)", ]; let bad_expected = [ - CheckErrors::NoSuchBlockInfoProperty("none".to_string()), - CheckErrors::TypeError(Box::new(UIntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::RequiresAtLeastArguments(2, 1), + CheckErrorKind::NoSuchBlockInfoProperty("none".to_string()), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::RequiresAtLeastArguments(2, 1), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -296,7 +296,7 @@ fn test_get_block_info() { } for good_test in good_v210.iter() { - if let CheckErrors::NoSuchBlockInfoProperty(_) = + if let CheckErrorKind::NoSuchBlockInfoProperty(_) = *type_check_helper_v1(good_test).unwrap_err().err { } else { @@ -317,10 +317,10 @@ fn test_get_burn_block_info() { r#"(get-burn-block-info? header-hash "a")"#, ]; let bad_expected = [ - CheckErrors::NoSuchBlockInfoProperty("none".to_string()), - CheckErrors::IncorrectArgumentCount(2, 0), - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::TypeError( + CheckErrorKind::NoSuchBlockInfoProperty("none".to_string()), + CheckErrorKind::IncorrectArgumentCount(2, 0), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::TypeError( Box::new(UIntType), Box::new(SequenceType(StringType(ASCII( BufferLength::try_from(1u32).expect("BufferLength::try_from failed"), @@ -361,10 +361,10 @@ fn test_define_trait(#[case] version: ClarityVersion, #[case] epoch: StacksEpoch "(define-trait)", ]; let bad_expected = [ - CheckErrors::InvalidTypeDescription, - CheckErrors::DefineTraitBadSignature, - CheckErrors::DefineTraitBadSignature, - CheckErrors::InvalidTypeDescription, + CheckErrorKind::InvalidTypeDescription, + CheckErrorKind::DefineTraitBadSignature, + CheckErrorKind::DefineTraitBadSignature, + CheckErrorKind::InvalidTypeDescription, ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -459,42 +459,42 @@ fn test_stx_ops() { "(stx-get-balance 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR)" ]; let bad_expected = [ - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(PrincipalType), Box::new(SequenceType(BufferType( BufferLength::try_from(2_u32).unwrap(), ))), ), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(3, 5), - CheckErrors::TypeError(Box::new(PrincipalType), Box::new(UIntType)), - CheckErrors::TypeError(Box::new(PrincipalType), Box::new(BoolType)), - CheckErrors::TypeError( + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(3, 5), + CheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(UIntType)), + CheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + CheckErrorKind::TypeError( Box::new(PrincipalType), Box::new(OptionalType(Box::from(PrincipalType))), ), - CheckErrors::IncorrectArgumentCount(3, 4), - CheckErrors::TypeError( + CheckErrorKind::IncorrectArgumentCount(3, 4), + CheckErrorKind::TypeError( Box::new(PrincipalType), Box::new(SequenceType(BufferType( BufferLength::try_from(2_u32).unwrap(), ))), ), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(4, 5), - CheckErrors::TypeError(Box::new(PrincipalType), Box::new(UIntType)), - CheckErrors::TypeError(Box::new(PrincipalType), Box::new(BoolType)), - CheckErrors::TypeError( + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(4, 5), + CheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(UIntType)), + CheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + CheckErrorKind::TypeError( Box::new(PrincipalType), Box::new(OptionalType(Box::from(PrincipalType))), ), - CheckErrors::IncorrectArgumentCount(4, 3), - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::TypeError(Box::new(PrincipalType), Box::new(BoolType)), - CheckErrors::IncorrectArgumentCount(2, 3), - CheckErrors::TypeError(Box::new(PrincipalType), Box::new(BoolType)), - CheckErrors::IncorrectArgumentCount(1, 2), + CheckErrorKind::IncorrectArgumentCount(4, 3), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + CheckErrorKind::IncorrectArgumentCount(2, 3), + CheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + CheckErrorKind::IncorrectArgumentCount(1, 2), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -523,7 +523,7 @@ fn test_tx_sponsor() { ]; let bad = ["(stx-transfer? u10 tx-sponsor? 'SM2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0G)"]; - let bad_expected = [CheckErrors::TypeError( + let bad_expected = [CheckErrorKind::TypeError( Box::new(PrincipalType), Box::new(OptionalType(Box::from(PrincipalType))), )]; @@ -591,7 +591,7 @@ fn test_destructuring_opts(#[case] version: ClarityVersion, #[case] epoch: Stack let bad = [ ( "(unwrap-err! (some 2) 2)", - CheckErrors::ExpectedResponseType(Box::new(TypeSignature::from_string( + CheckErrorKind::ExpectedResponseType(Box::new(TypeSignature::from_string( "(optional int)", version, epoch, @@ -599,88 +599,92 @@ fn test_destructuring_opts(#[case] version: ClarityVersion, #[case] epoch: Stack ), ( "(unwrap! (err 3) 2)", - CheckErrors::CouldNotDetermineResponseOkType, + CheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(unwrap-err-panic (ok 3))", - CheckErrors::CouldNotDetermineResponseErrType, + CheckErrorKind::CouldNotDetermineResponseErrType, ), ( "(unwrap-panic none)", - CheckErrors::CouldNotDetermineResponseOkType, + CheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(define-private (foo) (if (> 1 0) none none)) (unwrap-panic (foo))", - CheckErrors::CouldNotDetermineResponseOkType, + CheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(unwrap-panic (err 3))", - CheckErrors::CouldNotDetermineResponseOkType, + CheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(match none inner-value (/ 1 0) (+ 1 8))", - CheckErrors::CouldNotDetermineMatchTypes, + CheckErrorKind::CouldNotDetermineMatchTypes, ), ( "(match (ok 1) ok-val (/ ok-val 0) err-val (+ err-val 7))", - CheckErrors::CouldNotDetermineMatchTypes, + CheckErrorKind::CouldNotDetermineMatchTypes, ), ( "(match (err 1) ok-val (/ ok-val 0) err-val (+ err-val 7))", - CheckErrors::CouldNotDetermineMatchTypes, + CheckErrorKind::CouldNotDetermineMatchTypes, ), ( "(define-private (foo) (if (> 1 0) (ok 1) (err u8))) (match (foo) ok-val (+ 1 ok-val) err-val (/ err-val u0))", - CheckErrors::MatchArmsMustMatch( + CheckErrorKind::MatchArmsMustMatch( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), ), ( "(match (some 1) inner-value (+ 1 inner-value) (> 1 28))", - CheckErrors::MatchArmsMustMatch( + CheckErrorKind::MatchArmsMustMatch( Box::new(TypeSignature::IntType), Box::new(TypeSignature::BoolType), ), ), ( "(match (some 1) inner-value (+ 1 inner-value))", - CheckErrors::BadMatchOptionSyntax(Box::new(CheckErrors::IncorrectArgumentCount(4, 3))), + CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::IncorrectArgumentCount( + 4, 3, + ))), ), ( "(match (ok 1) inner-value (+ 1 inner-value))", - CheckErrors::BadMatchResponseSyntax(Box::new(CheckErrors::IncorrectArgumentCount( - 5, 3, - ))), + CheckErrorKind::BadMatchResponseSyntax(Box::new( + CheckErrorKind::IncorrectArgumentCount(5, 3), + )), ), ( "(match (ok 1) 1 (+ 1 1) err-val (+ 2 err-val))", - CheckErrors::BadMatchResponseSyntax(Box::new(CheckErrors::ExpectedName)), + CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)), ), ( "(match (ok 1) ok-val (+ 1 1) (+ 3 4) (+ 2 err-val))", - CheckErrors::BadMatchResponseSyntax(Box::new(CheckErrors::ExpectedName)), + CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)), ), ( "(match (some 1) 2 (+ 1 1) (+ 3 4))", - CheckErrors::BadMatchOptionSyntax(Box::new(CheckErrors::ExpectedName)), + CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::ExpectedName)), ), - ("(match)", CheckErrors::RequiresAtLeastArguments(1, 0)), + ("(match)", CheckErrorKind::RequiresAtLeastArguments(1, 0)), ( "(match 1 ok-val (/ ok-val 0) err-val (+ err-val 7))", - CheckErrors::BadMatchInput(Box::new(TypeSignature::from_string("int", version, epoch))), + CheckErrorKind::BadMatchInput(Box::new(TypeSignature::from_string( + "int", version, epoch, + ))), ), ( "(default-to 3 5)", - CheckErrors::ExpectedOptionalType(Box::new(TypeSignature::IntType)), + CheckErrorKind::ExpectedOptionalType(Box::new(TypeSignature::IntType)), ), ( "(define-private (foo (x int)) (match (some 3) x (+ x 2) 5))", - CheckErrors::NameAlreadyUsed("x".to_string()), + CheckErrorKind::NameAlreadyUsed("x".to_string()), ), ( "(define-private (t1 (x uint)) (if (> x u1) (ok x) (err false))) @@ -688,7 +692,7 @@ fn test_destructuring_opts(#[case] version: ClarityVersion, #[case] epoch: Stack (if (> x u4) (err u3) (ok (+ u2 (try! (t1 x))))))", - CheckErrors::ReturnTypesMustMatch( + CheckErrorKind::ReturnTypesMustMatch( Box::new( TypeSignature::new_response(TypeSignature::NoType, TypeSignature::BoolType) .unwrap(), @@ -703,7 +707,7 @@ fn test_destructuring_opts(#[case] version: ClarityVersion, #[case] epoch: Stack "(define-private (t1 (x uint)) (if (> x u1) (ok x) (err false))) (define-private (t2 (x uint)) (> u2 (try! (t1 x))))", - CheckErrors::ReturnTypesMustMatch( + CheckErrorKind::ReturnTypesMustMatch( Box::new( TypeSignature::new_response(TypeSignature::NoType, TypeSignature::BoolType) .unwrap(), @@ -713,18 +717,24 @@ fn test_destructuring_opts(#[case] version: ClarityVersion, #[case] epoch: Stack ), ( "(try! (ok 3))", - CheckErrors::CouldNotDetermineResponseErrType, + CheckErrorKind::CouldNotDetermineResponseErrType, + ), + ( + "(try! none)", + CheckErrorKind::CouldNotDetermineResponseOkType, ), - ("(try! none)", CheckErrors::CouldNotDetermineResponseOkType), ( "(try! (err 3))", - CheckErrors::CouldNotDetermineResponseOkType, + CheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(try! 3)", - CheckErrors::ExpectedOptionalOrResponseType(Box::new(TypeSignature::IntType)), + CheckErrorKind::ExpectedOptionalOrResponseType(Box::new(TypeSignature::IntType)), + ), + ( + "(try! (ok 3) 4)", + CheckErrorKind::IncorrectArgumentCount(1, 2), ), - ("(try! (ok 3) 4)", CheckErrors::IncorrectArgumentCount(1, 2)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -746,11 +756,11 @@ fn test_at_block() { let bad = [ ( "(at-block (sha512 u0) u1)", - CheckErrors::TypeError(Box::new(BUFF_32.clone()), Box::new(BUFF_64.clone())), + CheckErrorKind::TypeError(Box::new(BUFF_32.clone()), Box::new(BUFF_64.clone())), ), ( "(at-block (sha256 u0) u1 u2)", - CheckErrors::IncorrectArgumentCount(2, 3), + CheckErrorKind::IncorrectArgumentCount(2, 3), ), ]; @@ -784,7 +794,7 @@ fn test_trait_reference_unknown(#[case] version: ClarityVersion, #[case] epoch: fn test_unexpected_use_of_field_or_trait_reference() { let bad = [( "(+ 1 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR.contract.field)", - CheckErrors::UnexpectedTraitOrFieldReference, + CheckErrorKind::UnexpectedTraitOrFieldReference, )]; for (bad_test, expected) in bad.iter() { @@ -831,23 +841,23 @@ fn test_bitwise_bad_checks() { "(bit-or 1 2 u4)", ]; let bad_expected = [ - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::TypeError(Box::new(IntType), Box::new(UIntType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::UnionTypeError( + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::UnionTypeError( vec![IntType, UIntType], Box::new(SequenceType(StringType(ASCII( BufferLength::try_from(5u32).unwrap(), )))), ), - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::TypeError(Box::new(IntType), Box::new(UIntType)), - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(UIntType)), + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -872,12 +882,12 @@ fn test_simple_arithmetic_checks() { "(and (or true false) (+ 1 2 3))", ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::RequiresAtLeastArguments(1, 0), - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::UndefinedVariable("x".to_string()), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::RequiresAtLeastArguments(1, 0), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::UndefinedVariable("x".to_string()), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -938,14 +948,14 @@ fn test_simple_hash_checks() { for bad_test in bad_types.iter() { assert!(matches!( *type_check_helper(bad_test).unwrap_err().err, - CheckErrors::UnionTypeError(_, _) + CheckErrorKind::UnionTypeError(_, _) )); } for bad_test in invalid_args.iter() { assert!(matches!( *type_check_helper(bad_test).unwrap_err().err, - CheckErrors::IncorrectArgumentCount(_, _) + CheckErrorKind::IncorrectArgumentCount(_, _) )); } } @@ -968,10 +978,10 @@ fn test_simple_ifs() { ]; let bad_expected = [ - CheckErrors::IfArmsMustMatch(Box::new(BoolType), Box::new(IntType)), - CheckErrors::IfArmsMustMatch(Box::new(ascii_type(1)), Box::new(BoolType)), - CheckErrors::IncorrectArgumentCount(3, 0), - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IfArmsMustMatch(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IfArmsMustMatch(Box::new(ascii_type(1)), Box::new(BoolType)), + CheckErrorKind::IncorrectArgumentCount(3, 0), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1004,9 +1014,9 @@ fn test_simple_lets() { ]; let bad_expected = [ - CheckErrors::BadSyntaxBinding(SyntaxBindingError::let_binding_invalid_length(0)), - CheckErrors::BadSyntaxBinding(SyntaxBindingError::let_binding_not_atom(0)), - CheckErrors::TypeError( + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_invalid_length(0)), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_not_atom(0)), + CheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), @@ -1079,47 +1089,47 @@ fn test_index_of() { ]; let bad_expected = [ - CheckErrors::ExpectedSequence(Box::new(TypeSignature::IntType)), - CheckErrors::TypeError( + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), + CheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::min_buffer().unwrap()), Box::new(TypeSignature::min_string_ascii().unwrap()), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::min_string_utf8().unwrap()), Box::new(TypeSignature::min_string_ascii().unwrap()), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::min_string_ascii().unwrap()), Box::new(TypeSignature::min_string_utf8().unwrap()), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::list_of(TypeSignature::IntType, 1).unwrap()), Box::new(TypeSignature::list_of(TypeSignature::IntType, 2).unwrap()), ), - CheckErrors::ExpectedSequence(Box::new(TypeSignature::IntType)), - CheckErrors::TypeError( + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), + CheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::min_buffer().unwrap()), Box::new(TypeSignature::min_string_ascii().unwrap()), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::min_string_utf8().unwrap()), Box::new(TypeSignature::min_string_ascii().unwrap()), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::min_string_ascii().unwrap()), Box::new(TypeSignature::min_string_utf8().unwrap()), ), - CheckErrors::CouldNotDetermineType, - CheckErrors::CouldNotDetermineType, - CheckErrors::CouldNotDetermineType, + CheckErrorKind::CouldNotDetermineType, + CheckErrorKind::CouldNotDetermineType, + CheckErrorKind::CouldNotDetermineType, ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -1163,16 +1173,16 @@ fn test_element_at() { ]; let bad_expected = [ - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrors::ExpectedSequence(Box::new(TypeSignature::IntType)), - CheckErrors::TypeError( + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), + CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrors::ExpectedSequence(Box::new(TypeSignature::IntType)), + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1204,12 +1214,12 @@ fn test_eqs(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) { ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrors::TypeError( + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::TypeError( Box::new(TypeSignature::list_of(IntType, 1).unwrap()), Box::new(IntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::from_string( "(optional bool)", version, @@ -1247,9 +1257,9 @@ fn test_asserts() { ]; let bad_expected = [ - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(2, 3), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(2, 3), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1313,23 +1323,23 @@ fn test_lists() { "(map + (list 1 2 3 4 5) (list true true true true true))", ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(BoolType), Box::new(buff_type(20))), - CheckErrors::TypeError(Box::new(BoolType), Box::new(buff_type(20))), - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(2, 3), - CheckErrors::UnknownFunction("ynot".to_string()), - CheckErrors::IllegalOrUnknownFunctionApplication("if".to_string()), - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), - CheckErrors::ExpectedSequence(Box::new(UIntType)), - CheckErrors::ExpectedSequence(Box::new(IntType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(buff_type(20))), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(buff_type(20))), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(2, 3), + CheckErrorKind::UnknownFunction("ynot".to_string()), + CheckErrorKind::IllegalOrUnknownFunctionApplication("if".to_string()), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), + CheckErrorKind::ExpectedSequence(Box::new(UIntType)), + CheckErrorKind::ExpectedSequence(Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1370,20 +1380,20 @@ fn test_buff() { "(len 1)", ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(BoolType), Box::new(buff_type(20))), - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(2, 3), - CheckErrors::UnknownFunction("ynot".to_string()), - CheckErrors::IllegalOrUnknownFunctionApplication("if".to_string()), - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), - CheckErrors::ExpectedSequence(Box::new(UIntType)), - CheckErrors::ExpectedSequence(Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(buff_type(20))), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(2, 3), + CheckErrorKind::UnknownFunction("ynot".to_string()), + CheckErrorKind::IllegalOrUnknownFunctionApplication("if".to_string()), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), + CheckErrorKind::ExpectedSequence(Box::new(UIntType)), + CheckErrorKind::ExpectedSequence(Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1451,9 +1461,9 @@ fn test_native_as_max_len() { "(as-max-len? 0x01 u1048577)", ]; let bad_expected = [ - CheckErrors::ValueTooLarge, - CheckErrors::ValueTooLarge, - CheckErrors::ValueTooLarge, + CheckErrorKind::ValueTooLarge, + CheckErrorKind::ValueTooLarge, + CheckErrorKind::ValueTooLarge, ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { assert_eq!(*expected, *type_check_helper(bad_test).unwrap_err().err); @@ -1497,9 +1507,9 @@ fn test_native_append() { ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(IntType), Box::new(UIntType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(2, 1), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(2, 1), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { assert_eq!(*expected, *type_check_helper(bad_test).unwrap_err().err); @@ -1537,9 +1547,9 @@ fn test_slice_list() { ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(3, 2), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(3, 2), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { assert_eq!(*expected, *type_check_helper(bad_test).unwrap_err().err); @@ -1568,9 +1578,9 @@ fn test_slice_buff() { ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(3, 2), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(3, 2), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { assert_eq!(*expected, *type_check_helper(bad_test).unwrap_err().err); @@ -1602,9 +1612,9 @@ fn test_slice_ascii() { ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(3, 2), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(3, 2), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { assert_eq!(*expected, *type_check_helper(bad_test).unwrap_err().err); @@ -1633,9 +1643,9 @@ fn test_slice_utf8() { ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(3, 2), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(3, 2), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { assert_eq!(*expected, *type_check_helper(bad_test).unwrap_err().err); @@ -1681,17 +1691,17 @@ fn test_replace_at_list() { ]; let bad_expected = [ - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(IntType), Box::new(SequenceType(ListType( ListTypeData::new_list(IntType, 1).unwrap(), ))), ), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(3, 4), - CheckErrors::IncorrectArgumentCount(3, 2), - CheckErrors::TypeError( + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(3, 4), + CheckErrorKind::IncorrectArgumentCount(3, 2), + CheckErrorKind::TypeError( Box::new(SequenceType(ListType( ListTypeData::new_list(IntType, 1).unwrap(), ))), @@ -1739,20 +1749,20 @@ fn test_replace_at_buff() { let buff_len = BufferLength::try_from(1u32).unwrap(); let buff_len_two = BufferLength::try_from(2u32).unwrap(); let bad_expected = [ - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(SequenceType(BufferType(buff_len.clone()))), Box::new(SequenceType(ListType( ListTypeData::new_list(IntType, 1).unwrap(), ))), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(SequenceType(BufferType(buff_len.clone()))), Box::new(SequenceType(StringType(ASCII(buff_len.clone())))), ), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(3, 4), - CheckErrors::IncorrectArgumentCount(3, 2), - CheckErrors::TypeError( + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(3, 4), + CheckErrorKind::IncorrectArgumentCount(3, 2), + CheckErrorKind::TypeError( Box::new(SequenceType(BufferType(buff_len))), Box::new(SequenceType(BufferType(buff_len_two))), ), @@ -1797,20 +1807,20 @@ fn test_replace_at_ascii() { let buff_len = BufferLength::try_from(1u32).unwrap(); let buff_len_two = BufferLength::try_from(2u32).unwrap(); let bad_expected = [ - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(SequenceType(StringType(ASCII(buff_len.clone())))), Box::new(SequenceType(ListType( ListTypeData::new_list(IntType, 1).unwrap(), ))), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(SequenceType(StringType(ASCII(buff_len.clone())))), Box::new(SequenceType(BufferType(buff_len.clone()))), ), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(3, 4), - CheckErrors::IncorrectArgumentCount(3, 2), - CheckErrors::TypeError( + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(3, 4), + CheckErrorKind::IncorrectArgumentCount(3, 2), + CheckErrorKind::TypeError( Box::new(SequenceType(StringType(ASCII(buff_len)))), Box::new(SequenceType(StringType(ASCII(buff_len_two)))), ), @@ -1855,20 +1865,20 @@ fn test_replace_at_utf8() { let str_len = StringUTF8Length::try_from(1u32).unwrap(); let str_len_two = StringUTF8Length::try_from(2u32).unwrap(); let bad_expected = [ - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(SequenceType(StringType(UTF8(str_len.clone())))), Box::new(SequenceType(ListType( ListTypeData::new_list(IntType, 1).unwrap(), ))), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(SequenceType(StringType(UTF8(str_len.clone())))), Box::new(SequenceType(BufferType(buff_len))), ), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(3, 4), - CheckErrors::IncorrectArgumentCount(3, 2), - CheckErrors::TypeError( + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(3, 4), + CheckErrorKind::IncorrectArgumentCount(3, 2), + CheckErrorKind::TypeError( Box::new(SequenceType(StringType(UTF8(str_len)))), Box::new(SequenceType(StringType(UTF8(str_len_two)))), ), @@ -1897,9 +1907,9 @@ fn test_native_concat() { ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(IntType), Box::new(UIntType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::IncorrectArgumentCount(2, 1), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::IncorrectArgumentCount(2, 1), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { assert_eq!(*expected, *type_check_helper(bad_test).unwrap_err().err); @@ -1982,8 +1992,8 @@ fn test_tuples() { ]; let bad_expected = [ - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(BoolType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -2007,7 +2017,7 @@ fn test_empty_tuple_should_fail() { assert_eq!( *mem_type_check(contract_src).unwrap_err().err, - CheckErrors::EmptyTuplesNotAllowed, + CheckErrorKind::EmptyTuplesNotAllowed, ); } @@ -2087,9 +2097,9 @@ fn test_simple_uints() { let bad = ["(> u1 1)", "(to-uint true)", "(to-int false)"]; let bad_expected = [ - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrors::TypeError(Box::new(UIntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(BoolType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -2121,9 +2131,9 @@ fn test_buffer_to_ints() { ]; let bad_expected = [ - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::IncorrectArgumentCount(1, 0), - CheckErrors::TypeError( + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::IncorrectArgumentCount(1, 0), + CheckErrorKind::TypeError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32).unwrap(), ))), @@ -2131,7 +2141,7 @@ fn test_buffer_to_ints() { BufferLength::try_from(17_u32).unwrap(), ))), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32).unwrap(), ))), @@ -2195,37 +2205,37 @@ fn test_string_to_ints() { ]; let bad_expected = [ - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::IncorrectArgumentCount(1, 0), - CheckErrors::UnionTypeError( + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::IncorrectArgumentCount(1, 0), + CheckErrorKind::UnionTypeError( vec![IntType, UIntType], Box::new(SequenceType(BufferType( BufferLength::try_from(17_u32).unwrap(), ))), ), - CheckErrors::UnionTypeError( + CheckErrorKind::UnionTypeError( vec![IntType, UIntType], Box::new(SequenceType(StringType(ASCII( BufferLength::try_from(1_u32).unwrap(), )))), ), - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::IncorrectArgumentCount(1, 0), - CheckErrors::UnionTypeError( + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::IncorrectArgumentCount(1, 0), + CheckErrorKind::UnionTypeError( vec![IntType, UIntType], Box::new(SequenceType(BufferType( BufferLength::try_from(17_u32).unwrap(), ))), ), - CheckErrors::UnionTypeError( + CheckErrorKind::UnionTypeError( vec![IntType, UIntType], Box::new(SequenceType(StringType(ASCII( BufferLength::try_from(1_u32).unwrap(), )))), ), - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::IncorrectArgumentCount(1, 0), - CheckErrors::UnionTypeError( + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::IncorrectArgumentCount(1, 0), + CheckErrorKind::UnionTypeError( vec![ TypeSignature::max_string_ascii().unwrap(), TypeSignature::max_string_utf8().unwrap(), @@ -2234,16 +2244,16 @@ fn test_string_to_ints() { BufferLength::try_from(17_u32).unwrap(), ))), ), - CheckErrors::UnionTypeError( + CheckErrorKind::UnionTypeError( vec![ TypeSignature::max_string_ascii().unwrap(), TypeSignature::max_string_utf8().unwrap(), ], Box::new(IntType), ), - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::IncorrectArgumentCount(1, 0), - CheckErrors::UnionTypeError( + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::IncorrectArgumentCount(1, 0), + CheckErrorKind::UnionTypeError( vec![ TypeSignature::max_string_ascii().unwrap(), TypeSignature::max_string_utf8().unwrap(), @@ -2252,7 +2262,7 @@ fn test_string_to_ints() { BufferLength::try_from(17_u32).unwrap(), ))), ), - CheckErrors::UnionTypeError( + CheckErrorKind::UnionTypeError( vec![ TypeSignature::max_string_ascii().unwrap(), TypeSignature::max_string_utf8().unwrap(), @@ -2307,7 +2317,7 @@ fn test_response_inference(#[case] version: ClarityVersion, #[case] epoch: Stack ]; let bad_expected = [ - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::from_string( "(response bool int)", version, @@ -2315,8 +2325,8 @@ fn test_response_inference(#[case] version: ClarityVersion, #[case] epoch: Stack )), Box::new(BoolType), ), - CheckErrors::ReturnTypesMustMatch(Box::new(IntType), Box::new(BoolType)), - CheckErrors::CouldNotDetermineResponseOkType, + CheckErrorKind::ReturnTypesMustMatch(Box::new(IntType), Box::new(BoolType)), + CheckErrorKind::CouldNotDetermineResponseOkType, ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -2434,7 +2444,7 @@ fn test_options(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) { if version < ClarityVersion::Clarity2 { assert!( match *mem_run_analysis(contract, version, epoch).unwrap_err().err { - CheckErrors::TypeError(t1, t2) => { + CheckErrorKind::TypeError(t1, t2) => { *t1 == TypeSignature::from_string("(optional bool)", version, epoch) && *t2 == TypeSignature::from_string("(optional int)", version, epoch) } @@ -2444,7 +2454,7 @@ fn test_options(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) { } else { assert!( match *mem_run_analysis(contract, version, epoch).unwrap_err().err { - CheckErrors::TypeError(t1, t2) => { + CheckErrorKind::TypeError(t1, t2) => { *t1 == TypeSignature::from_string("bool", version, epoch) && *t2 == TypeSignature::from_string("int", version, epoch) } @@ -2553,7 +2563,7 @@ fn test_missing_value_on_declaration_should_fail() { let res = mem_type_check(contract_src).unwrap_err(); assert!(matches!( *res.err, - CheckErrors::IncorrectArgumentCount(_, _) + CheckErrorKind::IncorrectArgumentCount(_, _) )); } @@ -2564,7 +2574,7 @@ fn test_mismatching_type_on_declaration_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); } #[test] @@ -2580,7 +2590,7 @@ fn test_mismatching_type_on_update_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); } #[test] @@ -2592,7 +2602,7 @@ fn test_direct_access_to_persisted_var_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::UndefinedVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); } #[test] @@ -2607,7 +2617,7 @@ fn test_data_var_shadowed_by_let_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NameAlreadyUsed(_))); + assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -2620,7 +2630,7 @@ fn test_mutating_unknown_data_var_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NoSuchDataVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::NoSuchDataVariable(_))); } #[test] @@ -2631,7 +2641,7 @@ fn test_accessing_unknown_data_var_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NoSuchDataVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::NoSuchDataVariable(_))); } #[test] @@ -2642,7 +2652,7 @@ fn test_let_shadowed_by_let_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NameAlreadyUsed(_))); + assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -2654,7 +2664,7 @@ fn test_let_shadowed_by_nested_let_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NameAlreadyUsed(_))); + assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -2667,7 +2677,7 @@ fn test_define_constant_shadowed_by_let_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NameAlreadyUsed(_))); + assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -2679,7 +2689,7 @@ fn test_define_constant_shadowed_by_argument_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::NameAlreadyUsed(_))); + assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -2879,7 +2889,7 @@ fn test_fetch_entry_mismatching_type_signatures() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); } } @@ -2894,7 +2904,7 @@ fn test_fetch_entry_unbound_variables() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::UndefinedVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); } } @@ -2936,7 +2946,7 @@ fn test_insert_entry_mismatching_type_signatures() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); } } @@ -2954,7 +2964,7 @@ fn test_insert_entry_unbound_variables() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::UndefinedVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); } } @@ -2994,7 +3004,7 @@ fn test_delete_entry_mismatching_type_signatures() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); } } @@ -3009,7 +3019,7 @@ fn test_delete_entry_unbound_variables() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::UndefinedVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); } } @@ -3053,7 +3063,7 @@ fn test_set_entry_mismatching_type_signatures() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::TypeError(_, _))); + assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); } } @@ -3071,7 +3081,7 @@ fn test_set_entry_unbound_variables() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrors::UndefinedVariable(_))); + assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); } } @@ -3187,7 +3197,7 @@ fn test_buff_negative_len() { (func 0x00)"; let res = mem_type_check(contract_src).unwrap_err(); - assert_eq!(*res.err, CheckErrors::ValueOutOfBounds); + assert_eq!(*res.err, CheckErrorKind::ValueOutOfBounds); } #[test] @@ -3196,7 +3206,7 @@ fn test_string_ascii_negative_len() { (func \"\")"; let res = mem_type_check(contract_src).unwrap_err(); - assert_eq!(*res.err, CheckErrors::ValueOutOfBounds); + assert_eq!(*res.err, CheckErrorKind::ValueOutOfBounds); } #[test] @@ -3205,7 +3215,7 @@ fn test_string_utf8_negative_len() { (func u\"\")"; let res = mem_type_check(contract_src).unwrap_err(); - assert_eq!(*res.err, CheckErrors::ValueOutOfBounds); + assert_eq!(*res.err, CheckErrorKind::ValueOutOfBounds); } #[test] @@ -3249,7 +3259,7 @@ fn test_comparison_types() { r#"(>= "aaa" "aaa" "aaa")"#, ]; let bad_expected = [ - CheckErrors::UnionTypeError( + CheckErrorKind::UnionTypeError( vec![ IntType, UIntType, @@ -3263,7 +3273,7 @@ fn test_comparison_types() { ], Box::new(PrincipalType), ), - CheckErrors::UnionTypeError( + CheckErrorKind::UnionTypeError( vec![ IntType, UIntType, @@ -3279,7 +3289,7 @@ fn test_comparison_types() { ListTypeData::new_list(IntType, 3).unwrap(), ))), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(SequenceType(StringType(UTF8( StringUTF8Length::try_from(3u32).unwrap(), )))), @@ -3287,7 +3297,7 @@ fn test_comparison_types() { BufferLength::try_from(2_u32).unwrap(), )))), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(SequenceType(StringType(ASCII( BufferLength::try_from(3_u32).unwrap(), )))), @@ -3295,7 +3305,7 @@ fn test_comparison_types() { BufferLength::try_from(2_u32).unwrap(), ))), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(SequenceType(BufferType( BufferLength::try_from(2_u32).unwrap(), ))), @@ -3303,7 +3313,7 @@ fn test_comparison_types() { StringUTF8Length::try_from(3u32).unwrap(), )))), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(SequenceType(BufferType( BufferLength::try_from(2_u32).unwrap(), ))), @@ -3311,9 +3321,9 @@ fn test_comparison_types() { BufferLength::try_from(3_u32).unwrap(), )))), ), - CheckErrors::IncorrectArgumentCount(2, 0), - CheckErrors::IncorrectArgumentCount(2, 1), - CheckErrors::IncorrectArgumentCount(2, 3), + CheckErrorKind::IncorrectArgumentCount(2, 0), + CheckErrorKind::IncorrectArgumentCount(2, 1), + CheckErrorKind::IncorrectArgumentCount(2, 3), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -3342,9 +3352,9 @@ fn test_principal_destruct() { r#"(principal-destruct? 0x22)"#, ]; let bad_expected = [ - CheckErrors::IncorrectArgumentCount(1, 2), - CheckErrors::IncorrectArgumentCount(1, 0), - CheckErrors::TypeError( + CheckErrorKind::IncorrectArgumentCount(1, 2), + CheckErrorKind::IncorrectArgumentCount(1, 0), + CheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(BUFF_1.clone()), ), @@ -3398,32 +3408,32 @@ fn test_principal_construct() { // Too few arguments, just has the `(buff 1)`. ( r#"(principal-construct? 0x22)"#, - CheckErrors::RequiresAtLeastArguments(2, 1), + CheckErrorKind::RequiresAtLeastArguments(2, 1), ), // Too few arguments, just hs the `(buff 20)`. ( r#"(principal-construct? 0xfa6bf38ed557fe417333710d6033e9419391a320)"#, - CheckErrors::RequiresAtLeastArguments(2, 1), + CheckErrorKind::RequiresAtLeastArguments(2, 1), ), // The first buffer is too long, should be `(buff 1)`. ( r#"(principal-construct? 0xfa6bf38ed557fe417333710d6033e9419391a320 0xfa6bf38ed557fe417333710d6033e9419391a320)"#, - CheckErrors::TypeError(Box::new(BUFF_1.clone()), Box::new(BUFF_20.clone())), + CheckErrorKind::TypeError(Box::new(BUFF_1.clone()), Box::new(BUFF_20.clone())), ), // The second buffer is too long, should be `(buff 20)`. ( r#"(principal-construct? 0x22 0xfa6bf38ed557fe417333710d6033e9419391a32009)"#, - CheckErrors::TypeError(Box::new(BUFF_20.clone()), Box::new(BUFF_21.clone())), + CheckErrorKind::TypeError(Box::new(BUFF_20.clone()), Box::new(BUFF_21.clone())), ), // `int` argument instead of `(buff 1)` for version. ( r#"(principal-construct? 22 0xfa6bf38ed557fe417333710d6033e9419391a320)"#, - CheckErrors::TypeError(Box::new(BUFF_1.clone()), Box::new(IntType.clone())), + CheckErrorKind::TypeError(Box::new(BUFF_1.clone()), Box::new(IntType.clone())), ), // `name` argument is too long ( r#"(principal-construct? 0x22 0xfa6bf38ed557fe417333710d6033e9419391a320 "foooooooooooooooooooooooooooooooooooooooo")"#, - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::contract_name_string_ascii_type().unwrap()), Box::new(TypeSignature::bound_string_ascii_type(41).unwrap()), ), @@ -3431,7 +3441,7 @@ fn test_principal_construct() { // bad argument type for `name` ( r#"(principal-construct? 0x22 0xfa6bf38ed557fe417333710d6033e9419391a320 u123)"#, - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::contract_name_string_ascii_type().unwrap()), Box::new(UIntType), ), @@ -3439,7 +3449,7 @@ fn test_principal_construct() { // too many arguments ( r#"(principal-construct? 0x22 0xfa6bf38ed557fe417333710d6033e9419391a320 "foo" "bar")"#, - CheckErrors::RequiresAtMostArguments(3, 4), + CheckErrorKind::RequiresAtMostArguments(3, 4), ), ]; @@ -3493,7 +3503,7 @@ fn test_trait_args() { )"]; let contract_identifier = QualifiedContractIdentifier::transient(); - let bad_expected = [CheckErrors::IncompatibleTrait( + let bad_expected = [CheckErrorKind::IncompatibleTrait( Box::new(TraitIdentifier { name: ClarityName::from("trait-foo"), contract_identifier: contract_identifier.clone(), @@ -3659,15 +3669,15 @@ fn test_list_arg(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ", ]; let bad_expected = [ - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::list_of(TypeSignature::IntType, 3).unwrap()), Box::new(TypeSignature::list_of(TypeSignature::IntType, 4).unwrap()), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::list_of(TypeSignature::IntType, 3).unwrap()), Box::new(TypeSignature::list_of(TypeSignature::UIntType, 1).unwrap()), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::list_of(TypeSignature::IntType, 3).unwrap()), Box::new( TypeSignature::list_of( @@ -3679,15 +3689,15 @@ fn test_list_arg(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ), ]; let bad_expected2 = [ - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::list_of(TypeSignature::IntType, 3).unwrap()), Box::new(TypeSignature::list_of(TypeSignature::IntType, 4).unwrap()), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::list_of(TypeSignature::NoType, 0).unwrap()), ), @@ -3799,17 +3809,17 @@ fn test_simple_bad_syntax_bindings() { "(from-consensus-buff? (tuple (a (string-ascii -12))) 0x00)", ]; let expected = [ - CheckErrors::BadSyntaxBinding(SyntaxBindingError::let_binding_not_list(0)), - CheckErrors::BadSyntaxBinding(SyntaxBindingError::let_binding_invalid_length(0)), - CheckErrors::BadSyntaxBinding(SyntaxBindingError::let_binding_not_atom(0)), - CheckErrors::BadSyntaxBinding(SyntaxBindingError::eval_binding_not_list(0)), - CheckErrors::BadSyntaxBinding(SyntaxBindingError::eval_binding_invalid_length(0)), - CheckErrors::BadSyntaxBinding(SyntaxBindingError::eval_binding_not_atom(0)), - CheckErrors::BadSyntaxBinding(SyntaxBindingError::tuple_cons_not_list(0)), - CheckErrors::BadSyntaxBinding(SyntaxBindingError::tuple_cons_invalid_length(0)), - CheckErrors::BadSyntaxBinding(SyntaxBindingError::tuple_cons_not_atom(0)), - CheckErrors::ValueOutOfBounds, - CheckErrors::ValueOutOfBounds, + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_not_list(0)), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_invalid_length(0)), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_not_atom(0)), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::eval_binding_not_list(0)), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::eval_binding_invalid_length(0)), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::eval_binding_not_atom(0)), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::tuple_cons_not_list(0)), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::tuple_cons_invalid_length(0)), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::tuple_cons_not_atom(0)), + CheckErrorKind::ValueOutOfBounds, + CheckErrorKind::ValueOutOfBounds, ]; for (bad_code, expected_err) in bad.iter().zip(expected.iter()) { @@ -3833,9 +3843,9 @@ fn test_nested_bad_type_signature_syntax_bindings() { ]; let expected = [ - CheckErrors::ValueOutOfBounds, - CheckErrors::InvalidTypeDescription, - CheckErrors::ValueOutOfBounds, + CheckErrorKind::ValueOutOfBounds, + CheckErrorKind::InvalidTypeDescription, + CheckErrorKind::ValueOutOfBounds, ]; for (bad_code, expected_err) in bad.iter().zip(expected.iter()) { diff --git a/clarity/src/vm/analysis/types.rs b/clarity/src/vm/analysis/types.rs index 145ce59bd3..63ec3dcde2 100644 --- a/clarity/src/vm/analysis/types.rs +++ b/clarity/src/vm/analysis/types.rs @@ -22,7 +22,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::analysis::analysis_db::AnalysisDatabase; use crate::vm::analysis::contract_interface_builder::ContractInterface; -use crate::vm::analysis::errors::{CheckError, CheckErrors}; +use crate::vm::analysis::errors::{CheckError, CheckErrorKind}; use crate::vm::analysis::type_checker::contexts::TypeMap; use crate::vm::costs::LimitedCostTracker; use crate::vm::types::signatures::FunctionSignature; @@ -242,7 +242,7 @@ impl ContractAnalysis { | (None, Some(FunctionType::Fixed(func))) => { let args_sig = func.args.iter().map(|a| a.signature.clone()).collect(); if !expected_sig.check_args_trait_compliance(epoch, args_sig)? { - return Err(CheckErrors::BadTraitImplementation( + return Err(CheckErrorKind::BadTraitImplementation( trait_name, func_name.to_string(), ) @@ -250,7 +250,7 @@ impl ContractAnalysis { } if !expected_sig.returns.admits_type(epoch, &func.returns)? { - return Err(CheckErrors::BadTraitImplementation( + return Err(CheckErrorKind::BadTraitImplementation( trait_name, func_name.to_string(), ) @@ -258,7 +258,7 @@ impl ContractAnalysis { } } (_, _) => { - return Err(CheckErrors::BadTraitImplementation( + return Err(CheckErrorKind::BadTraitImplementation( trait_name, func_name.to_string(), ) diff --git a/clarity/src/vm/callables.rs b/clarity/src/vm/callables.rs index b697b3a095..eb7ed9c97e 100644 --- a/clarity/src/vm/callables.rs +++ b/clarity/src/vm/callables.rs @@ -24,7 +24,7 @@ use super::costs::{CostErrors, CostOverflowingMath}; use super::errors::InterpreterError; use super::types::signatures::CallableSubtype; use super::ClarityVersion; -use crate::vm::analysis::errors::CheckErrors; +use crate::vm::analysis::errors::CheckErrorKind; use crate::vm::contexts::ContractContext; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; @@ -156,7 +156,7 @@ impl DefinedFunction { let mut context = LocalContext::new(); if args.len() != self.arguments.len() { - Err(CheckErrors::IncorrectArgumentCount( + Err(CheckErrorKind::IncorrectArgumentCount( self.arguments.len(), args.len(), ))? @@ -227,7 +227,7 @@ impl DefinedFunction { } _ => { if !type_sig.admits(env.epoch(), value)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(type_sig.clone()), Box::new(value.clone()), ) @@ -238,7 +238,7 @@ impl DefinedFunction { .insert(name.clone(), value.clone()) .is_some() { - return Err(CheckErrors::NameAlreadyUsed(name.to_string()).into()); + return Err(CheckErrorKind::NameAlreadyUsed(name.to_string()).into()); } } } @@ -272,7 +272,7 @@ impl DefinedFunction { } _ => { if !type_sig.admits(env.epoch(), &cast_value)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(type_sig.clone()), Box::new(cast_value), ) @@ -282,7 +282,7 @@ impl DefinedFunction { } if context.variables.insert(name.clone(), cast_value).is_some() { - return Err(CheckErrors::NameAlreadyUsed(name.to_string()).into()); + return Err(CheckErrorKind::NameAlreadyUsed(name.to_string()).into()); } } } @@ -309,11 +309,13 @@ impl DefinedFunction { let trait_name = trait_identifier.name.to_string(); let constraining_trait = contract_defining_trait .lookup_trait_definition(&trait_name) - .ok_or(CheckErrors::TraitReferenceUnknown(trait_name.to_string()))?; + .ok_or(CheckErrorKind::TraitReferenceUnknown( + trait_name.to_string(), + ))?; let expected_sig = constraining_trait .get(&self.name) - .ok_or(CheckErrors::TraitMethodUnknown( + .ok_or(CheckErrorKind::TraitMethodUnknown( trait_name.to_string(), self.name.to_string(), ))?; @@ -321,7 +323,7 @@ impl DefinedFunction { let args = self.arg_types.to_vec(); if !expected_sig.check_args_trait_compliance(epoch, args)? { return Err( - CheckErrors::BadTraitImplementation(trait_name, self.name.to_string()).into(), + CheckErrorKind::BadTraitImplementation(trait_name, self.name.to_string()).into(), ); } @@ -449,7 +451,7 @@ fn clarity2_implicit_cast(type_sig: &TypeSignature, value: &Value) -> Result ty, None => { // This should be unreachable if the type-checker has already run successfully - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(type_sig.clone()), Box::new(value.clone()), ) diff --git a/clarity/src/vm/clarity.rs b/clarity/src/vm/clarity.rs index 979d815268..92c3195588 100644 --- a/clarity/src/vm/clarity.rs +++ b/clarity/src/vm/clarity.rs @@ -2,7 +2,7 @@ use std::fmt; use stacks_common::types::StacksEpochId; -use crate::vm::analysis::{AnalysisDatabase, CheckError, CheckErrors, ContractAnalysis}; +use crate::vm::analysis::{AnalysisDatabase, CheckError, CheckErrorKind, ContractAnalysis}; use crate::vm::ast::errors::{ParseError, ParseErrors}; use crate::vm::ast::{ASTRules, ContractAST}; use crate::vm::contexts::{AssetMap, Environment, OwnedEnvironment}; @@ -66,14 +66,14 @@ impl std::error::Error for Error { impl From for Error { fn from(e: CheckError) -> Self { match *e.err { - CheckErrors::CostOverflow => { + CheckErrorKind::CostOverflow => { Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - CheckErrors::CostBalanceExceeded(a, b) => Error::CostError(a, b), - CheckErrors::MemoryBalanceExceeded(_a, _b) => { + CheckErrorKind::CostBalanceExceeded(a, b) => Error::CostError(a, b), + CheckErrorKind::MemoryBalanceExceeded(_a, _b) => { Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - CheckErrors::ExecutionTimeExpired => { + CheckErrorKind::ExecutionTimeExpired => { Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } _ => Error::Analysis(e), @@ -84,13 +84,13 @@ impl From for Error { impl From for Error { fn from(e: InterpreterError) -> Self { match &e { - InterpreterError::Unchecked(CheckErrors::CostBalanceExceeded(a, b)) => { + InterpreterError::Unchecked(CheckErrorKind::CostBalanceExceeded(a, b)) => { Error::CostError(a.clone(), b.clone()) } - InterpreterError::Unchecked(CheckErrors::CostOverflow) => { + InterpreterError::Unchecked(CheckErrorKind::CostOverflow) => { Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - InterpreterError::Unchecked(CheckErrors::ExecutionTimeExpired) => { + InterpreterError::Unchecked(CheckErrorKind::ExecutionTimeExpired) => { Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } _ => Error::Interpreter(e), @@ -264,13 +264,13 @@ pub trait TransactionConnection: ClarityConnection { Ok(_) => { let result = db .commit() - .map_err(|e| CheckErrors::Expects(format!("{e:?}")).into()); + .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")).into()); (cost_tracker, result) } Err(e) => { let result = db .roll_back() - .map_err(|e| CheckErrors::Expects(format!("{e:?}")).into()); + .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")).into()); if result.is_err() { (cost_tracker, result) } else { diff --git a/clarity/src/vm/contexts.rs b/clarity/src/vm/contexts.rs index 355a0e9d53..59105ee5d6 100644 --- a/clarity/src/vm/contexts.rs +++ b/clarity/src/vm/contexts.rs @@ -37,7 +37,7 @@ use crate::vm::database::{ NonFungibleTokenMetadata, }; use crate::vm::errors::{ - CheckErrors, InterpreterError, InterpreterResult as Result, RuntimeErrorType, + CheckErrorKind, InterpreterError, InterpreterResult as Result, RuntimeErrorType, }; use crate::vm::events::*; use crate::vm::representations::SymbolicExpression; @@ -1116,11 +1116,11 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { let contract = self.global_context.database.get_contract(contract_identifier)?; let func = contract.contract_context.lookup_function(tx_name) - .ok_or_else(|| { CheckErrors::UndefinedFunction(tx_name.to_string()) })?; + .ok_or_else(|| { CheckErrorKind::UndefinedFunction(tx_name.to_string()) })?; if !allow_private && !func.is_public() { - return Err(CheckErrors::NoSuchPublicFunction(contract_identifier.to_string(), tx_name.to_string()).into()); + return Err(CheckErrorKind::NoSuchPublicFunction(contract_identifier.to_string(), tx_name.to_string()).into()); } else if read_only && !func.is_read_only() { - return Err(CheckErrors::PublicFunctionNotReadOnly(contract_identifier.to_string(), tx_name.to_string()).into()); + return Err(CheckErrorKind::PublicFunctionNotReadOnly(contract_identifier.to_string(), tx_name.to_string()).into()); } let args: Result> = args.iter() @@ -1134,7 +1134,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { self.epoch(), &expected_type, value.clone(), - ).ok_or_else(|| CheckErrors::TypeValueError( + ).ok_or_else(|| CheckErrorKind::TypeValueError( Box::new(expected_type), Box::new(value.clone()), ) @@ -1148,7 +1148,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { let func_identifier = func.get_identifier(); if self.call_stack.contains(&func_identifier) { - return Err(CheckErrors::CircularReference(vec![func_identifier.to_string()]).into()) + return Err(CheckErrorKind::CircularReference(vec![func_identifier.to_string()]).into()) } self.call_stack.insert(&func_identifier, true); let res = self.execute_function_as_transaction(&func, &args, Some(&contract.contract_context), allow_private); @@ -1290,7 +1290,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { .has_contract(&contract_identifier) { return Err( - CheckErrors::ContractAlreadyExists(contract_identifier.to_string()).into(), + CheckErrorKind::ContractAlreadyExists(contract_identifier.to_string()).into(), ); } @@ -1766,7 +1766,7 @@ impl<'a, 'hooks> GlobalContext<'a, 'hooks> { self.commit()?; Ok(result) } else { - Err(CheckErrors::PublicFunctionMustReturnResponse(Box::new( + Err(CheckErrorKind::PublicFunctionMustReturnResponse(Box::new( TypeSignature::type_of(&result)?, )) .into()) diff --git a/clarity/src/vm/costs/mod.rs b/clarity/src/vm/costs/mod.rs index 669f6f483d..c3d3103213 100644 --- a/clarity/src/vm/costs/mod.rs +++ b/clarity/src/vm/costs/mod.rs @@ -28,7 +28,7 @@ use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; use stacks_common::types::StacksEpochId; -use super::errors::{CheckErrors, RuntimeErrorType}; +use super::errors::{CheckErrorKind, RuntimeErrorType}; use crate::boot_util::boot_code_id; use crate::vm::contexts::{ContractContext, GlobalContext}; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -216,7 +216,8 @@ impl DefaultVersion { r.map_err(|e| { let e = match e { crate::vm::errors::Error::Runtime(RuntimeErrorType::NotImplemented, _) => { - CheckErrors::UndefinedFunction(cost_function_ref.function_name.clone()).into() + CheckErrorKind::UndefinedFunction(cost_function_ref.function_name.clone()) + .into() } other => other, }; diff --git a/clarity/src/vm/database/clarity_db.rs b/clarity/src/vm/database/clarity_db.rs index a895b00ddb..cf6e7143fd 100644 --- a/clarity/src/vm/database/clarity_db.rs +++ b/clarity/src/vm/database/clarity_db.rs @@ -38,7 +38,7 @@ use crate::vm::database::structures::{ }; use crate::vm::database::{ClarityBackingStore, RollbackWrapper}; use crate::vm::errors::{ - CheckErrors, Error, InterpreterError, InterpreterResult as Result, RuntimeErrorType, + CheckErrorKind, Error, InterpreterError, InterpreterResult as Result, RuntimeErrorType, }; use crate::vm::representations::ClarityName; use crate::vm::types::serialization::NONE_SERIALIZATION_LEN; @@ -553,7 +553,7 @@ impl<'a> ClarityDatabase<'a> { let (sanitized_value, did_sanitize) = Value::sanitize_value(epoch, &TypeSignature::type_of(&value)?, value) - .ok_or_else(|| CheckErrors::CouldNotDetermineType)?; + .ok_or_else(|| CheckErrorKind::CouldNotDetermineType)?; // if data needed to be sanitized *charge* for the unsanitized cost if did_sanitize { pre_sanitized_size = Some(value_size); @@ -1485,7 +1485,7 @@ impl ClarityDatabase<'_> { // will throw NoSuchFoo errors instead of NoSuchContract errors. fn map_no_contract_as_none(res: Result>) -> Result> { res.or_else(|e| match e { - Error::Unchecked(CheckErrors::NoSuchContract(_)) => Ok(None), + Error::Unchecked(CheckErrorKind::NoSuchContract(_)) => Ok(None), x => Err(x), }) } @@ -1513,7 +1513,7 @@ impl ClarityDatabase<'_> { let key = ClarityDatabase::make_metadata_key(StoreType::VariableMeta, variable_name); map_no_contract_as_none(self.fetch_metadata(contract_identifier, &key))? - .ok_or(CheckErrors::NoSuchDataVariable(variable_name.to_string()).into()) + .ok_or(CheckErrorKind::NoSuchDataVariable(variable_name.to_string()).into()) } #[cfg(any(test, feature = "testing"))] @@ -1547,7 +1547,7 @@ impl ClarityDatabase<'_> { .value_type .admits(&self.get_clarity_epoch_version()?, &value)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(variable_descriptor.value_type.clone()), Box::new(value), ) @@ -1654,7 +1654,7 @@ impl ClarityDatabase<'_> { let key = ClarityDatabase::make_metadata_key(StoreType::DataMapMeta, map_name); map_no_contract_as_none(self.fetch_metadata(contract_identifier, &key))? - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()).into()) + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()).into()) } pub fn make_key_for_data_map_entry( @@ -1706,7 +1706,7 @@ impl ClarityDatabase<'_> { .key_type .admits(&self.get_clarity_epoch_version()?, key_value)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(map_descriptor.key_type.clone()), Box::new(key_value.clone()), ) @@ -1737,7 +1737,7 @@ impl ClarityDatabase<'_> { .key_type .admits(&self.get_clarity_epoch_version()?, key_value)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(map_descriptor.key_type.clone()), Box::new(key_value.clone()), ) @@ -1880,7 +1880,7 @@ impl ClarityDatabase<'_> { .key_type .admits(&self.get_clarity_epoch_version()?, &key_value)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(map_descriptor.key_type.clone()), Box::new(key_value), ) @@ -1890,7 +1890,7 @@ impl ClarityDatabase<'_> { .value_type .admits(&self.get_clarity_epoch_version()?, &value)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(map_descriptor.value_type.clone()), Box::new(value), ) @@ -1939,7 +1939,7 @@ impl ClarityDatabase<'_> { .key_type .admits(&self.get_clarity_epoch_version()?, key_value)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(map_descriptor.key_type.clone()), Box::new(key_value.clone()), ) @@ -2010,7 +2010,7 @@ impl ClarityDatabase<'_> { let key = ClarityDatabase::make_metadata_key(StoreType::FungibleTokenMeta, token_name); map_no_contract_as_none(self.fetch_metadata(contract_identifier, &key))? - .ok_or(CheckErrors::NoSuchFT(token_name.to_string()).into()) + .ok_or(CheckErrorKind::NoSuchFT(token_name.to_string()).into()) } pub fn create_non_fungible_token( @@ -2036,7 +2036,7 @@ impl ClarityDatabase<'_> { let key = ClarityDatabase::make_metadata_key(StoreType::NonFungibleTokenMeta, token_name); map_no_contract_as_none(self.fetch_metadata(contract_identifier, &key))? - .ok_or(CheckErrors::NoSuchNFT(token_name.to_string()).into()) + .ok_or(CheckErrorKind::NoSuchNFT(token_name.to_string()).into()) } pub fn checked_increase_token_supply( @@ -2157,7 +2157,7 @@ impl ClarityDatabase<'_> { key_type: &TypeSignature, ) -> Result { if !key_type.admits(&self.get_clarity_epoch_version()?, asset)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(key_type.clone()), Box::new(asset.clone()), ) @@ -2210,7 +2210,7 @@ impl ClarityDatabase<'_> { epoch: &StacksEpochId, ) -> Result<()> { if !key_type.admits(&self.get_clarity_epoch_version()?, asset)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(key_type.clone()), Box::new(asset.clone()), ) @@ -2239,7 +2239,7 @@ impl ClarityDatabase<'_> { epoch: &StacksEpochId, ) -> Result<()> { if !key_type.admits(&self.get_clarity_epoch_version()?, asset)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(key_type.clone()), Box::new(asset.clone()), ) diff --git a/clarity/src/vm/database/sqlite.rs b/clarity/src/vm/database/sqlite.rs index c1af553041..aec7e37c65 100644 --- a/clarity/src/vm/database/sqlite.rs +++ b/clarity/src/vm/database/sqlite.rs @@ -25,7 +25,7 @@ use super::{ ClarityBackingStore, ClarityDatabase, ClarityDeserializable, SpecialCaseHandler, NULL_BURN_STATE_DB, NULL_HEADER_DB, }; -use crate::vm::analysis::{AnalysisDatabase, CheckErrors}; +use crate::vm::analysis::{AnalysisDatabase, CheckErrorKind}; use crate::vm::errors::{ IncomparableError, InterpreterError, InterpreterResult as Result, RuntimeErrorType, }; @@ -82,7 +82,7 @@ pub fn sqlite_get_contract_hash( let contract_commitment = store .get_data(&key)? .map(|x| ContractCommitment::deserialize(&x)) - .ok_or_else(|| CheckErrors::NoSuchContract(contract.to_string()))?; + .ok_or_else(|| CheckErrorKind::NoSuchContract(contract.to_string()))?; let ContractCommitment { block_height, hash: contract_hash, diff --git a/clarity/src/vm/errors.rs b/clarity/src/vm/errors.rs index 764ac466e5..3c8610fecc 100644 --- a/clarity/src/vm/errors.rs +++ b/clarity/src/vm/errors.rs @@ -20,7 +20,7 @@ pub use clarity_types::errors::{ }; pub use crate::vm::analysis::errors::{ - check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckErrors, + check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckErrorKind, SyntaxBindingError, SyntaxBindingErrorType, }; diff --git a/clarity/src/vm/functions/arithmetic.rs b/clarity/src/vm/functions/arithmetic.rs index 2d5c2aff3a..61a57d3644 100644 --- a/clarity/src/vm/functions/arithmetic.rs +++ b/clarity/src/vm/functions/arithmetic.rs @@ -21,7 +21,7 @@ use integer_sqrt::IntegerSquareRoot; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, CheckErrors, InterpreterError, InterpreterResult, RuntimeErrorType, + check_argument_count, CheckErrorKind, InterpreterError, InterpreterResult, RuntimeErrorType, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::{ @@ -76,7 +76,7 @@ macro_rules! type_force_binary_arithmetic { match ($x, $y) { (Value::Int(x), Value::Int(y)) => I128Ops::$function(x, y), (Value::UInt(x), Value::UInt(y)) => U128Ops::$function(x, y), - (x, _) => Err(CheckErrors::UnionTypeValueError( + (x, _) => Err(CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(x), ) @@ -91,7 +91,7 @@ macro_rules! type_force_binary_comparison_v1 { match ($x, $y) { (Value::Int(x), Value::Int(y)) => I128Ops::$function(x, y), (Value::UInt(x), Value::UInt(y)) => U128Ops::$function(x, y), - (x, _) => Err(CheckErrors::UnionTypeValueError( + (x, _) => Err(CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(x), ) @@ -119,7 +119,7 @@ macro_rules! type_force_binary_comparison_v2 { Value::Sequence(SequenceData::Buffer(BuffData { data: x })), Value::Sequence(SequenceData::Buffer(BuffData { data: y })), ) => BuffOps::$function(x, y), - (x, _) => Err(CheckErrors::UnionTypeValueError( + (x, _) => Err(CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -139,7 +139,7 @@ macro_rules! type_force_unary_arithmetic { match $x { Value::Int(x) => I128Ops::$function(x), Value::UInt(x) => U128Ops::$function(x), - x => Err(CheckErrors::UnionTypeValueError( + x => Err(CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(x), ) @@ -155,14 +155,14 @@ macro_rules! type_force_variadic_arithmetic { ($function: ident, $args: expr) => {{ let first = $args .get(0) - .ok_or(CheckErrors::IncorrectArgumentCount(1, $args.len()))?; + .ok_or(CheckErrorKind::IncorrectArgumentCount(1, $args.len()))?; match first { Value::Int(_) => { let typed_args: Result, _> = $args .drain(..) .map(|x| match x { Value::Int(value) => Ok(value), - _ => Err(CheckErrors::TypeValueError( + _ => Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::IntType), Box::new(x.clone()), )), @@ -176,7 +176,7 @@ macro_rules! type_force_variadic_arithmetic { .drain(..) .map(|x| match x { Value::UInt(value) => Ok(value), - _ => Err(CheckErrors::TypeValueError( + _ => Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::UIntType), Box::new(x.clone()), )), @@ -185,7 +185,7 @@ macro_rules! type_force_variadic_arithmetic { let checked_args = typed_args?; U128Ops::$function(&checked_args) } - _ => Err(CheckErrors::UnionTypeValueError( + _ => Err(CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(first.clone()), ) @@ -254,7 +254,7 @@ macro_rules! make_arithmetic_ops { fn sub(args: &[$type]) -> InterpreterResult { let (first, rest) = args .split_first() - .ok_or(CheckErrors::IncorrectArgumentCount(1, 0))?; + .ok_or(CheckErrorKind::IncorrectArgumentCount(1, 0))?; if rest.len() == 0 { // return negation return Self::make_value( @@ -280,7 +280,7 @@ macro_rules! make_arithmetic_ops { fn div(args: &[$type]) -> InterpreterResult { let (first, rest) = args .split_first() - .ok_or(CheckErrors::IncorrectArgumentCount(1, 0))?; + .ok_or(CheckErrorKind::IncorrectArgumentCount(1, 0))?; let result = rest .iter() .try_fold(*first, |acc: $type, x: &$type| acc.checked_div(*x)) @@ -598,14 +598,14 @@ pub fn native_bitwise_left_shift(input: Value, pos: Value) -> InterpreterResult< let result = input.wrapping_shl(shamt); Ok(Value::UInt(result)) } - _ => Err(CheckErrors::UnionTypeError( + _ => Err(CheckErrorKind::UnionTypeError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(TypeSignature::type_of(&input)?), ) .into()), } } else { - Err(CheckErrors::TypeValueError(Box::new(TypeSignature::UIntType), Box::new(pos)).into()) + Err(CheckErrorKind::TypeValueError(Box::new(TypeSignature::UIntType), Box::new(pos)).into()) } } @@ -624,14 +624,14 @@ pub fn native_bitwise_right_shift(input: Value, pos: Value) -> InterpreterResult let result = input.wrapping_shr(shamt); Ok(Value::UInt(result)) } - _ => Err(CheckErrors::UnionTypeError( + _ => Err(CheckErrorKind::UnionTypeError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(TypeSignature::type_of(&input)?), ) .into()), } } else { - Err(CheckErrors::TypeValueError(Box::new(TypeSignature::UIntType), Box::new(pos)).into()) + Err(CheckErrorKind::TypeValueError(Box::new(TypeSignature::UIntType), Box::new(pos)).into()) } } @@ -641,7 +641,10 @@ pub fn native_to_uint(input: Value) -> InterpreterResult { u128::try_from(int_val).map_err(|_| RuntimeErrorType::ArithmeticUnderflow)?; Ok(Value::UInt(uint_val)) } else { - Err(CheckErrors::TypeValueError(Box::new(TypeSignature::IntType), Box::new(input)).into()) + Err( + CheckErrorKind::TypeValueError(Box::new(TypeSignature::IntType), Box::new(input)) + .into(), + ) } } @@ -650,6 +653,9 @@ pub fn native_to_int(input: Value) -> InterpreterResult { let int_val = i128::try_from(uint_val).map_err(|_| RuntimeErrorType::ArithmeticOverflow)?; Ok(Value::Int(int_val)) } else { - Err(CheckErrors::TypeValueError(Box::new(TypeSignature::UIntType), Box::new(input)).into()) + Err( + CheckErrorKind::TypeValueError(Box::new(TypeSignature::UIntType), Box::new(input)) + .into(), + ) } } diff --git a/clarity/src/vm/functions/assets.rs b/clarity/src/vm/functions/assets.rs index 62763fa3fc..0a32c700a4 100644 --- a/clarity/src/vm/functions/assets.rs +++ b/clarity/src/vm/functions/assets.rs @@ -20,7 +20,7 @@ use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostTracker}; use crate::vm::database::STXBalance; use crate::vm::errors::{ - check_argument_count, CheckErrors, Error, InterpreterError, InterpreterResult as Result, + check_argument_count, CheckErrorKind, Error, InterpreterError, InterpreterResult as Result, RuntimeErrorType, }; use crate::vm::representations::SymbolicExpression; @@ -109,7 +109,7 @@ pub fn special_stx_balance( Ok(Value::UInt(balance)) } else { Err( - CheckErrors::TypeValueError(Box::new(TypeSignature::PrincipalType), Box::new(owner)) + CheckErrorKind::TypeValueError(Box::new(TypeSignature::PrincipalType), Box::new(owner)) .into(), ) } @@ -181,7 +181,7 @@ pub fn special_stx_transfer( { stx_transfer_consolidated(env, from, to, amount, memo) } else { - Err(CheckErrors::BadTransferSTXArguments.into()) + Err(CheckErrorKind::BadTransferSTXArguments.into()) } } @@ -207,7 +207,7 @@ pub fn special_stx_transfer_memo( { stx_transfer_consolidated(env, from, to, amount, memo) } else { - Err(CheckErrors::BadTransferSTXArguments.into()) + Err(CheckErrorKind::BadTransferSTXArguments.into()) } } @@ -225,7 +225,7 @@ pub fn special_stx_account( let principal = if let Value::Principal(p) = owner { p } else { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::PrincipalType), Box::new(owner), ) @@ -309,7 +309,7 @@ pub fn special_stx_burn( Ok(Value::okay_true()) } else { - Err(CheckErrors::BadTransferSTXArguments.into()) + Err(CheckErrorKind::BadTransferSTXArguments.into()) } } @@ -322,7 +322,7 @@ pub fn special_mint_token( runtime_cost(ClarityCostFunction::FtMint, env, 0)?; - let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let amount = eval(&args[1], env, context)?; let to = eval(&args[2], env, context)?; @@ -336,7 +336,7 @@ pub fn special_mint_token( .contract_context .meta_ft .get(token_name) - .ok_or(CheckErrors::NoSuchFT(token_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchFT(token_name.to_string()))?; env.global_context.database.checked_increase_token_supply( &env.contract_context.contract_identifier, @@ -374,7 +374,7 @@ pub fn special_mint_token( Ok(Value::okay_true()) } else { - Err(CheckErrors::BadMintFTArguments.into()) + Err(CheckErrorKind::BadMintFTArguments.into()) } } @@ -385,7 +385,7 @@ pub fn special_mint_asset_v200( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let asset = eval(&args[1], env, context)?; let to = eval(&args[2], env, context)?; @@ -394,7 +394,7 @@ pub fn special_mint_asset_v200( .contract_context .meta_nft .get(asset_name) - .ok_or(CheckErrors::NoSuchNFT(asset_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))?; let expected_asset_type = &nft_metadata.key_type; runtime_cost( @@ -404,7 +404,7 @@ pub fn special_mint_asset_v200( )?; if !expected_asset_type.admits(env.epoch(), &asset)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(expected_asset_type.clone()), Box::new(asset), ) @@ -445,7 +445,7 @@ pub fn special_mint_asset_v200( Ok(Value::okay_true()) } else { Err( - CheckErrors::TypeValueError(Box::new(TypeSignature::PrincipalType), Box::new(to)) + CheckErrorKind::TypeValueError(Box::new(TypeSignature::PrincipalType), Box::new(to)) .into(), ) } @@ -460,7 +460,7 @@ pub fn special_mint_asset_v205( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let asset = eval(&args[1], env, context)?; let to = eval(&args[2], env, context)?; @@ -469,7 +469,7 @@ pub fn special_mint_asset_v205( .contract_context .meta_nft .get(asset_name) - .ok_or(CheckErrors::NoSuchNFT(asset_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))?; let expected_asset_type = &nft_metadata.key_type; let asset_size = asset @@ -478,7 +478,7 @@ pub fn special_mint_asset_v205( runtime_cost(ClarityCostFunction::NftMint, env, asset_size)?; if !expected_asset_type.admits(env.epoch(), &asset)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(expected_asset_type.clone()), Box::new(asset), ) @@ -519,7 +519,7 @@ pub fn special_mint_asset_v205( Ok(Value::okay_true()) } else { Err( - CheckErrors::TypeValueError(Box::new(TypeSignature::PrincipalType), Box::new(to)) + CheckErrorKind::TypeValueError(Box::new(TypeSignature::PrincipalType), Box::new(to)) .into(), ) } @@ -532,7 +532,7 @@ pub fn special_transfer_asset_v200( ) -> Result { check_argument_count(4, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let asset = eval(&args[1], env, context)?; let from = eval(&args[2], env, context)?; @@ -542,7 +542,7 @@ pub fn special_transfer_asset_v200( .contract_context .meta_nft .get(asset_name) - .ok_or(CheckErrors::NoSuchNFT(asset_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))?; let expected_asset_type = &nft_metadata.key_type; runtime_cost( @@ -552,7 +552,7 @@ pub fn special_transfer_asset_v200( )?; if !expected_asset_type.admits(env.epoch(), &asset)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(expected_asset_type.clone()), Box::new(asset), ) @@ -614,7 +614,7 @@ pub fn special_transfer_asset_v200( Ok(Value::okay_true()) } else { - Err(CheckErrors::BadTransferNFTArguments.into()) + Err(CheckErrorKind::BadTransferNFTArguments.into()) } } @@ -627,7 +627,7 @@ pub fn special_transfer_asset_v205( ) -> Result { check_argument_count(4, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let asset = eval(&args[1], env, context)?; let from = eval(&args[2], env, context)?; @@ -637,7 +637,7 @@ pub fn special_transfer_asset_v205( .contract_context .meta_nft .get(asset_name) - .ok_or(CheckErrors::NoSuchNFT(asset_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))?; let expected_asset_type = &nft_metadata.key_type; let asset_size = asset @@ -646,7 +646,7 @@ pub fn special_transfer_asset_v205( runtime_cost(ClarityCostFunction::NftTransfer, env, asset_size)?; if !expected_asset_type.admits(env.epoch(), &asset)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(expected_asset_type.clone()), Box::new(asset), ) @@ -708,7 +708,7 @@ pub fn special_transfer_asset_v205( Ok(Value::okay_true()) } else { - Err(CheckErrors::BadTransferNFTArguments.into()) + Err(CheckErrorKind::BadTransferNFTArguments.into()) } } @@ -721,7 +721,7 @@ pub fn special_transfer_token( runtime_cost(ClarityCostFunction::FtTransfer, env, 0)?; - let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let amount = eval(&args[1], env, context)?; let from = eval(&args[2], env, context)?; @@ -745,7 +745,7 @@ pub fn special_transfer_token( .contract_context .meta_ft .get(token_name) - .ok_or(CheckErrors::NoSuchFT(token_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchFT(token_name.to_string()))?; let from_bal = env.global_context.database.get_ft_balance( &env.contract_context.contract_identifier, @@ -809,7 +809,7 @@ pub fn special_transfer_token( Ok(Value::okay_true()) } else { - Err(CheckErrors::BadTransferFTArguments.into()) + Err(CheckErrorKind::BadTransferFTArguments.into()) } } @@ -822,7 +822,7 @@ pub fn special_get_balance( runtime_cost(ClarityCostFunction::FtBalance, env, 0)?; - let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let owner = eval(&args[1], env, context)?; @@ -831,7 +831,7 @@ pub fn special_get_balance( .contract_context .meta_ft .get(token_name) - .ok_or(CheckErrors::NoSuchFT(token_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchFT(token_name.to_string()))?; let balance = env.global_context.database.get_ft_balance( &env.contract_context.contract_identifier, @@ -842,7 +842,7 @@ pub fn special_get_balance( Ok(Value::UInt(balance)) } else { Err( - CheckErrors::TypeValueError(Box::new(TypeSignature::PrincipalType), Box::new(owner)) + CheckErrorKind::TypeValueError(Box::new(TypeSignature::PrincipalType), Box::new(owner)) .into(), ) } @@ -855,7 +855,7 @@ pub fn special_get_owner_v200( ) -> Result { check_argument_count(2, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let asset = eval(&args[1], env, context)?; @@ -863,7 +863,7 @@ pub fn special_get_owner_v200( .contract_context .meta_nft .get(asset_name) - .ok_or(CheckErrors::NoSuchNFT(asset_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))?; let expected_asset_type = &nft_metadata.key_type; runtime_cost( @@ -873,7 +873,7 @@ pub fn special_get_owner_v200( )?; if !expected_asset_type.admits(env.epoch(), &asset)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(expected_asset_type.clone()), Box::new(asset), ) @@ -903,7 +903,7 @@ pub fn special_get_owner_v205( ) -> Result { check_argument_count(2, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let asset = eval(&args[1], env, context)?; @@ -911,7 +911,7 @@ pub fn special_get_owner_v205( .contract_context .meta_nft .get(asset_name) - .ok_or(CheckErrors::NoSuchNFT(asset_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))?; let expected_asset_type = &nft_metadata.key_type; let asset_size = asset @@ -920,7 +920,7 @@ pub fn special_get_owner_v205( runtime_cost(ClarityCostFunction::NftOwner, env, asset_size)?; if !expected_asset_type.admits(env.epoch(), &asset)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(expected_asset_type.clone()), Box::new(asset), ) @@ -950,7 +950,7 @@ pub fn special_get_token_supply( runtime_cost(ClarityCostFunction::FtSupply, env, 0)?; - let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let supply = env .global_context @@ -968,7 +968,7 @@ pub fn special_burn_token( runtime_cost(ClarityCostFunction::FtBurn, env, 0)?; - let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let amount = eval(&args[1], env, context)?; let from = eval(&args[2], env, context)?; @@ -1022,7 +1022,7 @@ pub fn special_burn_token( Ok(Value::okay_true()) } else { - Err(CheckErrors::BadBurnFTArguments.into()) + Err(CheckErrorKind::BadBurnFTArguments.into()) } } @@ -1035,7 +1035,7 @@ pub fn special_burn_asset_v200( runtime_cost(ClarityCostFunction::NftBurn, env, 0)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let asset = eval(&args[1], env, context)?; let sender = eval(&args[2], env, context)?; @@ -1044,7 +1044,7 @@ pub fn special_burn_asset_v200( .contract_context .meta_nft .get(asset_name) - .ok_or(CheckErrors::NoSuchNFT(asset_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))?; let expected_asset_type = &nft_metadata.key_type; runtime_cost( @@ -1054,7 +1054,7 @@ pub fn special_burn_asset_v200( )?; if !expected_asset_type.admits(env.epoch(), &asset)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(expected_asset_type.clone()), Box::new(asset), ) @@ -1106,10 +1106,11 @@ pub fn special_burn_asset_v200( Ok(Value::okay_true()) } else { - Err( - CheckErrors::TypeValueError(Box::new(TypeSignature::PrincipalType), Box::new(sender)) - .into(), + Err(CheckErrorKind::TypeValueError( + Box::new(TypeSignature::PrincipalType), + Box::new(sender), ) + .into()) } } @@ -1124,7 +1125,7 @@ pub fn special_burn_asset_v205( runtime_cost(ClarityCostFunction::NftBurn, env, 0)?; - let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; + let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; let asset = eval(&args[1], env, context)?; let sender = eval(&args[2], env, context)?; @@ -1133,7 +1134,7 @@ pub fn special_burn_asset_v205( .contract_context .meta_nft .get(asset_name) - .ok_or(CheckErrors::NoSuchNFT(asset_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))?; let expected_asset_type = &nft_metadata.key_type; let asset_size = asset @@ -1142,7 +1143,7 @@ pub fn special_burn_asset_v205( runtime_cost(ClarityCostFunction::NftBurn, env, asset_size)?; if !expected_asset_type.admits(env.epoch(), &asset)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(expected_asset_type.clone()), Box::new(asset), ) @@ -1194,9 +1195,10 @@ pub fn special_burn_asset_v205( Ok(Value::okay_true()) } else { - Err( - CheckErrors::TypeValueError(Box::new(TypeSignature::PrincipalType), Box::new(sender)) - .into(), + Err(CheckErrorKind::TypeValueError( + Box::new(TypeSignature::PrincipalType), + Box::new(sender), ) + .into()) } } diff --git a/clarity/src/vm/functions/boolean.rs b/clarity/src/vm/functions/boolean.rs index e692b4ad71..8edf279a9b 100644 --- a/clarity/src/vm/functions/boolean.rs +++ b/clarity/src/vm/functions/boolean.rs @@ -17,7 +17,7 @@ use crate::vm::contexts::{Environment, LocalContext}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; -use crate::vm::errors::{check_arguments_at_least, CheckErrors, InterpreterResult as Result}; +use crate::vm::errors::{check_arguments_at_least, CheckErrorKind, InterpreterResult as Result}; use crate::vm::eval; use crate::vm::representations::SymbolicExpression; use crate::vm::types::{TypeSignature, Value}; @@ -25,7 +25,7 @@ use crate::vm::types::{TypeSignature, Value}; fn type_force_bool(value: &Value) -> Result { match *value { Value::Bool(boolean) => Ok(boolean), - _ => Err(CheckErrors::TypeValueError( + _ => Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::BoolType), Box::new(value.clone()), ) diff --git a/clarity/src/vm/functions/conversions.rs b/clarity/src/vm/functions/conversions.rs index bd7834a552..319e1d368e 100644 --- a/clarity/src/vm/functions/conversions.rs +++ b/clarity/src/vm/functions/conversions.rs @@ -19,7 +19,7 @@ use clarity_types::types::serialization::SerializationError; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, CheckErrors, InterpreterError, InterpreterResult as Result, + check_argument_count, CheckErrorKind, InterpreterError, InterpreterResult as Result, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::signatures::TO_ASCII_MAX_BUFF; @@ -57,7 +57,7 @@ pub fn buff_to_int_generic( > BufferLength::try_from(16_u32) .map_err(|_| InterpreterError::Expect("Failed to construct".into()))? { - Err(CheckErrors::TypeValueError( + Err(CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32) .map_err(|_| InterpreterError::Expect("Failed to construct".into()))?, @@ -83,7 +83,7 @@ pub fn buff_to_int_generic( Ok(value) } } - _ => Err(CheckErrors::TypeValueError( + _ => Err(CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32) .map_err(|_| InterpreterError::Expect("Failed to construct".into()))?, @@ -149,7 +149,7 @@ pub fn native_string_to_int_generic( Err(_error) => Ok(Value::none()), } } - _ => Err(CheckErrors::UnionTypeValueError( + _ => Err(CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::max_string_ascii()?, TypeSignature::max_string_utf8()?, @@ -205,7 +205,7 @@ pub fn native_int_to_string_generic( InterpreterError::Expect("Unexpected error converting UInt to string.".into()) })?) } - _ => Err(CheckErrors::UnionTypeValueError( + _ => Err(CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(value), ) @@ -271,7 +271,7 @@ pub fn special_to_ascii( Err(_) => Ok(Value::err_uint(1)), // Invalid UTF8 } } - _ => Err(CheckErrors::UnionTypeValueError( + _ => Err(CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -324,7 +324,7 @@ pub fn from_consensus_buff( let input_bytes = if let Value::Sequence(SequenceData::Buffer(buff_data)) = value { Ok(buff_data.data) } else { - Err(CheckErrors::TypeValueError( + Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::max_buffer()?), Box::new(value), )) @@ -346,7 +346,7 @@ pub fn from_consensus_buff( ) { Ok(value) => value, Err(SerializationError::UnexpectedSerialization) => { - return Err(CheckErrors::Expects("UnexpectedSerialization".into()).into()); + return Err(CheckErrorKind::Expects("UnexpectedSerialization".into()).into()); } Err(_) => return Ok(Value::none()), }; diff --git a/clarity/src/vm/functions/crypto.rs b/clarity/src/vm/functions/crypto.rs index 3b5223bd72..4879b59cf7 100644 --- a/clarity/src/vm/functions/crypto.rs +++ b/clarity/src/vm/functions/crypto.rs @@ -24,7 +24,7 @@ use stacks_common::util::secp256k1::{secp256k1_recover, secp256k1_verify, Secp25 use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, CheckErrors, InterpreterError, InterpreterResult as Result, + check_argument_count, CheckErrorKind, InterpreterError, InterpreterResult as Result, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::{BuffData, SequenceData, TypeSignature, Value, BUFF_32, BUFF_33, BUFF_65}; @@ -37,7 +37,7 @@ macro_rules! native_hash_func { Value::Int(value) => Ok(value.to_le_bytes().to_vec()), Value::UInt(value) => Ok(value.to_le_bytes().to_vec()), Value::Sequence(SequenceData::Buffer(value)) => Ok(value.data), - _ => Err(CheckErrors::UnionTypeValueError( + _ => Err(CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -102,7 +102,7 @@ pub fn special_principal_of( let pub_key = match param0 { Value::Sequence(SequenceData::Buffer(BuffData { ref data })) => { if data.len() != 33 { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(BUFF_33.clone()), Box::new(param0), ) @@ -112,7 +112,7 @@ pub fn special_principal_of( } _ => { return Err( - CheckErrors::TypeValueError(Box::new(BUFF_33.clone()), Box::new(param0)).into(), + CheckErrorKind::TypeValueError(Box::new(BUFF_33.clone()), Box::new(param0)).into(), ) } }; @@ -148,7 +148,7 @@ pub fn special_secp256k1_recover( let message = match param0 { Value::Sequence(SequenceData::Buffer(BuffData { ref data })) => { if data.len() != 32 { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(BUFF_32.clone()), Box::new(param0), ) @@ -158,7 +158,7 @@ pub fn special_secp256k1_recover( } _ => { return Err( - CheckErrors::TypeValueError(Box::new(BUFF_32.clone()), Box::new(param0)).into(), + CheckErrorKind::TypeValueError(Box::new(BUFF_32.clone()), Box::new(param0)).into(), ) } }; @@ -167,7 +167,7 @@ pub fn special_secp256k1_recover( let signature = match param1 { Value::Sequence(SequenceData::Buffer(BuffData { ref data })) => { if data.len() > 65 { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(BUFF_65.clone()), Box::new(param1), ) @@ -180,12 +180,14 @@ pub fn special_secp256k1_recover( } _ => { return Err( - CheckErrors::TypeValueError(Box::new(BUFF_65.clone()), Box::new(param1)).into(), + CheckErrorKind::TypeValueError(Box::new(BUFF_65.clone()), Box::new(param1)).into(), ) } }; - match secp256k1_recover(message, signature).map_err(|_| CheckErrors::InvalidSecp65k1Signature) { + match secp256k1_recover(message, signature) + .map_err(|_| CheckErrorKind::InvalidSecp65k1Signature) + { Ok(pubkey) => Ok(Value::okay( Value::buff_from(pubkey.to_vec()) .map_err(|_| InterpreterError::Expect("Failed to construct buff".into()))?, @@ -210,7 +212,7 @@ pub fn special_secp256k1_verify( let message = match param0 { Value::Sequence(SequenceData::Buffer(BuffData { ref data })) => { if data.len() != 32 { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(BUFF_32.clone()), Box::new(param0), ) @@ -220,7 +222,7 @@ pub fn special_secp256k1_verify( } _ => { return Err( - CheckErrors::TypeValueError(Box::new(BUFF_32.clone()), Box::new(param0)).into(), + CheckErrorKind::TypeValueError(Box::new(BUFF_32.clone()), Box::new(param0)).into(), ) } }; @@ -229,7 +231,7 @@ pub fn special_secp256k1_verify( let signature = match param1 { Value::Sequence(SequenceData::Buffer(BuffData { ref data })) => { if data.len() > 65 { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(BUFF_65.clone()), Box::new(param1), ) @@ -245,7 +247,7 @@ pub fn special_secp256k1_verify( } _ => { return Err( - CheckErrors::TypeValueError(Box::new(BUFF_65.clone()), Box::new(param1)).into(), + CheckErrorKind::TypeValueError(Box::new(BUFF_65.clone()), Box::new(param1)).into(), ) } }; @@ -254,7 +256,7 @@ pub fn special_secp256k1_verify( let pubkey = match param2 { Value::Sequence(SequenceData::Buffer(BuffData { ref data })) => { if data.len() != 33 { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(BUFF_33.clone()), Box::new(param2), ) @@ -264,7 +266,7 @@ pub fn special_secp256k1_verify( } _ => { return Err( - CheckErrors::TypeValueError(Box::new(BUFF_33.clone()), Box::new(param2)).into(), + CheckErrorKind::TypeValueError(Box::new(BUFF_33.clone()), Box::new(param2)).into(), ) } }; diff --git a/clarity/src/vm/functions/database.rs b/clarity/src/vm/functions/database.rs index 93fbef0258..bf4e39f425 100644 --- a/clarity/src/vm/functions/database.rs +++ b/clarity/src/vm/functions/database.rs @@ -22,7 +22,7 @@ use crate::vm::callables::DefineType; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{constants as cost_constants, runtime_cost, CostTracker, MemoryConsumer}; use crate::vm::errors::{ - check_argument_count, check_arguments_at_least, CheckErrors, InterpreterError, + check_argument_count, check_arguments_at_least, CheckErrorKind, InterpreterError, InterpreterResult as Result, RuntimeErrorType, }; use crate::vm::representations::{SymbolicExpression, SymbolicExpressionType}; @@ -69,7 +69,7 @@ pub fn special_contract_call( // is checked in callables::DefinedFunction::execute_apply. runtime_cost(ClarityCostFunction::ContractCall, env, 0)?; - let function_name = args[1].match_atom().ok_or(CheckErrors::ExpectedName)?; + let function_name = args[1].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let rest_args_slice = &args[2..]; let rest_args_len = rest_args_slice.len(); let mut rest_args = Vec::with_capacity(rest_args_len); @@ -93,7 +93,7 @@ pub fn special_contract_call( Some(trait_data) => { // Ensure that contract-call is used for inter-contract calls only if trait_data.contract_identifier == env.contract_context.contract_identifier { - return Err(CheckErrors::CircularReference(vec![trait_data + return Err(CheckErrorKind::CircularReference(vec![trait_data .contract_identifier .name .to_string()]) @@ -105,7 +105,9 @@ pub fn special_contract_call( .database .get_contract(&trait_data.contract_identifier) .map_err(|_e| { - CheckErrors::NoSuchContract(trait_data.contract_identifier.to_string()) + CheckErrorKind::NoSuchContract( + trait_data.contract_identifier.to_string(), + ) })?; let contract_context_to_check = contract_to_check.contract_context; @@ -114,7 +116,7 @@ pub fn special_contract_call( let trait_identifier = trait_data .trait_identifier .as_ref() - .ok_or(CheckErrors::ExpectedTraitIdentifier)?; + .ok_or(CheckErrorKind::ExpectedTraitIdentifier)?; // Attempt to short circuit the dynamic dispatch checks: // If the contract is explicitely implementing the trait with `impl-trait`, @@ -131,7 +133,7 @@ pub fn special_contract_call( .database .get_contract(&trait_identifier.contract_identifier) .map_err(|_e| { - CheckErrors::NoSuchContract( + CheckErrorKind::NoSuchContract( trait_identifier.contract_identifier.to_string(), ) })?; @@ -141,19 +143,19 @@ pub fn special_contract_call( // Retrieve the function that will be invoked let function_to_check = contract_context_to_check .lookup_function(function_name) - .ok_or(CheckErrors::BadTraitImplementation( + .ok_or(CheckErrorKind::BadTraitImplementation( trait_name.clone(), function_name.to_string(), ))?; // Check read/write compatibility if env.global_context.is_read_only() { - return Err(CheckErrors::TraitBasedContractCallInReadOnly.into()); + return Err(CheckErrorKind::TraitBasedContractCallInReadOnly.into()); } // Check visibility if function_to_check.define_type == DefineType::Private { - return Err(CheckErrors::NoSuchPublicFunction( + return Err(CheckErrorKind::NoSuchPublicFunction( trait_data.contract_identifier.to_string(), function_name.to_string(), ) @@ -169,9 +171,12 @@ pub fn special_contract_call( // Retrieve the expected method signature let constraining_trait = contract_context_defining_trait .lookup_trait_definition(&trait_name) - .ok_or(CheckErrors::TraitReferenceUnknown(trait_name.clone()))?; + .ok_or(CheckErrorKind::TraitReferenceUnknown(trait_name.clone()))?; let expected_sig = constraining_trait.get(function_name).ok_or( - CheckErrors::TraitMethodUnknown(trait_name, function_name.to_string()), + CheckErrorKind::TraitMethodUnknown( + trait_name, + function_name.to_string(), + ), )?; ( &trait_data.contract_identifier, @@ -179,10 +184,10 @@ pub fn special_contract_call( ) } } - _ => return Err(CheckErrors::ContractCallExpectName.into()), + _ => return Err(CheckErrorKind::ContractCallExpectName.into()), } } - _ => return Err(CheckErrors::ContractCallExpectName.into()), + _ => return Err(CheckErrorKind::ContractCallExpectName.into()), }; let contract_principal = env.contract_context.contract_identifier.clone().into(); @@ -203,14 +208,14 @@ pub fn special_contract_call( // sanitize contract-call outputs in epochs >= 2.4 let result_type = TypeSignature::type_of(&result)?; let (result, _) = Value::sanitize_value(env.epoch(), &result_type, result) - .ok_or_else(|| CheckErrors::CouldNotDetermineType)?; + .ok_or_else(|| CheckErrorKind::CouldNotDetermineType)?; // Ensure that the expected type from the trait spec admits // the type of the value returned by the dynamic dispatch. if let Some(returns_type_signature) = type_returns_constraint { let actual_returns = TypeSignature::type_of(&result)?; if !returns_type_signature.admits_type(env.epoch(), &actual_returns)? { - return Err(CheckErrors::ReturnTypesMustMatch( + return Err(CheckErrorKind::ReturnTypesMustMatch( Box::new(returns_type_signature), Box::new(actual_returns), ) @@ -228,7 +233,7 @@ pub fn special_fetch_variable_v200( ) -> Result { check_argument_count(1, args)?; - let var_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let var_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let contract = &env.contract_context.contract_identifier; @@ -236,7 +241,7 @@ pub fn special_fetch_variable_v200( .contract_context .meta_data_var .get(var_name) - .ok_or(CheckErrors::NoSuchDataVariable(var_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchDataVariable(var_name.to_string()))?; runtime_cost( ClarityCostFunction::FetchVar, @@ -259,7 +264,7 @@ pub fn special_fetch_variable_v205( ) -> Result { check_argument_count(1, args)?; - let var_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let var_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let contract = &env.contract_context.contract_identifier; @@ -267,7 +272,7 @@ pub fn special_fetch_variable_v205( .contract_context .meta_data_var .get(var_name) - .ok_or(CheckErrors::NoSuchDataVariable(var_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchDataVariable(var_name.to_string()))?; let epoch = *env.epoch(); let result = env @@ -291,14 +296,14 @@ pub fn special_set_variable_v200( context: &LocalContext, ) -> Result { if env.global_context.is_read_only() { - return Err(CheckErrors::WriteAttemptedInReadOnly.into()); + return Err(CheckErrorKind::WriteAttemptedInReadOnly.into()); } check_argument_count(2, args)?; let value = eval(&args[1], env, context)?; - let var_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let var_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let contract = &env.contract_context.contract_identifier; @@ -306,7 +311,7 @@ pub fn special_set_variable_v200( .contract_context .meta_data_var .get(var_name) - .ok_or(CheckErrors::NoSuchDataVariable(var_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchDataVariable(var_name.to_string()))?; runtime_cost( ClarityCostFunction::SetVar, @@ -331,14 +336,14 @@ pub fn special_set_variable_v205( context: &LocalContext, ) -> Result { if env.global_context.is_read_only() { - return Err(CheckErrors::WriteAttemptedInReadOnly.into()); + return Err(CheckErrorKind::WriteAttemptedInReadOnly.into()); } check_argument_count(2, args)?; let value = eval(&args[1], env, context)?; - let var_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let var_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let contract = &env.contract_context.contract_identifier; @@ -346,7 +351,7 @@ pub fn special_set_variable_v205( .contract_context .meta_data_var .get(var_name) - .ok_or(CheckErrors::NoSuchDataVariable(var_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchDataVariable(var_name.to_string()))?; let epoch = *env.epoch(); let result = env @@ -373,7 +378,7 @@ pub fn special_fetch_entry_v200( ) -> Result { check_argument_count(2, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let key = eval(&args[1], env, context)?; @@ -383,7 +388,7 @@ pub fn special_fetch_entry_v200( .contract_context .meta_data_map .get(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::FetchEntry, @@ -406,7 +411,7 @@ pub fn special_fetch_entry_v205( ) -> Result { check_argument_count(2, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let key = eval(&args[1], env, context)?; @@ -416,7 +421,7 @@ pub fn special_fetch_entry_v205( .contract_context .meta_data_map .get(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; let epoch = *env.epoch(); let result = env @@ -452,7 +457,9 @@ pub fn special_at_block( } } x => { - return Err(CheckErrors::TypeValueError(Box::new(BUFF_32.clone()), Box::new(x)).into()) + return Err( + CheckErrorKind::TypeValueError(Box::new(BUFF_32.clone()), Box::new(x)).into(), + ) } }; @@ -469,7 +476,7 @@ pub fn special_set_entry_v200( context: &LocalContext, ) -> Result { if env.global_context.is_read_only() { - return Err(CheckErrors::WriteAttemptedInReadOnly.into()); + return Err(CheckErrorKind::WriteAttemptedInReadOnly.into()); } check_argument_count(3, args)?; @@ -478,7 +485,7 @@ pub fn special_set_entry_v200( let value = eval(&args[2], env, context)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let contract = &env.contract_context.contract_identifier; @@ -486,7 +493,7 @@ pub fn special_set_entry_v200( .contract_context .meta_data_map .get(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::SetEntry, @@ -512,7 +519,7 @@ pub fn special_set_entry_v205( context: &LocalContext, ) -> Result { if env.global_context.is_read_only() { - return Err(CheckErrors::WriteAttemptedInReadOnly.into()); + return Err(CheckErrorKind::WriteAttemptedInReadOnly.into()); } check_argument_count(3, args)?; @@ -521,7 +528,7 @@ pub fn special_set_entry_v205( let value = eval(&args[2], env, context)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let contract = &env.contract_context.contract_identifier; @@ -529,7 +536,7 @@ pub fn special_set_entry_v205( .contract_context .meta_data_map .get(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; let epoch = *env.epoch(); let result = env @@ -555,7 +562,7 @@ pub fn special_insert_entry_v200( context: &LocalContext, ) -> Result { if env.global_context.is_read_only() { - return Err(CheckErrors::WriteAttemptedInReadOnly.into()); + return Err(CheckErrorKind::WriteAttemptedInReadOnly.into()); } check_argument_count(3, args)?; @@ -564,7 +571,7 @@ pub fn special_insert_entry_v200( let value = eval(&args[2], env, context)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let contract = &env.contract_context.contract_identifier; @@ -572,7 +579,7 @@ pub fn special_insert_entry_v200( .contract_context .meta_data_map .get(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::SetEntry, @@ -599,7 +606,7 @@ pub fn special_insert_entry_v205( context: &LocalContext, ) -> Result { if env.global_context.is_read_only() { - return Err(CheckErrors::WriteAttemptedInReadOnly.into()); + return Err(CheckErrorKind::WriteAttemptedInReadOnly.into()); } check_argument_count(3, args)?; @@ -608,7 +615,7 @@ pub fn special_insert_entry_v205( let value = eval(&args[2], env, context)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let contract = &env.contract_context.contract_identifier; @@ -616,7 +623,7 @@ pub fn special_insert_entry_v205( .contract_context .meta_data_map .get(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; let epoch = *env.epoch(); let result = env @@ -642,14 +649,14 @@ pub fn special_delete_entry_v200( context: &LocalContext, ) -> Result { if env.global_context.is_read_only() { - return Err(CheckErrors::WriteAttemptedInReadOnly.into()); + return Err(CheckErrorKind::WriteAttemptedInReadOnly.into()); } check_argument_count(2, args)?; let key = eval(&args[1], env, context)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let contract = &env.contract_context.contract_identifier; @@ -657,7 +664,7 @@ pub fn special_delete_entry_v200( .contract_context .meta_data_map .get(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::SetEntry, @@ -682,14 +689,14 @@ pub fn special_delete_entry_v205( context: &LocalContext, ) -> Result { if env.global_context.is_read_only() { - return Err(CheckErrors::WriteAttemptedInReadOnly.into()); + return Err(CheckErrorKind::WriteAttemptedInReadOnly.into()); } check_argument_count(2, args)?; let key = eval(&args[1], env, context)?; - let map_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let map_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let contract = &env.contract_context.contract_identifier; @@ -697,7 +704,7 @@ pub fn special_delete_entry_v205( .contract_context .meta_data_map .get(map_name) - .ok_or(CheckErrors::NoSuchMap(map_name.to_string()))?; + .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; let epoch = *env.epoch(); let result = env @@ -731,10 +738,10 @@ pub fn special_delete_entry_v205( /// - `block-reward` returns the block reward for the block at `block-height` /// /// # Errors: -/// - CheckErrors::IncorrectArgumentCount if there aren't 2 arguments. -/// - CheckErrors::GetStacksBlockInfoExpectPropertyName if `args[0]` isn't a ClarityName. -/// - CheckErrors::NoSuchStacksBlockInfoProperty if `args[0]` isn't a StacksBlockInfoProperty. -/// - CheckErrors::TypeValueError if `args[1]` isn't a `uint`. +/// - CheckErrorKind::IncorrectArgumentCount if there aren't 2 arguments. +/// - CheckErrorKind::GetStacksBlockInfoExpectPropertyName if `args[0]` isn't a ClarityName. +/// - CheckErrorKind::NoSuchStacksBlockInfoProperty if `args[0]` isn't a StacksBlockInfoProperty. +/// - CheckErrorKind::TypeValueError if `args[1]` isn't a `uint`. pub fn special_get_block_info( args: &[SymbolicExpression], env: &mut Environment, @@ -748,18 +755,18 @@ pub fn special_get_block_info( // Handle the block property name input arg. let property_name = args[0] .match_atom() - .ok_or(CheckErrors::GetBlockInfoExpectPropertyName)?; + .ok_or(CheckErrorKind::GetBlockInfoExpectPropertyName)?; let version = env.contract_context.get_clarity_version(); let block_info_prop = BlockInfoProperty::lookup_by_name_at_version(property_name, version) - .ok_or(CheckErrors::GetBlockInfoExpectPropertyName)?; + .ok_or(CheckErrorKind::GetBlockInfoExpectPropertyName)?; // Handle the block-height input arg clause. let height_eval = eval(&args[1], env, context)?; let height_value = match height_eval { Value::UInt(result) => Ok(result), - x => Err(CheckErrors::TypeValueError( + x => Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::UIntType), Box::new(x), )), @@ -883,10 +890,10 @@ pub fn special_get_block_info( /// - `pox_addrs` returns the list of PoX addresses paid out at `burn_block_height` /// /// # Errors: -/// - CheckErrors::IncorrectArgumentCount if there aren't 2 arguments. -/// - CheckErrors::GetBlockInfoExpectPropertyName if `args[0]` isn't a ClarityName. -/// - CheckErrors::NoSuchBurnBlockInfoProperty if `args[0]` isn't a BurnBlockInfoProperty. -/// - CheckErrors::TypeValueError if `args[1]` isn't a `uint`. +/// - CheckErrorKind::IncorrectArgumentCount if there aren't 2 arguments. +/// - CheckErrorKind::GetBlockInfoExpectPropertyName if `args[0]` isn't a ClarityName. +/// - CheckErrorKind::NoSuchBurnBlockInfoProperty if `args[0]` isn't a BurnBlockInfoProperty. +/// - CheckErrorKind::TypeValueError if `args[1]` isn't a `uint`. pub fn special_get_burn_block_info( args: &[SymbolicExpression], env: &mut Environment, @@ -899,10 +906,10 @@ pub fn special_get_burn_block_info( // Handle the block property name input arg. let property_name = args[0] .match_atom() - .ok_or(CheckErrors::GetBlockInfoExpectPropertyName)?; + .ok_or(CheckErrorKind::GetBlockInfoExpectPropertyName)?; let block_info_prop = BurnBlockInfoProperty::lookup_by_name(property_name).ok_or( - CheckErrors::NoSuchBurnBlockInfoProperty(property_name.to_string()), + CheckErrorKind::NoSuchBurnBlockInfoProperty(property_name.to_string()), )?; // Handle the block-height input arg clause. @@ -910,7 +917,7 @@ pub fn special_get_burn_block_info( let height_value = match height_eval { Value::UInt(result) => result, x => { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::UIntType), Box::new(x), ) @@ -984,10 +991,10 @@ pub fn special_get_burn_block_info( /// - `time` returns the block time at `block-height` /// /// # Errors: -/// - CheckErrors::IncorrectArgumentCount if there aren't 2 arguments. -/// - CheckErrors::GetStacksBlockInfoExpectPropertyName if `args[0]` isn't a ClarityName. -/// - CheckErrors::NoSuchStacksBlockInfoProperty if `args[0]` isn't a StacksBlockInfoProperty. -/// - CheckErrors::TypeValueError if `args[1]` isn't a `uint`. +/// - CheckErrorKind::IncorrectArgumentCount if there aren't 2 arguments. +/// - CheckErrorKind::GetStacksBlockInfoExpectPropertyName if `args[0]` isn't a ClarityName. +/// - CheckErrorKind::NoSuchStacksBlockInfoProperty if `args[0]` isn't a StacksBlockInfoProperty. +/// - CheckErrorKind::TypeValueError if `args[1]` isn't a `uint`. pub fn special_get_stacks_block_info( args: &[SymbolicExpression], env: &mut Environment, @@ -1001,17 +1008,17 @@ pub fn special_get_stacks_block_info( // Handle the block property name input arg. let property_name = args[0] .match_atom() - .ok_or(CheckErrors::GetStacksBlockInfoExpectPropertyName)?; + .ok_or(CheckErrorKind::GetStacksBlockInfoExpectPropertyName)?; let block_info_prop = StacksBlockInfoProperty::lookup_by_name(property_name).ok_or( - CheckErrors::NoSuchStacksBlockInfoProperty(property_name.to_string()), + CheckErrorKind::NoSuchStacksBlockInfoProperty(property_name.to_string()), )?; // Handle the block-height input arg. let height_eval = eval(&args[1], env, context)?; let height_value = match height_eval { Value::UInt(result) => Ok(result), - x => Err(CheckErrors::TypeValueError( + x => Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::UIntType), Box::new(x), )), @@ -1066,10 +1073,10 @@ pub fn special_get_stacks_block_info( /// - `block-reward` returns the block reward for the tenure of which `block-height` is a part /// /// # Errors: -/// - CheckErrors::IncorrectArgumentCount if there aren't 2 arguments. -/// - CheckErrors::GetTenureInfoExpectPropertyName if `args[0]` isn't a ClarityName. -/// - CheckErrors::NoSuchTenureInfoProperty if `args[0]` isn't a TenureInfoProperty. -/// - CheckErrors::TypeValueError if `args[1]` isn't a `uint`. +/// - CheckErrorKind::IncorrectArgumentCount if there aren't 2 arguments. +/// - CheckErrorKind::GetTenureInfoExpectPropertyName if `args[0]` isn't a ClarityName. +/// - CheckErrorKind::NoSuchTenureInfoProperty if `args[0]` isn't a TenureInfoProperty. +/// - CheckErrorKind::TypeValueError if `args[1]` isn't a `uint`. pub fn special_get_tenure_info( args: &[SymbolicExpression], env: &mut Environment, @@ -1083,16 +1090,16 @@ pub fn special_get_tenure_info( // Handle the block property name input arg. let property_name = args[0] .match_atom() - .ok_or(CheckErrors::GetTenureInfoExpectPropertyName)?; + .ok_or(CheckErrorKind::GetTenureInfoExpectPropertyName)?; let block_info_prop = TenureInfoProperty::lookup_by_name(property_name) - .ok_or(CheckErrors::GetTenureInfoExpectPropertyName)?; + .ok_or(CheckErrorKind::GetTenureInfoExpectPropertyName)?; // Handle the block-height input arg. let height_eval = eval(&args[1], env, context)?; let height_value = match height_eval { Value::UInt(result) => Ok(result), - x => Err(CheckErrors::TypeValueError( + x => Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::UIntType), Box::new(x), )), @@ -1176,7 +1183,7 @@ pub fn special_contract_hash( check_argument_count(1, args)?; let contract_expr = args .first() - .ok_or(CheckErrors::IncorrectArgumentCount(1, 0))?; + .ok_or(CheckErrorKind::IncorrectArgumentCount(1, 0))?; let contract_value = eval(contract_expr, env, context)?; let contract_identifier = match contract_value { Value::Principal(PrincipalData::Standard(_)) => { @@ -1187,7 +1194,7 @@ pub fn special_contract_hash( _ => { // If the value is not a principal, we return a check error. return Err( - CheckErrors::ExpectedContractPrincipalValue(Box::new(contract_value)).into(), + CheckErrorKind::ExpectedContractPrincipalValue(Box::new(contract_value)).into(), ); } }; diff --git a/clarity/src/vm/functions/define.rs b/clarity/src/vm/functions/define.rs index 9cef564074..f3b5ee01d2 100644 --- a/clarity/src/vm/functions/define.rs +++ b/clarity/src/vm/functions/define.rs @@ -19,7 +19,7 @@ use std::collections::BTreeMap; use crate::vm::callables::{DefineType, DefinedFunction}; use crate::vm::contexts::{ContractContext, Environment, LocalContext}; use crate::vm::errors::{ - check_argument_count, check_arguments_at_least, CheckErrors, InterpreterResult as Result, + check_argument_count, check_arguments_at_least, CheckErrorKind, InterpreterResult as Result, SyntaxBindingErrorType, }; use crate::vm::eval; @@ -110,7 +110,7 @@ pub enum DefineResult { fn check_legal_define(name: &str, contract_context: &ContractContext) -> Result<()> { if contract_context.is_name_used(name) { - Err(CheckErrors::NameAlreadyUsed(name.to_string()).into()) + Err(CheckErrorKind::NameAlreadyUsed(name.to_string()).into()) } else { Ok(()) } @@ -136,15 +136,15 @@ fn handle_define_function( ) -> Result { let (function_symbol, arg_symbols) = signature .split_first() - .ok_or(CheckErrors::DefineFunctionBadSignature)?; + .ok_or(CheckErrorKind::DefineFunctionBadSignature)?; let function_name = function_symbol .match_atom() - .ok_or(CheckErrors::ExpectedName)?; + .ok_or(CheckErrorKind::ExpectedName)?; check_legal_define(function_name, env.contract_context)?; - let arguments = parse_name_type_pairs::<_, CheckErrors>( + let arguments = parse_name_type_pairs::<_, CheckErrorKind>( *env.epoch(), arg_symbols, SyntaxBindingErrorType::Eval, @@ -217,7 +217,7 @@ fn handle_define_fungible_token( Some(total_supply_int), )) } else { - Err(CheckErrors::TypeValueError( + Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::UIntType), Box::new(total_supply_value), ) @@ -294,7 +294,7 @@ impl<'a> DefineFunctionsParsed<'a> { /// a define-statement, returns None if the supplied expression is not a define. pub fn try_parse( expression: &'a SymbolicExpression, - ) -> std::result::Result>, CheckErrors> { + ) -> std::result::Result>, CheckErrorKind> { let (define_type, args) = match DefineFunctions::try_parse(expression) { Some(x) => x, None => return Ok(None), @@ -302,7 +302,7 @@ impl<'a> DefineFunctionsParsed<'a> { let result = match define_type { DefineFunctions::Constant => { check_argument_count(2, args)?; - let name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; DefineFunctionsParsed::Constant { name, value: &args[1], @@ -312,7 +312,7 @@ impl<'a> DefineFunctionsParsed<'a> { check_argument_count(2, args)?; let signature = args[0] .match_list() - .ok_or(CheckErrors::DefineFunctionBadSignature)?; + .ok_or(CheckErrorKind::DefineFunctionBadSignature)?; DefineFunctionsParsed::PrivateFunction { signature, body: &args[1], @@ -322,7 +322,7 @@ impl<'a> DefineFunctionsParsed<'a> { check_argument_count(2, args)?; let signature = args[0] .match_list() - .ok_or(CheckErrors::DefineFunctionBadSignature)?; + .ok_or(CheckErrorKind::DefineFunctionBadSignature)?; DefineFunctionsParsed::ReadOnlyFunction { signature, body: &args[1], @@ -332,7 +332,7 @@ impl<'a> DefineFunctionsParsed<'a> { check_argument_count(2, args)?; let signature = args[0] .match_list() - .ok_or(CheckErrors::DefineFunctionBadSignature)?; + .ok_or(CheckErrorKind::DefineFunctionBadSignature)?; DefineFunctionsParsed::PublicFunction { signature, body: &args[1], @@ -340,7 +340,7 @@ impl<'a> DefineFunctionsParsed<'a> { } DefineFunctions::NonFungibleToken => { check_argument_count(2, args)?; - let name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; DefineFunctionsParsed::NonFungibleToken { name, nft_type: &args[1], @@ -348,7 +348,7 @@ impl<'a> DefineFunctionsParsed<'a> { } DefineFunctions::FungibleToken => { check_arguments_at_least(1, args)?; - let name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; if args.len() == 1 { DefineFunctionsParsed::UnboundedFungibleToken { name } } else if args.len() == 2 { @@ -357,12 +357,12 @@ impl<'a> DefineFunctionsParsed<'a> { max_supply: &args[1], } } else { - return Err(CheckErrors::IncorrectArgumentCount(1, args.len())); + return Err(CheckErrorKind::IncorrectArgumentCount(1, args.len())); } } DefineFunctions::Map => { check_argument_count(3, args)?; - let name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; DefineFunctionsParsed::Map { name, key_type: &args[1], @@ -371,7 +371,7 @@ impl<'a> DefineFunctionsParsed<'a> { } DefineFunctions::PersistedVariable => { check_argument_count(3, args)?; - let name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; DefineFunctionsParsed::PersistedVariable { name, data_type: &args[1], @@ -380,7 +380,7 @@ impl<'a> DefineFunctionsParsed<'a> { } DefineFunctions::Trait => { check_argument_count(2, args)?; - let name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; DefineFunctionsParsed::Trait { name, functions: &args[1..], @@ -388,13 +388,13 @@ impl<'a> DefineFunctionsParsed<'a> { } DefineFunctions::UseTrait => { check_argument_count(2, args)?; - let name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; match &args[1].expr { Field(ref field) => DefineFunctionsParsed::UseTrait { name, trait_identifier: field, }, - _ => return Err(CheckErrors::ExpectedTraitIdentifier), + _ => return Err(CheckErrorKind::ExpectedTraitIdentifier), } } DefineFunctions::ImplTrait => { @@ -403,7 +403,7 @@ impl<'a> DefineFunctionsParsed<'a> { Field(ref field) => DefineFunctionsParsed::ImplTrait { trait_identifier: field, }, - _ => return Err(CheckErrors::ExpectedTraitIdentifier), + _ => return Err(CheckErrorKind::ExpectedTraitIdentifier), } } }; diff --git a/clarity/src/vm/functions/mod.rs b/clarity/src/vm/functions/mod.rs index f458c282e6..7474b4015c 100644 --- a/clarity/src/vm/functions/mod.rs +++ b/clarity/src/vm/functions/mod.rs @@ -20,7 +20,7 @@ use crate::vm::callables::{cost_input_sized_vararg, CallableType, NativeHandle}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{constants as cost_constants, runtime_cost, CostTracker, MemoryConsumer}; use crate::vm::errors::{ - check_argument_count, check_arguments_at_least, CheckErrors, Error, + check_argument_count, check_arguments_at_least, CheckErrorKind, Error, InterpreterResult as Result, ShortReturnType, SyntaxBindingError, SyntaxBindingErrorType, }; pub use crate::vm::functions::assets::stx_transfer_consolidated; @@ -600,7 +600,7 @@ fn native_eq(args: Vec, env: &mut Environment) -> Result { fn native_begin(mut args: Vec) -> Result { match args.pop() { Some(v) => Ok(v), - None => Err(CheckErrors::RequiresAtLeastArguments(1, 0).into()), + None => Err(CheckErrorKind::RequiresAtLeastArguments(1, 0).into()), } } @@ -642,7 +642,7 @@ fn special_if( eval(&args[2], env, context) } } - _ => Err(CheckErrors::TypeValueError( + _ => Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::BoolType), Box::new(conditional), ) @@ -670,7 +670,7 @@ fn special_asserts( Err(ShortReturnType::AssertionFailed(Box::new(thrown)).into()) } } - _ => Err(CheckErrors::TypeValueError( + _ => Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::BoolType), Box::new(conditional), ) @@ -685,7 +685,7 @@ pub fn handle_binding_list( ) -> std::result::Result<(), E> where F: FnMut(&ClarityName, &SymbolicExpression) -> std::result::Result<(), E>, - E: for<'a> From<(CheckErrors, &'a SymbolicExpression)>, + E: for<'a> From<(CheckErrorKind, &'a SymbolicExpression)>, { for (i, binding) in bindings.iter().enumerate() { let binding_expression = binding.match_list().ok_or_else(|| { @@ -739,7 +739,7 @@ fn special_let( check_arguments_at_least(2, args)?; // parse and eval the bindings. - let bindings = args[0].match_list().ok_or(CheckErrors::BadLetSyntax)?; + let bindings = args[0].match_list().ok_or(CheckErrorKind::BadLetSyntax)?; runtime_cost(ClarityCostFunction::Let, env, bindings.len())?; @@ -753,7 +753,7 @@ fn special_let( if is_reserved(binding_name, env.contract_context.get_clarity_version()) || env.contract_context.lookup_function(binding_name).is_some() || inner_context.lookup_variable(binding_name).is_some() { - return Err(CheckErrors::NameAlreadyUsed(binding_name.clone().into()).into()) + return Err(CheckErrorKind::NameAlreadyUsed(binding_name.clone().into()).into()) } let binding_value = eval(var_sexp, env, &inner_context)?; @@ -821,7 +821,7 @@ fn special_contract_of( let contract_ref = match &args[0].expr { SymbolicExpressionType::Atom(contract_ref) => contract_ref, - _ => return Err(CheckErrors::ContractOfExpectsTrait.into()), + _ => return Err(CheckErrorKind::ContractOfExpectsTrait.into()), }; let contract_identifier = match context.lookup_callable_contract(contract_ref) { @@ -830,12 +830,12 @@ fn special_contract_of( .database .get_contract(&trait_data.contract_identifier) .map_err(|_e| { - CheckErrors::NoSuchContract(trait_data.contract_identifier.to_string()) + CheckErrorKind::NoSuchContract(trait_data.contract_identifier.to_string()) })?; &trait_data.contract_identifier } - _ => return Err(CheckErrors::ContractOfExpectsTrait.into()), + _ => return Err(CheckErrorKind::ContractOfExpectsTrait.into()), }; let contract_principal = Value::Principal(PrincipalData::Contract(contract_identifier.clone())); diff --git a/clarity/src/vm/functions/options.rs b/clarity/src/vm/functions/options.rs index c47dae91cc..419beafe22 100644 --- a/clarity/src/vm/functions/options.rs +++ b/clarity/src/vm/functions/options.rs @@ -18,7 +18,7 @@ use crate::vm::contexts::{Environment, LocalContext}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostTracker, MemoryConsumer}; use crate::vm::errors::{ - check_arguments_at_least, CheckErrors, InterpreterError, InterpreterResult as Result, + check_arguments_at_least, CheckErrorKind, InterpreterError, InterpreterResult as Result, RuntimeErrorType, ShortReturnType, }; use crate::vm::types::{CallableData, OptionalData, ResponseData, TypeSignature, Value}; @@ -35,7 +35,9 @@ fn inner_unwrap(to_unwrap: Value) -> Result> { None } } - _ => return Err(CheckErrors::ExpectedOptionalOrResponseValue(Box::new(to_unwrap)).into()), + _ => { + return Err(CheckErrorKind::ExpectedOptionalOrResponseValue(Box::new(to_unwrap)).into()) + } }; Ok(result) @@ -50,7 +52,7 @@ fn inner_unwrap_err(to_unwrap: Value) -> Result> { None } } - _ => return Err(CheckErrors::ExpectedResponseValue(Box::new(to_unwrap)).into()), + _ => return Err(CheckErrorKind::ExpectedResponseValue(Box::new(to_unwrap)).into()), }; Ok(result) @@ -102,7 +104,7 @@ pub fn native_try_ret(input: Value) -> Result { Err(ShortReturnType::ExpectedValue(Box::new(short_return_val)).into()) } } - _ => Err(CheckErrors::ExpectedOptionalOrResponseValue(Box::new(input)).into()), + _ => Err(CheckErrorKind::ExpectedOptionalOrResponseValue(Box::new(input)).into()), } } @@ -118,7 +120,7 @@ fn eval_with_new_binding( || env.contract_context.lookup_function(&bind_name).is_some() || inner_context.lookup_variable(&bind_name).is_some() { - return Err(CheckErrors::NameAlreadyUsed(bind_name.into()).into()); + return Err(CheckErrorKind::NameAlreadyUsed(bind_name.into()).into()); } let memory_use = bind_value.get_memory_use()?; @@ -150,14 +152,16 @@ fn special_match_opt( context: &LocalContext, ) -> Result { if args.len() != 3 { - Err(CheckErrors::BadMatchOptionSyntax(Box::new( - CheckErrors::IncorrectArgumentCount(4, args.len() + 1), + Err(CheckErrorKind::BadMatchOptionSyntax(Box::new( + CheckErrorKind::IncorrectArgumentCount(4, args.len() + 1), )))?; } let bind_name = args[0] .match_atom() - .ok_or_else(|| CheckErrors::BadMatchOptionSyntax(Box::new(CheckErrors::ExpectedName)))? + .ok_or_else(|| { + CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::ExpectedName)) + })? .clone(); let some_branch = &args[1]; let none_branch = &args[2]; @@ -175,19 +179,23 @@ fn special_match_resp( context: &LocalContext, ) -> Result { if args.len() != 4 { - Err(CheckErrors::BadMatchResponseSyntax(Box::new( - CheckErrors::IncorrectArgumentCount(5, args.len() + 1), + Err(CheckErrorKind::BadMatchResponseSyntax(Box::new( + CheckErrorKind::IncorrectArgumentCount(5, args.len() + 1), )))?; } let ok_bind_name = args[0] .match_atom() - .ok_or_else(|| CheckErrors::BadMatchResponseSyntax(Box::new(CheckErrors::ExpectedName)))? + .ok_or_else(|| { + CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)) + })? .clone(); let ok_branch = &args[1]; let err_bind_name = args[2] .match_atom() - .ok_or_else(|| CheckErrors::BadMatchResponseSyntax(Box::new(CheckErrors::ExpectedName)))? + .ok_or_else(|| { + CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)) + })? .clone(); let err_branch = &args[3]; @@ -212,7 +220,7 @@ pub fn special_match( match input { Value::Response(data) => special_match_resp(data, &args[1..], env, context), Value::Optional(data) => special_match_opt(data, &args[1..], env, context), - _ => Err(CheckErrors::BadMatchInput(Box::new(TypeSignature::type_of(&input)?)).into()), + _ => Err(CheckErrorKind::BadMatchInput(Box::new(TypeSignature::type_of(&input)?)).into()), } } @@ -223,14 +231,14 @@ pub fn native_some(input: Value) -> Result { fn is_some(input: Value) -> Result { match input { Value::Optional(ref data) => Ok(data.data.is_some()), - _ => Err(CheckErrors::ExpectedOptionalValue(Box::new(input)).into()), + _ => Err(CheckErrorKind::ExpectedOptionalValue(Box::new(input)).into()), } } fn is_okay(input: Value) -> Result { match input { Value::Response(data) => Ok(data.committed), - _ => Err(CheckErrors::ExpectedResponseValue(Box::new(input)).into()), + _ => Err(CheckErrorKind::ExpectedResponseValue(Box::new(input)).into()), } } @@ -264,6 +272,6 @@ pub fn native_default_to(default: Value, input: Value) -> Result { Some(data) => Ok(*data), None => Ok(default), }, - _ => Err(CheckErrors::ExpectedOptionalValue(Box::new(input)).into()), + _ => Err(CheckErrorKind::ExpectedOptionalValue(Box::new(input)).into()), } } diff --git a/clarity/src/vm/functions/principals.rs b/clarity/src/vm/functions/principals.rs index 51fc33136f..a8fdf739b7 100644 --- a/clarity/src/vm/functions/principals.rs +++ b/clarity/src/vm/functions/principals.rs @@ -7,7 +7,7 @@ use crate::vm::contexts::GlobalContext; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckErrors, + check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckErrorKind, InterpreterError, InterpreterResult as Result, }; use crate::vm::representations::{ @@ -61,7 +61,7 @@ pub fn special_is_standard( let version = if let Value::Principal(ref p) = owner { p.version() } else { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::PrincipalType), Box::new(owner), ) @@ -169,7 +169,7 @@ pub fn special_principal_destruct( (issuer.0, issuer.1, Some(name)) } _ => { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::PrincipalType), Box::new(principal), ) @@ -211,7 +211,10 @@ pub fn special_principal_construct( _ => { return { // This is an aborting error because this should have been caught in analysis pass. - Err(CheckErrors::TypeValueError(Box::new(BUFF_1.clone()), Box::new(version)).into()) + Err( + CheckErrorKind::TypeValueError(Box::new(BUFF_1.clone()), Box::new(version)) + .into(), + ) }; } }; @@ -219,7 +222,7 @@ pub fn special_principal_construct( let version_byte = if verified_version.len() > 1 { // should have been caught by the type-checker return Err( - CheckErrors::TypeValueError(Box::new(BUFF_1.clone()), Box::new(version)).into(), + CheckErrorKind::TypeValueError(Box::new(BUFF_1.clone()), Box::new(version)).into(), ); } else if verified_version.is_empty() { // the type checker does not check the actual length of the buffer, but a 0-length buffer @@ -244,7 +247,7 @@ pub fn special_principal_construct( let verified_hash_bytes = match hash_bytes { Value::Sequence(SequenceData::Buffer(BuffData { ref data })) => data, _ => { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(BUFF_20.clone()), Box::new(hash_bytes), ) @@ -255,9 +258,11 @@ pub fn special_principal_construct( // This must have been a (buff 20). // This is an aborting error because this should have been caught in analysis pass. if verified_hash_bytes.len() > 20 { - return Err( - CheckErrors::TypeValueError(Box::new(BUFF_20.clone()), Box::new(hash_bytes)).into(), - ); + return Err(CheckErrorKind::TypeValueError( + Box::new(BUFF_20.clone()), + Box::new(hash_bytes), + ) + .into()); } // If the hash-bytes buffer has less than 20 bytes, this is a runtime error, because it @@ -277,7 +282,7 @@ pub fn special_principal_construct( let name_bytes = match name { Value::Sequence(SequenceData::String(CharType::ASCII(ascii_data))) => ascii_data, _ => { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::contract_name_string_ascii_type()?), Box::new(name), ) @@ -294,7 +299,7 @@ pub fn special_principal_construct( // if it's too long, then this should have been caught by the type-checker if name_bytes.data.len() > CONTRACT_MAX_NAME_LENGTH { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::contract_name_string_ascii_type()?), Box::new(Value::from(name_bytes)), ) diff --git a/clarity/src/vm/functions/sequences.rs b/clarity/src/vm/functions/sequences.rs index cafc795d36..ecfd085cb7 100644 --- a/clarity/src/vm/functions/sequences.rs +++ b/clarity/src/vm/functions/sequences.rs @@ -21,7 +21,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostOverflowingMath}; use crate::vm::errors::{ - check_argument_count, check_arguments_at_least, CheckErrors, InterpreterResult as Result, + check_argument_count, check_arguments_at_least, CheckErrorKind, InterpreterResult as Result, RuntimeErrorType, }; use crate::vm::representations::SymbolicExpression; @@ -57,7 +57,7 @@ pub fn special_filter( runtime_cost(ClarityCostFunction::Filter, env, 0)?; - let function_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let function_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let mut sequence = eval(&args[1], env, context)?; let function = lookup_function(function_name, env)?; @@ -71,7 +71,7 @@ pub fn special_filter( Ok(include) } else { Err( - CheckErrors::TypeValueError(Box::new(BoolType), Box::new(filter_eval)) + CheckErrorKind::TypeValueError(Box::new(BoolType), Box::new(filter_eval)) .into(), ) } @@ -79,7 +79,8 @@ pub fn special_filter( } _ => { return Err( - CheckErrors::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)).into(), + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)) + .into(), ) } }; @@ -95,7 +96,7 @@ pub fn special_fold( runtime_cost(ClarityCostFunction::Fold, env, 0)?; - let function_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let function_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let function = lookup_function(function_name, env)?; let mut sequence = eval(&args[1], env, context)?; @@ -113,9 +114,9 @@ pub fn special_fold( context, ) }), - _ => { - Err(CheckErrors::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)).into()) - } + _ => Err( + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)).into(), + ), } } @@ -128,7 +129,7 @@ pub fn special_map( runtime_cost(ClarityCostFunction::Map, env, args.len())?; - let function_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let function_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let function = lookup_function(function_name, env)?; // Let's consider a function f (f a b c ...) @@ -154,7 +155,7 @@ pub fn special_map( } _ => { return Err( - CheckErrors::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)) + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)) .into(), ) } @@ -210,7 +211,7 @@ pub fn special_append( TypeSignature::least_supertype(env.epoch(), &entry_type, &element_type) { let (element, _) = Value::sanitize_value(env.epoch(), &next_entry_type, element) - .ok_or_else(|| CheckErrors::ListTypesMustMatch)?; + .ok_or_else(|| CheckErrorKind::ListTypesMustMatch)?; let next_type_signature = ListTypeData::new_list(next_entry_type, size + 1)?; data.push(element); @@ -219,10 +220,10 @@ pub fn special_append( data, }))) } else { - Err(CheckErrors::TypeValueError(Box::new(entry_type), Box::new(element)).into()) + Err(CheckErrorKind::TypeValueError(Box::new(entry_type), Box::new(element)).into()) } } - _ => Err(CheckErrors::ExpectedListApplication.into()), + _ => Err(CheckErrorKind::ExpectedListApplication.into()), } } @@ -299,7 +300,7 @@ pub fn special_as_max_len( Value::Sequence(ref sequence_data) => sequence_data.len() as u128, _ => { return Err( - CheckErrors::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)) + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)) .into(), ) } @@ -314,7 +315,7 @@ pub fn special_as_max_len( } } else { let actual_len = eval(&args[1], env, context)?; - Err(CheckErrors::TypeError( + Err(CheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::type_of(&actual_len)?), ) @@ -325,9 +326,9 @@ pub fn special_as_max_len( pub fn native_len(sequence: Value) -> Result { match sequence { Value::Sequence(sequence_data) => Ok(Value::UInt(sequence_data.len() as u128)), - _ => { - Err(CheckErrors::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)).into()) - } + _ => Err( + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)).into(), + ), } } @@ -338,7 +339,7 @@ pub fn native_index_of(sequence: Value, to_find: Value) -> Result { None => Ok(Value::none()), } } else { - Err(CheckErrors::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)).into()) + Err(CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)).into()) } } @@ -347,7 +348,7 @@ pub fn native_element_at(sequence: Value, index: Value) -> Result { sequence_data } else { return Err( - CheckErrors::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)).into(), + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::type_of(&sequence)?)).into(), ); }; @@ -358,7 +359,7 @@ pub fn native_element_at(sequence: Value, index: Value) -> Result { return Ok(Value::none()); } } else { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::UIntType), Box::new(index), ) @@ -439,7 +440,7 @@ pub fn special_replace_at( let expected_elem_type = if let TypeSignature::SequenceType(seq_subtype) = &seq_type { seq_subtype.unit_type()? } else { - return Err(CheckErrors::ExpectedSequence(Box::new(seq_type)).into()); + return Err(CheckErrorKind::ExpectedSequence(Box::new(seq_type)).into()); }; let index_val = eval(&args[1], env, context)?; let new_element = eval(&args[2], env, context)?; @@ -447,7 +448,7 @@ pub fn special_replace_at( if expected_elem_type != TypeSignature::NoType && !expected_elem_type.admits(env.epoch(), &new_element)? { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(expected_elem_type), Box::new(new_element), ) @@ -461,7 +462,7 @@ pub fn special_replace_at( return Ok(Value::none()); } } else { - return Err(CheckErrors::TypeValueError( + return Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::UIntType), Box::new(index_val), ) @@ -475,6 +476,6 @@ pub fn special_replace_at( } data.replace_at(env.epoch(), index, new_element) } else { - Err(CheckErrors::ExpectedSequence(Box::new(seq_type)).into()) + Err(CheckErrorKind::ExpectedSequence(Box::new(seq_type)).into()) } } diff --git a/clarity/src/vm/functions/tuples.rs b/clarity/src/vm/functions/tuples.rs index 7db8f13959..bc5778ebea 100644 --- a/clarity/src/vm/functions/tuples.rs +++ b/clarity/src/vm/functions/tuples.rs @@ -16,7 +16,7 @@ use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, check_arguments_at_least, CheckErrors, InterpreterError, + check_argument_count, check_arguments_at_least, CheckErrorKind, InterpreterError, InterpreterResult as Result, SyntaxBindingErrorType, }; use crate::vm::representations::SymbolicExpression; @@ -49,7 +49,7 @@ pub fn tuple_get( // if the tuple argument is an option type, then return option(field-name). check_argument_count(2, args)?; - let arg_name = args[0].match_atom().ok_or(CheckErrors::ExpectedName)?; + let arg_name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; let value = eval(&args[1], env, context)?; @@ -66,7 +66,7 @@ pub fn tuple_get( })?) } else { Err( - CheckErrors::ExpectedTuple(Box::new(TypeSignature::type_of(&data)?)) + CheckErrorKind::ExpectedTuple(Box::new(TypeSignature::type_of(&data)?)) .into(), ) } @@ -78,21 +78,21 @@ pub fn tuple_get( runtime_cost(ClarityCostFunction::TupleGet, env, tuple_data.len())?; tuple_data.get_owned(arg_name) } - _ => Err(CheckErrors::ExpectedTuple(Box::new(TypeSignature::type_of(&value)?)).into()), + _ => Err(CheckErrorKind::ExpectedTuple(Box::new(TypeSignature::type_of(&value)?)).into()), } } pub fn tuple_merge(base: Value, update: Value) -> Result { let initial_values = match base { Value::Tuple(initial_values) => Ok(initial_values), - _ => Err(CheckErrors::ExpectedTuple(Box::new( + _ => Err(CheckErrorKind::ExpectedTuple(Box::new( TypeSignature::type_of(&base)?, ))), }?; let new_values = match update { Value::Tuple(new_values) => Ok(new_values), - _ => Err(CheckErrors::ExpectedTuple(Box::new( + _ => Err(CheckErrorKind::ExpectedTuple(Box::new( TypeSignature::type_of(&update)?, ))), }?; diff --git a/clarity/src/vm/mod.rs b/clarity/src/vm/mod.rs index 781c7d4d7b..0e38f511e9 100644 --- a/clarity/src/vm/mod.rs +++ b/clarity/src/vm/mod.rs @@ -73,7 +73,7 @@ use crate::vm::costs::{ // publish the non-generic StacksEpoch form for use throughout module pub use crate::vm::database::clarity_db::StacksEpoch; use crate::vm::errors::{ - CheckErrors, Error, InterpreterError, InterpreterResult as Result, RuntimeErrorType, + CheckErrorKind, Error, InterpreterError, InterpreterResult as Result, RuntimeErrorType, }; use crate::vm::events::StacksTransactionEvent; use crate::vm::functions::define::DefineResult; @@ -183,7 +183,7 @@ fn lookup_variable(name: &str, context: &LocalContext, env: &mut Environment) -> runtime_cost(ClarityCostFunction::LookupVariableSize, env, value.size()?)?; let (value, _) = Value::sanitize_value(env.epoch(), &TypeSignature::type_of(&value)?, value) - .ok_or_else(|| CheckErrors::CouldNotDetermineType)?; + .ok_or_else(|| CheckErrorKind::CouldNotDetermineType)?; Ok(value) } else if let Some(callable_data) = context.lookup_callable_contract(name) { if env.contract_context.get_clarity_version() < &ClarityVersion::Clarity2 { @@ -192,7 +192,7 @@ fn lookup_variable(name: &str, context: &LocalContext, env: &mut Environment) -> Ok(Value::CallableContract(callable_data.clone())) } } else { - Err(CheckErrors::UndefinedVariable(name.to_string()).into()) + Err(CheckErrorKind::UndefinedVariable(name.to_string()).into()) } } } @@ -208,7 +208,7 @@ pub fn lookup_function(name: &str, env: &mut Environment) -> Result= MAX_CALL_STACK_DEPTH { @@ -341,11 +341,11 @@ pub fn eval( List(ref children) => { let (function_variable, rest) = children .split_first() - .ok_or(CheckErrors::NonFunctionApplication)?; + .ok_or(CheckErrorKind::NonFunctionApplication)?; let function_name = function_variable .match_atom() - .ok_or(CheckErrors::BadFunctionName)?; + .ok_or(CheckErrorKind::BadFunctionName)?; let f = lookup_function(function_name, env)?; apply(&f, rest, env, context) } diff --git a/clarity/src/vm/tests/assets.rs b/clarity/src/vm/tests/assets.rs index 0cfeebfb27..649deb4496 100644 --- a/clarity/src/vm/tests/assets.rs +++ b/clarity/src/vm/tests/assets.rs @@ -26,7 +26,7 @@ use crate::vm::types::{PrincipalData, QualifiedContractIdentifier, Value}; use crate::vm::{ ast::ASTRules, contexts::AssetMapEntry, - errors::{CheckErrors, RuntimeErrorType}, + errors::{CheckErrorKind, RuntimeErrorType}, tests::{ execute, is_committed, is_err_code, symbols_from_values, tl_env_factory as env_factory, TopLevelMemoryEnvironmentGenerator, @@ -622,7 +622,7 @@ fn test_simple_token_system( assert!(matches!( err, - Error::Unchecked(CheckErrors::TypeValueError(_, _)) + Error::Unchecked(CheckErrorKind::TypeValueError(_, _)) )); let (result, asset_map, _events) = execute_transaction( @@ -856,7 +856,7 @@ fn test_total_supply(epoch: StacksEpochId, mut env_factory: TopLevelMemoryEnviro .unwrap_err(); assert!(matches!( err, - Error::Unchecked(CheckErrors::TypeValueError(_, _)) + Error::Unchecked(CheckErrorKind::TypeValueError(_, _)) )); let err = owned_env @@ -869,7 +869,7 @@ fn test_total_supply(epoch: StacksEpochId, mut env_factory: TopLevelMemoryEnviro .unwrap_err(); assert!(matches!( err, - Error::Unchecked(CheckErrors::TypeValueError(_, _)) + Error::Unchecked(CheckErrorKind::TypeValueError(_, _)) )); owned_env diff --git a/clarity/src/vm/tests/contracts.rs b/clarity/src/vm/tests/contracts.rs index da9d4f3731..5ec0f71a56 100644 --- a/clarity/src/vm/tests/contracts.rs +++ b/clarity/src/vm/tests/contracts.rs @@ -27,7 +27,7 @@ use crate::vm::types::{PrincipalData, QualifiedContractIdentifier, StandardPrinc #[cfg(test)] use crate::vm::{ ast::{errors::ParseErrors, ASTRules}, - errors::{CheckErrors, Error, RuntimeErrorType}, + errors::{CheckErrorKind, Error, RuntimeErrorType}, tests::{ env_factory, execute, is_committed, is_err_code_i128 as is_err_code, symbols_from_values, tl_env_factory, MemoryEnvironmentGenerator, TopLevelMemoryEnvironmentGenerator, @@ -114,12 +114,12 @@ fn test_get_block_info_eval( Ok(Value::none()), Ok(Value::none()), Ok(Value::none()), - Err(CheckErrors::TypeValueError( + Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::UIntType), Box::new(Value::Int(-1)), ) .into()), - Err(CheckErrors::TypeValueError( + Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::UIntType), Box::new(Value::Bool(true)), ) @@ -972,7 +972,7 @@ fn test_factorial_contract(epoch: StacksEpochId, mut env_factory: MemoryEnvironm .unwrap_err(); assert!(matches!( err_result, - Error::Unchecked(CheckErrors::NoSuchPublicFunction(_, _)) + Error::Unchecked(CheckErrorKind::NoSuchPublicFunction(_, _)) )); let err_result = env @@ -985,7 +985,7 @@ fn test_factorial_contract(epoch: StacksEpochId, mut env_factory: MemoryEnvironm .unwrap_err(); assert!(matches!( err_result, - Error::Unchecked(CheckErrors::TypeValueError(_, _)) + Error::Unchecked(CheckErrorKind::TypeValueError(_, _)) )); } @@ -1180,7 +1180,7 @@ fn test_eval_with_non_existing_contract( ); assert_eq!( result.as_ref().unwrap_err(), - &Error::Unchecked(CheckErrors::NoSuchContract( + &Error::Unchecked(CheckErrorKind::NoSuchContract( QualifiedContractIdentifier::local("absent") .unwrap() .to_string() @@ -1382,7 +1382,7 @@ fn test_contract_hash_type_check( .unwrap_err(); assert_eq!( err, - Error::Unchecked(CheckErrors::ExpectedContractPrincipalValue(Box::new( + Error::Unchecked(CheckErrorKind::ExpectedContractPrincipalValue(Box::new( Value::UInt(123) ))) ); @@ -1440,6 +1440,8 @@ fn test_contract_hash_pre_clarity4( assert_eq!( err, - Error::Unchecked(CheckErrors::UndefinedFunction("contract-hash?".to_string())) + Error::Unchecked(CheckErrorKind::UndefinedFunction( + "contract-hash?".to_string() + )) ); } diff --git a/clarity/src/vm/tests/conversions.rs b/clarity/src/vm/tests/conversions.rs index c6835efaa4..7b81d0ebc0 100644 --- a/clarity/src/vm/tests/conversions.rs +++ b/clarity/src/vm/tests/conversions.rs @@ -16,7 +16,7 @@ use stacks_common::types::StacksEpochId; -pub use crate::vm::analysis::errors::CheckErrors; +pub use crate::vm::analysis::errors::CheckErrorKind; use crate::vm::tests::test_clarity_versions; use crate::vm::types::signatures::MAX_TO_ASCII_BUFFER_LEN; use crate::vm::types::SequenceSubtype::BufferType; @@ -48,14 +48,14 @@ fn test_simple_buff_to_int_le() { "(buff-to-int-le \"not-needed\" 0xfffffffffffffffffffffffffffffffe)"; assert_eq!( execute_v2(bad_wrong_number_test).unwrap_err(), - CheckErrors::IncorrectArgumentCount(1, 2).into() + CheckErrorKind::IncorrectArgumentCount(1, 2).into() ); // Right number of arguments, but wrong type. let bad_wrong_type_test = "(buff-to-int-le \"wrong-type\")"; assert_eq!( execute_v2(bad_wrong_type_test).unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32).unwrap() ))), @@ -72,7 +72,7 @@ fn test_simple_buff_to_int_le() { let bad_too_large_test = "(buff-to-int-le 0x000102030405060708090a0b0c0d0e0f00)"; assert_eq!( execute_v2(bad_too_large_test).unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32).unwrap() ))), @@ -106,14 +106,14 @@ fn test_simple_buff_to_uint_le() { "(buff-to-uint-le \"not-needed\" 0xfffffffffffffffffffffffffffffffe)"; assert_eq!( execute_v2(bad_wrong_number_test).unwrap_err(), - CheckErrors::IncorrectArgumentCount(1, 2).into() + CheckErrorKind::IncorrectArgumentCount(1, 2).into() ); // Right number of arguments, but wrong type. let bad_wrong_type_test = "(buff-to-uint-le \"wrong-type\")"; assert_eq!( execute_v2(bad_wrong_type_test).unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32).unwrap() ))), @@ -130,7 +130,7 @@ fn test_simple_buff_to_uint_le() { let bad_too_large_test = "(buff-to-uint-le 0x000102030405060708090a0b0c0d0e0f00)"; assert_eq!( execute_v2(bad_too_large_test).unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32).unwrap() ))), @@ -164,14 +164,14 @@ fn test_simple_buff_to_int_be() { "(buff-to-int-be \"not-needed\" 0xfffffffffffffffffffffffffffffffe)"; assert_eq!( execute_v2(bad_wrong_number_test).unwrap_err(), - CheckErrors::IncorrectArgumentCount(1, 2).into() + CheckErrorKind::IncorrectArgumentCount(1, 2).into() ); // Right number of arguments, but wrong type. let bad_wrong_type_test = "(buff-to-int-be \"wrong-type\")"; assert_eq!( execute_v2(bad_wrong_type_test).unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32).unwrap() ))), @@ -188,7 +188,7 @@ fn test_simple_buff_to_int_be() { let bad_too_large_test = "(buff-to-int-be 0x000102030405060708090a0b0c0d0e0f00)"; assert_eq!( execute_v2(bad_too_large_test).unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32).unwrap() ))), @@ -222,14 +222,14 @@ fn test_simple_buff_to_uint_be() { "(buff-to-uint-be \"not-needed\" 0xfffffffffffffffffffffffffffffffe)"; assert_eq!( execute_v2(bad_wrong_number_test).unwrap_err(), - CheckErrors::IncorrectArgumentCount(1, 2).into() + CheckErrorKind::IncorrectArgumentCount(1, 2).into() ); // Right number of arguments, but wrong type. let bad_wrong_type_test = "(buff-to-uint-be \"wrong-type\")"; assert_eq!( execute_v2(bad_wrong_type_test).unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32).unwrap() ))), @@ -246,7 +246,7 @@ fn test_simple_buff_to_uint_be() { let bad_too_large_test = "(buff-to-uint-be 0x000102030405060708090a0b0c0d0e0f00)"; assert_eq!( execute_v2(bad_too_large_test).unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32).unwrap() ))), @@ -306,13 +306,13 @@ fn test_simple_string_to_int() { let no_args_test = r#"(string-to-int?)"#; assert_eq!( execute_v2(no_args_test).unwrap_err(), - CheckErrors::IncorrectArgumentCount(1, 0).into() + CheckErrorKind::IncorrectArgumentCount(1, 0).into() ); let wrong_type_error_test = r#"(string-to-int? 1)"#; assert_eq!( execute_v2(wrong_type_error_test).unwrap_err(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::max_string_ascii().unwrap(), TypeSignature::max_string_utf8().unwrap(), @@ -371,13 +371,13 @@ fn test_simple_string_to_uint() { let no_args_test = r#"(string-to-uint?)"#; assert_eq!( execute_v2(no_args_test).unwrap_err(), - CheckErrors::IncorrectArgumentCount(1, 0).into() + CheckErrorKind::IncorrectArgumentCount(1, 0).into() ); let wrong_type_error_test = r#"(string-to-uint? 1)"#; assert_eq!( execute_v2(wrong_type_error_test).unwrap_err(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::max_string_ascii().unwrap(), TypeSignature::max_string_utf8().unwrap(), @@ -405,13 +405,13 @@ fn test_simple_int_to_ascii() { let no_args_test = r#"(int-to-ascii)"#; assert_eq!( execute_v2(no_args_test).unwrap_err(), - CheckErrors::IncorrectArgumentCount(1, 0).into() + CheckErrorKind::IncorrectArgumentCount(1, 0).into() ); let wrong_type_error_test = r#"(int-to-ascii "1")"#; assert_eq!( execute_v2(wrong_type_error_test).unwrap_err(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(Value::Sequence(SequenceData::String(CharType::ASCII( ASCIIData { @@ -440,13 +440,13 @@ fn test_simple_int_to_utf8() { let no_args_test = r#"(int-to-utf8)"#; assert_eq!( execute_v2(no_args_test).unwrap_err(), - CheckErrors::IncorrectArgumentCount(1, 0).into() + CheckErrorKind::IncorrectArgumentCount(1, 0).into() ); let wrong_type_error_test = r#"(int-to-utf8 "1")"#; assert_eq!( execute_v2(wrong_type_error_test).unwrap_err(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(Value::Sequence(SequenceData::String(CharType::ASCII( ASCIIData { diff --git a/clarity/src/vm/tests/datamaps.rs b/clarity/src/vm/tests/datamaps.rs index 83fef9ab76..65da80f743 100644 --- a/clarity/src/vm/tests/datamaps.rs +++ b/clarity/src/vm/tests/datamaps.rs @@ -16,7 +16,7 @@ use crate::vm::types::{TupleData, Value}; #[cfg(test)] use crate::vm::{ - errors::{CheckErrors, ShortReturnType, SyntaxBindingError}, + errors::{CheckErrorKind, ShortReturnType, SyntaxBindingError}, types::{ListData, SequenceData, TupleTypeSignature, TypeSignature}, }; use crate::vm::{execute, ClarityName, Error}; @@ -474,7 +474,7 @@ fn datamap_errors() { for program in tests.iter() { assert_eq!( execute(program).unwrap_err(), - CheckErrors::NoSuchMap("non-existent".to_string()).into() + CheckErrorKind::NoSuchMap("non-existent".to_string()).into() ); } } @@ -495,7 +495,7 @@ fn lists_system_2() { matches!( execute(test), - Err(Error::Unchecked(CheckErrors::TypeError(_, _))) + Err(Error::Unchecked(CheckErrorKind::TypeError(_, _))) ); } @@ -560,7 +560,7 @@ fn lists_system() { println!("{test:#?}"); assert!(matches!( test, - Err(Error::Unchecked(CheckErrors::TypeValueError(_, _))) + Err(Error::Unchecked(CheckErrorKind::TypeValueError(_, _))) )); } } @@ -623,7 +623,7 @@ fn tuples_system() { for test in type_error_tests.iter() { let expected_type_error = match execute(test) { - Err(Error::Unchecked(CheckErrors::TypeValueError(_, _))) => true, + Err(Error::Unchecked(CheckErrorKind::TypeValueError(_, _))) => true, _ => { println!("{:?}", execute(test)); false @@ -644,11 +644,11 @@ fn bad_define_maps() { "(define-map lists { name: int } { contents: (list 5 0 int) })", ]; let expected: Vec = vec![ - CheckErrors::BadSyntaxBinding(SyntaxBindingError::tuple_cons_invalid_length(0)).into(), - CheckErrors::UnknownTypeName("contents".to_string()).into(), - CheckErrors::ExpectedName.into(), - CheckErrors::IncorrectArgumentCount(3, 4).into(), - CheckErrors::InvalidTypeDescription.into(), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::tuple_cons_invalid_length(0)).into(), + CheckErrorKind::UnknownTypeName("contents".to_string()).into(), + CheckErrorKind::ExpectedName.into(), + CheckErrorKind::IncorrectArgumentCount(3, 4).into(), + CheckErrorKind::InvalidTypeDescription.into(), ]; for (test, expected_err) in tests.iter().zip(expected.into_iter()) { @@ -668,15 +668,15 @@ fn bad_tuples() { "(get 1234 (tuple (name 1)))", ]; let expected = vec![ - CheckErrors::NameAlreadyUsed("name".into()), - CheckErrors::BadSyntaxBinding(SyntaxBindingError::tuple_cons_not_list(0)), - CheckErrors::BadSyntaxBinding(SyntaxBindingError::tuple_cons_invalid_length(1)), - CheckErrors::NoSuchTupleField( + CheckErrorKind::NameAlreadyUsed("name".into()), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::tuple_cons_not_list(0)), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::tuple_cons_invalid_length(1)), + CheckErrorKind::NoSuchTupleField( "value".into(), TupleTypeSignature::try_from(vec![("name".into(), TypeSignature::IntType)]).unwrap(), ), - CheckErrors::IncorrectArgumentCount(2, 3), - CheckErrors::ExpectedName, + CheckErrorKind::IncorrectArgumentCount(2, 3), + CheckErrorKind::ExpectedName, ]; for (test, expected_err) in tests.iter().zip(expected.into_iter()) { @@ -769,7 +769,7 @@ fn test_non_tuple_map_get_set() { for test in type_error_tests.iter() { let expected_type_error = match execute(test) { - Err(Error::Unchecked(CheckErrors::TypeValueError(_, _))) => true, + Err(Error::Unchecked(CheckErrorKind::TypeValueError(_, _))) => true, _ => { println!("{:?}", execute(test)); false diff --git a/clarity/src/vm/tests/defines.rs b/clarity/src/vm/tests/defines.rs index 2cd874f2c3..7ea486cc6d 100644 --- a/clarity/src/vm/tests/defines.rs +++ b/clarity/src/vm/tests/defines.rs @@ -21,7 +21,7 @@ use rstest_reuse::{self, *}; #[cfg(test)] use stacks_common::types::StacksEpochId; -use crate::vm::errors::{CheckErrors, Error}; +use crate::vm::errors::{CheckErrorKind, Error}; use crate::vm::tests::test_clarity_versions; #[cfg(test)] use crate::vm::{ @@ -32,7 +32,7 @@ use crate::vm::{ {execute, ClarityVersion}, }; -fn assert_eq_err(e1: CheckErrors, e2: Error) { +fn assert_eq_err(e1: CheckErrorKind, e2: Error) { let e1: Error = e1.into(); assert_eq!(e1, e2) } @@ -51,7 +51,7 @@ fn test_defines() { assert_eq!( execute(tests).unwrap_err(), - CheckErrors::IncorrectArgumentCount(2, 3).into() + CheckErrorKind::IncorrectArgumentCount(2, 3).into() ); let tests = "1"; @@ -70,7 +70,7 @@ fn test_accept_options(#[case] version: ClarityVersion, #[case] epoch: StacksEpo let expectations: &[Result<_, Error>] = &[ Ok(Some(Value::Int(0))), Ok(Some(Value::Int(10))), - Err(CheckErrors::TypeValueError( + Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::from_string("(optional int)", version, epoch)), Box::new(Value::some(Value::Bool(true)).unwrap()), ) @@ -84,7 +84,7 @@ fn test_accept_options(#[case] version: ClarityVersion, #[case] epoch: StacksEpo let bad_defun = "(define-private (f (b (optional int int))) (* 10 (default-to 0 b)))"; assert_eq!( execute(bad_defun).unwrap_err(), - CheckErrors::InvalidTypeDescription.into() + CheckErrorKind::InvalidTypeDescription.into() ); } @@ -101,16 +101,16 @@ fn test_bad_define_names() { (+ foo foo)"; assert_eq_err( - CheckErrors::NameAlreadyUsed("tx-sender".to_string()), + CheckErrorKind::NameAlreadyUsed("tx-sender".to_string()), execute(test0).unwrap_err(), ); assert_eq_err( - CheckErrors::NameAlreadyUsed("*".to_string()), + CheckErrorKind::NameAlreadyUsed("*".to_string()), execute(test1).unwrap_err(), ); - assert_eq_err(CheckErrors::ExpectedName, execute(test2).unwrap_err()); + assert_eq_err(CheckErrorKind::ExpectedName, execute(test2).unwrap_err()); assert_eq_err( - CheckErrors::NameAlreadyUsed("foo".to_string()), + CheckErrorKind::NameAlreadyUsed("foo".to_string()), execute(test3).unwrap_err(), ); } @@ -126,20 +126,20 @@ fn test_unwrap_ret() { assert_eq!(Ok(Some(Value::Int(1))), execute(test0)); assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 1), + CheckErrorKind::IncorrectArgumentCount(2, 1), execute(test1).unwrap_err(), ); assert_eq_err( - CheckErrors::ExpectedOptionalOrResponseValue(Box::new(Value::Int(1))), + CheckErrorKind::ExpectedOptionalOrResponseValue(Box::new(Value::Int(1))), execute(test2).unwrap_err(), ); assert_eq_err( - CheckErrors::ExpectedResponseValue(Box::new(Value::Int(1))), + CheckErrorKind::ExpectedResponseValue(Box::new(Value::Int(1))), execute(test3).unwrap_err(), ); assert_eq!(Ok(Some(Value::Int(1))), execute(test4)); assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 1), + CheckErrorKind::IncorrectArgumentCount(2, 1), execute(test5).unwrap_err(), ); } @@ -155,15 +155,15 @@ fn test_define_read_only() { assert_eq!(Ok(Some(Value::Int(1))), execute(test0)); assert_eq_err( - CheckErrors::WriteAttemptedInReadOnly, + CheckErrorKind::WriteAttemptedInReadOnly, execute(test1).unwrap_err(), ); assert_eq_err( - CheckErrors::WriteAttemptedInReadOnly, + CheckErrorKind::WriteAttemptedInReadOnly, execute(test2).unwrap_err(), ); assert_eq_err( - CheckErrors::WriteAttemptedInReadOnly, + CheckErrorKind::WriteAttemptedInReadOnly, execute(test3).unwrap_err(), ); } @@ -213,19 +213,19 @@ fn test_recursive_panic(#[case] version: ClarityVersion, #[case] epoch: StacksEp #[test] fn test_bad_variables() { let test0 = "(+ a 1)"; - let expected = CheckErrors::UndefinedVariable("a".to_string()); + let expected = CheckErrorKind::UndefinedVariable("a".to_string()); assert_eq_err(expected, execute(test0).unwrap_err()); let test1 = "(foo 2 1)"; - let expected = CheckErrors::UndefinedFunction("foo".to_string()); + let expected = CheckErrorKind::UndefinedFunction("foo".to_string()); assert_eq_err(expected, execute(test1).unwrap_err()); let test2 = "((lambda (x y) 1) 2 1)"; - let expected = CheckErrors::BadFunctionName; + let expected = CheckErrorKind::BadFunctionName; assert_eq_err(expected, execute(test2).unwrap_err()); let test4 = "()"; - let expected = CheckErrors::NonFunctionApplication; + let expected = CheckErrorKind::NonFunctionApplication; assert_eq_err(expected, execute(test4).unwrap_err()); } @@ -249,19 +249,19 @@ fn test_variable_shadowing() { "#; assert_eq_err( - CheckErrors::NameAlreadyUsed("cursor".to_string()), + CheckErrorKind::NameAlreadyUsed("cursor".to_string()), execute(test0).unwrap_err(), ); assert_eq_err( - CheckErrors::NameAlreadyUsed("cursor".to_string()), + CheckErrorKind::NameAlreadyUsed("cursor".to_string()), execute(test1).unwrap_err(), ); assert_eq_err( - CheckErrors::NameAlreadyUsed("cursor".to_string()), + CheckErrorKind::NameAlreadyUsed("cursor".to_string()), execute(test2).unwrap_err(), ); assert_eq_err( - CheckErrors::NameAlreadyUsed("cursor".to_string()), + CheckErrorKind::NameAlreadyUsed("cursor".to_string()), execute(test3).unwrap_err(), ); } @@ -269,7 +269,7 @@ fn test_variable_shadowing() { #[test] fn test_define_parse_panic() { let tests = "(define-private () 1)"; - let expected = CheckErrors::DefineFunctionBadSignature; + let expected = CheckErrorKind::DefineFunctionBadSignature; assert_eq_err(expected, execute(tests).unwrap_err()); } @@ -277,7 +277,7 @@ fn test_define_parse_panic() { fn test_define_parse_panic_2() { let tests = "(define-private (a b (d)) 1)"; assert_eq_err( - CheckErrors::BadSyntaxBinding(SyntaxBindingError::eval_binding_not_list(0)), + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::eval_binding_not_list(0)), execute(tests).unwrap_err(), ); } @@ -290,16 +290,16 @@ fn test_define_constant_arg_count() { let test3 = "(define-constant foo u2 u3)"; assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 0), + CheckErrorKind::IncorrectArgumentCount(2, 0), execute(test0).unwrap_err(), ); assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 1), + CheckErrorKind::IncorrectArgumentCount(2, 1), execute(test1).unwrap_err(), ); execute(test2).unwrap(); assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 3), + CheckErrorKind::IncorrectArgumentCount(2, 3), execute(test3).unwrap_err(), ); } @@ -312,16 +312,16 @@ fn test_define_private_arg_count() { let test3 = "(define-private (foo) u2 u3)"; assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 0), + CheckErrorKind::IncorrectArgumentCount(2, 0), execute(test0).unwrap_err(), ); assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 1), + CheckErrorKind::IncorrectArgumentCount(2, 1), execute(test1).unwrap_err(), ); execute(test2).unwrap(); assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 3), + CheckErrorKind::IncorrectArgumentCount(2, 3), execute(test3).unwrap_err(), ); } @@ -334,16 +334,16 @@ fn test_define_public_arg_count() { let test3 = "(define-public (foo) (ok u2) u3)"; assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 0), + CheckErrorKind::IncorrectArgumentCount(2, 0), execute(test0).unwrap_err(), ); assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 1), + CheckErrorKind::IncorrectArgumentCount(2, 1), execute(test1).unwrap_err(), ); execute(test2).unwrap(); assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 3), + CheckErrorKind::IncorrectArgumentCount(2, 3), execute(test3).unwrap_err(), ); } @@ -356,16 +356,16 @@ fn test_define_read_only_arg_count() { let test3 = "(define-read-only (foo) u2 u3)"; assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 0), + CheckErrorKind::IncorrectArgumentCount(2, 0), execute(test0).unwrap_err(), ); assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 1), + CheckErrorKind::IncorrectArgumentCount(2, 1), execute(test1).unwrap_err(), ); execute(test2).unwrap(); assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 3), + CheckErrorKind::IncorrectArgumentCount(2, 3), execute(test3).unwrap_err(), ); } @@ -379,20 +379,20 @@ fn test_define_map_arg_count() { let test4 = "(define-map foo uint uint uint)"; assert_eq_err( - CheckErrors::IncorrectArgumentCount(3, 0), + CheckErrorKind::IncorrectArgumentCount(3, 0), execute(test0).unwrap_err(), ); assert_eq_err( - CheckErrors::IncorrectArgumentCount(3, 1), + CheckErrorKind::IncorrectArgumentCount(3, 1), execute(test1).unwrap_err(), ); assert_eq_err( - CheckErrors::IncorrectArgumentCount(3, 2), + CheckErrorKind::IncorrectArgumentCount(3, 2), execute(test2).unwrap_err(), ); execute(test3).unwrap(); assert_eq_err( - CheckErrors::IncorrectArgumentCount(3, 4), + CheckErrorKind::IncorrectArgumentCount(3, 4), execute(test4).unwrap_err(), ); } @@ -406,20 +406,20 @@ fn test_define_data_var_arg_count() { let test4 = "(define-data-var foo uint u3 u4)"; assert_eq_err( - CheckErrors::IncorrectArgumentCount(3, 0), + CheckErrorKind::IncorrectArgumentCount(3, 0), execute(test0).unwrap_err(), ); assert_eq_err( - CheckErrors::IncorrectArgumentCount(3, 1), + CheckErrorKind::IncorrectArgumentCount(3, 1), execute(test1).unwrap_err(), ); assert_eq_err( - CheckErrors::IncorrectArgumentCount(3, 2), + CheckErrorKind::IncorrectArgumentCount(3, 2), execute(test2).unwrap_err(), ); execute(test3).unwrap(); assert_eq_err( - CheckErrors::IncorrectArgumentCount(3, 4), + CheckErrorKind::IncorrectArgumentCount(3, 4), execute(test4).unwrap_err(), ); } @@ -432,13 +432,13 @@ fn test_define_fungible_token_arg_count() { let test3 = "(define-fungible-token foo u2 u3)"; assert_eq_err( - CheckErrors::RequiresAtLeastArguments(1, 0), + CheckErrorKind::RequiresAtLeastArguments(1, 0), execute(test0).unwrap_err(), ); execute(test1).unwrap(); execute(test2).unwrap(); assert_eq_err( - CheckErrors::IncorrectArgumentCount(1, 3), + CheckErrorKind::IncorrectArgumentCount(1, 3), execute(test3).unwrap_err(), ); } @@ -451,16 +451,16 @@ fn test_define_non_fungible_token_arg_count() { let test3 = "(define-non-fungible-token foo uint uint)"; assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 0), + CheckErrorKind::IncorrectArgumentCount(2, 0), execute(test0).unwrap_err(), ); assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 1), + CheckErrorKind::IncorrectArgumentCount(2, 1), execute(test1).unwrap_err(), ); execute(test2).unwrap(); assert_eq_err( - CheckErrors::IncorrectArgumentCount(2, 3), + CheckErrorKind::IncorrectArgumentCount(2, 3), execute(test3).unwrap_err(), ); } diff --git a/clarity/src/vm/tests/principals.rs b/clarity/src/vm/tests/principals.rs index aefbd2cc7a..080ffa0522 100644 --- a/clarity/src/vm/tests/principals.rs +++ b/clarity/src/vm/tests/principals.rs @@ -8,7 +8,7 @@ use crate::vm::types::{ }; #[cfg(test)] use crate::vm::{ - errors::CheckErrors, + errors::CheckErrorKind, functions::principals::PrincipalConstructErrorCode, types::TypeSignature::PrincipalType, types::{ResponseData, TypeSignature, BUFF_1, BUFF_20}, @@ -27,7 +27,7 @@ fn test_simple_is_standard_check_inputs() { true ) .unwrap_err(), - CheckErrors::TypeValueError(Box::new(PrincipalType), Box::new(Value::UInt(10)),).into() + CheckErrorKind::TypeValueError(Box::new(PrincipalType), Box::new(Value::UInt(10)),).into() ); } @@ -944,14 +944,14 @@ fn test_principal_construct_version_byte_future() { } #[test] -// Test cases where the wrong type should be a `CheckErrors` error, because it should have been +// Test cases where the wrong type should be a `CheckErrorKind` error, because it should have been // caught by the type checker. fn test_principal_construct_check_errors() { // The version bytes 0x5904934 are invalid. Should have been caught by type checker so use - // `CheckErrors`. + // `CheckErrorKind`. let input = r#"(principal-construct? 0x590493 0x0102030405060708091011121314151617181920)"#; assert_eq!( - Err(CheckErrors::TypeValueError( + Err(CheckErrorKind::TypeValueError( Box::new(BUFF_1.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("590493").unwrap() @@ -968,11 +968,11 @@ fn test_principal_construct_check_errors() { ); // u22 is not a byte buffer, so is invalid. Should have been caught by type checker so use - // `CheckErrors`. + // `CheckErrorKind`. let input = r#"(principal-construct? u22 0x0102030405060708091011121314151617181920)"#; assert_eq!( Err( - CheckErrors::TypeValueError(Box::new(BUFF_1.clone()), Box::new(Value::UInt(22)),) + CheckErrorKind::TypeValueError(Box::new(BUFF_1.clone()), Box::new(Value::UInt(22)),) .into() ), execute_with_parameters( @@ -984,7 +984,7 @@ fn test_principal_construct_check_errors() { ) ); - // Hash key part is too large, should have length 20. This is a `CheckErrors` error because it + // Hash key part is too large, should have length 20. This is a `CheckErrorKind` error because it // should have been caught by the type checker. let input = r#"(principal-construct? 0x16 0x010203040506070809101112131415161718192021)"#; assert_eq!( @@ -996,7 +996,7 @@ fn test_principal_construct_check_errors() { false ) .unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(BUFF_20.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("010203040506070809101112131415161718192021").unwrap() @@ -1008,7 +1008,7 @@ fn test_principal_construct_check_errors() { // Name is too long, which should have been caught by the type-checker let input = r#"(principal-construct? 0x16 0x0102030405060708091011121314151617181920 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")"#; assert_eq!( - Err(CheckErrors::TypeValueError( + Err(CheckErrorKind::TypeValueError( Box::new(TypeSignature::contract_name_string_ascii_type().unwrap()), Box::new(Value::Sequence(SequenceData::String(CharType::ASCII( ASCIIData { diff --git a/clarity/src/vm/tests/sequences.rs b/clarity/src/vm/tests/sequences.rs index 3ea779b7d6..671955d92c 100644 --- a/clarity/src/vm/tests/sequences.rs +++ b/clarity/src/vm/tests/sequences.rs @@ -22,7 +22,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::tests::test_clarity_versions; #[cfg(test)] use crate::vm::{ - errors::{CheckErrors, Error, RuntimeErrorType}, + errors::{CheckErrorKind, Error, RuntimeErrorType}, execute, execute_v2, types::{ signatures::{ @@ -59,7 +59,7 @@ fn test_simple_list_admission() { ); let err = execute(&t3).unwrap_err(); assert!(match err { - Error::Unchecked(CheckErrors::TypeValueError(_, _)) => true, + Error::Unchecked(CheckErrorKind::TypeValueError(_, _)) => true, _ => { eprintln!("Expected TypeError, but found: {err:?}"); false @@ -112,16 +112,16 @@ fn test_index_of() { ]; let bad_expected = [ - CheckErrors::ExpectedSequence(Box::new(TypeSignature::IntType)), - CheckErrors::TypeValueError( + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), + CheckErrorKind::TypeValueError( Box::new(TypeSignature::min_buffer().unwrap()), Box::new(execute("\"a\"").unwrap().unwrap()), ), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(TypeSignature::min_string_utf8().unwrap()), Box::new(execute("\"a\"").unwrap().unwrap()), ), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(TypeSignature::min_string_ascii().unwrap()), Box::new(execute("u\"a\"").unwrap().unwrap()), ), @@ -173,8 +173,8 @@ fn test_element_at() { let bad = ["(element-at 3 u1)", "(element-at (list 1 2 3) 1)"]; let bad_expected = [ - CheckErrors::ExpectedSequence(Box::new(TypeSignature::IntType)), - CheckErrors::TypeValueError(Box::new(TypeSignature::UIntType), Box::new(Value::Int(1))), + CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), + CheckErrorKind::TypeValueError(Box::new(TypeSignature::UIntType), Box::new(Value::Int(1))), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -451,7 +451,7 @@ fn test_simple_map_append() { assert_eq!( execute("(append (append (list) 1) u2)").unwrap_err(), - CheckErrors::TypeValueError(Box::new(IntType), Box::new(Value::UInt(2))).into() + CheckErrorKind::TypeValueError(Box::new(IntType), Box::new(Value::UInt(2))).into() ); } @@ -587,7 +587,7 @@ fn test_simple_list_concat() { assert_eq!( execute("(concat (list 1) (list u4 u8))").unwrap_err(), - CheckErrors::TypeError(Box::new(IntType), Box::new(UIntType)).into() + CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)).into() ); assert_eq!( @@ -710,25 +710,26 @@ fn test_simple_list_replace_at() { // The sequence input has the wrong type assert_eq!( execute_v2("(replace-at? 0 u0 (list 0))").unwrap_err(), - CheckErrors::ExpectedSequence(Box::new(IntType)).into() + CheckErrorKind::ExpectedSequence(Box::new(IntType)).into() ); // The type of the index should be uint. assert_eq!( execute_v2("(replace-at? (list 1) 0 0)").unwrap_err(), - CheckErrors::TypeValueError(Box::new(UIntType), Box::new(Value::Int(0))).into() + CheckErrorKind::TypeValueError(Box::new(UIntType), Box::new(Value::Int(0))).into() ); // The element input has the wrong type assert_eq!( execute_v2("(replace-at? (list 2 3) u0 true)").unwrap_err(), - CheckErrors::TypeValueError(Box::new(IntType), Box::new(Value::Bool(true))).into() + CheckErrorKind::TypeValueError(Box::new(IntType), Box::new(Value::Bool(true))).into() ); // The element input has the wrong type assert_eq!( execute_v2("(replace-at? (list 2 3) u0 0x00)").unwrap_err(), - CheckErrors::TypeValueError(Box::new(IntType), Box::new(Value::buff_from_byte(0))).into() + CheckErrorKind::TypeValueError(Box::new(IntType), Box::new(Value::buff_from_byte(0))) + .into() ); } @@ -768,20 +769,20 @@ fn test_simple_buff_replace_at() { // The sequence input has the wrong type assert_eq!( execute_v2("(replace-at? 33 u0 0x00)").unwrap_err(), - CheckErrors::ExpectedSequence(Box::new(IntType)).into() + CheckErrorKind::ExpectedSequence(Box::new(IntType)).into() ); // The type of the index should be uint. assert_eq!( execute_v2("(replace-at? 0x002244 0 0x99)").unwrap_err(), - CheckErrors::TypeValueError(Box::new(UIntType), Box::new(Value::Int(0))).into() + CheckErrorKind::TypeValueError(Box::new(UIntType), Box::new(Value::Int(0))).into() ); // The element input has the wrong type let buff_len = BufferLength::try_from(1u32).unwrap(); assert_eq!( execute_v2("(replace-at? 0x445522 u0 55)").unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType(buff_len.clone()))), Box::new(Value::Int(55)) ) @@ -791,7 +792,7 @@ fn test_simple_buff_replace_at() { // The element input has the wrong type assert_eq!( execute_v2("(replace-at? 0x445522 u0 (list 5))").unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType(buff_len.clone()))), Box::new(Value::list_from(vec![Value::Int(5)]).unwrap()) ) @@ -801,7 +802,7 @@ fn test_simple_buff_replace_at() { // The element input has the wrong type (not length 1) assert_eq!( execute_v2("(replace-at? 0x445522 u0 0x0044)").unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(BufferType(buff_len))), Box::new(Value::buff_from(vec![0, 68]).unwrap()) ) @@ -845,20 +846,20 @@ fn test_simple_string_ascii_replace_at() { // The sequence input has the wrong type assert_eq!( execute_v2("(replace-at? 33 u0 \"c\")").unwrap_err(), - CheckErrors::ExpectedSequence(Box::new(IntType)).into() + CheckErrorKind::ExpectedSequence(Box::new(IntType)).into() ); // The type of the index should be uint. assert_eq!( execute_v2("(replace-at? \"abc\" 0 \"c\")").unwrap_err(), - CheckErrors::TypeValueError(Box::new(UIntType), Box::new(Value::Int(0))).into() + CheckErrorKind::TypeValueError(Box::new(UIntType), Box::new(Value::Int(0))).into() ); // The element input has the wrong type let buff_len = BufferLength::try_from(1u32).unwrap(); assert_eq!( execute_v2("(replace-at? \"abc\" u0 55)").unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(StringType(ASCII(buff_len.clone())))), Box::new(Value::Int(55)) ) @@ -868,7 +869,7 @@ fn test_simple_string_ascii_replace_at() { // The element input has the wrong type assert_eq!( execute_v2("(replace-at? \"abc\" u0 0x00)").unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(StringType(ASCII(buff_len.clone())))), Box::new(Value::buff_from_byte(0)) ) @@ -878,7 +879,7 @@ fn test_simple_string_ascii_replace_at() { // The element input has the wrong type assert_eq!( execute_v2("(replace-at? \"abc\" u0 \"de\")").unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(SequenceType(StringType(ASCII(buff_len)))), Box::new(Value::string_ascii_from_bytes("de".into()).unwrap()) ) @@ -926,20 +927,20 @@ fn test_simple_string_utf8_replace_at() { // The sequence input has the wrong type assert_eq!( execute_v2("(replace-at? 33 u0 u\"c\")").unwrap_err(), - CheckErrors::ExpectedSequence(Box::new(IntType)).into() + CheckErrorKind::ExpectedSequence(Box::new(IntType)).into() ); // The type of the index should be uint. assert_eq!( execute_v2("(replace-at? u\"abc\" 0 u\"c\")").unwrap_err(), - CheckErrors::TypeValueError(Box::new(UIntType), Box::new(Value::Int(0))).into() + CheckErrorKind::TypeValueError(Box::new(UIntType), Box::new(Value::Int(0))).into() ); // The element input has the wrong type let str_len = StringUTF8Length::try_from(1u32).unwrap(); assert_eq!( execute_v2("(replace-at? u\"abc\" u0 55)").unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(TypeSignature::SequenceType(StringType( StringSubtype::UTF8(str_len.clone()) ))), @@ -951,7 +952,7 @@ fn test_simple_string_utf8_replace_at() { // The element input has the wrong type assert_eq!( execute_v2("(replace-at? u\"abc\" u0 0x00)").unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(TypeSignature::SequenceType(StringType( StringSubtype::UTF8(str_len.clone()) ))), @@ -963,7 +964,7 @@ fn test_simple_string_utf8_replace_at() { // The element input has the wrong type assert_eq!( execute_v2("(replace-at? u\"abc\" u0 u\"de\")").unwrap_err(), - CheckErrors::TypeValueError( + CheckErrorKind::TypeValueError( Box::new(TypeSignature::SequenceType(StringType( StringSubtype::UTF8(str_len) ))), @@ -993,22 +994,22 @@ fn test_simple_buff_assert_max_len() { assert_eq!( execute("(as-max-len? 0x313233)").unwrap_err(), - CheckErrors::IncorrectArgumentCount(2, 1).into() + CheckErrorKind::IncorrectArgumentCount(2, 1).into() ); assert_eq!( execute("(as-max-len? 0x313233 3)").unwrap_err(), - CheckErrors::TypeError(Box::new(UIntType), Box::new(IntType)).into() + CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)).into() ); assert_eq!( execute("(as-max-len? 1 u3)").unwrap_err(), - CheckErrors::ExpectedSequence(Box::new(IntType)).into() + CheckErrorKind::ExpectedSequence(Box::new(IntType)).into() ); assert_eq!( execute("(as-max-len? 0x313233 0x31)").unwrap_err(), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(UIntType), Box::new(SequenceType(SequenceSubtype::BufferType( 1_u32.try_into().unwrap() @@ -1175,14 +1176,14 @@ fn test_construct_bad_list(#[case] version: ClarityVersion, #[case] epoch: Stack let test1 = "(list 1 2 3 true)"; assert_eq!( execute(test1).unwrap_err(), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)).into() + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)).into() ); let test2 = "(define-private (bad-function (x int)) (if (is-eq x 1) true x)) (map bad-function (list 0 1 2 3))"; assert_eq!( execute(test2).unwrap_err(), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)).into() + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)).into() ); let bad_2d_list = "(list (list 1 2 3) (list true false true))"; @@ -1190,11 +1191,11 @@ fn test_construct_bad_list(#[case] version: ClarityVersion, #[case] epoch: Stack assert_eq!( execute(bad_2d_list).unwrap_err(), - CheckErrors::TypeError(Box::new(IntType), Box::new(BoolType)).into() + CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)).into() ); assert_eq!( execute(bad_high_order_list).unwrap_err(), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(IntType), Box::new(TypeSignature::from_string("(list 3 int)", version, epoch)) ) @@ -1205,23 +1206,23 @@ fn test_construct_bad_list(#[case] version: ClarityVersion, #[case] epoch: Stack #[test] fn test_eval_func_arg_panic() { let test1 = "(fold (lambda (x y) (* x y)) (list 1 2 3 4) 1)"; - let e: Error = CheckErrors::ExpectedName.into(); + let e: Error = CheckErrorKind::ExpectedName.into(); assert_eq!(e, execute(test1).unwrap_err()); let test2 = "(map (lambda (x) (* x x)) (list 1 2 3 4))"; - let e: Error = CheckErrors::ExpectedName.into(); + let e: Error = CheckErrorKind::ExpectedName.into(); assert_eq!(e, execute(test2).unwrap_err()); let test3 = "(map square (list 1 2 3 4) 2)"; - let e: Error = CheckErrors::UndefinedFunction("square".to_string()).into(); + let e: Error = CheckErrorKind::UndefinedFunction("square".to_string()).into(); assert_eq!(e, execute(test3).unwrap_err()); let test4 = "(define-private (multiply-all (x int) (acc int)) (* x acc)) (fold multiply-all (list 1 2 3 4))"; - let e: Error = CheckErrors::IncorrectArgumentCount(3, 2).into(); + let e: Error = CheckErrorKind::IncorrectArgumentCount(3, 2).into(); assert_eq!(e, execute(test4).unwrap_err()); let test5 = "(map + (list 1 2 3 4) 2)"; - let e: Error = CheckErrors::ExpectedSequence(Box::new(IntType)).into(); + let e: Error = CheckErrorKind::ExpectedSequence(Box::new(IntType)).into(); assert_eq!(e, execute(test5).unwrap_err()); } diff --git a/clarity/src/vm/tests/simple_apply_eval.rs b/clarity/src/vm/tests/simple_apply_eval.rs index 53558e3548..2d3de4a1f7 100644 --- a/clarity/src/vm/tests/simple_apply_eval.rs +++ b/clarity/src/vm/tests/simple_apply_eval.rs @@ -31,7 +31,7 @@ use crate::vm::callables::DefinedFunction; use crate::vm::contexts::OwnedEnvironment; use crate::vm::costs::LimitedCostTracker; use crate::vm::database::MemoryBackingStore; -use crate::vm::errors::{CheckErrors, Error, RuntimeErrorType, ShortReturnType}; +use crate::vm::errors::{CheckErrorKind, Error, RuntimeErrorType, ShortReturnType}; use crate::vm::tests::{execute, test_clarity_versions}; use crate::vm::types::signatures::*; use crate::vm::types::{ @@ -55,7 +55,7 @@ fn test_doubly_defined_persisted_vars() { for p in tests.iter() { assert_eq!( vm_execute(p).unwrap_err(), - CheckErrors::NameAlreadyUsed("cursor".into()).into() + CheckErrorKind::NameAlreadyUsed("cursor".into()).into() ); } } @@ -581,18 +581,18 @@ fn test_secp256k1_errors() { ]; let expectations: &[Error] = &[ - CheckErrors::TypeValueError(Box::new(BUFF_32.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("de5b9eb9e7c5592930eb2e30a01369c36586d872082ed8181ee83d2a0ec20f").unwrap() })))).into(), - CheckErrors::TypeValueError(Box::new(BUFF_65.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("8738487ebe69b93d8e51583be8eee50bb4213fc49c767d329632730cc193b873554428fc936ca3569afc15f1c9365f6591d6251a89fee9c9ac661116824d3a130100").unwrap() })))).into(), - CheckErrors::IncorrectArgumentCount(2, 1).into(), - CheckErrors::IncorrectArgumentCount(2, 3).into(), - - CheckErrors::TypeValueError(Box::new(BUFF_32.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("de5b9eb9e7c5592930eb2e30a01369c36586d872082ed8181ee83d2a0ec20f").unwrap() })))).into(), - CheckErrors::TypeValueError(Box::new(BUFF_65.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("8738487ebe69b93d8e51583be8eee50bb4213fc49c767d329632730cc193b873554428fc936ca3569afc15f1c9365f6591d6251a89fee9c9ac661116824d3a130111").unwrap() })))).into(), - CheckErrors::TypeValueError(Box::new(BUFF_33.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("03adb8de4bfb65db2cfd6120d55c6526ae9c52e675db7e47308636534ba7").unwrap() })))).into(), - CheckErrors::IncorrectArgumentCount(3, 2).into(), - - CheckErrors::IncorrectArgumentCount(1, 2).into(), - CheckErrors::IncorrectArgumentCount(1, 0).into(), + CheckErrorKind::TypeValueError(Box::new(BUFF_32.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("de5b9eb9e7c5592930eb2e30a01369c36586d872082ed8181ee83d2a0ec20f").unwrap() })))).into(), + CheckErrorKind::TypeValueError(Box::new(BUFF_65.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("8738487ebe69b93d8e51583be8eee50bb4213fc49c767d329632730cc193b873554428fc936ca3569afc15f1c9365f6591d6251a89fee9c9ac661116824d3a130100").unwrap() })))).into(), + CheckErrorKind::IncorrectArgumentCount(2, 1).into(), + CheckErrorKind::IncorrectArgumentCount(2, 3).into(), + + CheckErrorKind::TypeValueError(Box::new(BUFF_32.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("de5b9eb9e7c5592930eb2e30a01369c36586d872082ed8181ee83d2a0ec20f").unwrap() })))).into(), + CheckErrorKind::TypeValueError(Box::new(BUFF_65.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("8738487ebe69b93d8e51583be8eee50bb4213fc49c767d329632730cc193b873554428fc936ca3569afc15f1c9365f6591d6251a89fee9c9ac661116824d3a130111").unwrap() })))).into(), + CheckErrorKind::TypeValueError(Box::new(BUFF_33.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("03adb8de4bfb65db2cfd6120d55c6526ae9c52e675db7e47308636534ba7").unwrap() })))).into(), + CheckErrorKind::IncorrectArgumentCount(3, 2).into(), + + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::IncorrectArgumentCount(1, 0).into(), ]; for (program, expectation) in secp256k1_evals.iter().zip(expectations.iter()) { @@ -878,7 +878,7 @@ fn test_sequence_comparisons_clarity1() { "(<= \"baa\" \"aaa\")", ]; let error_expectations: &[Error] = &[ - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(Value::Sequence(SequenceData::String(CharType::ASCII( ASCIIData { @@ -887,7 +887,7 @@ fn test_sequence_comparisons_clarity1() { )))), ) .into(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(Value::Sequence(SequenceData::String(CharType::ASCII( ASCIIData { @@ -896,7 +896,7 @@ fn test_sequence_comparisons_clarity1() { )))), ) .into(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(Value::Sequence(SequenceData::String(CharType::ASCII( ASCIIData { @@ -905,7 +905,7 @@ fn test_sequence_comparisons_clarity1() { )))), ) .into(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(Value::Sequence(SequenceData::String(CharType::ASCII( ASCIIData { @@ -989,12 +989,12 @@ fn test_sequence_comparisons_mismatched_types() { // Tests that comparing objects of different types results in an error in Clarity1. let error_tests = ["(> 0 u1)", "(< 0 u1)"]; let v1_error_expectations: &[Error] = &[ - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(Value::Int(0)), ) .into(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(Value::Int(0)), ) @@ -1010,7 +1010,7 @@ fn test_sequence_comparisons_mismatched_types() { }); let v2_error_expectations: &[Error] = &[ - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -1021,7 +1021,7 @@ fn test_sequence_comparisons_mismatched_types() { Box::new(Value::Int(0)), ) .into(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -1044,7 +1044,7 @@ fn test_sequence_comparisons_mismatched_types() { // Tests that comparing objects of different types results in an error in Clarity2. let error_tests = ["(> \"baa\" u\"aaa\")", "(> \"baa\" 0x0001)"]; let error_expectations: &[Error] = &[ - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -1059,7 +1059,7 @@ fn test_sequence_comparisons_mismatched_types() { )))), ) .into(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -1113,8 +1113,8 @@ fn test_simple_arithmetic_errors(#[case] version: ClarityVersion, #[case] epoch: ]; let expectations: &[Error] = &[ - CheckErrors::IncorrectArgumentCount(2, 1).into(), - CheckErrors::TypeValueError( + CheckErrorKind::IncorrectArgumentCount(2, 1).into(), + CheckErrorKind::TypeValueError( Box::new(TypeSignature::IntType), Box::new(Value::Bool(true)), ) @@ -1125,17 +1125,17 @@ fn test_simple_arithmetic_errors(#[case] version: ClarityVersion, #[case] epoch: RuntimeErrorType::ArithmeticOverflow.into(), RuntimeErrorType::ArithmeticOverflow.into(), RuntimeErrorType::ArithmeticUnderflow.into(), - CheckErrors::IncorrectArgumentCount(1, 0).into(), - CheckErrors::IncorrectArgumentCount(1, 0).into(), - CheckErrors::IncorrectArgumentCount(2, 1).into(), - CheckErrors::IncorrectArgumentCount(2, 1).into(), - CheckErrors::IncorrectArgumentCount(1, 0).into(), - CheckErrors::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::IncorrectArgumentCount(1, 0).into(), + CheckErrorKind::IncorrectArgumentCount(1, 0).into(), + CheckErrorKind::IncorrectArgumentCount(2, 1).into(), + CheckErrorKind::IncorrectArgumentCount(2, 1).into(), + CheckErrorKind::IncorrectArgumentCount(1, 0).into(), + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), RuntimeErrorType::Arithmetic("sqrti must be passed a positive integer".to_string()).into(), - CheckErrors::IncorrectArgumentCount(1, 0).into(), - CheckErrors::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::IncorrectArgumentCount(1, 0).into(), + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), RuntimeErrorType::Arithmetic("log2 must be passed a positive integer".to_string()).into(), - CheckErrors::IncorrectArgumentCount(2, 1).into(), + CheckErrorKind::IncorrectArgumentCount(2, 1).into(), RuntimeErrorType::Arithmetic( "Power argument to (pow ...) must be a u32 integer".to_string(), ) @@ -1144,7 +1144,7 @@ fn test_simple_arithmetic_errors(#[case] version: ClarityVersion, #[case] epoch: "Power argument to (pow ...) must be a u32 integer".to_string(), ) .into(), - CheckErrors::TypeError( + CheckErrorKind::TypeError( Box::new(TypeSignature::from_string("bool", version, epoch)), Box::new(TypeSignature::from_string("int", version, epoch)), ) @@ -1170,12 +1170,12 @@ fn test_unsigned_arithmetic() { let expectations: &[Error] = &[ RuntimeErrorType::ArithmeticUnderflow.into(), RuntimeErrorType::ArithmeticUnderflow.into(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(Value::UInt(10)), ) .into(), - CheckErrors::TypeValueError(Box::new(TypeSignature::UIntType), Box::new(Value::Int(80))) + CheckErrorKind::TypeValueError(Box::new(TypeSignature::UIntType), Box::new(Value::Int(80))) .into(), RuntimeErrorType::ArithmeticUnderflow.into(), RuntimeErrorType::ArithmeticOverflow.into(), @@ -1207,21 +1207,21 @@ fn test_options_errors() { ]; let expectations: &[Error] = &[ - CheckErrors::IncorrectArgumentCount(1, 2).into(), - CheckErrors::ExpectedOptionalValue(Box::new(Value::Bool(true))).into(), - CheckErrors::IncorrectArgumentCount(1, 2).into(), - CheckErrors::ExpectedResponseValue(Box::new(Value::Bool(true))).into(), - CheckErrors::IncorrectArgumentCount(1, 2).into(), - CheckErrors::ExpectedResponseValue(Box::new(Value::Bool(true))).into(), - CheckErrors::IncorrectArgumentCount(1, 2).into(), - CheckErrors::ExpectedOptionalValue(Box::new(Value::Bool(true))).into(), - CheckErrors::IncorrectArgumentCount(1, 2).into(), - CheckErrors::IncorrectArgumentCount(1, 2).into(), - CheckErrors::IncorrectArgumentCount(1, 2).into(), - CheckErrors::IncorrectArgumentCount(2, 3).into(), - CheckErrors::ExpectedOptionalValue(Box::new(Value::Bool(true))).into(), - CheckErrors::ExpectedTuple(Box::new(TypeSignature::IntType)).into(), - CheckErrors::ExpectedTuple(Box::new(TypeSignature::IntType)).into(), + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::ExpectedOptionalValue(Box::new(Value::Bool(true))).into(), + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::ExpectedResponseValue(Box::new(Value::Bool(true))).into(), + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::ExpectedResponseValue(Box::new(Value::Bool(true))).into(), + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::ExpectedOptionalValue(Box::new(Value::Bool(true))).into(), + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::IncorrectArgumentCount(2, 3).into(), + CheckErrorKind::ExpectedOptionalValue(Box::new(Value::Bool(true))).into(), + CheckErrorKind::ExpectedTuple(Box::new(TypeSignature::IntType)).into(), + CheckErrorKind::ExpectedTuple(Box::new(TypeSignature::IntType)).into(), ]; for (program, expectation) in tests.iter().zip(expectations.iter()) { @@ -1245,16 +1245,16 @@ fn test_stx_ops_errors() { ]; let expectations: &[Error] = &[ - CheckErrors::IncorrectArgumentCount(3, 2).into(), - CheckErrors::BadTransferSTXArguments.into(), - CheckErrors::BadTransferSTXArguments.into(), - CheckErrors::BadTransferSTXArguments.into(), - CheckErrors::IncorrectArgumentCount(4, 3).into(), - CheckErrors::BadTransferSTXArguments.into(), - CheckErrors::BadTransferSTXArguments.into(), - CheckErrors::BadTransferSTXArguments.into(), - CheckErrors::IncorrectArgumentCount(2, 1).into(), - CheckErrors::BadTransferSTXArguments.into(), + CheckErrorKind::IncorrectArgumentCount(3, 2).into(), + CheckErrorKind::BadTransferSTXArguments.into(), + CheckErrorKind::BadTransferSTXArguments.into(), + CheckErrorKind::BadTransferSTXArguments.into(), + CheckErrorKind::IncorrectArgumentCount(4, 3).into(), + CheckErrorKind::BadTransferSTXArguments.into(), + CheckErrorKind::BadTransferSTXArguments.into(), + CheckErrorKind::BadTransferSTXArguments.into(), + CheckErrorKind::IncorrectArgumentCount(2, 1).into(), + CheckErrorKind::BadTransferSTXArguments.into(), ]; for (program, expectation) in tests.iter().zip(expectations.iter()) { @@ -1427,7 +1427,7 @@ fn test_option_destructs() { Ok(Value::Int(1)), Ok(Value::Int(1)), Err( - CheckErrors::ExpectedResponseValue(Box::new(Value::some(Value::Int(2)).unwrap())) + CheckErrorKind::ExpectedResponseValue(Box::new(Value::some(Value::Int(2)).unwrap())) .into(), ), Ok(Value::Int(3)), @@ -1442,14 +1442,14 @@ fn test_option_destructs() { Ok(Value::Int(9)), Ok(Value::Int(2)), Ok(Value::Int(8)), - Err(CheckErrors::BadMatchInput(Box::new(TypeSignature::IntType)).into()), - Err(CheckErrors::BadMatchInput(Box::new(TypeSignature::IntType)).into()), + Err(CheckErrorKind::BadMatchInput(Box::new(TypeSignature::IntType)).into()), + Err(CheckErrorKind::BadMatchInput(Box::new(TypeSignature::IntType)).into()), Err(ShortReturnType::ExpectedValue(Box::new(Value::error(Value::UInt(1)).unwrap())).into()), Ok(Value::Int(3)), Err(ShortReturnType::ExpectedValue(Box::new(Value::none())).into()), Ok(Value::Bool(true)), - Err(CheckErrors::IncorrectArgumentCount(1, 2).into()), - Err(CheckErrors::ExpectedOptionalOrResponseValue(Box::new(Value::Int(1))).into()), + Err(CheckErrorKind::IncorrectArgumentCount(1, 2).into()), + Err(CheckErrorKind::ExpectedOptionalOrResponseValue(Box::new(Value::Int(1))).into()), ]; for (program, expectation) in tests.iter().zip(expectations.iter()) { @@ -1473,10 +1473,10 @@ fn test_hash_errors() { ]; let expectations: &[Error] = &[ - CheckErrors::IncorrectArgumentCount(1, 2).into(), - CheckErrors::IncorrectArgumentCount(1, 2).into(), - CheckErrors::IncorrectArgumentCount(1, 2).into(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -1485,7 +1485,7 @@ fn test_hash_errors() { Box::new(Value::Bool(true)), ) .into(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -1494,7 +1494,7 @@ fn test_hash_errors() { Box::new(Value::Bool(true)), ) .into(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -1503,7 +1503,7 @@ fn test_hash_errors() { Box::new(Value::Bool(true)), ) .into(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -1512,8 +1512,8 @@ fn test_hash_errors() { Box::new(Value::Bool(true)), ) .into(), - CheckErrors::IncorrectArgumentCount(1, 2).into(), - CheckErrors::UnionTypeValueError( + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::UnionTypeValueError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -1522,7 +1522,7 @@ fn test_hash_errors() { Box::new(Value::Bool(true)), ) .into(), - CheckErrors::IncorrectArgumentCount(1, 2).into(), + CheckErrorKind::IncorrectArgumentCount(1, 2).into(), ]; for (program, expectation) in tests.iter().zip(expectations.iter()) { @@ -1574,12 +1574,12 @@ fn test_bad_lets() { ]; let expectations: &[Error] = &[ - CheckErrors::NameAlreadyUsed("tx-sender".to_string()).into(), - CheckErrors::NameAlreadyUsed("*".to_string()).into(), - CheckErrors::NameAlreadyUsed("a".to_string()).into(), - CheckErrors::NoSuchDataVariable("cursor".to_string()).into(), - CheckErrors::NameAlreadyUsed("true".to_string()).into(), - CheckErrors::NameAlreadyUsed("false".to_string()).into(), + CheckErrorKind::NameAlreadyUsed("tx-sender".to_string()).into(), + CheckErrorKind::NameAlreadyUsed("*".to_string()).into(), + CheckErrorKind::NameAlreadyUsed("a".to_string()).into(), + CheckErrorKind::NoSuchDataVariable("cursor".to_string()).into(), + CheckErrorKind::NameAlreadyUsed("true".to_string()).into(), + CheckErrorKind::NameAlreadyUsed("false".to_string()).into(), ]; tests diff --git a/clarity/src/vm/tests/traits.rs b/clarity/src/vm/tests/traits.rs index 09c95cdbcc..7e3065a8be 100644 --- a/clarity/src/vm/tests/traits.rs +++ b/clarity/src/vm/tests/traits.rs @@ -22,7 +22,7 @@ use crate::vm::tests::{test_clarity_versions, test_epochs}; #[cfg(test)] use crate::vm::{ ast::ASTRules, - errors::{CheckErrors, Error}, + errors::{CheckErrorKind, Error}, tests::{env_factory, execute, symbols_from_values}, types::{PrincipalData, QualifiedContractIdentifier, Value}, version::ClarityVersion, @@ -251,7 +251,7 @@ fn test_dynamic_dispatch_intra_contract_call( ) .unwrap_err(); match err_result { - Error::Unchecked(CheckErrors::CircularReference(_)) => {} + Error::Unchecked(CheckErrorKind::CircularReference(_)) => {} _ => panic!("{err_result:?}"), } } @@ -582,7 +582,7 @@ fn test_dynamic_dispatch_mismatched_args( ) .unwrap_err(); match err_result { - Error::Unchecked(CheckErrors::BadTraitImplementation(_, _)) => {} + Error::Unchecked(CheckErrorKind::BadTraitImplementation(_, _)) => {} _ => panic!("{err_result:?}"), } } @@ -639,7 +639,7 @@ fn test_dynamic_dispatch_mismatched_returned( ) .unwrap_err(); match err_result { - Error::Unchecked(CheckErrors::ReturnTypesMustMatch(_, _)) => {} + Error::Unchecked(CheckErrorKind::ReturnTypesMustMatch(_, _)) => {} _ => panic!("{err_result:?}"), } } @@ -699,7 +699,7 @@ fn test_reentrant_dynamic_dispatch( ) .unwrap_err(); match err_result { - Error::Unchecked(CheckErrors::CircularReference(_)) => {} + Error::Unchecked(CheckErrorKind::CircularReference(_)) => {} _ => panic!("{err_result:?}"), } } @@ -756,7 +756,7 @@ fn test_readwrite_dynamic_dispatch( ) .unwrap_err(); match err_result { - Error::Unchecked(CheckErrors::TraitBasedContractCallInReadOnly) => {} + Error::Unchecked(CheckErrorKind::TraitBasedContractCallInReadOnly) => {} _ => panic!("{err_result:?}"), } } @@ -813,7 +813,7 @@ fn test_readwrite_violation_dynamic_dispatch( ) .unwrap_err(); match err_result { - Error::Unchecked(CheckErrors::TraitBasedContractCallInReadOnly) => {} + Error::Unchecked(CheckErrorKind::TraitBasedContractCallInReadOnly) => {} _ => panic!("{err_result:?}"), } } diff --git a/clarity/src/vm/tests/variables.rs b/clarity/src/vm/tests/variables.rs index f1a0f16e13..b4c98faa8e 100644 --- a/clarity/src/vm/tests/variables.rs +++ b/clarity/src/vm/tests/variables.rs @@ -25,7 +25,7 @@ use crate::vm::{ analysis::type_checker::v2_1::tests::contracts::type_check_version, ast::{parse, ASTRules}, database::MemoryBackingStore, - errors::{CheckErrors, Error}, + errors::{CheckErrorKind, Error}, tests::{tl_env_factory, TopLevelMemoryEnvironmentGenerator}, types::{PrincipalData, QualifiedContractIdentifier, Value}, ClarityVersion, ContractContext, @@ -54,7 +54,7 @@ fn test_block_height( if version >= ClarityVersion::Clarity3 { let err = analysis.unwrap_err(); assert_eq!( - CheckErrors::UndefinedVariable("block-height".to_string()), + CheckErrorKind::UndefinedVariable("block-height".to_string()), *err.err ); } else { @@ -81,7 +81,9 @@ fn test_block_height( if version >= ClarityVersion::Clarity3 { let err = eval_result.unwrap_err(); assert_eq!( - Error::Unchecked(CheckErrors::UndefinedVariable("block-height".to_string(),)), + Error::Unchecked(CheckErrorKind::UndefinedVariable( + "block-height".to_string(), + )), err ); } else { @@ -112,7 +114,7 @@ fn test_stacks_block_height( if version < ClarityVersion::Clarity3 { let err = analysis.unwrap_err(); assert_eq!( - CheckErrors::UndefinedVariable("stacks-block-height".to_string()), + CheckErrorKind::UndefinedVariable("stacks-block-height".to_string()), *err.err ); } else { @@ -139,7 +141,7 @@ fn test_stacks_block_height( if version < ClarityVersion::Clarity3 { let err = eval_result.unwrap_err(); assert_eq!( - Error::Unchecked(CheckErrors::UndefinedVariable( + Error::Unchecked(CheckErrorKind::UndefinedVariable( "stacks-block-height".to_string(), )), err @@ -172,7 +174,7 @@ fn test_tenure_height( if version < ClarityVersion::Clarity3 { let err = analysis.unwrap_err(); assert_eq!( - CheckErrors::UndefinedVariable("tenure-height".to_string()), + CheckErrorKind::UndefinedVariable("tenure-height".to_string()), *err.err ); } else { @@ -199,7 +201,9 @@ fn test_tenure_height( if version < ClarityVersion::Clarity3 { let err = eval_result.unwrap_err(); assert_eq!( - Error::Unchecked(CheckErrors::UndefinedVariable("tenure-height".to_string(),)), + Error::Unchecked(CheckErrorKind::UndefinedVariable( + "tenure-height".to_string(), + )), err ); } else { @@ -226,7 +230,7 @@ fn expect_contract_error( expected_errors: &[( WhenError, fn(ClarityVersion, StacksEpochId) -> bool, - CheckErrors, + CheckErrorKind, )], expected_success: Value, ) { @@ -328,12 +332,12 @@ fn reuse_block_height( ( WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("block-height".to_string()), ), ( WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::ReservedWord("block-height".to_string()), + CheckErrorKind::ReservedWord("block-height".to_string()), ), ], Value::UInt(1234), @@ -355,12 +359,12 @@ fn reuse_block_height( ( WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("block-height".to_string()), ), ( WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::ReservedWord("block-height".to_string()), + CheckErrorKind::ReservedWord("block-height".to_string()), ), ], Value::Bool(true), @@ -383,12 +387,12 @@ fn reuse_block_height( ( WhenError::Runtime, |version, _| version < ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("block-height".to_string()), ), ( WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::ReservedWord("block-height".to_string()), + CheckErrorKind::ReservedWord("block-height".to_string()), ), ], Value::Int(32), @@ -414,12 +418,12 @@ fn reuse_block_height( ( WhenError::Runtime, |version, _| version < ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("block-height".to_string()), ), ( WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::ReservedWord("block-height".to_string()), + CheckErrorKind::ReservedWord("block-height".to_string()), ), ], Value::Int(3), @@ -439,12 +443,12 @@ fn reuse_block_height( ( WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("block-height".to_string()), ), ( WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::ReservedWord("block-height".to_string()), + CheckErrorKind::ReservedWord("block-height".to_string()), ), ], Value::Bool(true), @@ -464,12 +468,12 @@ fn reuse_block_height( ( WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("block-height".to_string()), ), ( WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::ReservedWord("block-height".to_string()), + CheckErrorKind::ReservedWord("block-height".to_string()), ), ], Value::UInt(1234), @@ -489,12 +493,12 @@ fn reuse_block_height( ( WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("block-height".to_string()), ), ( WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::ReservedWord("block-height".to_string()), + CheckErrorKind::ReservedWord("block-height".to_string()), ), ], Value::Bool(false), @@ -529,12 +533,12 @@ fn reuse_block_height( ( WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("block-height".to_string()), ), ( WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::ReservedWord("block-height".to_string()), + CheckErrorKind::ReservedWord("block-height".to_string()), ), ], Value::Bool(false), @@ -554,12 +558,12 @@ fn reuse_block_height( ( WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("block-height".to_string()), ), ( WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::ReservedWord("block-height".to_string()), + CheckErrorKind::ReservedWord("block-height".to_string()), ), ], Value::Bool(false), @@ -579,12 +583,12 @@ fn reuse_block_height( ( WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("block-height".to_string()), ), ( WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::ReservedWord("block-height".to_string()), + CheckErrorKind::ReservedWord("block-height".to_string()), ), ], Value::Bool(true), @@ -604,12 +608,12 @@ fn reuse_block_height( ( WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("block-height".to_string()), ), ( WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::ReservedWord("block-height".to_string()), + CheckErrorKind::ReservedWord("block-height".to_string()), ), ], Value::Bool(true), @@ -637,7 +641,7 @@ fn reuse_stacks_block_height( &[( WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("stacks-block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), )], Value::UInt(1234), ); @@ -657,7 +661,7 @@ fn reuse_stacks_block_height( &[( WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("stacks-block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), )], Value::Bool(true), ); @@ -678,7 +682,7 @@ fn reuse_stacks_block_height( &[( WhenError::Runtime, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("stacks-block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), )], Value::Int(32), ); @@ -702,7 +706,7 @@ fn reuse_stacks_block_height( &[( WhenError::Runtime, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("stacks-block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), )], Value::Int(3), ); @@ -720,7 +724,7 @@ fn reuse_stacks_block_height( &[( WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("stacks-block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), )], Value::Bool(true), ); @@ -738,7 +742,7 @@ fn reuse_stacks_block_height( &[( WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("stacks-block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), )], Value::UInt(1234), ); @@ -756,7 +760,7 @@ fn reuse_stacks_block_height( &[( WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("stacks-block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), )], Value::Bool(false), ); @@ -789,7 +793,7 @@ fn reuse_stacks_block_height( &[( WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("stacks-block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), )], Value::Bool(false), ); @@ -807,7 +811,7 @@ fn reuse_stacks_block_height( &[( WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("stacks-block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), )], Value::Bool(false), ); @@ -825,7 +829,7 @@ fn reuse_stacks_block_height( &[( WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("stacks-block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), )], Value::Bool(true), ); @@ -843,7 +847,7 @@ fn reuse_stacks_block_height( &[( WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrors::NameAlreadyUsed("stacks-block-height".to_string()), + CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), )], Value::Bool(true), ); @@ -874,7 +878,7 @@ fn reuse_builtin_name( &[( WhenError::Initialization, version_check, - CheckErrors::NameAlreadyUsed(name.to_string()), + CheckErrorKind::NameAlreadyUsed(name.to_string()), )], Value::UInt(1234), ); @@ -896,7 +900,7 @@ fn reuse_builtin_name( &[( WhenError::Initialization, version_check, - CheckErrors::NameAlreadyUsed(name.to_string()), + CheckErrorKind::NameAlreadyUsed(name.to_string()), )], Value::Bool(true), ); @@ -919,7 +923,7 @@ fn reuse_builtin_name( &[( WhenError::Runtime, version_check, - CheckErrors::NameAlreadyUsed(name.to_string()), + CheckErrorKind::NameAlreadyUsed(name.to_string()), )], Value::Int(32), ); @@ -945,7 +949,7 @@ fn reuse_builtin_name( &[( WhenError::Runtime, version_check, - CheckErrors::NameAlreadyUsed(name.to_string()), + CheckErrorKind::NameAlreadyUsed(name.to_string()), )], Value::Int(3), ); @@ -965,7 +969,7 @@ fn reuse_builtin_name( &[( WhenError::Initialization, version_check, - CheckErrors::NameAlreadyUsed(name.to_string()), + CheckErrorKind::NameAlreadyUsed(name.to_string()), )], Value::Bool(true), ); @@ -985,7 +989,7 @@ fn reuse_builtin_name( &[( WhenError::Initialization, version_check, - CheckErrors::NameAlreadyUsed(name.to_string()), + CheckErrorKind::NameAlreadyUsed(name.to_string()), )], Value::UInt(1234), ); @@ -1005,7 +1009,7 @@ fn reuse_builtin_name( &[( WhenError::Initialization, version_check, - CheckErrors::NameAlreadyUsed(name.to_string()), + CheckErrorKind::NameAlreadyUsed(name.to_string()), )], Value::Bool(false), ); @@ -1042,7 +1046,7 @@ fn reuse_builtin_name( &[( WhenError::Initialization, version_check, - CheckErrors::NameAlreadyUsed(name.to_string()), + CheckErrorKind::NameAlreadyUsed(name.to_string()), )], Value::Bool(false), ); @@ -1062,7 +1066,7 @@ fn reuse_builtin_name( &[( WhenError::Initialization, version_check, - CheckErrors::NameAlreadyUsed(name.to_string()), + CheckErrorKind::NameAlreadyUsed(name.to_string()), )], Value::Bool(false), ); @@ -1082,7 +1086,7 @@ fn reuse_builtin_name( &[( WhenError::Initialization, version_check, - CheckErrors::NameAlreadyUsed(name.to_string()), + CheckErrorKind::NameAlreadyUsed(name.to_string()), )], Value::Bool(true), ); @@ -1102,7 +1106,7 @@ fn reuse_builtin_name( &[( WhenError::Initialization, version_check, - CheckErrors::NameAlreadyUsed(name.to_string()), + CheckErrorKind::NameAlreadyUsed(name.to_string()), )], Value::Bool(true), ); @@ -1133,7 +1137,7 @@ fn test_block_time( if version < ClarityVersion::Clarity4 { let err = analysis.unwrap_err(); assert_eq!( - CheckErrors::UndefinedVariable("block-time".to_string()), + CheckErrorKind::UndefinedVariable("block-time".to_string()), *err.err ); } else { @@ -1161,7 +1165,7 @@ fn test_block_time( if version < ClarityVersion::Clarity4 { let err = eval_result.unwrap_err(); assert_eq!( - Error::Unchecked(CheckErrors::UndefinedVariable("block-time".to_string(),)), + Error::Unchecked(CheckErrorKind::UndefinedVariable("block-time".to_string(),)), err ); } else { @@ -1260,7 +1264,7 @@ fn test_current_contract( if version < ClarityVersion::Clarity4 { let err = analysis.unwrap_err(); assert_eq!( - CheckErrors::UndefinedVariable("current-contract".to_string()), + CheckErrorKind::UndefinedVariable("current-contract".to_string()), *err.err ); } else { @@ -1287,7 +1291,7 @@ fn test_current_contract( if version < ClarityVersion::Clarity4 { let err = eval_result.unwrap_err(); assert_eq!( - Error::Unchecked(CheckErrors::UndefinedVariable( + Error::Unchecked(CheckErrorKind::UndefinedVariable( "current-contract".to_string(), )), err diff --git a/clarity/src/vm/types/mod.rs b/clarity/src/vm/types/mod.rs index 5d18da01fa..0986e160d5 100644 --- a/clarity/src/vm/types/mod.rs +++ b/clarity/src/vm/types/mod.rs @@ -28,7 +28,7 @@ pub use clarity_types::types::{ }; pub use self::std_principals::StandardPrincipalData; -use crate::vm::errors::CheckErrors; +use crate::vm::errors::CheckErrorKind; pub use crate::vm::types::signatures::{ parse_name_type_pairs, AssetIdentifier, BufferLength, FixedFunction, FunctionArg, FunctionSignature, FunctionType, ListTypeData, SequenceSubtype, StringSubtype, @@ -88,7 +88,7 @@ impl BlockInfoProperty { } impl BurnBlockInfoProperty { - pub fn type_result(&self) -> std::result::Result { + pub fn type_result(&self) -> std::result::Result { use self::BurnBlockInfoProperty::*; let result = match self { HeaderHash => BUFF_32.clone(), @@ -102,18 +102,20 @@ impl BurnBlockInfoProperty { ("hashbytes".into(), BUFF_32.clone()), ]) .map_err(|_| { - CheckErrors::Expects( + CheckErrorKind::Expects( "FATAL: bad type signature for pox addr".into(), ) })?, ), 2, ) - .map_err(|_| CheckErrors::Expects("FATAL: bad list type signature".into()))?, + .map_err(|_| { + CheckErrorKind::Expects("FATAL: bad list type signature".into()) + })?, ), ("payout".into(), TypeSignature::UIntType), ]) - .map_err(|_| CheckErrors::Expects("FATAL: bad type signature for pox addr".into()))? + .map_err(|_| CheckErrorKind::Expects("FATAL: bad type signature for pox addr".into()))? .into(), }; Ok(result) diff --git a/clarity/src/vm/types/signatures.rs b/clarity/src/vm/types/signatures.rs index 09e0c74be4..4d35554ca5 100644 --- a/clarity/src/vm/types/signatures.rs +++ b/clarity/src/vm/types/signatures.rs @@ -28,7 +28,7 @@ use stacks_common::types::StacksEpochId; use self::TypeSignature::SequenceType; use crate::vm::costs::{runtime_cost, CostOverflowingMath}; -use crate::vm::errors::{CheckErrors, SyntaxBindingError, SyntaxBindingErrorType}; +use crate::vm::errors::{CheckErrorKind, SyntaxBindingError, SyntaxBindingErrorType}; use crate::vm::representations::{ ClarityName, SymbolicExpression, SymbolicExpressionType, TraitDefinition, }; @@ -164,58 +164,59 @@ impl From for FunctionSignature { /// This is not included in clarity-types because it requires the /// [`CostTracker`] trait. pub trait TypeSignatureExt { - fn parse_atom_type(typename: &str) -> Result; + fn parse_atom_type(typename: &str) -> Result; fn parse_list_type_repr( epoch: StacksEpochId, type_args: &[SymbolicExpression], accounting: &mut A, - ) -> Result; + ) -> Result; fn parse_tuple_type_repr( epoch: StacksEpochId, type_args: &[SymbolicExpression], accounting: &mut A, - ) -> Result; - fn parse_buff_type_repr(type_args: &[SymbolicExpression]) - -> Result; + ) -> Result; + fn parse_buff_type_repr( + type_args: &[SymbolicExpression], + ) -> Result; fn parse_string_utf8_type_repr( type_args: &[SymbolicExpression], - ) -> Result; + ) -> Result; fn parse_string_ascii_type_repr( type_args: &[SymbolicExpression], - ) -> Result; + ) -> Result; fn parse_optional_type_repr( epoch: StacksEpochId, type_args: &[SymbolicExpression], accounting: &mut A, - ) -> Result; + ) -> Result; fn parse_response_type_repr( epoch: StacksEpochId, type_args: &[SymbolicExpression], accounting: &mut A, - ) -> Result; + ) -> Result; fn parse_type_repr( epoch: StacksEpochId, x: &SymbolicExpression, accounting: &mut A, - ) -> Result; + ) -> Result; fn parse_trait_type_repr( type_args: &[SymbolicExpression], accounting: &mut A, epoch: StacksEpochId, clarity_version: ClarityVersion, - ) -> Result, CheckErrors>; + ) -> Result, CheckErrorKind>; #[cfg(test)] fn from_string(val: &str, version: ClarityVersion, epoch: StacksEpochId) -> Self; } impl TypeSignatureExt for TypeSignature { - fn parse_atom_type(typename: &str) -> Result { + fn parse_atom_type(typename: &str) -> Result { match typename { "int" => Ok(TypeSignature::IntType), "uint" => Ok(TypeSignature::UIntType), "bool" => Ok(TypeSignature::BoolType), "principal" => Ok(TypeSignature::PrincipalType), - _ => Err(CheckErrors::UnknownTypeName(typename.into())), + _ => Err(CheckErrorKind::UnknownTypeName(typename.into())), } } @@ -225,18 +226,18 @@ impl TypeSignatureExt for TypeSignature { epoch: StacksEpochId, type_args: &[SymbolicExpression], accounting: &mut A, - ) -> Result { + ) -> Result { if type_args.len() != 2 { - return Err(CheckErrors::InvalidTypeDescription); + return Err(CheckErrorKind::InvalidTypeDescription); } if let SymbolicExpressionType::LiteralValue(Value::Int(max_len)) = &type_args[0].expr { let atomic_type_arg = &type_args[type_args.len() - 1]; let entry_type = TypeSignature::parse_type_repr(epoch, atomic_type_arg, accounting)?; - let max_len = u32::try_from(*max_len).map_err(|_| CheckErrors::ValueTooLarge)?; + let max_len = u32::try_from(*max_len).map_err(|_| CheckErrorKind::ValueTooLarge)?; ListTypeData::new_list(entry_type, max_len).map(|x| x.into()) } else { - Err(CheckErrors::InvalidTypeDescription) + Err(CheckErrorKind::InvalidTypeDescription) } } @@ -246,8 +247,8 @@ impl TypeSignatureExt for TypeSignature { epoch: StacksEpochId, type_args: &[SymbolicExpression], accounting: &mut A, - ) -> Result { - let mapped_key_types = parse_name_type_pairs::<_, CheckErrors>( + ) -> Result { + let mapped_key_types = parse_name_type_pairs::<_, CheckErrorKind>( epoch, type_args, SyntaxBindingErrorType::TupleCons, @@ -261,15 +262,15 @@ impl TypeSignatureExt for TypeSignature { // (buff 10) fn parse_buff_type_repr( type_args: &[SymbolicExpression], - ) -> Result { + ) -> Result { if type_args.len() != 1 { - return Err(CheckErrors::InvalidTypeDescription); + return Err(CheckErrorKind::InvalidTypeDescription); } if let SymbolicExpressionType::LiteralValue(Value::Int(buff_len)) = &type_args[0].expr { BufferLength::try_from(*buff_len) .map(|buff_len| SequenceType(SequenceSubtype::BufferType(buff_len))) } else { - Err(CheckErrors::InvalidTypeDescription) + Err(CheckErrorKind::InvalidTypeDescription) } } @@ -277,16 +278,16 @@ impl TypeSignatureExt for TypeSignature { // (string-utf8 10) fn parse_string_utf8_type_repr( type_args: &[SymbolicExpression], - ) -> Result { + ) -> Result { if type_args.len() != 1 { - return Err(CheckErrors::InvalidTypeDescription); + return Err(CheckErrorKind::InvalidTypeDescription); } if let SymbolicExpressionType::LiteralValue(Value::Int(utf8_len)) = &type_args[0].expr { StringUTF8Length::try_from(*utf8_len).map(|utf8_len| { SequenceType(SequenceSubtype::StringType(StringSubtype::UTF8(utf8_len))) }) } else { - Err(CheckErrors::InvalidTypeDescription) + Err(CheckErrorKind::InvalidTypeDescription) } } @@ -294,16 +295,16 @@ impl TypeSignatureExt for TypeSignature { // (string-ascii 10) fn parse_string_ascii_type_repr( type_args: &[SymbolicExpression], - ) -> Result { + ) -> Result { if type_args.len() != 1 { - return Err(CheckErrors::InvalidTypeDescription); + return Err(CheckErrorKind::InvalidTypeDescription); } if let SymbolicExpressionType::LiteralValue(Value::Int(buff_len)) = &type_args[0].expr { BufferLength::try_from(*buff_len).map(|buff_len| { SequenceType(SequenceSubtype::StringType(StringSubtype::ASCII(buff_len))) }) } else { - Err(CheckErrors::InvalidTypeDescription) + Err(CheckErrorKind::InvalidTypeDescription) } } @@ -311,9 +312,9 @@ impl TypeSignatureExt for TypeSignature { epoch: StacksEpochId, type_args: &[SymbolicExpression], accounting: &mut A, - ) -> Result { + ) -> Result { if type_args.len() != 1 { - return Err(CheckErrors::InvalidTypeDescription); + return Err(CheckErrorKind::InvalidTypeDescription); } let inner_type = TypeSignature::parse_type_repr(epoch, &type_args[0], accounting)?; @@ -324,9 +325,9 @@ impl TypeSignatureExt for TypeSignature { epoch: StacksEpochId, type_args: &[SymbolicExpression], accounting: &mut A, - ) -> Result { + ) -> Result { if type_args.len() != 2 { - return Err(CheckErrors::InvalidTypeDescription); + return Err(CheckErrorKind::InvalidTypeDescription); } let ok_type = TypeSignature::parse_type_repr(epoch, &type_args[0], accounting)?; let err_type = TypeSignature::parse_type_repr(epoch, &type_args[1], accounting)?; @@ -337,7 +338,7 @@ impl TypeSignatureExt for TypeSignature { epoch: StacksEpochId, x: &SymbolicExpression, accounting: &mut A, - ) -> Result { + ) -> Result { runtime_cost(ClarityCostFunction::TypeParseStep, accounting, 0)?; match x.expr { @@ -348,7 +349,7 @@ impl TypeSignatureExt for TypeSignature { SymbolicExpressionType::List(ref list_contents) => { let (compound_type, rest) = list_contents .split_first() - .ok_or(CheckErrors::InvalidTypeDescription)?; + .ok_or(CheckErrorKind::InvalidTypeDescription)?; if let SymbolicExpressionType::Atom(ref compound_type) = compound_type.expr { match compound_type.as_ref() { "list" => TypeSignature::parse_list_type_repr(epoch, rest, accounting), @@ -362,10 +363,10 @@ impl TypeSignatureExt for TypeSignature { "response" => { TypeSignature::parse_response_type_repr(epoch, rest, accounting) } - _ => Err(CheckErrors::InvalidTypeDescription), + _ => Err(CheckErrorKind::InvalidTypeDescription), } } else { - Err(CheckErrors::InvalidTypeDescription) + Err(CheckErrorKind::InvalidTypeDescription) } } SymbolicExpressionType::TraitReference(_, ref trait_definition) @@ -390,7 +391,7 @@ impl TypeSignatureExt for TypeSignature { )), } } - _ => Err(CheckErrors::InvalidTypeDescription), + _ => Err(CheckErrorKind::InvalidTypeDescription), } } @@ -399,43 +400,43 @@ impl TypeSignatureExt for TypeSignature { accounting: &mut A, epoch: StacksEpochId, clarity_version: ClarityVersion, - ) -> Result, CheckErrors> { + ) -> Result, CheckErrorKind> { let mut trait_signature: BTreeMap = BTreeMap::new(); let functions_types = type_args .first() - .ok_or_else(|| CheckErrors::InvalidTypeDescription)? + .ok_or_else(|| CheckErrorKind::InvalidTypeDescription)? .match_list() - .ok_or(CheckErrors::DefineTraitBadSignature)?; + .ok_or(CheckErrorKind::DefineTraitBadSignature)?; for function_type in functions_types.iter() { let args = function_type .match_list() - .ok_or(CheckErrors::DefineTraitBadSignature)?; + .ok_or(CheckErrorKind::DefineTraitBadSignature)?; if args.len() != 3 { - return Err(CheckErrors::InvalidTypeDescription); + return Err(CheckErrorKind::InvalidTypeDescription); } // Extract function's name let fn_name = args[0] .match_atom() - .ok_or(CheckErrors::DefineTraitBadSignature)?; + .ok_or(CheckErrorKind::DefineTraitBadSignature)?; // Extract function's arguments let fn_args_exprs = args[1] .match_list() - .ok_or(CheckErrors::DefineTraitBadSignature)?; + .ok_or(CheckErrorKind::DefineTraitBadSignature)?; let fn_args = fn_args_exprs .iter() .map(|arg_type| TypeSignature::parse_type_repr(epoch, arg_type, accounting)) - .collect::>()?; + .collect::>()?; // Extract function's type return - must be a response let fn_return = match TypeSignature::parse_type_repr(epoch, &args[2], accounting) { Ok(response) => match response { TypeSignature::ResponseType(_) => Ok(response), - _ => Err(CheckErrors::DefineTraitBadSignature), + _ => Err(CheckErrorKind::DefineTraitBadSignature), }, - _ => Err(CheckErrors::DefineTraitBadSignature), + _ => Err(CheckErrorKind::DefineTraitBadSignature), }?; if trait_signature @@ -449,7 +450,9 @@ impl TypeSignatureExt for TypeSignature { .is_some() && clarity_version >= ClarityVersion::Clarity2 { - return Err(CheckErrors::DefineTraitDuplicateMethod(fn_name.to_string())); + return Err(CheckErrorKind::DefineTraitDuplicateMethod( + fn_name.to_string(), + )); } } Ok(trait_signature) @@ -472,7 +475,7 @@ impl TypeSignatureExt for TypeSignature { } impl FixedFunction { - pub fn total_type_size(&self) -> Result { + pub fn total_type_size(&self) -> Result { let mut function_type_size = u64::from(self.returns.type_size()?); for arg in self.args.iter() { function_type_size = @@ -483,7 +486,7 @@ impl FixedFunction { } impl FunctionSignature { - pub fn total_type_size(&self) -> Result { + pub fn total_type_size(&self) -> Result { let mut function_type_size = u64::from(self.returns.type_size()?); for arg in self.args.iter() { function_type_size = @@ -496,7 +499,7 @@ impl FunctionSignature { &self, epoch: &StacksEpochId, args: Vec, - ) -> Result { + ) -> Result { if args.len() != self.args.len() { return Ok(false); } @@ -545,7 +548,7 @@ pub fn parse_name_type_pairs( accounting: &mut A, ) -> Result, E> where - E: for<'a> From<(CheckErrors, &'a SymbolicExpression)>, + E: for<'a> From<(CheckErrorKind, &'a SymbolicExpression)>, { // this is a pretty deep nesting here, but what we're trying to do is pick out the values of // the form: @@ -554,14 +557,14 @@ where use crate::vm::representations::SymbolicExpressionType::List; // step 1: parse it into a vec of symbolicexpression pairs. - let as_pairs: Result, (CheckErrors, &SymbolicExpression)> = name_type_pairs + let as_pairs: Result, (CheckErrorKind, &SymbolicExpression)> = name_type_pairs .iter() .enumerate() .map(|(i, key_type_pair)| { if let List(ref as_vec) = key_type_pair.expr { if as_vec.len() != 2 { Err(( - CheckErrors::BadSyntaxBinding(SyntaxBindingError::InvalidLength( + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::InvalidLength( binding_error_type, i, )), @@ -580,7 +583,7 @@ where .collect(); // step 2: turn into a vec of (name, typesignature) pairs. - let key_types: Result, (CheckErrors, &SymbolicExpression)> = (as_pairs?) + let key_types: Result, (CheckErrorKind, &SymbolicExpression)> = (as_pairs?) .iter() .enumerate() .map(|(i, (name_symbol, type_symbol))| { @@ -588,7 +591,7 @@ where .match_atom() .ok_or_else(|| { ( - CheckErrors::BadSyntaxBinding(SyntaxBindingError::NotAtom( + CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::NotAtom( binding_error_type, i, )), @@ -619,13 +622,13 @@ mod test { use rstest_reuse::{self, *}; use stacks_common::types::StacksEpochId; - use super::CheckErrors::*; + use super::CheckErrorKind::*; use super::*; use crate::vm::tests::test_clarity_versions; use crate::vm::types::QualifiedContractIdentifier; use crate::vm::{execute, ClarityVersion}; - fn fail_parse(val: &str, version: ClarityVersion, epoch: StacksEpochId) -> CheckErrors { + fn fail_parse(val: &str, version: ClarityVersion, epoch: StacksEpochId) -> CheckErrorKind { use crate::vm::ast::parse; let expr = &parse( &QualifiedContractIdentifier::transient(), diff --git a/stackslib/src/chainstate/stacks/boot/contract_tests.rs b/stackslib/src/chainstate/stacks/boot/contract_tests.rs index 7514ba3632..77c7f2268a 100644 --- a/stackslib/src/chainstate/stacks/boot/contract_tests.rs +++ b/stackslib/src/chainstate/stacks/boot/contract_tests.rs @@ -7,7 +7,7 @@ use clarity::vm::ast::ASTRules; use clarity::vm::clarity::TransactionConnection; use clarity::vm::contexts::OwnedEnvironment; use clarity::vm::database::*; -use clarity::vm::errors::{CheckErrors, Error}; +use clarity::vm::errors::{CheckErrorKind, Error}; use clarity::vm::test_util::{execute, symbols_from_values, TEST_BURN_STATE_DB, TEST_HEADER_DB}; use clarity::vm::types::{ OptionalData, PrincipalData, QualifiedContractIdentifier, ResponseData, StandardPrincipalData, @@ -1717,7 +1717,10 @@ fn simple_epoch21_test() { .expect_err("2.0 'bad' contract should not deploy successfully") { ClarityError::Analysis(e) => { - assert_eq!(*e.err, CheckErrors::UnknownFunction("stx-account".into())); + assert_eq!( + *e.err, + CheckErrorKind::UnknownFunction("stx-account".into()) + ); } e => panic!("Should have caused an analysis error: {:#?}", e), }; @@ -1746,7 +1749,7 @@ fn simple_epoch21_test() { ClarityError::Interpreter(e) => { assert_eq!( e, - Error::Unchecked(CheckErrors::NameAlreadyUsed("stx-account".into())) + Error::Unchecked(CheckErrorKind::NameAlreadyUsed("stx-account".into())) ); } e => panic!("Should have caused an Interpreter error: {:#?}", e), diff --git a/stackslib/src/chainstate/stacks/boot/mod.rs b/stackslib/src/chainstate/stacks/boot/mod.rs index 83afc46301..321a47934c 100644 --- a/stackslib/src/chainstate/stacks/boot/mod.rs +++ b/stackslib/src/chainstate/stacks/boot/mod.rs @@ -19,7 +19,7 @@ use std::collections::BTreeMap; use std::sync::LazyLock; use clarity::types::Address; -use clarity::vm::analysis::CheckErrors; +use clarity::vm::analysis::CheckErrorKind; use clarity::vm::ast::ASTRules; use clarity::vm::clarity::{Error as ClarityError, TransactionConnection}; use clarity::vm::costs::LimitedCostTracker; @@ -1363,7 +1363,7 @@ impl StacksChainState { // there hasn't yet been a Stacks block. match result { Err(Error::ClarityError(ClarityError::Interpreter(VmError::Unchecked( - CheckErrors::NoSuchContract(_), + CheckErrorKind::NoSuchContract(_), )))) => { warn!("Reward cycle attempted to calculate rewards before the PoX contract was instantiated"); return Ok(vec![]); diff --git a/stackslib/src/chainstate/stacks/db/blocks.rs b/stackslib/src/chainstate/stacks/db/blocks.rs index 061fba56bc..7d5aa9672d 100644 --- a/stackslib/src/chainstate/stacks/db/blocks.rs +++ b/stackslib/src/chainstate/stacks/db/blocks.rs @@ -19,7 +19,7 @@ use std::io::{Read, Write}; use std::path::PathBuf; use std::{cmp, fs, io}; -pub use clarity::vm::analysis::errors::{CheckError, CheckErrors}; +pub use clarity::vm::analysis::errors::{CheckError, CheckErrorKind}; use clarity::vm::ast::ASTRules; use clarity::vm::clarity::TransactionConnection; use clarity::vm::costs::LimitedCostTracker; diff --git a/stackslib/src/chainstate/stacks/db/contracts.rs b/stackslib/src/chainstate/stacks/db/contracts.rs index 11b2ee0d02..89aa37d56a 100644 --- a/stackslib/src/chainstate/stacks/db/contracts.rs +++ b/stackslib/src/chainstate/stacks/db/contracts.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -pub use clarity::vm::analysis::errors::CheckErrors; +pub use clarity::vm::analysis::errors::CheckErrorKind; use clarity::vm::contracts::Contract; use clarity::vm::errors::Error as clarity_vm_error; use clarity::vm::types::{QualifiedContractIdentifier, Value}; @@ -31,7 +31,7 @@ impl StacksChainState { clarity_tx .with_clarity_db_readonly(|ref mut db| match db.get_contract(contract_id) { Ok(c) => Ok(Some(c)), - Err(clarity_vm_error::Unchecked(CheckErrors::NoSuchContract(_))) => Ok(None), + Err(clarity_vm_error::Unchecked(CheckErrorKind::NoSuchContract(_))) => Ok(None), Err(e) => Err(clarity_error::Interpreter(e)), }) .map_err(Error::ClarityError) @@ -47,7 +47,7 @@ impl StacksChainState { .with_clarity_db_readonly(|ref mut db| { match db.lookup_variable_unknown_descriptor(contract_id, data_var, &epoch) { Ok(c) => Ok(Some(c)), - Err(clarity_vm_error::Unchecked(CheckErrors::NoSuchDataVariable(_))) => { + Err(clarity_vm_error::Unchecked(CheckErrorKind::NoSuchDataVariable(_))) => { Ok(None) } Err(e) => Err(clarity_error::Interpreter(e)), diff --git a/stackslib/src/chainstate/stacks/db/transactions.rs b/stackslib/src/chainstate/stacks/db/transactions.rs index 2deee7b642..07780dbd83 100644 --- a/stackslib/src/chainstate/stacks/db/transactions.rs +++ b/stackslib/src/chainstate/stacks/db/transactions.rs @@ -255,7 +255,7 @@ impl StacksTransactionReceipt { tx: StacksTransaction, cost: ExecutionCost, contract_analysis: ContractAnalysis, - error: CheckErrors, + error: CheckErrorKind, ) -> StacksTransactionReceipt { StacksTransactionReceipt { transaction: tx.into(), @@ -274,7 +274,7 @@ impl StacksTransactionReceipt { pub fn from_runtime_failure_contract_call( tx: StacksTransaction, cost: ExecutionCost, - error: CheckErrors, + error: CheckErrorKind, ) -> StacksTransactionReceipt { StacksTransactionReceipt { transaction: tx.into(), @@ -369,7 +369,7 @@ pub enum ClarityRuntimeTxError { reason: String, }, CostError(ExecutionCost, ExecutionCost), - AnalysisError(CheckErrors), + AnalysisError(CheckErrorKind), Rejectable(clarity_error), } diff --git a/stackslib/src/clarity_vm/clarity.rs b/stackslib/src/clarity_vm/clarity.rs index 416c6e99ed..ffb7cb0a5f 100644 --- a/stackslib/src/clarity_vm/clarity.rs +++ b/stackslib/src/clarity_vm/clarity.rs @@ -2143,7 +2143,7 @@ mod tests { use std::path::PathBuf; use clarity::types::chainstate::{BurnchainHeaderHash, SortitionId, StacksAddress}; - use clarity::vm::analysis::errors::CheckErrors; + use clarity::vm::analysis::errors::CheckErrorKind; use clarity::vm::database::{ClarityBackingStore, STXBalance, SqliteConnection}; use clarity::vm::test_util::{TEST_BURN_STATE_DB, TEST_HEADER_DB}; use clarity::vm::types::{StandardPrincipalData, TupleData, Value}; @@ -2553,7 +2553,7 @@ mod tests { // should not be in the marf. assert_eq!( conn.get_contract_hash(&contract_identifier).unwrap_err(), - CheckErrors::NoSuchContract(contract_identifier.to_string()).into() + CheckErrorKind::NoSuchContract(contract_identifier.to_string()).into() ); let sql = conn.get_side_store(); // sqlite only have entries @@ -2700,7 +2700,7 @@ mod tests { // should not be in the marf. assert_eq!( conn.get_contract_hash(&contract_identifier).unwrap_err(), - CheckErrors::NoSuchContract(contract_identifier.to_string()).into() + CheckErrorKind::NoSuchContract(contract_identifier.to_string()).into() ); let sql = conn.get_side_store(); diff --git a/stackslib/src/clarity_vm/tests/analysis_costs.rs b/stackslib/src/clarity_vm/tests/analysis_costs.rs index 601fd7e78e..048394c15a 100644 --- a/stackslib/src/clarity_vm/tests/analysis_costs.rs +++ b/stackslib/src/clarity_vm/tests/analysis_costs.rs @@ -17,7 +17,7 @@ use clarity::vm::ast::ASTRules; use clarity::vm::clarity::{Error as ClarityError, TransactionConnection}; use clarity::vm::costs::ExecutionCost; -use clarity::vm::errors::CheckErrors; +use clarity::vm::errors::CheckErrorKind; use clarity::vm::functions::NativeFunctions; use clarity::vm::test_util::TEST_HEADER_DB; use clarity::vm::tests::{test_only_mainnet_to_chain_id, UnitTestBurnStateDB}; @@ -343,7 +343,7 @@ fn undefined_top_variable_error(#[case] use_mainnet: bool, #[case] epoch: Stacks let Err(ClarityError::Analysis(check_error)) = analysis_result else { panic!("Bad analysis result: {:?}", &analysis_result); }; - let CheckErrors::UndefinedVariable(var_name) = *check_error.err else { + let CheckErrorKind::UndefinedVariable(var_name) = *check_error.err else { panic!("Bad analysis error: {:?}", &check_error); }; assert_eq!(var_name, "foo".to_string()); diff --git a/stackslib/src/clarity_vm/tests/contracts.rs b/stackslib/src/clarity_vm/tests/contracts.rs index 27a9023e46..22b4248ad7 100644 --- a/stackslib/src/clarity_vm/tests/contracts.rs +++ b/stackslib/src/clarity_vm/tests/contracts.rs @@ -17,7 +17,7 @@ use clarity::types::StacksEpochId; use clarity::vm::ast::ASTRules; use clarity::vm::clarity::Error as ClarityError; -use clarity::vm::errors::{CheckErrors, Error}; +use clarity::vm::errors::{CheckErrorKind, Error}; use clarity::vm::types::SequenceData::Buffer; use clarity::vm::types::{ BuffData, OptionalData, PrincipalData, QualifiedContractIdentifier, TupleData, TypeSignature, @@ -54,7 +54,7 @@ fn test_get_burn_block_info_eval() { ASTRules::PrecheckSize, ); if let Err(ClarityError::Analysis(check_error)) = res { - if let CheckErrors::UnknownFunction(func_name) = *check_error.err { + if let CheckErrorKind::UnknownFunction(func_name) = *check_error.err { assert_eq!(func_name, "get-burn-block-info?"); } else { panic!("Bad analysis error: {:?}", &check_error); @@ -79,7 +79,7 @@ fn test_get_burn_block_info_eval() { ASTRules::PrecheckSize, ); if let Err(ClarityError::Analysis(check_error)) = res { - if let CheckErrors::UnknownFunction(func_name) = *check_error.err { + if let CheckErrorKind::UnknownFunction(func_name) = *check_error.err { assert_eq!(func_name, "get-burn-block-info?"); } else { panic!("Bad analysis error: {:?}", &check_error); @@ -180,7 +180,7 @@ fn test_get_block_info_eval_v210() { ASTRules::PrecheckSize, ); if let Err(ClarityError::Analysis(check_error)) = res { - if let CheckErrors::NoSuchBlockInfoProperty(name) = *check_error.err { + if let CheckErrorKind::NoSuchBlockInfoProperty(name) = *check_error.err { assert_eq!(name, "block-reward"); } else { panic!("Bad analysis error: {:?}", &check_error); @@ -205,7 +205,7 @@ fn test_get_block_info_eval_v210() { ASTRules::PrecheckSize, ); if let Err(ClarityError::Analysis(check_error)) = res { - if let CheckErrors::NoSuchBlockInfoProperty(name) = *check_error.err { + if let CheckErrorKind::NoSuchBlockInfoProperty(name) = *check_error.err { assert_eq!(name, "block-reward"); } else { panic!("Bad analysis error: {:?}", &check_error); @@ -368,7 +368,7 @@ fn trait_invocation_205_with_stored_principal() { .unwrap_err(); match error { ClarityError::Analysis(ref e) => match *e.err { - CheckErrors::TypeError(..) => (), + CheckErrorKind::TypeError(..) => (), _ => panic!("Unexpected error: {:?}", error), }, _ => panic!("Unexpected error: {:?}", error), @@ -461,7 +461,7 @@ fn trait_invocation_cross_epoch() { ) .unwrap_err(); - if let ClarityError::Interpreter(Error::Unchecked(CheckErrors::TypeValueError(trait_ref_type, value))) = error { + if let ClarityError::Interpreter(Error::Unchecked(CheckErrorKind::TypeValueError(trait_ref_type, value))) = error { assert!(matches!(*trait_ref_type, TypeSignature::TraitReferenceType(_))); } else { panic!("Expected an Interpreter(UncheckedError(TypeValue(TraitReferenceType, Principal))) during Epoch-2.2"); @@ -485,7 +485,7 @@ fn trait_invocation_cross_epoch() { ) .unwrap_err(); - if let ClarityError::Interpreter(Error::Unchecked(CheckErrors::TypeValueError(trait_ref_type, value))) = error { + if let ClarityError::Interpreter(Error::Unchecked(CheckErrorKind::TypeValueError(trait_ref_type, value))) = error { assert!(matches!(*trait_ref_type, TypeSignature::TraitReferenceType(_))); } else { panic!("Expected an Interpreter(UncheckedError(TypeValue(TraitReferenceType, Principal))) during Epoch-2.2"); @@ -936,7 +936,7 @@ fn test_block_heights() { ASTRules::PrecheckSize, ); if let Err(ClarityError::Analysis(check_error)) = res { - if let CheckErrors::UndefinedVariable(var_name) = *check_error.err { + if let CheckErrorKind::UndefinedVariable(var_name) = *check_error.err { assert_eq!(var_name, "stacks-block-height"); } else { panic!("Bad analysis error: {:?}", &check_error); @@ -972,7 +972,7 @@ fn test_block_heights() { ASTRules::PrecheckSize, ); if let Err(ClarityError::Analysis(check_error)) = res { - if let CheckErrors::UndefinedVariable(var_name) = *check_error.err { + if let CheckErrorKind::UndefinedVariable(var_name) = *check_error.err { assert_eq!(var_name, "stacks-block-height"); } else { panic!("Bad analysis error: {:?}", &check_error); @@ -989,7 +989,7 @@ fn test_block_heights() { ASTRules::PrecheckSize, ); if let Err(ClarityError::Analysis(check_error)) = res { - if let CheckErrors::UndefinedVariable(var_name) = *check_error.err { + if let CheckErrorKind::UndefinedVariable(var_name) = *check_error.err { assert_eq!(var_name, "block-height"); } else { panic!("Bad analysis error: {:?}", &check_error); diff --git a/stackslib/src/clarity_vm/tests/forking.rs b/stackslib/src/clarity_vm/tests/forking.rs index 6dc3305562..c9240146a5 100644 --- a/stackslib/src/clarity_vm/tests/forking.rs +++ b/stackslib/src/clarity_vm/tests/forking.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use clarity::vm::analysis::errors::CheckErrors; +use clarity::vm::analysis::errors::CheckErrorKind; use clarity::vm::ast::ASTRules; use clarity::vm::contexts::OwnedEnvironment; use clarity::vm::errors::{Error, InterpreterResult as Result, RuntimeErrorType}; @@ -251,7 +251,7 @@ fn test_at_block_missing_defines(#[case] version: ClarityVersion, #[case] epoch: let err = initialize_2(env); assert_eq!( err, - CheckErrors::NoSuchContract( + CheckErrorKind::NoSuchContract( "S1G2081040G2081040G2081040G208105NK8PE5.contract-a".into() ) .into() diff --git a/stackslib/src/net/api/callreadonly.rs b/stackslib/src/net/api/callreadonly.rs index cc9715b172..46124bd115 100644 --- a/stackslib/src/net/api/callreadonly.rs +++ b/stackslib/src/net/api/callreadonly.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use clarity::vm::analysis::CheckErrors; +use clarity::vm::analysis::CheckErrorKind; use clarity::vm::ast::parser::v1::CLARITY_NAME_REGEX; use clarity::vm::clarity::ClarityConnection; use clarity::vm::costs::{ExecutionCost, LimitedCostTracker}; @@ -265,7 +265,7 @@ impl RPCRequestHandler for RPCCallReadOnlyRequestHandler { } } Ok(Some(Err(e))) => match e { - Unchecked(CheckErrors::CostBalanceExceeded(actual_cost, _)) + Unchecked(CheckErrorKind::CostBalanceExceeded(actual_cost, _)) if actual_cost.write_count > 0 => { CallReadOnlyResponse { diff --git a/stackslib/src/net/api/fastcallreadonly.rs b/stackslib/src/net/api/fastcallreadonly.rs index cabd8c9db2..f806b9f19b 100644 --- a/stackslib/src/net/api/fastcallreadonly.rs +++ b/stackslib/src/net/api/fastcallreadonly.rs @@ -15,7 +15,7 @@ use std::time::Duration; -use clarity::vm::analysis::CheckErrors; +use clarity::vm::analysis::CheckErrorKind; use clarity::vm::ast::parser::v1::CLARITY_NAME_REGEX; use clarity::vm::clarity::ClarityConnection; use clarity::vm::costs::{ExecutionCost, LimitedCostTracker}; @@ -266,7 +266,7 @@ impl RPCRequestHandler for RPCFastCallReadOnlyRequestHandler { } } Ok(Some(Err(e))) => match e { - Unchecked(CheckErrors::CostBalanceExceeded(actual_cost, _)) + Unchecked(CheckErrorKind::CostBalanceExceeded(actual_cost, _)) if actual_cost.write_count > 0 => { CallReadOnlyResponse { @@ -275,7 +275,7 @@ impl RPCRequestHandler for RPCFastCallReadOnlyRequestHandler { cause: Some("NotReadOnly".to_string()), } } - Unchecked(CheckErrors::ExecutionTimeExpired) => { + Unchecked(CheckErrorKind::ExecutionTimeExpired) => { return StacksHttpResponse::new_error( &preamble, &HttpRequestTimeout::new("ExecutionTime expired".to_string()), diff --git a/stackslib/src/net/tests/mod.rs b/stackslib/src/net/tests/mod.rs index 486a2496af..5b88536c48 100644 --- a/stackslib/src/net/tests/mod.rs +++ b/stackslib/src/net/tests/mod.rs @@ -965,7 +965,7 @@ impl NakamotoBootPlan { for (receipt, tx) in stacks_receipts.iter().zip(block.txs.iter()) { // transactions processed in the same order assert_eq!(receipt.transaction.txid(), tx.txid()); - // no CheckErrors + // no CheckErrorKind assert!(receipt.vm_error.is_none()); // transaction was not aborted post-hoc assert!(!receipt.post_condition_aborted); From a885af45573833f5ed6bc9c190d83bfd79db665a Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 12:13:56 -0700 Subject: [PATCH 13/34] Add descriptions to CheckErrorKind variants Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/analysis.rs | 157 +++++++++++++++++++++++---- 1 file changed, 136 insertions(+), 21 deletions(-) diff --git a/clarity-types/src/errors/analysis.rs b/clarity-types/src/errors/analysis.rs index 2a1a0b7c75..f845e87907 100644 --- a/clarity-types/src/errors/analysis.rs +++ b/clarity-types/src/errors/analysis.rs @@ -141,172 +141,287 @@ impl From for CheckErrorKind { Self::BadSyntaxBinding(e) } } - +/// Errors encountered during type-checking and analysis of Clarity contract code, ensuring +/// type safety, correct function signatures, and adherence to resource constraints. +/// These errors prevent invalid contracts from being deployed or executed, +/// halting analysis and failing the transaction or contract deployment. #[derive(Debug, PartialEq)] pub enum CheckErrorKind { - // cost checker errors + // Cost checker errors + /// Arithmetic overflow in cost computation during type-checking, exceeding the maximum threshold. CostOverflow, + /// Cumulative type-checking cost exceeds the allocated budget, indicating budget depletion. CostBalanceExceeded(ExecutionCost, ExecutionCost), + /// Memory usage during type-checking exceeds the allocated memory budget. MemoryBalanceExceeded(u64, u64), + /// Failure in the cost-tracking mechanism due to an unexpected condition or invalid state. CostComputationFailed(String), + // Time checker errors + /// Type-checking time exceeds the allowed budget, halting analysis to ensure responsiveness. + ExecutionTimeExpired, + /// Value exceeds the maximum allowed size for type-checking or serialization. ValueTooLarge, + /// Value is outside the acceptable range for its type (e.g., integer bounds). ValueOutOfBounds, + /// Type signature nesting depth exceeds the allowed limit during analysis. TypeSignatureTooDeep, + /// Expected a name (e.g., variable, function) but found an invalid or missing token. ExpectedName, + /// Supertype (e.g., trait or union) exceeds the maximum allowed size or complexity. + /// This error indicates a transaction would invalidate a block if included. SupertypeTooLarge, - // unexpected interpreter behavior + // Unexpected interpreter behavior + /// Unexpected condition or failure in the type-checker, indicating a bug or invalid state. + /// This error indicates a transaction would invalidate a block if included. Expects(String), - // match errors + // Match errors + /// Invalid syntax in an `option` match expression, wrapping the underlying error. BadMatchOptionSyntax(Box), + /// Invalid syntax in a `response` match expression, wrapping the underlying error. BadMatchResponseSyntax(Box), + /// Input to a match expression does not conform to the expected type. BadMatchInput(Box), - // list typing errors + // List typing errors + /// List elements have mismatched types, violating type consistency. ListTypesMustMatch, + /// Constructed list exceeds the maximum allowed length during type-checking. ConstructedListTooLarge, - // simple type expectation mismatch + // Simple type expectation mismatch + /// Expected type does not match the actual type during analysis. TypeError(Box, Box), + /// Value does not match the expected type during type-checking. TypeValueError(Box, Box), + /// Type description is invalid or malformed, preventing proper type-checking. InvalidTypeDescription, + /// Referenced type name does not exist or is undefined. UnknownTypeName(String), - // union type mismatch + // Union type mismatch + /// Type does not belong to the expected union of types during analysis. UnionTypeError(Vec, Box), + /// Value does not belong to the expected union of types during type-checking. UnionTypeValueError(Vec, Box), + /// Expected an optional type but found a different type. ExpectedOptionalType(Box), + /// Expected a response type but found a different type. ExpectedResponseType(Box), + /// Expected an optional or response type but found a different type. ExpectedOptionalOrResponseType(Box), + /// Expected an optional value but found a different value. ExpectedOptionalValue(Box), + /// Expected a response value but found a different value. ExpectedResponseValue(Box), + /// Expected an optional or response value but found a different value. ExpectedOptionalOrResponseValue(Box), + /// Could not determine the type of the `ok` branch in a response type. CouldNotDetermineResponseOkType, + /// Could not determine the type of the `err` branch in a response type. CouldNotDetermineResponseErrType, + /// Could not determine the serialization type for a value during analysis. CouldNotDetermineSerializationType, + /// Intermediary response types were not properly checked, risking type safety. UncheckedIntermediaryResponses, + /// Expected a contract principal value but found a different value. ExpectedContractPrincipalValue(Box), + /// Could not determine the types for a match expression’s branches. CouldNotDetermineMatchTypes, + /// Could not determine the type of an expression during analysis. CouldNotDetermineType, // Checker runtime failures + /// Attempt to re-annotate a type that was already annotated, indicating a bug. TypeAlreadyAnnotatedFailure, + /// Unexpected failure in the type-checker implementation, indicating a bug. CheckerImplementationFailure, // Assets + /// Expected a token name as an argument BadTokenName, + /// Invalid or malformed signature in a `(define-non-fungible-token ...)` expression. DefineNFTBadSignature, + /// Referenced non-fungible token (NFT) does not exist. NoSuchNFT(String), + /// Referenced fungible token (FT) does not exist. NoSuchFT(String), + /// Invalid arguments provided to a `stx-transfer?` function. BadTransferSTXArguments, + /// Invalid arguments provided to a fungible token transfer function. BadTransferFTArguments, + /// Invalid arguments provided to a non-fungible token transfer function. BadTransferNFTArguments, + /// Invalid arguments provided to a fungible token mint function. BadMintFTArguments, + /// Invalid arguments provided to a fungible token burn function. BadBurnFTArguments, - // tuples + // Tuples + /// Tuple field name is invalid or violates naming rules. BadTupleFieldName, + /// Expected a tuple type but found a different type. ExpectedTuple(Box), + /// Referenced tuple field does not exist in the tuple type. NoSuchTupleField(String, TupleTypeSignature), + /// Empty tuple is not allowed in Clarity. EmptyTuplesNotAllowed, + /// Invalid tuple construction due to malformed syntax or type mismatch. BadTupleConstruction(String), - // variables + // Variables + /// Referenced data variable does not exist in scope. NoSuchDataVariable(String), - // data map + // Data map + /// Map name is invalid or violates naming rules. BadMapName, + /// Referenced data map does not exist in scope. NoSuchMap(String), - // defines + // Defines + /// Invalid or malformed signature in a function definition. DefineFunctionBadSignature, + /// Function name is invalid or violates naming rules. BadFunctionName, + /// Invalid or malformed map type definition in a `(define-map ...)` expression. BadMapTypeDefinition, + /// Public function must return a response type, but found a different type. PublicFunctionMustReturnResponse(Box), + /// Invalid or malformed variable definition in a `(define-data-var ...)` expression. DefineVariableBadSignature, + /// Return types of function branches do not match the expected type. ReturnTypesMustMatch(Box, Box), + /// Circular reference detected in interdependent function definitions. CircularReference(Vec), - // contract-call errors + // Contract-call errors + /// Referenced contract does not exist. NoSuchContract(String), + /// Referenced public function does not exist in the specified contract. NoSuchPublicFunction(String, String), + /// Public function is not read-only when expected to be. PublicFunctionNotReadOnly(String, String), + /// Attempt to define a contract with a name that already exists. ContractAlreadyExists(String), + /// Expected a contract name in a `contract-call?` expression but found an invalid token. ContractCallExpectName, + /// Expected a callable type (e.g., function or trait) but found a different type. ExpectedCallableType(Box), // get-block-info? errors + /// Referenced block info property does not exist. NoSuchBlockInfoProperty(String), + /// Referenced burn block info property does not exist. NoSuchBurnBlockInfoProperty(String), + /// Referenced Stacks block info property does not exist. NoSuchStacksBlockInfoProperty(String), + /// Referenced tenure info property does not exist. NoSuchTenureInfoProperty(String), + /// Expected a block info property name but found an invalid token. GetBlockInfoExpectPropertyName, + /// Expected a burn block info property name but found an invalid token. GetBurnBlockInfoExpectPropertyName, + /// Expected a Stacks block info property name but found an invalid token. GetStacksBlockInfoExpectPropertyName, + /// Expected a tenure info property name but found an invalid token. GetTenureInfoExpectPropertyName, + /// Name (e.g., variable, function) is already in use within the same scope. NameAlreadyUsed(String), + /// Name is a reserved word in Clarity and cannot be used. ReservedWord(String), - // expect a function, or applying a function to a list + // Expect a function, or applying a function to a list + /// Attempt to apply a non-function value as a function. NonFunctionApplication, + /// Expected a list application but found a different expression. ExpectedListApplication, + /// Expected a sequence type (e.g., list, buffer) but found a different type. ExpectedSequence(Box), + /// Sequence length exceeds the maximum allowed limit. MaxLengthOverflow, - // let syntax + // Let syntax + /// Invalid syntax in a `let` expression, violating binding or structure rules. BadLetSyntax, - // generic binding syntax + // Generic binding syntax + /// Invalid binding syntax in a generic construct (e.g., `let`, `match`). BadSyntaxBinding(SyntaxBindingError), + /// Maximum context depth for type-checking has been reached. MaxContextDepthReached, + /// Referenced function is not defined in the current scope. UndefinedFunction(String), + /// Referenced variable is not defined in the current scope. UndefinedVariable(String), - // argument counts + // Argument counts + /// Function requires at least the specified number of arguments, but fewer were provided. RequiresAtLeastArguments(usize, usize), + /// Function requires at most the specified number of arguments, but more were provided. RequiresAtMostArguments(usize, usize), + /// Incorrect number of arguments provided to a function. IncorrectArgumentCount(usize, usize), + /// `if` expression arms have mismatched return types. IfArmsMustMatch(Box, Box), + /// `match` expression arms have mismatched return types. MatchArmsMustMatch(Box, Box), + /// 'default-to` expression types are mismatched. DefaultTypesMustMatch(Box, Box), + /// Application of an illegal or unknown function. IllegalOrUnknownFunctionApplication(String), + /// Referenced function is unknown or not defined. UnknownFunction(String), - // traits + // Traits + /// Referenced trait does not exist in the specified contract. NoSuchTrait(String, String), + /// Referenced trait is not defined or cannot be found. TraitReferenceUnknown(String), + /// Referenced method does not exist in the specified trait. TraitMethodUnknown(String, String), + /// Expected a trait identifier (e.g., `.trait-name`) but found an invalid token. ExpectedTraitIdentifier, + /// Trait reference is not allowed in the current context (e.g., storage). TraitReferenceNotAllowed, + /// Invalid implementation of a trait method. BadTraitImplementation(String, String), + /// Invalid or malformed signature in a `(define-trait ...)` expression. DefineTraitBadSignature, + /// Trait definition contains duplicate method names. DefineTraitDuplicateMethod(String), + /// Unexpected use of a trait or field reference in a non-trait context. UnexpectedTraitOrFieldReference, + /// Trait-based contract call used in a read-only context, which is prohibited. TraitBasedContractCallInReadOnly, + /// `contract-of` expects a trait type but found a different type. ContractOfExpectsTrait, + /// Trait implementation is incompatible with the expected trait definition. IncompatibleTrait(Box, Box), - // strings + // Strings + /// String contains invalid or disallowed characters (e.g., non-ASCII in ASCII strings). InvalidCharactersDetected, + /// String contains invalid UTF-8 encoding. InvalidUTF8Encoding, // secp256k1 signature + /// Invalid secp256k1 signature provided in an expression. InvalidSecp65k1Signature, + /// Attempt to write to contract state in a read-only function. WriteAttemptedInReadOnly, + /// `at-block` closure must be read-only but contains write operations. AtBlockClosureMustBeReadOnly, - - // time checker errors - ExecutionTimeExpired, } #[derive(Debug, PartialEq)] From 0e23fdada3bd7891b8ea5e2d285f8654023bc733 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 13:02:46 -0700 Subject: [PATCH 14/34] Rename CheckError to StaticCheckError Signed-off-by: Jacinta Ferrant --- CONTRIBUTING.md | 2 +- clarity-types/src/errors/analysis.rs | 24 ++-- clarity-types/src/errors/mod.rs | 2 +- clarity-types/src/types/serialization.rs | 4 +- clarity/src/vm/analysis/analysis_db.rs | 26 ++--- .../src/vm/analysis/arithmetic_checker/mod.rs | 4 +- .../contract_interface_builder/mod.rs | 8 +- clarity/src/vm/analysis/errors.rs | 4 +- clarity/src/vm/analysis/mod.rs | 8 +- .../src/vm/analysis/read_only_checker/mod.rs | 36 +++--- clarity/src/vm/analysis/trait_checker/mod.rs | 6 +- .../src/vm/analysis/trait_checker/tests.rs | 4 +- .../src/vm/analysis/type_checker/contexts.rs | 16 ++- clarity/src/vm/analysis/type_checker/mod.rs | 6 +- .../analysis/type_checker/v2_05/contexts.rs | 28 ++--- .../src/vm/analysis/type_checker/v2_05/mod.rs | 64 ++++++----- .../type_checker/v2_05/natives/assets.rs | 20 ++-- .../type_checker/v2_05/natives/maps.rs | 20 ++-- .../type_checker/v2_05/natives/mod.rs | 74 ++++++------- .../type_checker/v2_05/natives/options.rs | 40 +++---- .../type_checker/v2_05/natives/sequences.rs | 22 ++-- .../analysis/type_checker/v2_05/tests/mod.rs | 4 +- .../vm/analysis/type_checker/v2_1/contexts.rs | 38 ++++--- .../src/vm/analysis/type_checker/v2_1/mod.rs | 81 +++++++------- .../type_checker/v2_1/natives/assets.rs | 24 ++-- .../type_checker/v2_1/natives/conversions.rs | 10 +- .../type_checker/v2_1/natives/maps.rs | 20 ++-- .../analysis/type_checker/v2_1/natives/mod.rs | 103 +++++++++--------- .../type_checker/v2_1/natives/options.rs | 39 +++---- .../type_checker/v2_1/natives/sequences.rs | 26 ++--- .../type_checker/v2_1/tests/contracts.rs | 12 +- .../analysis/type_checker/v2_1/tests/mod.rs | 12 +- clarity/src/vm/analysis/types.rs | 6 +- clarity/src/vm/clarity.rs | 10 +- clarity/src/vm/database/clarity_db.rs | 2 +- clarity/src/vm/tooling/mod.rs | 4 +- stackslib/src/chainstate/stacks/db/blocks.rs | 4 +- stackslib/src/chainstate/stacks/events.rs | 2 +- .../stacks/tests/block_construction.rs | 2 +- stackslib/src/clarity_cli.rs | 6 +- 40 files changed, 423 insertions(+), 400 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 613e8c973e..9ca821712a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -501,7 +501,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { /// - Returns CheckErrors::WriteAttemptedInReadOnly if there is a read-only /// violation, i.e. if some function marked read-only attempts to modify /// the chainstate. - pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), CheckError> + pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), StaticCheckError> ``` This comment is considered positive because it explains the contract of the function in pseudo-code. Someone who understands the constructs mentioned could, e.g., write a test for this method from this description. diff --git a/clarity-types/src/errors/analysis.rs b/clarity-types/src/errors/analysis.rs index 09e4e5f056..08408e8bb8 100644 --- a/clarity-types/src/errors/analysis.rs +++ b/clarity-types/src/errors/analysis.rs @@ -310,7 +310,7 @@ pub enum CheckErrors { } #[derive(Debug, PartialEq)] -pub struct CheckError { +pub struct StaticCheckError { pub err: Box, pub expressions: Option>, pub diagnostic: Diagnostic, @@ -327,10 +327,10 @@ impl CheckErrors { } } -impl CheckError { - pub fn new(err: CheckErrors) -> CheckError { +impl StaticCheckError { + pub fn new(err: CheckErrors) -> StaticCheckError { let diagnostic = Diagnostic::err(&err); - CheckError { + StaticCheckError { err: Box::new(err), expressions: None, diagnostic, @@ -358,13 +358,13 @@ impl CheckError { } } -impl From<(SyntaxBindingError, &SymbolicExpression)> for CheckError { +impl From<(SyntaxBindingError, &SymbolicExpression)> for StaticCheckError { fn from(e: (SyntaxBindingError, &SymbolicExpression)) -> Self { Self::with_expression(CheckErrors::BadSyntaxBinding(e.0), e.1) } } -impl From<(CheckErrors, &SymbolicExpression)> for CheckError { +impl From<(CheckErrors, &SymbolicExpression)> for StaticCheckError { fn from(e: (CheckErrors, &SymbolicExpression)) -> Self { let mut ce = Self::new(e.0); ce.set_expression(e.1); @@ -384,7 +384,7 @@ impl fmt::Display for CheckErrors { } } -impl fmt::Display for CheckError { +impl fmt::Display for StaticCheckError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.err)?; @@ -396,9 +396,9 @@ impl fmt::Display for CheckError { } } -impl From for CheckError { +impl From for StaticCheckError { fn from(err: CostErrors) -> Self { - CheckError::from(CheckErrors::from(err)) + StaticCheckError::from(CheckErrors::from(err)) } } @@ -421,7 +421,7 @@ impl From for CheckErrors { } } -impl error::Error for CheckError { +impl error::Error for StaticCheckError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { None } @@ -433,9 +433,9 @@ impl error::Error for CheckErrors { } } -impl From for CheckError { +impl From for StaticCheckError { fn from(err: CheckErrors) -> Self { - CheckError::new(err) + StaticCheckError::new(err) } } diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 58b42b8a99..e3bd2a191c 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -20,7 +20,7 @@ pub mod lexer; use std::{error, fmt}; -pub use analysis::{CheckError, CheckErrors}; +pub use analysis::{CheckErrors, StaticCheckError}; pub use ast::{ParseError, ParseErrors, ParseResult}; pub use cost::CostErrors; pub use lexer::LexerError; diff --git a/clarity-types/src/types/serialization.rs b/clarity-types/src/types/serialization.rs index 2179efd824..a152ef7eaa 100644 --- a/clarity-types/src/types/serialization.rs +++ b/clarity-types/src/types/serialization.rs @@ -33,7 +33,7 @@ use crate::types::{ /// Errors that may occur in serialization or deserialization /// If deserialization failed because the described type is a bad type and -/// a CheckError is thrown, it gets wrapped in BadTypeError. +/// a CheckErrorKind is thrown, it gets wrapped in BadTypeError. /// Any IOErrrors from the supplied buffer will manifest as IOError variants, /// except for EOF -- if the deserialization code experiences an EOF, it is caught /// and rethrown as DeserializationError @@ -493,7 +493,7 @@ impl TypeSignature { Err(CheckErrors::CouldNotDetermineSerializationType) => { if no_ok_type { // if both the ok type and the error type are NoType, - // throw a CheckError. This should not be possible, but the check + // throw a CheckErrorKind. This should not be possible, but the check // is done out of caution. return Err(CheckErrors::CouldNotDetermineSerializationType); } else { diff --git a/clarity/src/vm/analysis/analysis_db.rs b/clarity/src/vm/analysis/analysis_db.rs index 390d3e9dbe..fcea02397f 100644 --- a/clarity/src/vm/analysis/analysis_db.rs +++ b/clarity/src/vm/analysis/analysis_db.rs @@ -20,7 +20,7 @@ use clarity_types::representations::ClarityName; use clarity_types::types::{QualifiedContractIdentifier, TraitIdentifier}; use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::{CheckError, CheckErrors}; +use crate::vm::analysis::errors::{CheckErrors, StaticCheckError}; use crate::vm::analysis::type_checker::ContractAnalysis; use crate::vm::database::{ ClarityBackingStore, ClarityDeserializable, ClaritySerializable, RollbackWrapper, @@ -63,13 +63,13 @@ impl<'a> AnalysisDatabase<'a> { self.store.nest(); } - pub fn commit(&mut self) -> Result<(), CheckError> { + pub fn commit(&mut self) -> Result<(), StaticCheckError> { self.store .commit() .map_err(|e| CheckErrors::Expects(format!("{e:?}")).into()) } - pub fn roll_back(&mut self) -> Result<(), CheckError> { + pub fn roll_back(&mut self) -> Result<(), StaticCheckError> { self.store .rollback() .map_err(|e| CheckErrors::Expects(format!("{e:?}")).into()) @@ -99,11 +99,11 @@ impl<'a> AnalysisDatabase<'a> { pub fn load_contract_non_canonical( &mut self, contract_identifier: &QualifiedContractIdentifier, - ) -> Result, CheckError> { + ) -> Result, StaticCheckError> { self.store .get_metadata(contract_identifier, AnalysisDatabase::storage_key()) // treat NoSuchContract error thrown by get_metadata as an Option::None -- - // the analysis will propagate that as a CheckError anyways. + // the analysis will propagate that as a StaticCheckError anyways. .ok() .flatten() .map(|x| { @@ -118,12 +118,12 @@ impl<'a> AnalysisDatabase<'a> { &mut self, contract_identifier: &QualifiedContractIdentifier, epoch: &StacksEpochId, - ) -> Result, CheckError> { + ) -> Result, StaticCheckError> { Ok(self .store .get_metadata(contract_identifier, AnalysisDatabase::storage_key()) // treat NoSuchContract error thrown by get_metadata as an Option::None -- - // the analysis will propagate that as a CheckError anyways. + // the analysis will propagate that as a StaticCheckError anyways. .ok() .flatten() .map(|x| { @@ -141,7 +141,7 @@ impl<'a> AnalysisDatabase<'a> { &mut self, contract_identifier: &QualifiedContractIdentifier, contract: &ContractAnalysis, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { let key = AnalysisDatabase::storage_key(); if self.store.has_metadata_entry(contract_identifier, key) { return Err(CheckErrors::ContractAlreadyExists(contract_identifier.to_string()).into()); @@ -156,7 +156,7 @@ impl<'a> AnalysisDatabase<'a> { pub fn get_clarity_version( &mut self, contract_identifier: &QualifiedContractIdentifier, - ) -> Result { + ) -> Result { // TODO: this function loads the whole contract to obtain the function type. // but it doesn't need to -- rather this information can just be // stored as its own entry. the analysis cost tracking currently only @@ -172,7 +172,7 @@ impl<'a> AnalysisDatabase<'a> { contract_identifier: &QualifiedContractIdentifier, function_name: &str, epoch: &StacksEpochId, - ) -> Result, CheckError> { + ) -> Result, StaticCheckError> { // TODO: this function loads the whole contract to obtain the function type. // but it doesn't need to -- rather this information can just be // stored as its own entry. the analysis cost tracking currently only @@ -190,7 +190,7 @@ impl<'a> AnalysisDatabase<'a> { contract_identifier: &QualifiedContractIdentifier, function_name: &str, epoch: &StacksEpochId, - ) -> Result, CheckError> { + ) -> Result, StaticCheckError> { // TODO: this function loads the whole contract to obtain the function type. // but it doesn't need to -- rather this information can just be // stored as its own entry. the analysis cost tracking currently only @@ -208,7 +208,7 @@ impl<'a> AnalysisDatabase<'a> { contract_identifier: &QualifiedContractIdentifier, trait_name: &str, epoch: &StacksEpochId, - ) -> Result>, CheckError> { + ) -> Result>, StaticCheckError> { // TODO: this function loads the whole contract to obtain the function type. // but it doesn't need to -- rather this information can just be // stored as its own entry. the analysis cost tracking currently only @@ -227,7 +227,7 @@ impl<'a> AnalysisDatabase<'a> { pub fn get_implemented_traits( &mut self, contract_identifier: &QualifiedContractIdentifier, - ) -> Result, CheckError> { + ) -> Result, StaticCheckError> { let contract = self .load_contract_non_canonical(contract_identifier)? .ok_or(CheckErrors::NoSuchContract(contract_identifier.to_string()))?; diff --git a/clarity/src/vm/analysis/arithmetic_checker/mod.rs b/clarity/src/vm/analysis/arithmetic_checker/mod.rs index 83be68ab23..df7d5ae33e 100644 --- a/clarity/src/vm/analysis/arithmetic_checker/mod.rs +++ b/clarity/src/vm/analysis/arithmetic_checker/mod.rs @@ -16,7 +16,9 @@ use clarity_types::representations::ClarityName; -pub use super::errors::{check_argument_count, check_arguments_at_least, CheckError, CheckErrors}; +pub use super::errors::{ + check_argument_count, check_arguments_at_least, CheckErrors, StaticCheckError, +}; use crate::vm::analysis::types::ContractAnalysis; use crate::vm::functions::define::{DefineFunctions, DefineFunctionsParsed}; use crate::vm::functions::NativeFunctions; diff --git a/clarity/src/vm/analysis/contract_interface_builder/mod.rs b/clarity/src/vm/analysis/contract_interface_builder/mod.rs index 26c71f695b..35b5869556 100644 --- a/clarity/src/vm/analysis/contract_interface_builder/mod.rs +++ b/clarity/src/vm/analysis/contract_interface_builder/mod.rs @@ -19,7 +19,7 @@ use std::collections::{BTreeMap, BTreeSet}; use stacks_common::types::StacksEpochId; use crate::vm::analysis::types::ContractAnalysis; -use crate::vm::analysis::CheckError; +use crate::vm::analysis::StaticCheckError; use crate::vm::types::signatures::CallableSubtype; use crate::vm::types::{ FixedFunction, FunctionArg, FunctionType, TupleTypeSignature, TypeSignature, @@ -28,7 +28,7 @@ use crate::vm::{CheckErrors, ClarityName, ClarityVersion}; pub fn build_contract_interface( contract_analysis: &ContractAnalysis, -) -> Result { +) -> Result { let mut contract_interface = ContractInterface::new(contract_analysis.epoch, contract_analysis.clarity_version); @@ -267,7 +267,7 @@ impl ContractInterfaceFunction { fn from_map( map: &BTreeMap, access: ContractInterfaceFunctionAccess, - ) -> Result, CheckError> { + ) -> Result, StaticCheckError> { map.iter() .map(|(name, function_type)| { Ok(ContractInterfaceFunction { @@ -400,7 +400,7 @@ impl ContractInterface { } } - pub fn serialize(&self) -> Result { + pub fn serialize(&self) -> Result { serde_json::to_string(self).map_err(|_| { CheckErrors::Expects("Failed to serialize contract interface".into()).into() }) diff --git a/clarity/src/vm/analysis/errors.rs b/clarity/src/vm/analysis/errors.rs index f7ce7072f3..ced9c8afff 100644 --- a/clarity/src/vm/analysis/errors.rs +++ b/clarity/src/vm/analysis/errors.rs @@ -15,6 +15,6 @@ // along with this program. If not, see . pub use clarity_types::errors::analysis::{ - check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckError, - CheckErrors, SyntaxBindingError, SyntaxBindingErrorType, + check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckErrors, + StaticCheckError, SyntaxBindingError, SyntaxBindingErrorType, }; diff --git a/clarity/src/vm/analysis/mod.rs b/clarity/src/vm/analysis/mod.rs index 404f468609..43f549ef8e 100644 --- a/clarity/src/vm/analysis/mod.rs +++ b/clarity/src/vm/analysis/mod.rs @@ -28,7 +28,7 @@ use stacks_common::types::StacksEpochId; pub use self::analysis_db::AnalysisDatabase; use self::arithmetic_checker::ArithmeticOnlyChecker; use self::contract_interface_builder::build_contract_interface; -pub use self::errors::{CheckError, CheckErrors}; +pub use self::errors::{CheckErrors, StaticCheckError}; use self::read_only_checker::ReadOnlyChecker; use self::trait_checker::TraitChecker; use self::type_checker::v2_05::TypeChecker as TypeChecker2_05; @@ -52,7 +52,7 @@ pub fn mem_type_check( snippet: &str, version: ClarityVersion, epoch: StacksEpochId, -) -> Result<(Option, ContractAnalysis), CheckError> { +) -> Result<(Option, ContractAnalysis), StaticCheckError> { let contract_identifier = QualifiedContractIdentifier::transient(); let contract = build_ast_with_rules( &contract_identifier, @@ -106,7 +106,7 @@ pub fn type_check( insert_contract: bool, epoch: &StacksEpochId, version: &ClarityVersion, -) -> Result { +) -> Result { run_analysis( contract_identifier, expressions, @@ -132,7 +132,7 @@ pub fn run_analysis( epoch: StacksEpochId, version: ClarityVersion, build_type_map: bool, -) -> Result> { +) -> Result> { let mut contract_analysis = ContractAnalysis::new( contract_identifier.clone(), expressions.to_vec(), diff --git a/clarity/src/vm/analysis/read_only_checker/mod.rs b/clarity/src/vm/analysis/read_only_checker/mod.rs index 21b2bbd8f7..52c3b6ef5b 100644 --- a/clarity/src/vm/analysis/read_only_checker/mod.rs +++ b/clarity/src/vm/analysis/read_only_checker/mod.rs @@ -21,7 +21,8 @@ use clarity_types::types::{PrincipalData, Value}; use stacks_common::types::StacksEpochId; pub use super::errors::{ - check_argument_count, check_arguments_at_least, CheckError, CheckErrors, SyntaxBindingError, + check_argument_count, check_arguments_at_least, CheckErrors, StaticCheckError, + SyntaxBindingError, }; use super::AnalysisDatabase; use crate::vm::analysis::types::{AnalysisPass, ContractAnalysis}; @@ -54,7 +55,7 @@ impl AnalysisPass for ReadOnlyChecker<'_, '_> { epoch: &StacksEpochId, contract_analysis: &mut ContractAnalysis, analysis_db: &mut AnalysisDatabase, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { let mut command = ReadOnlyChecker::new(analysis_db, epoch, &contract_analysis.clarity_version); command.run(contract_analysis)?; @@ -83,7 +84,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { /// # Errors /// - `CheckErrors::WriteAttemptedInReadOnly` /// - Contract parsing errors - pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), CheckError> { + pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), StaticCheckError> { // Iterate over all the top-level statements in a contract. for exp in contract_analysis.expressions.iter() { let mut result = self.check_top_level_expression(exp); @@ -110,7 +111,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { fn check_top_level_expression( &mut self, expression: &SymbolicExpression, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { use crate::vm::functions::define::DefineFunctionsParsed::*; if let Some(define_type) = DefineFunctionsParsed::try_parse(expression)? { match define_type { @@ -168,7 +169,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { &mut self, signature: &[SymbolicExpression], body: &SymbolicExpression, - ) -> Result<(ClarityName, bool), CheckError> { + ) -> Result<(ClarityName, bool), StaticCheckError> { let function_name = signature .first() .ok_or(CheckErrors::DefineFunctionBadSignature)? @@ -180,7 +181,10 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { Ok((function_name.clone(), is_read_only)) } - fn check_reads_only_valid(&mut self, expr: &SymbolicExpression) -> Result<(), CheckError> { + fn check_reads_only_valid( + &mut self, + expr: &SymbolicExpression, + ) -> Result<(), StaticCheckError> { use crate::vm::functions::define::DefineFunctionsParsed::*; if let Some(define_type) = DefineFunctionsParsed::try_parse(expr)? { match define_type { @@ -225,7 +229,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { /// (1) for whether or not they are valid with respect to read-only requirements. /// (2) if valid, returns whether or not they are read only. /// Note that because of (1), this function _cannot_ short-circuit on read-only. - fn check_read_only(&mut self, expr: &SymbolicExpression) -> Result { + fn check_read_only(&mut self, expr: &SymbolicExpression) -> Result { match expr.expr { AtomValue(_) | LiteralValue(_) | Atom(_) | TraitReference(_, _) | Field(_) => Ok(true), List(ref expression) => self.check_expression_application_is_read_only(expression), @@ -242,7 +246,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { fn check_each_expression_is_read_only( &mut self, expressions: &[SymbolicExpression], - ) -> Result { + ) -> Result { let mut result = true; for expression in expressions.iter() { let expr_read_only = self.check_read_only(expression)?; @@ -265,7 +269,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { &mut self, function: &str, args: &[SymbolicExpression], - ) -> Option> { + ) -> Option> { NativeFunctions::lookup_by_name_at_version(function, &self.clarity_version) .map(|function| self.check_native_function_is_read_only(&function, args)) } @@ -278,7 +282,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { &mut self, function: &NativeFunctions, args: &[SymbolicExpression], - ) -> Result { + ) -> Result { use crate::vm::functions::NativeFunctions::*; match function { @@ -331,13 +335,13 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { for (i, pair) in binding_list.iter().enumerate() { let pair_expression = pair.match_list().ok_or_else(|| { - CheckError::with_expression( + StaticCheckError::with_expression( SyntaxBindingError::let_binding_not_list(i).into(), pair, ) })?; if pair_expression.len() != 2 { - return Err(CheckError::with_expression( + return Err(StaticCheckError::with_expression( SyntaxBindingError::let_binding_invalid_length(i).into(), pair, )); @@ -379,13 +383,13 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { TupleCons => { for (i, pair) in args.iter().enumerate() { let pair_expression = pair.match_list().ok_or_else(|| { - CheckError::with_expression( + StaticCheckError::with_expression( SyntaxBindingError::tuple_cons_not_list(i).into(), pair, ) })?; if pair_expression.len() != 2 { - return Err(CheckError::with_expression( + return Err(StaticCheckError::with_expression( SyntaxBindingError::tuple_cons_invalid_length(i).into(), pair, )); @@ -421,7 +425,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { // As such dynamic dispatch is currently forbidden. false } - _ => return Err(CheckError::new(CheckErrors::ContractCallExpectName)), + _ => return Err(StaticCheckError::new(CheckErrors::ContractCallExpectName)), }; self.check_each_expression_is_read_only(&args[2..]) @@ -443,7 +447,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { fn check_expression_application_is_read_only( &mut self, expressions: &[SymbolicExpression], - ) -> Result { + ) -> Result { let (function_name, args) = expressions .split_first() .ok_or(CheckErrors::NonFunctionApplication)?; diff --git a/clarity/src/vm/analysis/trait_checker/mod.rs b/clarity/src/vm/analysis/trait_checker/mod.rs index 491fe81c24..0029cdc544 100644 --- a/clarity/src/vm/analysis/trait_checker/mod.rs +++ b/clarity/src/vm/analysis/trait_checker/mod.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::{CheckError, CheckErrors}; +use crate::vm::analysis::errors::{CheckErrors, StaticCheckError}; use crate::vm::analysis::types::{AnalysisPass, ContractAnalysis}; use crate::vm::analysis::AnalysisDatabase; @@ -28,7 +28,7 @@ impl AnalysisPass for TraitChecker { epoch: &StacksEpochId, contract_analysis: &mut ContractAnalysis, analysis_db: &mut AnalysisDatabase, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { let mut command = TraitChecker::new(epoch); command.run(contract_analysis, analysis_db)?; Ok(()) @@ -44,7 +44,7 @@ impl TraitChecker { &mut self, contract_analysis: &ContractAnalysis, analysis_db: &mut AnalysisDatabase, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { for trait_identifier in &contract_analysis.implemented_traits { let trait_name = trait_identifier.name.to_string(); let contract_defining_trait = analysis_db diff --git a/clarity/src/vm/analysis/trait_checker/tests.rs b/clarity/src/vm/analysis/trait_checker/tests.rs index 305781f959..fa7641a356 100644 --- a/clarity/src/vm/analysis/trait_checker/tests.rs +++ b/clarity/src/vm/analysis/trait_checker/tests.rs @@ -21,7 +21,7 @@ use rstest_reuse::{self, *}; use stacks_common::types::StacksEpochId; use crate::vm::analysis::errors::CheckErrors; -use crate::vm::analysis::{type_check, CheckError}; +use crate::vm::analysis::{type_check, StaticCheckError}; use crate::vm::ast::errors::ParseErrors; use crate::vm::ast::{build_ast, parse}; use crate::vm::database::MemoryBackingStore; @@ -1818,7 +1818,7 @@ fn test_trait_contract_not_found(#[case] version: ClarityVersion, #[case] epoch: &version, ) }) { - Err(CheckError { err, .. }) if version < ClarityVersion::Clarity2 => match *err { + Err(StaticCheckError { err, .. }) if version < ClarityVersion::Clarity2 => match *err { CheckErrors::NoSuchContract(contract) => { assert!(contract.ends_with(".trait-contract")) } diff --git a/clarity/src/vm/analysis/type_checker/contexts.rs b/clarity/src/vm/analysis/type_checker/contexts.rs index ddc34d8b8b..71c3b1fccc 100644 --- a/clarity/src/vm/analysis/type_checker/contexts.rs +++ b/clarity/src/vm/analysis/type_checker/contexts.rs @@ -18,7 +18,7 @@ use std::collections::{HashMap, HashSet}; use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::{CheckError, CheckErrors}; +use crate::vm::analysis::errors::{CheckErrors, StaticCheckError}; use crate::vm::types::signatures::CallableSubtype; use crate::vm::types::{TraitIdentifier, TypeSignature}; use crate::vm::{ClarityName, ClarityVersion, SymbolicExpression, MAX_CONTEXT_DEPTH}; @@ -64,18 +64,22 @@ impl TypeMap { &mut self, expr: &SymbolicExpression, type_sig: TypeSignature, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { match self.map { TypeMapDataType::Map(ref mut map) => { if map.insert(expr.id, type_sig).is_some() { - Err(CheckError::new(CheckErrors::TypeAlreadyAnnotatedFailure)) + Err(StaticCheckError::new( + CheckErrors::TypeAlreadyAnnotatedFailure, + )) } else { Ok(()) } } TypeMapDataType::Set(ref mut map) => { if !map.insert(expr.id) { - Err(CheckError::new(CheckErrors::TypeAlreadyAnnotatedFailure)) + Err(StaticCheckError::new( + CheckErrors::TypeAlreadyAnnotatedFailure, + )) } else { Ok(()) } @@ -103,9 +107,9 @@ impl TypingContext<'_> { } } - pub fn extend(&self) -> Result, CheckError> { + pub fn extend(&self) -> Result, StaticCheckError> { if self.depth >= MAX_CONTEXT_DEPTH { - Err(CheckError::new(CheckErrors::MaxContextDepthReached)) + Err(StaticCheckError::new(CheckErrors::MaxContextDepthReached)) } else { Ok(TypingContext { epoch: self.epoch, diff --git a/clarity/src/vm/analysis/type_checker/mod.rs b/clarity/src/vm/analysis/type_checker/mod.rs index d33c7c87e6..f813b83139 100644 --- a/clarity/src/vm/analysis/type_checker/mod.rs +++ b/clarity/src/vm/analysis/type_checker/mod.rs @@ -20,7 +20,7 @@ pub mod v2_1; use stacks_common::types::StacksEpochId; -use super::errors::{CheckError, CheckErrors}; +use super::errors::{CheckErrors, StaticCheckError}; pub use super::types::{AnalysisPass, ContractAnalysis}; use super::AnalysisDatabase; use crate::vm::costs::CostTracker; @@ -34,7 +34,7 @@ impl FunctionType { args: &[TypeSignature], epoch: StacksEpochId, clarity_version: ClarityVersion, - ) -> Result { + ) -> Result { match epoch { StacksEpochId::Epoch20 | StacksEpochId::Epoch2_05 => { self.check_args_2_05(accounting, args) @@ -60,7 +60,7 @@ impl FunctionType { func_args: &[Value], epoch: StacksEpochId, clarity_version: ClarityVersion, - ) -> Result { + ) -> Result { match epoch { StacksEpochId::Epoch20 | StacksEpochId::Epoch2_05 => { self.check_args_by_allowing_trait_cast_2_05(db, func_args) diff --git a/clarity/src/vm/analysis/type_checker/v2_05/contexts.rs b/clarity/src/vm/analysis/type_checker/v2_05/contexts.rs index d89baac36e..75bc0c5f7e 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/contexts.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/contexts.rs @@ -16,7 +16,7 @@ use std::collections::{BTreeMap, HashMap, HashSet}; -use crate::vm::analysis::errors::{CheckError, CheckErrors}; +use crate::vm::analysis::errors::{CheckErrors, StaticCheckError}; use crate::vm::analysis::types::ContractAnalysis; use crate::vm::representations::ClarityName; use crate::vm::types::signatures::FunctionSignature; @@ -57,7 +57,7 @@ impl ContractContext { } } - pub fn check_name_used(&self, name: &str) -> Result<(), CheckError> { + pub fn check_name_used(&self, name: &str) -> Result<(), StaticCheckError> { if self.variable_types.contains_key(name) || self.persisted_variable_types.contains_key(name) || self.private_function_types.contains_key(name) @@ -67,7 +67,7 @@ impl ContractContext { || self.traits.contains_key(name) || self.map_types.contains_key(name) { - Err(CheckError::new(CheckErrors::NameAlreadyUsed( + Err(StaticCheckError::new(CheckErrors::NameAlreadyUsed( name.to_string(), ))) } else { @@ -75,7 +75,7 @@ impl ContractContext { } } - fn check_function_type(&mut self, f_name: &str) -> Result<(), CheckError> { + fn check_function_type(&mut self, f_name: &str) -> Result<(), StaticCheckError> { self.check_name_used(f_name)?; Ok(()) } @@ -92,7 +92,7 @@ impl ContractContext { &mut self, name: ClarityName, func_type: FunctionType, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_function_type(&name)?; self.public_function_types.insert(name, func_type); Ok(()) @@ -102,7 +102,7 @@ impl ContractContext { &mut self, name: ClarityName, func_type: FunctionType, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_function_type(&name)?; self.read_only_function_types.insert(name, func_type); Ok(()) @@ -112,7 +112,7 @@ impl ContractContext { &mut self, name: ClarityName, func_type: FunctionType, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_function_type(&name)?; self.private_function_types.insert(name, func_type); Ok(()) @@ -122,7 +122,7 @@ impl ContractContext { &mut self, map_name: ClarityName, map_type: (TypeSignature, TypeSignature), - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_name_used(&map_name)?; self.map_types.insert(map_name, map_type); Ok(()) @@ -132,7 +132,7 @@ impl ContractContext { &mut self, const_name: ClarityName, var_type: TypeSignature, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_name_used(&const_name)?; self.variable_types.insert(const_name, var_type); Ok(()) @@ -142,13 +142,13 @@ impl ContractContext { &mut self, var_name: ClarityName, var_type: TypeSignature, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_name_used(&var_name)?; self.persisted_variable_types.insert(var_name, var_type); Ok(()) } - pub fn add_ft(&mut self, token_name: ClarityName) -> Result<(), CheckError> { + pub fn add_ft(&mut self, token_name: ClarityName) -> Result<(), StaticCheckError> { self.check_name_used(&token_name)?; self.fungible_tokens.insert(token_name); Ok(()) @@ -158,7 +158,7 @@ impl ContractContext { &mut self, token_name: ClarityName, token_type: TypeSignature, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_name_used(&token_name)?; self.non_fungible_tokens.insert(token_name, token_type); Ok(()) @@ -168,7 +168,7 @@ impl ContractContext { &mut self, trait_name: ClarityName, trait_signature: BTreeMap, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.traits.insert(trait_name, trait_signature); Ok(()) } @@ -176,7 +176,7 @@ impl ContractContext { pub fn add_implemented_trait( &mut self, trait_identifier: TraitIdentifier, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.implemented_traits.insert(trait_identifier); Ok(()) } diff --git a/clarity/src/vm/analysis/type_checker/v2_05/mod.rs b/clarity/src/vm/analysis/type_checker/v2_05/mod.rs index 31cf5140dd..76ea8eaeb9 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/mod.rs @@ -27,7 +27,8 @@ pub use self::natives::{SimpleNativeFunction, TypedNativeFunction}; use super::contexts::{TypeMap, TypingContext}; use super::ContractAnalysis; pub use crate::vm::analysis::errors::{ - check_argument_count, check_arguments_at_least, CheckError, CheckErrors, SyntaxBindingErrorType, + check_argument_count, check_arguments_at_least, CheckErrors, StaticCheckError, + SyntaxBindingErrorType, }; use crate::vm::analysis::AnalysisDatabase; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -114,7 +115,7 @@ impl TypeChecker<'_, '_> { contract_analysis: &mut ContractAnalysis, analysis_db: &mut AnalysisDatabase, build_type_map: bool, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { let cost_track = contract_analysis.take_contract_cost_tracker(); let mut command = TypeChecker::new(analysis_db, cost_track, build_type_map); // run the analysis, and replace the cost tracker whether or not the @@ -139,7 +140,7 @@ impl FunctionType { &self, accounting: &mut T, args: &[TypeSignature], - ) -> Result { + ) -> Result { match self { FunctionType::Variadic(expected_type, return_type) => { check_arguments_at_least(1, args)?; @@ -254,7 +255,7 @@ impl FunctionType { &self, db: &mut AnalysisDatabase, func_args: &[Value], - ) -> Result { + ) -> Result { let (expected_args, returns) = match self { FunctionType::Fixed(FixedFunction { args, returns }) => (args, returns), _ => return Err(CheckErrors::Expects("Unexpected function type".into()).into()), @@ -306,7 +307,7 @@ impl FunctionType { fn trait_type_size( trait_sig: &BTreeMap, -) -> Result { +) -> Result { let mut total_size = 0; for (_func_name, value) in trait_sig.iter() { total_size = total_size.cost_overflow_add(value.total_type_size()?)?; @@ -314,7 +315,7 @@ fn trait_type_size( Ok(total_size) } -fn type_reserved_variable(variable_name: &str) -> Result, CheckError> { +fn type_reserved_variable(variable_name: &str) -> Result, StaticCheckError> { if let Some(variable) = NativeVariables::lookup_by_name_at_version(variable_name, &ClarityVersion::Clarity1) { @@ -372,7 +373,10 @@ impl<'a, 'b> TypeChecker<'a, 'b> { self.cost_track } - pub fn track_return_type(&mut self, return_type: TypeSignature) -> Result<(), CheckError> { + pub fn track_return_type( + &mut self, + return_type: TypeSignature, + ) -> Result<(), StaticCheckError> { runtime_cost( ClarityCostFunction::AnalysisTypeCheck, self, @@ -407,7 +411,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { } } - pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), CheckError> { + pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), StaticCheckError> { // charge for the eventual storage cost of the analysis -- // it is linear in the size of the AST. let mut size: u64 = 0; @@ -449,7 +453,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { expr: &SymbolicExpression, context: &TypingContext, expected_type: &TypeSignature, - ) -> Result { + ) -> Result { if let ( LiteralValue(Value::Principal(PrincipalData::Contract(ref contract_identifier))), TypeSignature::TraitReferenceType(trait_identifier), @@ -489,7 +493,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { analysis_typecheck_cost(self, expected_type, &actual_type)?; if !expected_type.admits_type(&StacksEpochId::Epoch2_05, &actual_type)? { - let mut err: CheckError = + let mut err: StaticCheckError = CheckErrors::TypeError(Box::new(expected_type.clone()), Box::new(actual_type)) .into(); err.set_expression(expr); @@ -504,7 +508,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, expr: &SymbolicExpression, context: &TypingContext, - ) -> Result { + ) -> Result { runtime_cost(ClarityCostFunction::AnalysisVisit, self, 0)?; let mut result = self.inner_type_check(expr, context); @@ -522,12 +526,12 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, args: &[SymbolicExpression], context: &TypingContext, - ) -> Result { + ) -> Result { let mut types_returned = self.type_check_all(args, context)?; - let last_return = types_returned - .pop() - .ok_or(CheckError::new(CheckErrors::CheckerImplementationFailure))?; + let last_return = types_returned.pop().ok_or(StaticCheckError::new( + CheckErrors::CheckerImplementationFailure, + ))?; for type_return in types_returned.iter() { if type_return.is_response_type() { @@ -541,7 +545,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, args: &[SymbolicExpression], context: &TypingContext, - ) -> Result, CheckError> { + ) -> Result, StaticCheckError> { let mut result = Vec::with_capacity(args.len()); for arg in args.iter() { // don't use map here, since type_check has side-effects. @@ -555,7 +559,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { func_type: &FunctionType, args: &[SymbolicExpression], context: &TypingContext, - ) -> Result { + ) -> Result { let typed_args = self.type_check_all(args, context)?; func_type.check_args(self, &typed_args, context.epoch, context.clarity_version) } @@ -571,14 +575,14 @@ impl<'a, 'b> TypeChecker<'a, 'b> { signature: &[SymbolicExpression], body: &SymbolicExpression, context: &TypingContext, - ) -> Result<(ClarityName, FixedFunction), CheckError> { + ) -> Result<(ClarityName, FixedFunction), StaticCheckError> { let (function_name, args) = signature .split_first() .ok_or(CheckErrors::RequiresAtLeastArguments(1, 0))?; let function_name = function_name .match_atom() .ok_or(CheckErrors::BadFunctionName)?; - let args = parse_name_type_pairs::<(), CheckError>( + let args = parse_name_type_pairs::<(), StaticCheckError>( StacksEpochId::Epoch2_05, args, SyntaxBindingErrorType::Eval, @@ -661,7 +665,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { map_name: &ClarityName, key_type: &SymbolicExpression, value_type: &SymbolicExpression, - ) -> Result<(ClarityName, (TypeSignature, TypeSignature)), CheckError> { + ) -> Result<(ClarityName, (TypeSignature, TypeSignature)), StaticCheckError> { self.type_map.set_type(key_type, no_type())?; self.type_map.set_type(value_type, no_type())?; // should we set the type of the subexpressions of the signature to no-type as well? @@ -681,7 +685,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { function: &str, args: &[SymbolicExpression], context: &TypingContext, - ) -> Option> { + ) -> Option> { if let Some(ref native_function) = NativeFunctions::lookup_by_name_at_version(function, &ClarityVersion::Clarity1) { @@ -699,7 +703,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, expression: &[SymbolicExpression], context: &TypingContext, - ) -> Result { + ) -> Result { let (function_name, args) = expression .split_first() .ok_or(CheckErrors::NonFunctionApplication)?; @@ -730,7 +734,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, name: &str, context: &TypingContext, - ) -> Result { + ) -> Result { runtime_cost(ClarityCostFunction::AnalysisLookupVariableConst, self, 0)?; if let Some(type_result) = type_reserved_variable(name)? { @@ -765,7 +769,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, expr: &SymbolicExpression, context: &TypingContext, - ) -> Result { + ) -> Result { let type_sig = match expr.expr { AtomValue(ref value) | LiteralValue(ref value) => TypeSignature::type_of(value)?, Atom(ref name) => self.lookup_variable(name, context)?, @@ -789,7 +793,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { var_name: &ClarityName, var_type: &SymbolicExpression, context: &mut TypingContext, - ) -> Result<(ClarityName, TypeSignature), CheckError> { + ) -> Result<(ClarityName, TypeSignature), StaticCheckError> { let var_type = self.type_check(var_type, context)?; Ok((var_name.clone(), var_type)) } @@ -800,7 +804,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { var_type: &SymbolicExpression, initial: &SymbolicExpression, context: &mut TypingContext, - ) -> Result<(ClarityName, TypeSignature), CheckError> { + ) -> Result<(ClarityName, TypeSignature), StaticCheckError> { let expected_type = TypeSignature::parse_type_repr::<()>(StacksEpochId::Epoch2_05, var_type, &mut ()) .map_err(|_e| CheckErrors::DefineVariableBadSignature)?; @@ -815,7 +819,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { token_name: &ClarityName, bound: Option<&SymbolicExpression>, context: &mut TypingContext, - ) -> Result { + ) -> Result { if let Some(bound) = bound { self.type_check_expects(bound, context, &TypeSignature::UIntType)?; } @@ -828,7 +832,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { asset_name: &ClarityName, nft_type: &SymbolicExpression, _context: &mut TypingContext, - ) -> Result<(ClarityName, TypeSignature), CheckError> { + ) -> Result<(ClarityName, TypeSignature), StaticCheckError> { let asset_type = TypeSignature::parse_type_repr::<()>(StacksEpochId::Epoch2_05, nft_type, &mut ()) .map_err(|_| CheckErrors::DefineNFTBadSignature)?; @@ -841,7 +845,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { trait_name: &ClarityName, function_types: &[SymbolicExpression], _context: &mut TypingContext, - ) -> Result<(ClarityName, BTreeMap), CheckError> { + ) -> Result<(ClarityName, BTreeMap), StaticCheckError> { let trait_signature = TypeSignature::parse_trait_type_repr( function_types, &mut (), @@ -857,7 +861,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, expression: &SymbolicExpression, context: &mut TypingContext, - ) -> Result, CheckError> { + ) -> Result, StaticCheckError> { if let Some(define_type) = DefineFunctionsParsed::try_parse(expression)? { match define_type { DefineFunctionsParsed::Constant { name, value } => { diff --git a/clarity/src/vm/analysis/type_checker/v2_05/natives/assets.rs b/clarity/src/vm/analysis/type_checker/v2_05/natives/assets.rs index 13f967e6af..6f3d72c681 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/natives/assets.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/natives/assets.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . use super::{TypeChecker, TypingContext}; -use crate::vm::analysis::errors::{check_argument_count, CheckError, CheckErrors}; +use crate::vm::analysis::errors::{check_argument_count, CheckErrors, StaticCheckError}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::representations::SymbolicExpression; @@ -25,7 +25,7 @@ pub fn check_special_get_owner( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -53,7 +53,7 @@ pub fn check_special_get_balance( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -74,7 +74,7 @@ pub fn check_special_mint_asset( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -105,7 +105,7 @@ pub fn check_special_mint_token( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -132,7 +132,7 @@ pub fn check_special_transfer_asset( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(4, args)?; let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -164,7 +164,7 @@ pub fn check_special_transfer_token( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(4, args)?; let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -192,7 +192,7 @@ pub fn check_special_get_token_supply( checker: &mut TypeChecker, args: &[SymbolicExpression], _context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -210,7 +210,7 @@ pub fn check_special_burn_asset( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -241,7 +241,7 @@ pub fn check_special_burn_token( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; diff --git a/clarity/src/vm/analysis/type_checker/v2_05/natives/maps.rs b/clarity/src/vm/analysis/type_checker/v2_05/natives/maps.rs index ccbf880e17..0ff6aaf99a 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/natives/maps.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/natives/maps.rs @@ -17,7 +17,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::analysis::type_checker::v2_05::{ - check_arguments_at_least, CheckError, CheckErrors, TypeChecker, TypingContext, + check_arguments_at_least, CheckErrors, StaticCheckError, TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost}; @@ -28,7 +28,7 @@ pub fn check_special_fetch_entry( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; let map_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; @@ -55,7 +55,7 @@ pub fn check_special_fetch_entry( let option_type = TypeSignature::new_option(value_type.clone())?; if !expected_key_type.admits_type(&StacksEpochId::Epoch2_05, &key_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(StaticCheckError::new(CheckErrors::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) @@ -68,7 +68,7 @@ pub fn check_special_delete_entry( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; let map_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; @@ -88,7 +88,7 @@ pub fn check_special_delete_entry( analysis_typecheck_cost(&mut checker.cost_track, expected_key_type, &key_type)?; if !expected_key_type.admits_type(&StacksEpochId::Epoch2_05, &key_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(StaticCheckError::new(CheckErrors::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) @@ -101,7 +101,7 @@ fn check_set_or_insert_entry( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(3, args)?; let map_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; @@ -129,12 +129,12 @@ fn check_set_or_insert_entry( analysis_typecheck_cost(&mut checker.cost_track, expected_value_type, &value_type)?; if !expected_key_type.admits_type(&StacksEpochId::Epoch2_05, &key_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(StaticCheckError::new(CheckErrors::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) } else if !expected_value_type.admits_type(&StacksEpochId::Epoch2_05, &value_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(StaticCheckError::new(CheckErrors::TypeError( Box::new(expected_value_type.clone()), Box::new(value_type), ))) @@ -147,7 +147,7 @@ pub fn check_special_set_entry( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_set_or_insert_entry(checker, args, context) } @@ -155,6 +155,6 @@ pub fn check_special_insert_entry( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_set_or_insert_entry(checker, args, context) } diff --git a/clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs b/clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs index 08297f7440..e2a830abea 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs @@ -17,7 +17,7 @@ use stacks_common::types::StacksEpochId; use super::{check_argument_count, check_arguments_at_least, no_type, TypeChecker, TypingContext}; -use crate::vm::analysis::errors::{CheckError, CheckErrors, SyntaxBindingErrorType}; +use crate::vm::analysis::errors::{CheckErrors, StaticCheckError, SyntaxBindingErrorType}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost}; use crate::vm::diagnostic::DiagnosableError; @@ -45,7 +45,7 @@ pub struct SpecialNativeFunction( &mut TypeChecker, &[SymbolicExpression], &TypingContext, - ) -> Result, + ) -> Result, ); pub struct SimpleNativeFunction(pub FunctionType); @@ -53,7 +53,7 @@ fn check_special_list_cons( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { let typed_args = checker.type_check_all(args, context)?; for type_arg in typed_args.iter() { runtime_cost( @@ -70,7 +70,7 @@ fn check_special_print( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; checker.type_check(&args[0], context) } @@ -79,7 +79,7 @@ fn check_special_as_contract( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; checker.type_check(&args[0], context) } @@ -88,7 +88,7 @@ fn check_special_at_block( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; checker.type_check_expects(&args[0], context, &BUFF_32)?; checker.type_check(&args[1], context) @@ -98,7 +98,7 @@ fn check_special_begin( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(1, args)?; checker.type_check_consecutive_statements(args, context) @@ -108,7 +108,7 @@ fn inner_handle_tuple_get( tuple_type_sig: &TupleTypeSignature, field_to_get: &str, checker: &mut TypeChecker, -) -> Result { +) -> Result { runtime_cost( ClarityCostFunction::AnalysisCheckTupleGet, checker, @@ -117,7 +117,7 @@ fn inner_handle_tuple_get( let return_type = tuple_type_sig .field_type(field_to_get) - .ok_or(CheckError::new(CheckErrors::NoSuchTupleField( + .ok_or(StaticCheckError::new(CheckErrors::NoSuchTupleField( field_to_get.to_string(), tuple_type_sig.clone(), )))? @@ -129,7 +129,7 @@ fn check_special_get( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let field_to_get = args[0].match_atom().ok_or(CheckErrors::BadTupleFieldName)?; @@ -155,7 +155,7 @@ fn check_special_merge( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let res = checker.type_check(&args[0], context)?; @@ -183,7 +183,7 @@ pub fn check_special_tuple_cons( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(1, args)?; let len = args.len(); @@ -217,12 +217,12 @@ fn check_special_let( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; let binding_list = args[0] .match_list() - .ok_or(CheckError::new(CheckErrors::BadLetSyntax))?; + .ok_or(StaticCheckError::new(CheckErrors::BadLetSyntax))?; let mut out_context = context.extend()?; @@ -234,7 +234,7 @@ fn check_special_let( |var_name, var_sexp| { checker.contract_context.check_name_used(var_name)?; if out_context.lookup_variable_type(var_name).is_some() { - return Err(CheckError::new(CheckErrors::NameAlreadyUsed( + return Err(StaticCheckError::new(CheckErrors::NameAlreadyUsed( var_name.to_string(), ))); } @@ -260,17 +260,17 @@ fn check_special_fetch_var( checker: &mut TypeChecker, args: &[SymbolicExpression], _context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let var_name = args[0] .match_atom() - .ok_or(CheckError::new(CheckErrors::BadMapName))?; + .ok_or(StaticCheckError::new(CheckErrors::BadMapName))?; let value_type = checker .contract_context .get_persisted_variable_type(var_name) - .ok_or(CheckError::new(CheckErrors::NoSuchDataVariable( + .ok_or(StaticCheckError::new(CheckErrors::NoSuchDataVariable( var_name.to_string(), )))?; @@ -287,7 +287,7 @@ fn check_special_set_var( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; let var_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; @@ -307,7 +307,7 @@ fn check_special_set_var( analysis_typecheck_cost(&mut checker.cost_track, &value_type, expected_value_type)?; if !expected_value_type.admits_type(&StacksEpochId::Epoch2_05, &value_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(StaticCheckError::new(CheckErrors::TypeError( Box::new(expected_value_type.clone()), Box::new(value_type), ))) @@ -320,7 +320,7 @@ fn check_special_equals( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(1, args)?; let arg_types = checker.type_check_all(args, context)?; @@ -339,7 +339,7 @@ fn check_special_if( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; checker.type_check_expects(&args[0], context, &TypeSignature::BoolType)?; @@ -360,12 +360,12 @@ fn check_contract_call( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; let func_name = args[1] .match_atom() - .ok_or(CheckError::new(CheckErrors::ContractCallExpectName))?; + .ok_or(StaticCheckError::new(CheckErrors::ContractCallExpectName))?; checker.type_map.set_type(&args[1], no_type())?; let expected_sig = match &args[0].expr { @@ -389,7 +389,7 @@ fn check_contract_call( { Ok(function) } else { - Err(CheckError::new(CheckErrors::NoSuchPublicFunction( + Err(StaticCheckError::new(CheckErrors::NoSuchPublicFunction( contract_identifier.to_string(), func_name.to_string(), ))) @@ -438,7 +438,7 @@ fn check_contract_call( func_signature.clone() } - _ => return Err(CheckError::new(CheckErrors::ContractCallExpectName)), + _ => return Err(StaticCheckError::new(CheckErrors::ContractCallExpectName)), }; check_argument_count(expected_sig.args.len(), &args[2..])?; @@ -453,12 +453,12 @@ fn check_contract_of( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let trait_instance = match &args[0].expr { SymbolicExpressionType::Atom(trait_instance) => trait_instance, - _ => return Err(CheckError::new(CheckErrors::ContractOfExpectsTrait)), + _ => return Err(StaticCheckError::new(CheckErrors::ContractOfExpectsTrait)), }; let trait_id = match context.lookup_trait_reference_type(trait_instance) { @@ -480,7 +480,7 @@ fn check_principal_of( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; checker.type_check_expects(&args[0], context, &BUFF_33)?; Ok( @@ -493,7 +493,7 @@ fn check_secp256k1_recover( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; checker.type_check_expects(&args[0], context, &BUFF_32)?; checker.type_check_expects(&args[1], context, &BUFF_65)?; @@ -507,7 +507,7 @@ fn check_secp256k1_verify( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; checker.type_check_expects(&args[0], context, &BUFF_32)?; checker.type_check_expects(&args[1], context, &BUFF_65)?; @@ -519,18 +519,18 @@ fn check_get_block_info( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; - let block_info_prop_str = args[0] - .match_atom() - .ok_or(CheckError::new(CheckErrors::GetBlockInfoExpectPropertyName))?; + let block_info_prop_str = args[0].match_atom().ok_or(StaticCheckError::new( + CheckErrors::GetBlockInfoExpectPropertyName, + ))?; let block_info_prop = BlockInfoProperty::lookup_by_name_at_version( block_info_prop_str, &ClarityVersion::Clarity1, ) - .ok_or(CheckError::new(CheckErrors::NoSuchBlockInfoProperty( + .ok_or(StaticCheckError::new(CheckErrors::NoSuchBlockInfoProperty( block_info_prop_str.to_string(), )))?; @@ -545,7 +545,7 @@ impl TypedNativeFunction { checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, - ) -> Result { + ) -> Result { use self::TypedNativeFunction::{Simple, Special}; match self { Special(SpecialNativeFunction(check)) => check(checker, args, context), diff --git a/clarity/src/vm/analysis/type_checker/v2_05/natives/options.rs b/clarity/src/vm/analysis/type_checker/v2_05/natives/options.rs index 1cf9b301a7..c2ea1c72d5 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/natives/options.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/natives/options.rs @@ -19,8 +19,8 @@ use clarity_types::types::TypeSignature; use stacks_common::types::StacksEpochId; use crate::vm::analysis::type_checker::v2_05::{ - check_argument_count, check_arguments_at_least, no_type, CheckError, CheckErrors, TypeChecker, - TypingContext, + check_argument_count, check_arguments_at_least, no_type, CheckErrors, StaticCheckError, + TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost}; @@ -30,7 +30,7 @@ pub fn check_special_okay( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; runtime_cost(ClarityCostFunction::AnalysisOptionCons, checker, 0)?; @@ -44,7 +44,7 @@ pub fn check_special_some( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; runtime_cost(ClarityCostFunction::AnalysisOptionCons, checker, 0)?; @@ -58,7 +58,7 @@ pub fn check_special_error( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; runtime_cost(ClarityCostFunction::AnalysisOptionCons, checker, 0)?; @@ -72,7 +72,7 @@ pub fn check_special_is_response( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let input = checker.type_check(&args[0], context)?; @@ -90,7 +90,7 @@ pub fn check_special_is_optional( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let input = checker.type_check(&args[0], context)?; @@ -108,7 +108,7 @@ pub fn check_special_default_to( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let default = checker.type_check(&args[0], context)?; @@ -132,7 +132,7 @@ pub fn check_special_asserts( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; checker.type_check_expects(&args[0], context, &TypeSignature::BoolType)?; @@ -146,7 +146,7 @@ pub fn check_special_asserts( fn inner_unwrap( input: TypeSignature, checker: &mut TypeChecker, -) -> Result { +) -> Result { runtime_cost(ClarityCostFunction::AnalysisOptionCheck, checker, 0)?; match input { @@ -172,7 +172,7 @@ fn inner_unwrap( fn inner_unwrap_err( input: TypeSignature, checker: &mut TypeChecker, -) -> Result { +) -> Result { runtime_cost(ClarityCostFunction::AnalysisOptionCheck, checker, 0)?; if let TypeSignature::ResponseType(response_type) = input { @@ -191,7 +191,7 @@ pub fn check_special_unwrap_or_ret( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let input = checker.type_check(&args[0], context)?; @@ -206,7 +206,7 @@ pub fn check_special_unwrap_err_or_ret( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let input = checker.type_check(&args[0], context)?; @@ -221,7 +221,7 @@ pub fn check_special_try_ret( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let input = checker.type_check(&args[0], context)?; @@ -259,7 +259,7 @@ pub fn check_special_unwrap( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let input = checker.type_check(&args[0], context)?; @@ -271,7 +271,7 @@ pub fn check_special_unwrap_err( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let input = checker.type_check(&args[0], context)?; @@ -285,7 +285,7 @@ fn eval_with_new_binding( bind_type: TypeSignature, checker: &mut TypeChecker, context: &TypingContext, -) -> Result { +) -> Result { let mut inner_context = context.extend()?; runtime_cost( @@ -310,7 +310,7 @@ fn check_special_match_opt( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { if args.len() != 3 { Err(CheckErrors::BadMatchOptionSyntax(Box::new( CheckErrors::IncorrectArgumentCount(4, args.len() + 1), @@ -350,7 +350,7 @@ fn check_special_match_resp( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { if args.len() != 4 { Err(CheckErrors::BadMatchResponseSyntax(Box::new( CheckErrors::IncorrectArgumentCount(5, args.len() + 1), @@ -391,7 +391,7 @@ pub fn check_special_match( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(1, args)?; let input = checker.type_check(&args[0], context)?; diff --git a/clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs b/clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs index 00904bfe49..7a4ec829a8 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs @@ -18,7 +18,7 @@ use stacks_common::types::StacksEpochId; use super::{SimpleNativeFunction, TypedNativeFunction}; use crate::vm::analysis::type_checker::v2_05::{ - check_argument_count, check_arguments_at_least, CheckError, CheckErrors, TypeChecker, + check_argument_count, check_arguments_at_least, CheckErrors, StaticCheckError, TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -34,7 +34,7 @@ use crate::vm::ClarityVersion; fn get_simple_native_or_user_define( function_name: &str, checker: &mut TypeChecker, -) -> Result { +) -> Result { runtime_cost(ClarityCostFunction::AnalysisLookupFunction, checker, 0)?; if let Some(ref native_function) = NativeFunctions::lookup_by_name_at_version(function_name, &ClarityVersion::Clarity1) @@ -57,7 +57,7 @@ pub fn check_special_map( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; let function_name = args[0] @@ -114,7 +114,7 @@ pub fn check_special_filter( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let function_name = args[0] @@ -158,7 +158,7 @@ pub fn check_special_fold( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; let function_name = args[0] @@ -205,7 +205,7 @@ pub fn check_special_concat( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let lhs_type = checker.type_check(&args[0], context)?; @@ -270,7 +270,7 @@ pub fn check_special_append( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; runtime_cost(ClarityCostFunction::AnalysisIterableFunc, checker, 0)?; @@ -302,7 +302,7 @@ pub fn check_special_as_max_len( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let expected_len = match args[1].expr { @@ -359,7 +359,7 @@ pub fn check_special_len( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let collection_type = checker.type_check(&args[0], context)?; @@ -377,7 +377,7 @@ pub fn check_special_element_at( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let _index_type = checker.type_check_expects(&args[1], context, &TypeSignature::UIntType)?; @@ -413,7 +413,7 @@ pub fn check_special_index_of( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; runtime_cost(ClarityCostFunction::AnalysisIterableFunc, checker, 0)?; diff --git a/clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs b/clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs index 99fd0191ce..fba6b31e6f 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs @@ -16,7 +16,7 @@ use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::{CheckError, CheckErrors, SyntaxBindingError}; +use crate::vm::analysis::errors::{CheckErrors, StaticCheckError, SyntaxBindingError}; use crate::vm::analysis::mem_type_check; use crate::vm::ast::build_ast; use crate::vm::ast::errors::ParseErrors; @@ -31,7 +31,7 @@ use crate::vm::ClarityVersion; mod assets; mod contracts; -fn type_check_helper(exp: &str) -> Result { +fn type_check_helper(exp: &str) -> Result { mem_type_check(exp, ClarityVersion::Clarity1, StacksEpochId::Epoch2_05) .map(|(type_sig_opt, _)| type_sig_opt.unwrap()) } diff --git a/clarity/src/vm/analysis/type_checker/v2_1/contexts.rs b/clarity/src/vm/analysis/type_checker/v2_1/contexts.rs index 2d068554c3..642dc77325 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/contexts.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/contexts.rs @@ -16,7 +16,7 @@ use std::collections::{BTreeMap, HashMap, HashSet}; -use crate::vm::analysis::errors::{CheckError, CheckErrors}; +use crate::vm::analysis::errors::{CheckErrors, StaticCheckError}; use crate::vm::analysis::type_checker::is_reserved_word; use crate::vm::analysis::types::ContractAnalysis; use crate::vm::representations::ClarityName; @@ -61,7 +61,7 @@ impl TraitContext { contract_identifier: QualifiedContractIdentifier, trait_name: ClarityName, trait_signature: BTreeMap, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { match self { Self::Clarity1(map) => { map.insert(trait_name, trait_signature); @@ -85,7 +85,7 @@ impl TraitContext { alias: ClarityName, trait_id: TraitIdentifier, trait_signature: BTreeMap, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { match self { Self::Clarity1(map) => { map.insert(trait_id.name, trait_signature); @@ -169,9 +169,11 @@ impl ContractContext { &self.contract_identifier == other } - pub fn check_name_used(&self, name: &str) -> Result<(), CheckError> { + pub fn check_name_used(&self, name: &str) -> Result<(), StaticCheckError> { if is_reserved_word(name, self.clarity_version) { - return Err(CheckError::new(CheckErrors::ReservedWord(name.to_string()))); + return Err(StaticCheckError::new(CheckErrors::ReservedWord( + name.to_string(), + ))); } if self.variable_types.contains_key(name) @@ -183,7 +185,7 @@ impl ContractContext { || self.traits.is_name_used(name) || self.map_types.contains_key(name) { - Err(CheckError::new(CheckErrors::NameAlreadyUsed( + Err(StaticCheckError::new(CheckErrors::NameAlreadyUsed( name.to_string(), ))) } else { @@ -191,7 +193,7 @@ impl ContractContext { } } - fn check_function_type(&mut self, f_name: &str) -> Result<(), CheckError> { + fn check_function_type(&mut self, f_name: &str) -> Result<(), StaticCheckError> { self.check_name_used(f_name)?; Ok(()) } @@ -208,7 +210,7 @@ impl ContractContext { &mut self, name: ClarityName, func_type: FunctionType, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_function_type(&name)?; self.public_function_types.insert(name, func_type); Ok(()) @@ -218,7 +220,7 @@ impl ContractContext { &mut self, name: ClarityName, func_type: FunctionType, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_function_type(&name)?; self.read_only_function_types.insert(name, func_type); Ok(()) @@ -228,7 +230,7 @@ impl ContractContext { &mut self, name: ClarityName, func_type: FunctionType, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_function_type(&name)?; self.private_function_types.insert(name, func_type); Ok(()) @@ -238,7 +240,7 @@ impl ContractContext { &mut self, map_name: ClarityName, map_type: (TypeSignature, TypeSignature), - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_name_used(&map_name)?; self.map_types.insert(map_name, map_type); Ok(()) @@ -248,7 +250,7 @@ impl ContractContext { &mut self, const_name: ClarityName, var_type: TypeSignature, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_name_used(&const_name)?; self.variable_types.insert(const_name, var_type); Ok(()) @@ -258,13 +260,13 @@ impl ContractContext { &mut self, var_name: ClarityName, var_type: TypeSignature, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_name_used(&var_name)?; self.persisted_variable_types.insert(var_name, var_type); Ok(()) } - pub fn add_ft(&mut self, token_name: ClarityName) -> Result<(), CheckError> { + pub fn add_ft(&mut self, token_name: ClarityName) -> Result<(), StaticCheckError> { self.check_name_used(&token_name)?; self.fungible_tokens.insert(token_name); Ok(()) @@ -274,7 +276,7 @@ impl ContractContext { &mut self, token_name: ClarityName, token_type: TypeSignature, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.check_name_used(&token_name)?; self.non_fungible_tokens.insert(token_name, token_type); Ok(()) @@ -284,7 +286,7 @@ impl ContractContext { &mut self, trait_name: ClarityName, trait_signature: BTreeMap, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { if self.clarity_version >= ClarityVersion::Clarity3 { self.check_name_used(&trait_name)?; } @@ -301,7 +303,7 @@ impl ContractContext { alias: ClarityName, trait_id: TraitIdentifier, trait_signature: BTreeMap, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { if self.clarity_version >= ClarityVersion::Clarity3 { self.check_name_used(&alias)?; } @@ -312,7 +314,7 @@ impl ContractContext { pub fn add_implemented_trait( &mut self, trait_identifier: TraitIdentifier, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.implemented_traits.insert(trait_identifier); Ok(()) } diff --git a/clarity/src/vm/analysis/type_checker/v2_1/mod.rs b/clarity/src/vm/analysis/type_checker/v2_1/mod.rs index 131186958c..3845ab143e 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/mod.rs @@ -26,8 +26,8 @@ pub use self::natives::{SimpleNativeFunction, TypedNativeFunction}; use super::contexts::{TypeMap, TypingContext}; use super::ContractAnalysis; pub use crate::vm::analysis::errors::{ - check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckError, - CheckErrors, SyntaxBindingErrorType, + check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckErrors, + StaticCheckError, SyntaxBindingErrorType, }; use crate::vm::analysis::AnalysisDatabase; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -121,7 +121,7 @@ impl TypeChecker<'_, '_> { contract_analysis: &mut ContractAnalysis, analysis_db: &mut AnalysisDatabase, build_type_map: bool, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { let cost_track = contract_analysis.take_contract_cost_tracker(); let mut command = TypeChecker::new( epoch, @@ -179,7 +179,7 @@ impl FunctionType { accumulated_type: Option<&TypeSignature>, ) -> ( Option>, - Result, CheckError>, + Result, StaticCheckError>, ) { match self { // variadic stops checking cost at the first error... @@ -283,7 +283,7 @@ impl FunctionType { accounting: &mut T, args: &[TypeSignature], clarity_version: ClarityVersion, - ) -> Result { + ) -> Result { match self { FunctionType::Variadic(expected_type, return_type) => { check_arguments_at_least(1, args)?; @@ -466,7 +466,7 @@ impl FunctionType { value: &Value, depth: u8, clarity_version: ClarityVersion, - ) -> Result { + ) -> Result { if clarity_version >= ClarityVersion::Clarity2 { // In Clarity2, we recurse into complex data types self.clarity2_principal_to_callable_type(value, depth) @@ -488,7 +488,7 @@ impl FunctionType { &self, value: &Value, depth: u8, - ) -> Result { + ) -> Result { if depth > MAX_TYPE_DEPTH { return Err(CheckErrors::TypeSignatureTooDeep.into()); } @@ -557,7 +557,7 @@ impl FunctionType { db: &mut AnalysisDatabase, clarity_version: ClarityVersion, func_args: &[Value], - ) -> Result { + ) -> Result { let (expected_args, returns) = match self { FunctionType::Fixed(FixedFunction { args, returns }) => (args, returns), _ => return Err(CheckErrors::Expects("Unexpected function type".into()).into()), @@ -629,7 +629,7 @@ fn check_function_arg_signature( cost_tracker: &mut T, expected_sig: &FunctionArgSignature, actual_type: &TypeSignature, -) -> Result<(), CheckError> { +) -> Result<(), StaticCheckError> { match expected_sig { FunctionArgSignature::Single(expected_type) => { analysis_typecheck_cost(cost_tracker, expected_type, actual_type)?; @@ -717,7 +717,7 @@ pub fn clarity2_trait_check_trait_compliance( expected_trait_identifier: &TraitIdentifier, expected_trait: &BTreeMap, tracker: &mut T, -) -> Result<(), CheckError> { +) -> Result<(), StaticCheckError> { // Shortcut for the simple case when the two traits are the same. if actual_trait_identifier == expected_trait_identifier { return Ok(()); @@ -758,7 +758,7 @@ fn clarity2_inner_type_check_type( expected_type: &TypeSignature, depth: u8, tracker: &mut T, -) -> Result { +) -> Result { if depth > MAX_TYPE_DEPTH { return Err(CheckErrors::TypeSignatureTooDeep.into()); } @@ -937,7 +937,7 @@ fn clarity2_lookup_trait( contract_context: Option<&ContractContext>, trait_id: &TraitIdentifier, tracker: &mut T, -) -> Result, CheckError> { +) -> Result, StaticCheckError> { if let Some(contract_context) = contract_context { // If the trait is from this contract, then it must be in the context or it doesn't exist. if contract_context.is_contract(&trait_id.contract_identifier) { @@ -985,7 +985,7 @@ fn clarity2_lookup_trait( fn trait_type_size( trait_sig: &BTreeMap, -) -> Result { +) -> Result { let mut total_size = 0; for (_func_name, value) in trait_sig.iter() { total_size = total_size.cost_overflow_add(value.total_type_size()?)?; @@ -993,7 +993,7 @@ fn trait_type_size( Ok(total_size) } -fn contract_analysis_size(contract: &ContractAnalysis) -> Result { +fn contract_analysis_size(contract: &ContractAnalysis) -> Result { let mut total_size = contract.public_function_types.len() as u64; total_size = total_size.cost_overflow_add(contract.read_only_function_types.len() as u64)?; Ok(total_size) @@ -1002,7 +1002,7 @@ fn contract_analysis_size(contract: &ContractAnalysis) -> Result Result, CheckError> { +) -> Result, StaticCheckError> { if let Some(variable) = NativeVariables::lookup_by_name_at_version(variable_name, version) { use crate::vm::variables::NativeVariables::*; let var_type = match variable { @@ -1065,7 +1065,10 @@ impl<'a, 'b> TypeChecker<'a, 'b> { self.cost_track } - pub fn track_return_type(&mut self, return_type: TypeSignature) -> Result<(), CheckError> { + pub fn track_return_type( + &mut self, + return_type: TypeSignature, + ) -> Result<(), StaticCheckError> { runtime_cost( ClarityCostFunction::AnalysisTypeCheck, self, @@ -1100,7 +1103,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { } } - pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), CheckError> { + pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), StaticCheckError> { // charge for the eventual storage cost of the analysis -- // it is linear in the size of the AST. let mut size: u64 = 0; @@ -1141,7 +1144,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { expr: &SymbolicExpression, context: &TypingContext, expected_type: &TypeSignature, - ) -> Result { + ) -> Result { // Clarity 2 allows traits embedded in compound types and allows // implicit casts between compatible traits, while Clarity 1 does not. if self.clarity_version >= ClarityVersion::Clarity2 { @@ -1162,7 +1165,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, expr: &SymbolicExpression, context: &TypingContext, - ) -> Result { + ) -> Result { runtime_cost(ClarityCostFunction::AnalysisVisit, self, 0)?; let mut result = self.inner_type_check(expr, context); @@ -1180,7 +1183,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, args: &[SymbolicExpression], context: &TypingContext, - ) -> Result { + ) -> Result { let mut last_return = None; let mut return_failure = Ok(()); for ix in 0..args.len() { @@ -1195,7 +1198,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { } let last_return = last_return - .ok_or_else(|| CheckError::new(CheckErrors::CheckerImplementationFailure))?; + .ok_or_else(|| StaticCheckError::new(CheckErrors::CheckerImplementationFailure))?; return_failure?; Ok(last_return) @@ -1205,7 +1208,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, args: &[SymbolicExpression], context: &TypingContext, - ) -> Result, CheckError> { + ) -> Result, StaticCheckError> { let mut result = Vec::with_capacity(args.len()); for arg in args.iter() { // don't use map here, since type_check has side-effects. @@ -1221,7 +1224,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { context: &TypingContext, epoch: StacksEpochId, clarity_version: ClarityVersion, - ) -> Result { + ) -> Result { if epoch <= StacksEpochId::Epoch2_05 { let typed_args = self.type_check_all(args, context)?; return func_type.check_args(self, &typed_args, epoch, clarity_version); @@ -1287,14 +1290,14 @@ impl<'a, 'b> TypeChecker<'a, 'b> { signature: &[SymbolicExpression], body: &SymbolicExpression, context: &TypingContext, - ) -> Result<(ClarityName, FixedFunction), CheckError> { + ) -> Result<(ClarityName, FixedFunction), StaticCheckError> { let (function_name, args) = signature .split_first() .ok_or(CheckErrors::RequiresAtLeastArguments(1, 0))?; let function_name = function_name .match_atom() .ok_or(CheckErrors::BadFunctionName)?; - let args = parse_name_type_pairs::<(), CheckError>( + let args = parse_name_type_pairs::<(), StaticCheckError>( StacksEpochId::Epoch21, args, SyntaxBindingErrorType::Eval, @@ -1392,7 +1395,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { map_name: &ClarityName, key_type: &SymbolicExpression, value_type: &SymbolicExpression, - ) -> Result<(ClarityName, (TypeSignature, TypeSignature)), CheckError> { + ) -> Result<(ClarityName, (TypeSignature, TypeSignature)), StaticCheckError> { self.type_map.set_type(key_type, no_type())?; self.type_map.set_type(value_type, no_type())?; // should we set the type of the subexpressions of the signature to no-type as well? @@ -1412,7 +1415,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { function: &str, args: &[SymbolicExpression], context: &TypingContext, - ) -> Option> { + ) -> Option> { if let Some(ref native_function) = NativeFunctions::lookup_by_name_at_version(function, &self.clarity_version) { @@ -1430,7 +1433,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, expression: &[SymbolicExpression], context: &TypingContext, - ) -> Result { + ) -> Result { let (function_name, args) = expression .split_first() .ok_or(CheckErrors::NonFunctionApplication)?; @@ -1461,7 +1464,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, name: &str, context: &TypingContext, - ) -> Result { + ) -> Result { runtime_cost(ClarityCostFunction::AnalysisLookupVariableConst, self, 0)?; if let Some(type_result) = type_reserved_variable(name, &self.clarity_version)? { @@ -1499,7 +1502,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { expr: &SymbolicExpression, context: &TypingContext, expected_type: &TypeSignature, - ) -> Result { + ) -> Result { if let ( LiteralValue(Value::Principal(PrincipalData::Contract(ref contract_identifier))), TypeSignature::CallableType(CallableSubtype::Trait(trait_identifier)), @@ -1539,7 +1542,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { analysis_typecheck_cost(self, expected_type, &actual_type)?; if !expected_type.admits_type(&StacksEpochId::Epoch21, &actual_type)? { - let mut err: CheckError = CheckErrors::TypeError( + let mut err: StaticCheckError = CheckErrors::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -1556,7 +1559,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { expr: &SymbolicExpression, context: &TypingContext, expected_type: &TypeSignature, - ) -> Result { + ) -> Result { let mut expr_type = match expr.expr { AtomValue(ref value) => TypeSignature::type_of(value)?, LiteralValue(ref value) => TypeSignature::literal_type_of(value)?, @@ -1594,7 +1597,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, expr: &SymbolicExpression, context: &TypingContext, - ) -> Result { + ) -> Result { let expr_type = match expr.expr { AtomValue(ref value) => TypeSignature::type_of(value)?, LiteralValue(ref value) => TypeSignature::literal_type_of(value)?, @@ -1619,7 +1622,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { var_name: &ClarityName, var_type: &SymbolicExpression, context: &mut TypingContext, - ) -> Result<(ClarityName, TypeSignature), CheckError> { + ) -> Result<(ClarityName, TypeSignature), StaticCheckError> { let var_type = self.type_check(var_type, context)?; Ok((var_name.clone(), var_type)) } @@ -1630,7 +1633,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { var_type: &SymbolicExpression, initial: &SymbolicExpression, context: &mut TypingContext, - ) -> Result<(ClarityName, TypeSignature), CheckError> { + ) -> Result<(ClarityName, TypeSignature), StaticCheckError> { let expected_type = TypeSignature::parse_type_repr::<()>(StacksEpochId::Epoch21, var_type, &mut ()) .map_err(|_e| CheckErrors::DefineVariableBadSignature)?; @@ -1645,7 +1648,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { token_name: &ClarityName, bound: Option<&SymbolicExpression>, context: &mut TypingContext, - ) -> Result { + ) -> Result { if let Some(bound) = bound { self.type_check_expects(bound, context, &TypeSignature::UIntType)?; } @@ -1658,7 +1661,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { asset_name: &ClarityName, nft_type: &SymbolicExpression, _context: &mut TypingContext, - ) -> Result<(ClarityName, TypeSignature), CheckError> { + ) -> Result<(ClarityName, TypeSignature), StaticCheckError> { let asset_type = TypeSignature::parse_type_repr::<()>(StacksEpochId::Epoch21, nft_type, &mut ()) .map_err(|_| CheckErrors::DefineNFTBadSignature)?; @@ -1671,7 +1674,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { trait_name: &ClarityName, function_types: &[SymbolicExpression], _context: &mut TypingContext, - ) -> Result<(ClarityName, BTreeMap), CheckError> { + ) -> Result<(ClarityName, BTreeMap), StaticCheckError> { let trait_signature = TypeSignature::parse_trait_type_repr( function_types, &mut (), @@ -1687,7 +1690,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &mut self, expression: &SymbolicExpression, context: &mut TypingContext, - ) -> Result, CheckError> { + ) -> Result, StaticCheckError> { if let Some(define_type) = DefineFunctionsParsed::try_parse(expression)? { match define_type { DefineFunctionsParsed::Constant { name, value } => { diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/assets.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/assets.rs index fbd2e251c4..a428d3f507 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/assets.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/assets.rs @@ -17,7 +17,7 @@ use stacks_common::consts::TOKEN_TRANSFER_MEMO_LENGTH; use super::{TypeChecker, TypingContext}; -use crate::vm::analysis::errors::{check_argument_count, CheckError, CheckErrors}; +use crate::vm::analysis::errors::{check_argument_count, CheckErrors, StaticCheckError}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::representations::SymbolicExpression; @@ -27,7 +27,7 @@ pub fn check_special_get_owner( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -55,7 +55,7 @@ pub fn check_special_get_balance( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -76,7 +76,7 @@ pub fn check_special_mint_asset( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -107,7 +107,7 @@ pub fn check_special_mint_token( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -134,7 +134,7 @@ pub fn check_special_transfer_asset( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(4, args)?; let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -166,7 +166,7 @@ pub fn check_special_transfer_token( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(4, args)?; let token_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -194,7 +194,7 @@ pub fn check_special_stx_transfer( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; let amount_type: TypeSignature = TypeSignature::UIntType; @@ -217,7 +217,7 @@ pub fn check_special_stx_transfer_memo( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(4, args)?; let amount_type: TypeSignature = TypeSignature::UIntType; @@ -245,7 +245,7 @@ pub fn check_special_get_token_supply( checker: &mut TypeChecker, args: &[SymbolicExpression], _context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -263,7 +263,7 @@ pub fn check_special_burn_asset( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; @@ -294,7 +294,7 @@ pub fn check_special_burn_token( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; let asset_name = args[0].match_atom().ok_or(CheckErrors::BadTokenName)?; diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/conversions.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/conversions.rs index 88f5470d53..f41702d56c 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/conversions.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/conversions.rs @@ -3,7 +3,7 @@ use stacks_common::types::StacksEpochId; use super::TypeChecker; use crate::vm::analysis::read_only_checker::check_argument_count; use crate::vm::analysis::type_checker::contexts::TypingContext; -use crate::vm::analysis::CheckError; +use crate::vm::analysis::StaticCheckError; use crate::vm::types::{BufferLength, SequenceSubtype, TypeSignature, TypeSignatureExt as _}; use crate::vm::SymbolicExpression; @@ -16,14 +16,14 @@ pub fn check_special_to_consensus_buff( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let input_type = checker.type_check(&args[0], context)?; let buffer_max_len = BufferLength::try_from(input_type.max_serialized_size()?)?; TypeSignature::new_option(TypeSignature::SequenceType(SequenceSubtype::BufferType( buffer_max_len, ))) - .map_err(CheckError::from) + .map_err(StaticCheckError::from) } /// `from-consensus-buff?` admits exactly two arguments: @@ -35,9 +35,9 @@ pub fn check_special_from_consensus_buff( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let result_type = TypeSignature::parse_type_repr(StacksEpochId::Epoch21, &args[0], checker)?; checker.type_check_expects(&args[1], context, &TypeSignature::max_buffer()?)?; - TypeSignature::new_option(result_type).map_err(CheckError::from) + TypeSignature::new_option(result_type).map_err(StaticCheckError::from) } diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/maps.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/maps.rs index 2dbc240798..d3bea2343b 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/maps.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/maps.rs @@ -17,7 +17,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::analysis::type_checker::v2_1::{ - check_arguments_at_least, CheckError, CheckErrors, TypeChecker, TypingContext, + check_arguments_at_least, CheckErrors, StaticCheckError, TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost}; @@ -28,7 +28,7 @@ pub fn check_special_fetch_entry( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; let map_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; @@ -55,7 +55,7 @@ pub fn check_special_fetch_entry( let option_type = TypeSignature::new_option(value_type.clone())?; if !expected_key_type.admits_type(&StacksEpochId::Epoch21, &key_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(StaticCheckError::new(CheckErrors::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) @@ -68,7 +68,7 @@ pub fn check_special_delete_entry( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; let map_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; @@ -88,7 +88,7 @@ pub fn check_special_delete_entry( analysis_typecheck_cost(&mut checker.cost_track, expected_key_type, &key_type)?; if !expected_key_type.admits_type(&StacksEpochId::Epoch21, &key_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(StaticCheckError::new(CheckErrors::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) @@ -101,7 +101,7 @@ fn check_set_or_insert_entry( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(3, args)?; let map_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; @@ -129,12 +129,12 @@ fn check_set_or_insert_entry( analysis_typecheck_cost(&mut checker.cost_track, expected_value_type, &value_type)?; if !expected_key_type.admits_type(&StacksEpochId::Epoch21, &key_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(StaticCheckError::new(CheckErrors::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) } else if !expected_value_type.admits_type(&StacksEpochId::Epoch21, &value_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(StaticCheckError::new(CheckErrors::TypeError( Box::new(expected_value_type.clone()), Box::new(value_type), ))) @@ -147,7 +147,7 @@ pub fn check_special_set_entry( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_set_or_insert_entry(checker, args, context) } @@ -155,6 +155,6 @@ pub fn check_special_insert_entry( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_set_or_insert_entry(checker, args, context) } diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/mod.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/mod.rs index 161e6a5689..75ff9d8582 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/mod.rs @@ -20,7 +20,7 @@ use super::{ check_argument_count, check_arguments_at_least, check_arguments_at_most, compute_typecheck_cost, no_type, TypeChecker, TypingContext, }; -use crate::vm::analysis::errors::{CheckError, CheckErrors, SyntaxBindingErrorType}; +use crate::vm::analysis::errors::{CheckErrors, StaticCheckError, SyntaxBindingErrorType}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost, CostErrors, CostTracker}; use crate::vm::diagnostic::DiagnosableError; @@ -55,7 +55,7 @@ pub struct SpecialNativeFunction( &mut TypeChecker, &[SymbolicExpression], &TypingContext, - ) -> Result, + ) -> Result, ); pub struct SimpleNativeFunction(pub FunctionType); @@ -63,7 +63,7 @@ fn check_special_list_cons( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { let mut result = Vec::with_capacity(args.len()); let mut entries_size: Option = Some(0); let mut costs = Vec::with_capacity(args.len()); @@ -110,7 +110,7 @@ fn check_special_print( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; checker.type_check(&args[0], context) } @@ -119,7 +119,7 @@ fn check_special_as_contract( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; checker.type_check(&args[0], context) } @@ -128,7 +128,7 @@ fn check_special_at_block( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; checker.type_check_expects(&args[0], context, &BUFF_32)?; checker.type_check(&args[1], context) @@ -138,7 +138,7 @@ fn check_special_begin( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(1, args)?; checker.type_check_consecutive_statements(args, context) @@ -148,7 +148,7 @@ fn inner_handle_tuple_get( tuple_type_sig: &TupleTypeSignature, field_to_get: &str, checker: &mut TypeChecker, -) -> Result { +) -> Result { runtime_cost( ClarityCostFunction::AnalysisCheckTupleGet, checker, @@ -157,7 +157,7 @@ fn inner_handle_tuple_get( let return_type = tuple_type_sig .field_type(field_to_get) - .ok_or(CheckError::new(CheckErrors::NoSuchTupleField( + .ok_or(StaticCheckError::new(CheckErrors::NoSuchTupleField( field_to_get.to_string(), tuple_type_sig.clone(), )))? @@ -169,7 +169,7 @@ fn check_special_get( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let field_to_get = args[0].match_atom().ok_or(CheckErrors::BadTupleFieldName)?; @@ -195,7 +195,7 @@ fn check_special_merge( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let res = checker.type_check(&args[0], context)?; @@ -223,7 +223,7 @@ pub fn check_special_tuple_cons( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(1, args)?; let mut tuple_type_data = Vec::with_capacity(args.len()); @@ -276,12 +276,12 @@ fn check_special_let( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; let binding_list = args[0] .match_list() - .ok_or(CheckError::new(CheckErrors::BadLetSyntax))?; + .ok_or(StaticCheckError::new(CheckErrors::BadLetSyntax))?; let mut out_context = context.extend()?; @@ -294,7 +294,7 @@ fn check_special_let( |var_name, var_sexp| { checker.contract_context.check_name_used(var_name)?; if out_context.lookup_variable_type(var_name).is_some() { - return Err(CheckError::new(CheckErrors::NameAlreadyUsed( + return Err(StaticCheckError::new(CheckErrors::NameAlreadyUsed( var_name.to_string(), ))); } @@ -331,17 +331,17 @@ fn check_special_fetch_var( checker: &mut TypeChecker, args: &[SymbolicExpression], _context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let var_name = args[0] .match_atom() - .ok_or(CheckError::new(CheckErrors::BadMapName))?; + .ok_or(StaticCheckError::new(CheckErrors::BadMapName))?; let value_type = checker .contract_context .get_persisted_variable_type(var_name) - .ok_or(CheckError::new(CheckErrors::NoSuchDataVariable( + .ok_or(StaticCheckError::new(CheckErrors::NoSuchDataVariable( var_name.to_string(), )))?; @@ -358,7 +358,7 @@ fn check_special_set_var( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; let var_name = args[0].match_atom().ok_or(CheckErrors::BadMapName)?; @@ -378,7 +378,7 @@ fn check_special_set_var( analysis_typecheck_cost(&mut checker.cost_track, &value_type, expected_value_type)?; if !expected_value_type.admits_type(&StacksEpochId::Epoch21, &value_type)? { - Err(CheckError::new(CheckErrors::TypeError( + Err(StaticCheckError::new(CheckErrors::TypeError( Box::new(expected_value_type.clone()), Box::new(value_type), ))) @@ -391,7 +391,7 @@ fn check_special_equals( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(1, args)?; let mut arg_type = None; @@ -428,7 +428,7 @@ fn check_special_if( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; checker.type_check_expects(&args[0], context, &TypeSignature::BoolType)?; @@ -451,12 +451,12 @@ fn check_contract_call( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; let func_name = args[1] .match_atom() - .ok_or(CheckError::new(CheckErrors::ContractCallExpectName))?; + .ok_or(StaticCheckError::new(CheckErrors::ContractCallExpectName))?; checker.type_map.set_type(&args[1], no_type())?; let expected_sig = match &args[0].expr { @@ -480,7 +480,7 @@ fn check_contract_call( { Ok(function) } else { - Err(CheckError::new(CheckErrors::NoSuchPublicFunction( + Err(StaticCheckError::new(CheckErrors::NoSuchPublicFunction( contract_identifier.to_string(), func_name.to_string(), ))) @@ -554,7 +554,7 @@ fn check_contract_call( { Ok(function) } else { - Err(CheckError::new(CheckErrors::NoSuchPublicFunction( + Err(StaticCheckError::new(CheckErrors::NoSuchPublicFunction( contract_identifier.to_string(), func_name.to_string(), ))) @@ -612,7 +612,7 @@ fn check_contract_call( } } } - _ => return Err(CheckError::new(CheckErrors::ContractCallExpectName)), + _ => return Err(StaticCheckError::new(CheckErrors::ContractCallExpectName)), }; check_argument_count(expected_sig.args.len(), &args[2..])?; @@ -627,12 +627,12 @@ fn check_contract_of( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let trait_instance = match &args[0].expr { SymbolicExpressionType::Atom(trait_instance) => trait_instance, - _ => return Err(CheckError::new(CheckErrors::ContractOfExpectsTrait)), + _ => return Err(StaticCheckError::new(CheckErrors::ContractOfExpectsTrait)), }; let trait_id = match context.lookup_trait_reference_type(trait_instance) { @@ -654,7 +654,7 @@ fn check_principal_of( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; checker.type_check_expects(&args[0], context, &BUFF_33)?; Ok( @@ -673,7 +673,7 @@ fn check_principal_construct( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; check_arguments_at_most(3, args)?; checker.type_check_expects(&args[0], context, &BUFF_1)?; @@ -705,7 +705,7 @@ fn check_secp256k1_recover( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; checker.type_check_expects(&args[0], context, &BUFF_32)?; checker.type_check_expects(&args[1], context, &BUFF_65)?; @@ -719,7 +719,7 @@ fn check_secp256k1_verify( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; checker.type_check_expects(&args[0], context, &BUFF_32)?; checker.type_check_expects(&args[1], context, &BUFF_65)?; @@ -731,16 +731,16 @@ fn check_get_block_info( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; - let block_info_prop_str = args[0] - .match_atom() - .ok_or(CheckError::new(CheckErrors::GetBlockInfoExpectPropertyName))?; + let block_info_prop_str = args[0].match_atom().ok_or(StaticCheckError::new( + CheckErrors::GetBlockInfoExpectPropertyName, + ))?; let block_info_prop = BlockInfoProperty::lookup_by_name_at_version(block_info_prop_str, &checker.clarity_version) - .ok_or(CheckError::new(CheckErrors::NoSuchBlockInfoProperty( + .ok_or(StaticCheckError::new(CheckErrors::NoSuchBlockInfoProperty( block_info_prop_str.to_string(), )))?; @@ -756,15 +756,15 @@ fn check_get_burn_block_info( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; - let block_info_prop_str = args[0].match_atom().ok_or(CheckError::new( + let block_info_prop_str = args[0].match_atom().ok_or(StaticCheckError::new( CheckErrors::GetBurnBlockInfoExpectPropertyName, ))?; let block_info_prop = - BurnBlockInfoProperty::lookup_by_name(block_info_prop_str).ok_or(CheckError::new( + BurnBlockInfoProperty::lookup_by_name(block_info_prop_str).ok_or(StaticCheckError::new( CheckErrors::NoSuchBlockInfoProperty(block_info_prop_str.to_string()), ))?; @@ -781,17 +781,18 @@ fn check_get_stacks_block_info( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; - let block_info_prop_str = args[0].match_atom().ok_or(CheckError::new( + let block_info_prop_str = args[0].match_atom().ok_or(StaticCheckError::new( CheckErrors::GetStacksBlockInfoExpectPropertyName, ))?; - let block_info_prop = - StacksBlockInfoProperty::lookup_by_name(block_info_prop_str).ok_or(CheckError::new( - CheckErrors::NoSuchStacksBlockInfoProperty(block_info_prop_str.to_string()), - ))?; + let block_info_prop = StacksBlockInfoProperty::lookup_by_name(block_info_prop_str).ok_or( + StaticCheckError::new(CheckErrors::NoSuchStacksBlockInfoProperty( + block_info_prop_str.to_string(), + )), + )?; checker.type_check_expects(&args[1], context, &TypeSignature::UIntType)?; @@ -802,15 +803,15 @@ fn check_get_tenure_info( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; - let block_info_prop_str = args[0].match_atom().ok_or(CheckError::new( + let block_info_prop_str = args[0].match_atom().ok_or(StaticCheckError::new( CheckErrors::GetTenureInfoExpectPropertyName, ))?; let block_info_prop = - TenureInfoProperty::lookup_by_name(block_info_prop_str).ok_or(CheckError::new( + TenureInfoProperty::lookup_by_name(block_info_prop_str).ok_or(StaticCheckError::new( CheckErrors::NoSuchTenureInfoProperty(block_info_prop_str.to_string()), ))?; @@ -825,7 +826,7 @@ impl TypedNativeFunction { checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, - ) -> Result { + ) -> Result { use self::TypedNativeFunction::{Simple, Special}; match self { Special(SpecialNativeFunction(check)) => check(checker, args, context), diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/options.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/options.rs index 56d145298a..bd3dbf785c 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/options.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/options.rs @@ -19,7 +19,8 @@ use clarity_types::types::TypeSignature; use stacks_common::types::StacksEpochId; use super::{ - check_argument_count, check_arguments_at_least, no_type, CheckError, CheckErrors, TypeChecker, + check_argument_count, check_arguments_at_least, no_type, CheckErrors, StaticCheckError, + TypeChecker, }; use crate::vm::analysis::type_checker::contexts::TypingContext; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -30,7 +31,7 @@ pub fn check_special_okay( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; runtime_cost(ClarityCostFunction::AnalysisOptionCons, checker, 0)?; @@ -44,7 +45,7 @@ pub fn check_special_some( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; runtime_cost(ClarityCostFunction::AnalysisOptionCons, checker, 0)?; @@ -58,7 +59,7 @@ pub fn check_special_error( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; runtime_cost(ClarityCostFunction::AnalysisOptionCons, checker, 0)?; @@ -72,7 +73,7 @@ pub fn check_special_is_response( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let input = checker.type_check(&args[0], context)?; @@ -90,7 +91,7 @@ pub fn check_special_is_optional( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let input = checker.type_check(&args[0], context)?; @@ -108,7 +109,7 @@ pub fn check_special_default_to( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let default = checker.type_check(&args[0], context)?; @@ -133,7 +134,7 @@ pub fn check_special_asserts( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; checker.type_check_expects(&args[0], context, &TypeSignature::BoolType)?; @@ -147,7 +148,7 @@ pub fn check_special_asserts( fn inner_unwrap( input: TypeSignature, checker: &mut TypeChecker, -) -> Result { +) -> Result { runtime_cost(ClarityCostFunction::AnalysisOptionCheck, checker, 0)?; match input { @@ -173,7 +174,7 @@ fn inner_unwrap( fn inner_unwrap_err( input: TypeSignature, checker: &mut TypeChecker, -) -> Result { +) -> Result { runtime_cost(ClarityCostFunction::AnalysisOptionCheck, checker, 0)?; if let TypeSignature::ResponseType(response_type) = input { @@ -192,7 +193,7 @@ pub fn check_special_unwrap_or_ret( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let input = checker.type_check(&args[0], context)?; @@ -207,7 +208,7 @@ pub fn check_special_unwrap_err_or_ret( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let input = checker.type_check(&args[0], context)?; @@ -222,7 +223,7 @@ pub fn check_special_try_ret( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let input = checker.type_check(&args[0], context)?; @@ -260,7 +261,7 @@ pub fn check_special_unwrap( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let input = checker.type_check(&args[0], context)?; @@ -272,7 +273,7 @@ pub fn check_special_unwrap_err( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let input = checker.type_check(&args[0], context)?; @@ -287,7 +288,7 @@ fn eval_with_new_binding( bind_type: TypeSignature, checker: &mut TypeChecker, context: &TypingContext, -) -> Result { +) -> Result { let mut inner_context = context.extend()?; runtime_cost( @@ -322,7 +323,7 @@ fn check_special_match_opt( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { if args.len() != 3 { Err(CheckErrors::BadMatchOptionSyntax(Box::new( CheckErrors::IncorrectArgumentCount(4, args.len() + 1), @@ -362,7 +363,7 @@ fn check_special_match_resp( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { if args.len() != 4 { Err(CheckErrors::BadMatchResponseSyntax(Box::new( CheckErrors::IncorrectArgumentCount(5, args.len() + 1), @@ -403,7 +404,7 @@ pub fn check_special_match( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(1, args)?; let input = checker.type_check(&args[0], context)?; diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/sequences.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/sequences.rs index 92143b80b0..42d6878dfd 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/sequences.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/sequences.rs @@ -18,7 +18,7 @@ use stacks_common::types::StacksEpochId; use super::{SimpleNativeFunction, TypedNativeFunction}; use crate::vm::analysis::type_checker::v2_1::{ - check_argument_count, check_arguments_at_least, CheckError, CheckErrors, TypeChecker, + check_argument_count, check_arguments_at_least, CheckErrors, StaticCheckError, TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -34,7 +34,7 @@ use crate::vm::types::{FunctionType, TypeSignature, Value}; fn get_simple_native_or_user_define( function_name: &str, checker: &mut TypeChecker, -) -> Result { +) -> Result { runtime_cost(ClarityCostFunction::AnalysisLookupFunction, checker, 0)?; if let Some(ref native_function) = NativeFunctions::lookup_by_name_at_version(function_name, &checker.clarity_version) @@ -57,7 +57,7 @@ pub fn check_special_map( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_arguments_at_least(2, args)?; let function_name = args[0] @@ -163,7 +163,7 @@ pub fn check_special_filter( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let function_name = args[0] @@ -207,7 +207,7 @@ pub fn check_special_fold( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; let function_name = args[0] @@ -254,7 +254,7 @@ pub fn check_special_concat( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let lhs_type = checker.type_check(&args[0], context)?; @@ -319,7 +319,7 @@ pub fn check_special_append( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; runtime_cost(ClarityCostFunction::AnalysisIterableFunc, checker, 0)?; @@ -351,7 +351,7 @@ pub fn check_special_as_max_len( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let expected_len = match args[1].expr { @@ -408,7 +408,7 @@ pub fn check_special_len( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(1, args)?; let collection_type = checker.type_check(&args[0], context)?; @@ -426,7 +426,7 @@ pub fn check_special_element_at( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; let _index_type = checker.type_check_expects(&args[1], context, &TypeSignature::UIntType)?; @@ -462,7 +462,7 @@ pub fn check_special_index_of( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(2, args)?; runtime_cost(ClarityCostFunction::AnalysisIterableFunc, checker, 0)?; @@ -483,7 +483,7 @@ pub fn check_special_slice( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; runtime_cost(ClarityCostFunction::AnalysisIterableFunc, checker, 0)?; @@ -509,7 +509,7 @@ pub fn check_special_replace_at( checker: &mut TypeChecker, args: &[SymbolicExpression], context: &TypingContext, -) -> Result { +) -> Result { check_argument_count(3, args)?; runtime_cost(ClarityCostFunction::AnalysisIterableFunc, checker, 0)?; diff --git a/clarity/src/vm/analysis/type_checker/v2_1/tests/contracts.rs b/clarity/src/vm/analysis/type_checker/v2_1/tests/contracts.rs index 82dd67ce0e..c393e300e5 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/tests/contracts.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/tests/contracts.rs @@ -24,8 +24,8 @@ use crate::vm::analysis::contract_interface_builder::build_contract_interface; use crate::vm::analysis::errors::CheckErrors; use crate::vm::analysis::type_checker::v2_1::tests::mem_type_check; use crate::vm::analysis::{ - mem_type_check as mem_run_analysis, run_analysis, AnalysisDatabase, CheckError, - ContractAnalysis, + mem_type_check as mem_run_analysis, run_analysis, AnalysisDatabase, ContractAnalysis, + StaticCheckError, }; use crate::vm::ast::parse; use crate::vm::costs::LimitedCostTracker; @@ -40,7 +40,7 @@ use crate::vm::{ClarityName, ClarityVersion, SymbolicExpression}; fn mem_type_check_v1( snippet: &str, -) -> Result<(Option, ContractAnalysis), CheckError> { +) -> Result<(Option, ContractAnalysis), StaticCheckError> { mem_run_analysis(snippet, ClarityVersion::Clarity1, StacksEpochId::latest()) } @@ -56,7 +56,7 @@ pub fn type_check( expressions: &mut [SymbolicExpression], analysis_db: &mut AnalysisDatabase, save_contract: bool, -) -> Result { +) -> Result { type_check_version( contract_identifier, expressions, @@ -74,7 +74,7 @@ pub fn type_check_version( save_contract: bool, epoch: StacksEpochId, version: ClarityVersion, -) -> Result { +) -> Result { run_analysis( contract_identifier, expressions, @@ -1507,7 +1507,7 @@ fn test_traits_multi_contract(#[case] version: ClarityVersion) { }); match result { Ok(_) if version >= ClarityVersion::Clarity2 => (), - Err(CheckError { err, .. }) if version < ClarityVersion::Clarity2 => match *err { + Err(StaticCheckError { err, .. }) if version < ClarityVersion::Clarity2 => match *err { CheckErrors::TraitMethodUnknown(trait_name, function) => { assert_eq!(trait_name.as_str(), "a"); assert_eq!(function.as_str(), "do-it"); diff --git a/clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs b/clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs index ac978b277b..78e372c910 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs @@ -20,7 +20,7 @@ use rstest::rstest; use rstest_reuse::{self, *}; use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::{CheckError, CheckErrors, SyntaxBindingError}; +use crate::vm::analysis::errors::{CheckErrors, StaticCheckError, SyntaxBindingError}; use crate::vm::analysis::mem_type_check as mem_run_analysis; use crate::vm::analysis::types::ContractAnalysis; use crate::vm::ast::build_ast; @@ -41,7 +41,9 @@ mod assets; pub mod contracts; /// Backwards-compatibility shim for type_checker tests. Runs at latest Clarity version. -pub fn mem_type_check(exp: &str) -> Result<(Option, ContractAnalysis), CheckError> { +pub fn mem_type_check( + exp: &str, +) -> Result<(Option, ContractAnalysis), StaticCheckError> { mem_run_analysis( exp, crate::vm::ClarityVersion::latest(), @@ -50,19 +52,19 @@ pub fn mem_type_check(exp: &str) -> Result<(Option, ContractAnaly } /// NOTE: runs at latest Clarity version -fn type_check_helper(exp: &str) -> Result { +fn type_check_helper(exp: &str) -> Result { mem_type_check(exp).map(|(type_sig_opt, _)| type_sig_opt.unwrap()) } fn type_check_helper_version( exp: &str, version: ClarityVersion, -) -> Result { +) -> Result { mem_run_analysis(exp, version, StacksEpochId::latest()) .map(|(type_sig_opt, _)| type_sig_opt.unwrap()) } -fn type_check_helper_v1(exp: &str) -> Result { +fn type_check_helper_v1(exp: &str) -> Result { type_check_helper_version(exp, ClarityVersion::Clarity1) } diff --git a/clarity/src/vm/analysis/types.rs b/clarity/src/vm/analysis/types.rs index 145ce59bd3..b5210e98fc 100644 --- a/clarity/src/vm/analysis/types.rs +++ b/clarity/src/vm/analysis/types.rs @@ -22,7 +22,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::analysis::analysis_db::AnalysisDatabase; use crate::vm::analysis::contract_interface_builder::ContractInterface; -use crate::vm::analysis::errors::{CheckError, CheckErrors}; +use crate::vm::analysis::errors::{CheckErrors, StaticCheckError}; use crate::vm::analysis::type_checker::contexts::TypeMap; use crate::vm::costs::LimitedCostTracker; use crate::vm::types::signatures::FunctionSignature; @@ -39,7 +39,7 @@ pub trait AnalysisPass { epoch: &StacksEpochId, contract_analysis: &mut ContractAnalysis, analysis_db: &mut AnalysisDatabase, - ) -> Result<(), CheckError>; + ) -> Result<(), StaticCheckError>; } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] @@ -230,7 +230,7 @@ impl ContractAnalysis { epoch: &StacksEpochId, trait_identifier: &TraitIdentifier, trait_definition: &BTreeMap, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { let trait_name = trait_identifier.name.to_string(); for (func_name, expected_sig) in trait_definition.iter() { diff --git a/clarity/src/vm/clarity.rs b/clarity/src/vm/clarity.rs index 979d815268..5f70e04885 100644 --- a/clarity/src/vm/clarity.rs +++ b/clarity/src/vm/clarity.rs @@ -2,7 +2,7 @@ use std::fmt; use stacks_common::types::StacksEpochId; -use crate::vm::analysis::{AnalysisDatabase, CheckError, CheckErrors, ContractAnalysis}; +use crate::vm::analysis::{AnalysisDatabase, CheckErrors, ContractAnalysis, StaticCheckError}; use crate::vm::ast::errors::{ParseError, ParseErrors}; use crate::vm::ast::{ASTRules, ContractAST}; use crate::vm::contexts::{AssetMap, Environment, OwnedEnvironment}; @@ -15,7 +15,7 @@ use crate::vm::{analysis, ast, ClarityVersion, ContractContext, SymbolicExpressi #[derive(Debug)] pub enum Error { - Analysis(CheckError), + Analysis(StaticCheckError), Parse(ParseError), Interpreter(InterpreterError), BadTransaction(String), @@ -63,8 +63,8 @@ impl std::error::Error for Error { } } -impl From for Error { - fn from(e: CheckError) -> Self { +impl From for Error { + fn from(e: StaticCheckError) -> Self { match *e.err { CheckErrors::CostOverflow => { Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) @@ -256,7 +256,7 @@ pub trait TransactionConnection: ClarityConnection { &mut self, identifier: &QualifiedContractIdentifier, contract_analysis: &ContractAnalysis, - ) -> Result<(), CheckError> { + ) -> Result<(), StaticCheckError> { self.with_analysis_db(|db, cost_tracker| { db.begin(); let result = db.insert_contract(identifier, contract_analysis); diff --git a/clarity/src/vm/database/clarity_db.rs b/clarity/src/vm/database/clarity_db.rs index a895b00ddb..f4fd6800af 100644 --- a/clarity/src/vm/database/clarity_db.rs +++ b/clarity/src/vm/database/clarity_db.rs @@ -761,7 +761,7 @@ impl<'a> ClarityDatabase<'a> { self.store .get_metadata(contract_identifier, AnalysisDatabase::storage_key()) // treat NoSuchContract error thrown by get_metadata as an Option::None -- - // the analysis will propagate that as a CheckError anyways. + // the analysis will propagate that as a StaticCheckError anyways. .ok() .flatten() .map(|x| ContractAnalysis::deserialize(&x)) diff --git a/clarity/src/vm/tooling/mod.rs b/clarity/src/vm/tooling/mod.rs index 5b0a7a01e1..1fe091c7fb 100644 --- a/clarity/src/vm/tooling/mod.rs +++ b/clarity/src/vm/tooling/mod.rs @@ -3,7 +3,7 @@ use stacks_common::types::StacksEpochId; use super::analysis::ContractAnalysis; use super::types::TypeSignature; use super::ClarityVersion; -use crate::vm::analysis::{run_analysis, CheckError}; +use crate::vm::analysis::{run_analysis, StaticCheckError}; use crate::vm::ast::{build_ast_with_rules, ASTRules}; use crate::vm::costs::LimitedCostTracker; use crate::vm::database::MemoryBackingStore; @@ -14,7 +14,7 @@ pub fn mem_type_check( snippet: &str, version: ClarityVersion, epoch: StacksEpochId, -) -> Result<(Option, ContractAnalysis), CheckError> { +) -> Result<(Option, ContractAnalysis), StaticCheckError> { let contract_identifier = QualifiedContractIdentifier::transient(); let contract = build_ast_with_rules( &contract_identifier, diff --git a/stackslib/src/chainstate/stacks/db/blocks.rs b/stackslib/src/chainstate/stacks/db/blocks.rs index 061fba56bc..d3e8222fa8 100644 --- a/stackslib/src/chainstate/stacks/db/blocks.rs +++ b/stackslib/src/chainstate/stacks/db/blocks.rs @@ -19,7 +19,7 @@ use std::io::{Read, Write}; use std::path::PathBuf; use std::{cmp, fs, io}; -pub use clarity::vm::analysis::errors::{CheckError, CheckErrors}; +pub use clarity::vm::analysis::errors::{CheckErrors, StaticCheckError}; use clarity::vm::ast::ASTRules; use clarity::vm::clarity::TransactionConnection; use clarity::vm::costs::LimitedCostTracker; @@ -110,7 +110,7 @@ pub enum MemPoolRejection { NotEnoughFunds(u128, u128), NoSuchContract, NoSuchPublicFunction, - BadFunctionArgument(CheckError), + BadFunctionArgument(StaticCheckError), ContractAlreadyExists(QualifiedContractIdentifier), PoisonMicroblocksDoNotConflict, NoAnchorBlockWithPubkeyHash(Hash160), diff --git a/stackslib/src/chainstate/stacks/events.rs b/stackslib/src/chainstate/stacks/events.rs index b9a716abbb..b78c478c6d 100644 --- a/stackslib/src/chainstate/stacks/events.rs +++ b/stackslib/src/chainstate/stacks/events.rs @@ -52,7 +52,7 @@ pub struct StacksTransactionReceipt { pub execution_cost: ExecutionCost, pub microblock_header: Option, pub tx_index: u32, - /// This is really a string-formatted CheckError (which can't be clone()'ed) + /// This is really a string-formatted StaticCheckError (which can't be clone()'ed) pub vm_error: Option, } diff --git a/stackslib/src/chainstate/stacks/tests/block_construction.rs b/stackslib/src/chainstate/stacks/tests/block_construction.rs index 6e49fcf876..5fe5cf0f30 100644 --- a/stackslib/src/chainstate/stacks/tests/block_construction.rs +++ b/stackslib/src/chainstate/stacks/tests/block_construction.rs @@ -3961,7 +3961,7 @@ fn test_is_tx_problematic() { expected_txids.push(contract_call_spends_too_much_tx.txid()); // for tenure_id == 4: - // make a contract that, when called, will result in a CheckError at + // make a contract that, when called, will result in a StaticCheckError at // runtime let runtime_checkerror_trait = " diff --git a/stackslib/src/clarity_cli.rs b/stackslib/src/clarity_cli.rs index 1ae8f648de..2ebbab9668 100644 --- a/stackslib/src/clarity_cli.rs +++ b/stackslib/src/clarity_cli.rs @@ -43,7 +43,7 @@ use crate::chainstate::stacks::boot::{ }; use crate::chainstate::stacks::index::ClarityMarfTrieId; use crate::clarity::vm::analysis::contract_interface_builder::build_contract_interface; -use crate::clarity::vm::analysis::errors::CheckError; +use crate::clarity::vm::analysis::errors::StaticCheckError; use crate::clarity::vm::analysis::{AnalysisDatabase, ContractAnalysis}; use crate::clarity::vm::ast::{build_ast_with_rules, ASTRules}; use crate::clarity::vm::contexts::{AssetMap, GlobalContext, OwnedEnvironment}; @@ -204,7 +204,7 @@ fn run_analysis_free( expressions: &mut [SymbolicExpression], marf_kv: &mut C, save_contract: bool, -) -> Result> { +) -> Result> { let clarity_version = ClarityVersion::default_for_epoch(DEFAULT_CLI_EPOCH); analysis::run_analysis( contract_identifier, @@ -225,7 +225,7 @@ fn run_analysis( header_db: &CLIHeadersDB, marf_kv: &mut C, save_contract: bool, -) -> Result> { +) -> Result> { let mainnet = header_db.is_mainnet(); let clarity_version = ClarityVersion::default_for_epoch(DEFAULT_CLI_EPOCH); let cost_track = LimitedCostTracker::new( From 5c54d4c1e79169c99a10b2a35b3d3cfc37e7a84a Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 13:07:25 -0700 Subject: [PATCH 15/34] Add descriptions to StaticCheckError and its components Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/analysis.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/clarity-types/src/errors/analysis.rs b/clarity-types/src/errors/analysis.rs index 08408e8bb8..c9bef9af16 100644 --- a/clarity-types/src/errors/analysis.rs +++ b/clarity-types/src/errors/analysis.rs @@ -310,9 +310,15 @@ pub enum CheckErrors { } #[derive(Debug, PartialEq)] +/// Represents an error encountered during Clarity's type-checking and semantic analysis phase. +/// Wraps a `CheckErrorKind` variant, optionally includes the expressions causing the error, +/// and provides diagnostic information for debugging. pub struct StaticCheckError { + /// The specific type-checking or semantic error that occurred. pub err: Box, + /// Optional vector of expressions related to the error, if available. pub expressions: Option>, + /// Diagnostic details (e.g., line/column numbers, error message, suggestions) around the error. pub diagnostic: Diagnostic, } From de87cfab858e273452f01488a4b6057908c592b6 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 13:23:16 -0700 Subject: [PATCH 16/34] Rename Error::Analaysis to Error::StaticCheck Signed-off-by: Jacinta Ferrant --- clarity/src/vm/clarity.rs | 8 ++++---- .../src/chainstate/stacks/boot/contract_tests.rs | 2 +- .../src/chainstate/stacks/db/transactions.rs | 4 ++-- stackslib/src/clarity_vm/tests/analysis_costs.rs | 2 +- stackslib/src/clarity_vm/tests/contracts.rs | 16 ++++++++-------- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/clarity/src/vm/clarity.rs b/clarity/src/vm/clarity.rs index 5f70e04885..2105caaccd 100644 --- a/clarity/src/vm/clarity.rs +++ b/clarity/src/vm/clarity.rs @@ -15,7 +15,7 @@ use crate::vm::{analysis, ast, ClarityVersion, ContractContext, SymbolicExpressi #[derive(Debug)] pub enum Error { - Analysis(StaticCheckError), + StaticCheck(StaticCheckError), Parse(ParseError), Interpreter(InterpreterError), BadTransaction(String), @@ -39,7 +39,7 @@ impl fmt::Display for Error { Error::CostError(ref a, ref b) => { write!(f, "Cost Error: {a} cost exceeded budget of {b} cost") } - Error::Analysis(ref e) => fmt::Display::fmt(e, f), + Error::StaticCheck(ref e) => fmt::Display::fmt(e, f), Error::Parse(ref e) => fmt::Display::fmt(e, f), Error::AbortedByCallback { reason, .. } => { write!(f, "Post condition aborted transaction: {reason}") @@ -55,7 +55,7 @@ impl std::error::Error for Error { match *self { Error::CostError(ref _a, ref _b) => None, Error::AbortedByCallback { .. } => None, - Error::Analysis(ref e) => Some(e), + Error::StaticCheck(ref e) => Some(e), Error::Parse(ref e) => Some(e), Error::Interpreter(ref e) => Some(e), Error::BadTransaction(ref _s) => None, @@ -76,7 +76,7 @@ impl From for Error { CheckErrors::ExecutionTimeExpired => { Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - _ => Error::Analysis(e), + _ => Error::StaticCheck(e), } } } diff --git a/stackslib/src/chainstate/stacks/boot/contract_tests.rs b/stackslib/src/chainstate/stacks/boot/contract_tests.rs index 7514ba3632..adc6524226 100644 --- a/stackslib/src/chainstate/stacks/boot/contract_tests.rs +++ b/stackslib/src/chainstate/stacks/boot/contract_tests.rs @@ -1716,7 +1716,7 @@ fn simple_epoch21_test() { ) .expect_err("2.0 'bad' contract should not deploy successfully") { - ClarityError::Analysis(e) => { + ClarityError::StaticCheck(e) => { assert_eq!(*e.err, CheckErrors::UnknownFunction("stx-account".into())); } e => panic!("Should have caused an analysis error: {:#?}", e), diff --git a/stackslib/src/chainstate/stacks/db/transactions.rs b/stackslib/src/chainstate/stacks/db/transactions.rs index 2deee7b642..7021ad47ef 100644 --- a/stackslib/src/chainstate/stacks/db/transactions.rs +++ b/stackslib/src/chainstate/stacks/db/transactions.rs @@ -196,7 +196,7 @@ impl StacksTransactionReceipt { error: clarity::vm::clarity::Error, ) -> StacksTransactionReceipt { let error_string = match error { - clarity_error::Analysis(ref check_error) => { + clarity_error::StaticCheck(ref check_error) => { if let Some(span) = check_error.diagnostic.spans.first() { format!( ":{}:{}: {}", @@ -1312,7 +1312,7 @@ impl StacksChainState { return Err(Error::ClarityError(other_error)); } } - if let clarity_error::Analysis(err) = &other_error { + if let clarity_error::StaticCheck(err) = &other_error { if err.err.rejectable() { info!("Transaction {} is problematic and should have prevented this block from being relayed", tx.txid()); return Err(Error::ClarityError(other_error)); diff --git a/stackslib/src/clarity_vm/tests/analysis_costs.rs b/stackslib/src/clarity_vm/tests/analysis_costs.rs index 601fd7e78e..dc31abc2f9 100644 --- a/stackslib/src/clarity_vm/tests/analysis_costs.rs +++ b/stackslib/src/clarity_vm/tests/analysis_costs.rs @@ -340,7 +340,7 @@ fn undefined_top_variable_error(#[case] use_mainnet: bool, #[case] epoch: Stacks &contract_self, ASTRules::PrecheckSize, ); - let Err(ClarityError::Analysis(check_error)) = analysis_result else { + let Err(ClarityError::StaticCheck(check_error)) = analysis_result else { panic!("Bad analysis result: {:?}", &analysis_result); }; let CheckErrors::UndefinedVariable(var_name) = *check_error.err else { diff --git a/stackslib/src/clarity_vm/tests/contracts.rs b/stackslib/src/clarity_vm/tests/contracts.rs index 27a9023e46..0baf31717d 100644 --- a/stackslib/src/clarity_vm/tests/contracts.rs +++ b/stackslib/src/clarity_vm/tests/contracts.rs @@ -53,7 +53,7 @@ fn test_get_burn_block_info_eval() { contract, ASTRules::PrecheckSize, ); - if let Err(ClarityError::Analysis(check_error)) = res { + if let Err(ClarityError::StaticCheck(check_error)) = res { if let CheckErrors::UnknownFunction(func_name) = *check_error.err { assert_eq!(func_name, "get-burn-block-info?"); } else { @@ -78,7 +78,7 @@ fn test_get_burn_block_info_eval() { contract, ASTRules::PrecheckSize, ); - if let Err(ClarityError::Analysis(check_error)) = res { + if let Err(ClarityError::StaticCheck(check_error)) = res { if let CheckErrors::UnknownFunction(func_name) = *check_error.err { assert_eq!(func_name, "get-burn-block-info?"); } else { @@ -179,7 +179,7 @@ fn test_get_block_info_eval_v210() { contract, ASTRules::PrecheckSize, ); - if let Err(ClarityError::Analysis(check_error)) = res { + if let Err(ClarityError::StaticCheck(check_error)) = res { if let CheckErrors::NoSuchBlockInfoProperty(name) = *check_error.err { assert_eq!(name, "block-reward"); } else { @@ -204,7 +204,7 @@ fn test_get_block_info_eval_v210() { contract, ASTRules::PrecheckSize, ); - if let Err(ClarityError::Analysis(check_error)) = res { + if let Err(ClarityError::StaticCheck(check_error)) = res { if let CheckErrors::NoSuchBlockInfoProperty(name) = *check_error.err { assert_eq!(name, "block-reward"); } else { @@ -367,7 +367,7 @@ fn trait_invocation_205_with_stored_principal() { let error = publish_contract(conn, &invoke_contract_id, invoke_contract, clarity_version) .unwrap_err(); match error { - ClarityError::Analysis(ref e) => match *e.err { + ClarityError::StaticCheck(ref e) => match *e.err { CheckErrors::TypeError(..) => (), _ => panic!("Unexpected error: {:?}", error), }, @@ -935,7 +935,7 @@ fn test_block_heights() { contract_clarity3, ASTRules::PrecheckSize, ); - if let Err(ClarityError::Analysis(check_error)) = res { + if let Err(ClarityError::StaticCheck(check_error)) = res { if let CheckErrors::UndefinedVariable(var_name) = *check_error.err { assert_eq!(var_name, "stacks-block-height"); } else { @@ -971,7 +971,7 @@ fn test_block_heights() { contract_clarity3, ASTRules::PrecheckSize, ); - if let Err(ClarityError::Analysis(check_error)) = res { + if let Err(ClarityError::StaticCheck(check_error)) = res { if let CheckErrors::UndefinedVariable(var_name) = *check_error.err { assert_eq!(var_name, "stacks-block-height"); } else { @@ -988,7 +988,7 @@ fn test_block_heights() { contract_clarity1, ASTRules::PrecheckSize, ); - if let Err(ClarityError::Analysis(check_error)) = res { + if let Err(ClarityError::StaticCheck(check_error)) = res { if let CheckErrors::UndefinedVariable(var_name) = *check_error.err { assert_eq!(var_name, "block-height"); } else { From 750ccc507fa15099ab3e19418475f88eabffe826 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 14:00:27 -0700 Subject: [PATCH 17/34] Rename clarity:src::vm::clarity::Error to ClarityError Signed-off-by: Jacinta Ferrant --- clarity/src/vm/clarity.rs | 82 +++++++++---------- .../chainstate/stacks/boot/contract_tests.rs | 2 +- stackslib/src/chainstate/stacks/boot/mod.rs | 2 +- .../src/chainstate/stacks/db/contracts.rs | 4 +- stackslib/src/chainstate/stacks/db/mod.rs | 10 +-- .../src/chainstate/stacks/db/transactions.rs | 56 ++++++------- stackslib/src/chainstate/stacks/miner.rs | 10 +-- stackslib/src/chainstate/stacks/mod.rs | 10 +-- stackslib/src/clarity_vm/clarity.rs | 79 ++++++++++-------- .../src/clarity_vm/tests/analysis_costs.rs | 2 +- stackslib/src/clarity_vm/tests/contracts.rs | 4 +- .../src/clarity_vm/tests/large_contract.rs | 2 +- stackslib/src/net/api/postblock_proposal.rs | 2 +- stackslib/src/net/mod.rs | 8 +- 14 files changed, 140 insertions(+), 133 deletions(-) diff --git a/clarity/src/vm/clarity.rs b/clarity/src/vm/clarity.rs index 979d815268..47d9876996 100644 --- a/clarity/src/vm/clarity.rs +++ b/clarity/src/vm/clarity.rs @@ -14,7 +14,7 @@ use crate::vm::types::{BuffData, PrincipalData, QualifiedContractIdentifier}; use crate::vm::{analysis, ast, ClarityVersion, ContractContext, SymbolicExpression, Value}; #[derive(Debug)] -pub enum Error { +pub enum ClarityError { Analysis(CheckError), Parse(ParseError), Interpreter(InterpreterError), @@ -33,85 +33,85 @@ pub enum Error { }, } -impl fmt::Display for Error { +impl fmt::Display for ClarityError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Error::CostError(ref a, ref b) => { + ClarityError::CostError(ref a, ref b) => { write!(f, "Cost Error: {a} cost exceeded budget of {b} cost") } - Error::Analysis(ref e) => fmt::Display::fmt(e, f), - Error::Parse(ref e) => fmt::Display::fmt(e, f), - Error::AbortedByCallback { reason, .. } => { + ClarityError::Analysis(ref e) => fmt::Display::fmt(e, f), + ClarityError::Parse(ref e) => fmt::Display::fmt(e, f), + ClarityError::AbortedByCallback { reason, .. } => { write!(f, "Post condition aborted transaction: {reason}") } - Error::Interpreter(ref e) => fmt::Display::fmt(e, f), - Error::BadTransaction(ref s) => fmt::Display::fmt(s, f), + ClarityError::Interpreter(ref e) => fmt::Display::fmt(e, f), + ClarityError::BadTransaction(ref s) => fmt::Display::fmt(s, f), } } } -impl std::error::Error for Error { +impl std::error::Error for ClarityError { fn cause(&self) -> Option<&dyn std::error::Error> { match *self { - Error::CostError(ref _a, ref _b) => None, - Error::AbortedByCallback { .. } => None, - Error::Analysis(ref e) => Some(e), - Error::Parse(ref e) => Some(e), - Error::Interpreter(ref e) => Some(e), - Error::BadTransaction(ref _s) => None, + ClarityError::CostError(ref _a, ref _b) => None, + ClarityError::AbortedByCallback { .. } => None, + ClarityError::Analysis(ref e) => Some(e), + ClarityError::Parse(ref e) => Some(e), + ClarityError::Interpreter(ref e) => Some(e), + ClarityError::BadTransaction(ref _s) => None, } } } -impl From for Error { +impl From for ClarityError { fn from(e: CheckError) -> Self { match *e.err { CheckErrors::CostOverflow => { - Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) + ClarityError::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - CheckErrors::CostBalanceExceeded(a, b) => Error::CostError(a, b), + CheckErrors::CostBalanceExceeded(a, b) => ClarityError::CostError(a, b), CheckErrors::MemoryBalanceExceeded(_a, _b) => { - Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) + ClarityError::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } CheckErrors::ExecutionTimeExpired => { - Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) + ClarityError::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - _ => Error::Analysis(e), + _ => ClarityError::Analysis(e), } } } -impl From for Error { +impl From for ClarityError { fn from(e: InterpreterError) -> Self { match &e { InterpreterError::Unchecked(CheckErrors::CostBalanceExceeded(a, b)) => { - Error::CostError(a.clone(), b.clone()) + ClarityError::CostError(a.clone(), b.clone()) } InterpreterError::Unchecked(CheckErrors::CostOverflow) => { - Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) + ClarityError::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } InterpreterError::Unchecked(CheckErrors::ExecutionTimeExpired) => { - Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) + ClarityError::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - _ => Error::Interpreter(e), + _ => ClarityError::Interpreter(e), } } } -impl From for Error { +impl From for ClarityError { fn from(e: ParseError) -> Self { match *e.err { ParseErrors::CostOverflow => { - Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) + ClarityError::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - ParseErrors::CostBalanceExceeded(a, b) => Error::CostError(a, b), + ParseErrors::CostBalanceExceeded(a, b) => ClarityError::CostError(a, b), ParseErrors::MemoryBalanceExceeded(_a, _b) => { - Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) + ClarityError::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } ParseErrors::ExecutionTimeExpired => { - Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) + ClarityError::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - _ => Error::Parse(e), + _ => ClarityError::Parse(e), } } } @@ -210,7 +210,7 @@ pub trait TransactionConnection: ClarityConnection { clarity_version: ClarityVersion, contract_content: &str, ast_rules: ASTRules, - ) -> Result<(ContractAST, ContractAnalysis), Error> { + ) -> Result<(ContractAST, ContractAnalysis), ClarityError> { let epoch_id = self.get_epoch(); self.with_analysis_db(|db, mut cost_track| { @@ -289,12 +289,12 @@ pub trait TransactionConnection: ClarityConnection { to: &PrincipalData, amount: u128, memo: &BuffData, - ) -> Result<(Value, AssetMap, Vec), Error> { + ) -> Result<(Value, AssetMap, Vec), ClarityError> { self.with_abort_callback( |vm_env| { vm_env .stx_transfer(from, to, amount, memo) - .map_err(Error::from) + .map_err(ClarityError::from) }, |_, _| None, ) @@ -316,7 +316,7 @@ pub trait TransactionConnection: ClarityConnection { args: &[Value], abort_call_back: F, max_execution_time: Option, - ) -> Result<(Value, AssetMap, Vec), Error> + ) -> Result<(Value, AssetMap, Vec), ClarityError> where F: FnOnce(&AssetMap, &mut ClarityDatabase) -> Option, { @@ -340,13 +340,13 @@ pub trait TransactionConnection: ClarityConnection { public_function, &expr_args, ) - .map_err(Error::from) + .map_err(ClarityError::from) }, abort_call_back, ) .and_then(|(value, assets_modified, tx_events, reason)| { if let Some(reason) = reason { - Err(Error::AbortedByCallback { + Err(ClarityError::AbortedByCallback { output: Some(Box::new(value)), assets_modified: Box::new(assets_modified), tx_events, @@ -373,7 +373,7 @@ pub trait TransactionConnection: ClarityConnection { sponsor: Option, abort_call_back: F, max_execution_time: Option, - ) -> Result<(AssetMap, Vec), Error> + ) -> Result<(AssetMap, Vec), ClarityError> where F: FnOnce(&AssetMap, &mut ClarityDatabase) -> Option, { @@ -392,12 +392,12 @@ pub trait TransactionConnection: ClarityConnection { contract_str, sponsor, ) - .map_err(Error::from) + .map_err(ClarityError::from) }, abort_call_back, )?; if let Some(reason) = reason { - Err(Error::AbortedByCallback { + Err(ClarityError::AbortedByCallback { output: None, assets_modified: Box::new(assets_modified), tx_events, diff --git a/stackslib/src/chainstate/stacks/boot/contract_tests.rs b/stackslib/src/chainstate/stacks/boot/contract_tests.rs index 7514ba3632..d808bde381 100644 --- a/stackslib/src/chainstate/stacks/boot/contract_tests.rs +++ b/stackslib/src/chainstate/stacks/boot/contract_tests.rs @@ -31,7 +31,7 @@ use crate::chainstate::stacks::boot::{ }; use crate::chainstate::stacks::index::ClarityMarfTrieId; use crate::chainstate::stacks::{C32_ADDRESS_VERSION_TESTNET_SINGLESIG, *}; -use crate::clarity_vm::clarity::{ClarityBlockConnection, Error as ClarityError}; +use crate::clarity_vm::clarity::{ClarityBlockConnection, ClarityError}; use crate::clarity_vm::database::marf::{MarfedKV, WritableMarfStore}; use crate::core::{ StacksEpoch, StacksEpochId, BITCOIN_REGTEST_FIRST_BLOCK_HASH, diff --git a/stackslib/src/chainstate/stacks/boot/mod.rs b/stackslib/src/chainstate/stacks/boot/mod.rs index 83afc46301..69acfa6241 100644 --- a/stackslib/src/chainstate/stacks/boot/mod.rs +++ b/stackslib/src/chainstate/stacks/boot/mod.rs @@ -21,7 +21,7 @@ use std::sync::LazyLock; use clarity::types::Address; use clarity::vm::analysis::CheckErrors; use clarity::vm::ast::ASTRules; -use clarity::vm::clarity::{Error as ClarityError, TransactionConnection}; +use clarity::vm::clarity::{ClarityError, TransactionConnection}; use clarity::vm::costs::LimitedCostTracker; use clarity::vm::database::{ClarityDatabase, NULL_BURN_STATE_DB, NULL_HEADER_DB}; use clarity::vm::errors::Error as VmError; diff --git a/stackslib/src/chainstate/stacks/db/contracts.rs b/stackslib/src/chainstate/stacks/db/contracts.rs index 11b2ee0d02..42d4c3c9d8 100644 --- a/stackslib/src/chainstate/stacks/db/contracts.rs +++ b/stackslib/src/chainstate/stacks/db/contracts.rs @@ -32,7 +32,7 @@ impl StacksChainState { .with_clarity_db_readonly(|ref mut db| match db.get_contract(contract_id) { Ok(c) => Ok(Some(c)), Err(clarity_vm_error::Unchecked(CheckErrors::NoSuchContract(_))) => Ok(None), - Err(e) => Err(clarity_error::Interpreter(e)), + Err(e) => Err(ClarityError::Interpreter(e)), }) .map_err(Error::ClarityError) } @@ -50,7 +50,7 @@ impl StacksChainState { Err(clarity_vm_error::Unchecked(CheckErrors::NoSuchDataVariable(_))) => { Ok(None) } - Err(e) => Err(clarity_error::Interpreter(e)), + Err(e) => Err(ClarityError::Interpreter(e)), } }) .map_err(Error::ClarityError) diff --git a/stackslib/src/chainstate/stacks/db/mod.rs b/stackslib/src/chainstate/stacks/db/mod.rs index fae90986e3..70464db5ac 100644 --- a/stackslib/src/chainstate/stacks/db/mod.rs +++ b/stackslib/src/chainstate/stacks/db/mod.rs @@ -66,8 +66,8 @@ use crate::chainstate::stacks::{ C32_ADDRESS_VERSION_TESTNET_SINGLESIG, *, }; use crate::clarity_vm::clarity::{ - ClarityBlockConnection, ClarityConnection, ClarityInstance, ClarityReadOnlyConnection, - Error as clarity_error, PreCommitClarityBlock, + ClarityBlockConnection, ClarityConnection, ClarityError, ClarityInstance, + ClarityReadOnlyConnection, PreCommitClarityBlock, }; use crate::clarity_vm::database::marf::MarfedKV; use crate::clarity_vm::database::HeadersDBConn; @@ -545,7 +545,7 @@ impl<'a, 'b> ClarityTx<'a, 'b> { pub fn commit_mined_block( self, block_hash: &StacksBlockId, - ) -> Result { + ) -> Result { Ok(self.block.commit_mined_block(block_hash)?.get_total()) } @@ -1977,7 +1977,7 @@ impl StacksChainState { parent_id_bhh: &StacksBlockId, contract: &QualifiedContractIdentifier, code: &str, - ) -> Result { + ) -> Result { self.clarity_state.eval_read_only( parent_id_bhh, &HeadersDBConn(StacksDBConn::new(&self.state_index, ())), @@ -1998,7 +1998,7 @@ impl StacksChainState { contract: &QualifiedContractIdentifier, function: &str, args: &[Value], - ) -> Result { + ) -> Result { let headers_db = HeadersDBConn(StacksDBConn::new(&self.state_index, ())); let mut conn = self.clarity_state.read_only_connection_checked( parent_id_bhh, diff --git a/stackslib/src/chainstate/stacks/db/transactions.rs b/stackslib/src/chainstate/stacks/db/transactions.rs index 2deee7b642..d92646d6eb 100644 --- a/stackslib/src/chainstate/stacks/db/transactions.rs +++ b/stackslib/src/chainstate/stacks/db/transactions.rs @@ -34,9 +34,7 @@ use clarity::vm::types::{ use crate::chainstate::stacks::db::*; use crate::chainstate::stacks::miner::TransactionResult; use crate::chainstate::stacks::{Error, StacksMicroblockHeader}; -use crate::clarity_vm::clarity::{ - ClarityConnection, ClarityTransactionConnection, Error as clarity_error, -}; +use crate::clarity_vm::clarity::{ClarityConnection, ClarityError, ClarityTransactionConnection}; use crate::util_lib::strings::VecDisplay; /// This is a safe-to-hash Clarity value @@ -193,10 +191,10 @@ impl StacksTransactionReceipt { pub fn from_analysis_failure( tx: StacksTransaction, analysis_cost: ExecutionCost, - error: clarity::vm::clarity::Error, + error: ClarityError, ) -> StacksTransactionReceipt { let error_string = match error { - clarity_error::Analysis(ref check_error) => { + ClarityError::Analysis(ref check_error) => { if let Some(span) = check_error.diagnostic.spans.first() { format!( ":{}:{}: {}", @@ -206,7 +204,7 @@ impl StacksTransactionReceipt { check_error.diagnostic.message.to_string() } } - clarity_error::Parse(ref parse_error) => { + ClarityError::Parse(ref parse_error) => { if let Some(span) = parse_error.diagnostic.spans.first() { format!( ":{}:{}: {}", @@ -354,7 +352,7 @@ impl From for MemPoolRejection { pub enum ClarityRuntimeTxError { Acceptable { - error: clarity_error, + error: ClarityError, err_type: &'static str, }, AbortedByCallback { @@ -370,34 +368,34 @@ pub enum ClarityRuntimeTxError { }, CostError(ExecutionCost, ExecutionCost), AnalysisError(CheckErrors), - Rejectable(clarity_error), + Rejectable(ClarityError), } -pub fn handle_clarity_runtime_error(error: clarity_error) -> ClarityRuntimeTxError { +pub fn handle_clarity_runtime_error(error: ClarityError) -> ClarityRuntimeTxError { match error { // runtime errors are okay - clarity_error::Interpreter(InterpreterError::Runtime(_, _)) => { + ClarityError::Interpreter(InterpreterError::Runtime(_, _)) => { ClarityRuntimeTxError::Acceptable { error, err_type: "runtime error", } } - clarity_error::Interpreter(InterpreterError::ShortReturn(_)) => { + ClarityError::Interpreter(InterpreterError::ShortReturn(_)) => { ClarityRuntimeTxError::Acceptable { error, err_type: "short return/panic", } } - clarity_error::Interpreter(InterpreterError::Unchecked(check_error)) => { + ClarityError::Interpreter(InterpreterError::Unchecked(check_error)) => { if check_error.rejectable() { - ClarityRuntimeTxError::Rejectable(clarity_error::Interpreter( + ClarityRuntimeTxError::Rejectable(ClarityError::Interpreter( InterpreterError::Unchecked(check_error), )) } else { ClarityRuntimeTxError::AnalysisError(check_error) } } - clarity_error::AbortedByCallback { + ClarityError::AbortedByCallback { output, assets_modified, tx_events, @@ -408,7 +406,7 @@ pub fn handle_clarity_runtime_error(error: clarity_error) -> ClarityRuntimeTxErr tx_events, reason, }, - clarity_error::CostError(cost, budget) => ClarityRuntimeTxError::CostError(cost, budget), + ClarityError::CostError(cost, budget) => ClarityRuntimeTxError::CostError(cost, budget), unhandled_error => ClarityRuntimeTxError::Rejectable(unhandled_error), } } @@ -1212,7 +1210,7 @@ impl StacksChainState { "function_name" => %contract_call.function_name, "function_args" => %VecDisplay(&contract_call.function_args), "error" => %check_error); - return Err(Error::ClarityError(clarity_error::Interpreter( + return Err(Error::ClarityError(ClarityError::Interpreter( InterpreterError::Unchecked(check_error), ))); } @@ -1282,7 +1280,7 @@ impl StacksChainState { Ok(x) => x, Err(e) => { match e { - clarity_error::CostError(ref cost_after, ref budget) => { + ClarityError::CostError(ref cost_after, ref budget) => { warn!("Block compute budget exceeded on {}: cost before={}, after={}, budget={}", tx.txid(), &cost_before, cost_after, budget); return Err(Error::CostOverflowError( cost_before, @@ -1295,7 +1293,7 @@ impl StacksChainState { // a [Vary]ExpressionDepthTooDeep error in this situation // invalidates the block, since this should have prevented the // block from getting relayed in the first place - if let clarity_error::Parse(ref parse_error) = &other_error { + if let ClarityError::Parse(ref parse_error) = &other_error { match *parse_error.err { ParseErrors::ExpressionStackDepthTooDeep | ParseErrors::VaryExpressionStackDepthTooDeep => { @@ -1306,13 +1304,13 @@ impl StacksChainState { } } } - if let clarity_error::Parse(err) = &other_error { + if let ClarityError::Parse(err) = &other_error { if err.rejectable() { info!("Transaction {} is problematic and should have prevented this block from being relayed", tx.txid()); return Err(Error::ClarityError(other_error)); } } - if let clarity_error::Analysis(err) = &other_error { + if let ClarityError::Analysis(err) = &other_error { if err.err.rejectable() { info!("Transaction {} is problematic and should have prevented this block from being relayed", tx.txid()); return Err(Error::ClarityError(other_error)); @@ -1454,7 +1452,7 @@ impl StacksChainState { "txid" => %tx.txid(), "contract" => %contract_id, "error" => %check_error); - return Err(Error::ClarityError(clarity_error::Interpreter( + return Err(Error::ClarityError(ClarityError::Interpreter( InterpreterError::Unchecked(check_error), ))); } @@ -8507,7 +8505,7 @@ pub mod test { None, ) .unwrap_err(); - let Error::ClarityError(clarity_error::BadTransaction(msg)) = &err else { + let Error::ClarityError(ClarityError::BadTransaction(msg)) = &err else { panic!("Unexpected error type"); }; assert!(msg.find("never seen in this fork").is_some()); @@ -9814,7 +9812,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(ClarityError::Interpreter(InterpreterError::Unchecked( _check_error, ))) = err { @@ -9871,7 +9869,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(ClarityError::Interpreter(InterpreterError::Unchecked( _check_error, ))) = err { @@ -9926,7 +9924,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(ClarityError::Interpreter(InterpreterError::Unchecked( _check_error, ))) = err { @@ -9982,7 +9980,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(ClarityError::Interpreter(InterpreterError::Unchecked( _check_error, ))) = err { @@ -10506,7 +10504,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(ClarityError::Interpreter(InterpreterError::Unchecked( check_error, ))) = err { @@ -10980,7 +10978,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(ClarityError::Interpreter(InterpreterError::Unchecked( check_error, ))) = err { @@ -11095,7 +11093,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(ClarityError::Interpreter(InterpreterError::Unchecked( check_error, ))) = err { diff --git a/stackslib/src/chainstate/stacks/miner.rs b/stackslib/src/chainstate/stacks/miner.rs index a6837e5c4f..20316d8677 100644 --- a/stackslib/src/chainstate/stacks/miner.rs +++ b/stackslib/src/chainstate/stacks/miner.rs @@ -51,7 +51,7 @@ use crate::chainstate::stacks::db::unconfirmed::UnconfirmedState; use crate::chainstate::stacks::db::{ChainstateTx, ClarityTx, StacksChainState}; use crate::chainstate::stacks::events::StacksTransactionReceipt; use crate::chainstate::stacks::{Error, StacksBlockHeader, StacksMicroblockHeader, *}; -use crate::clarity_vm::clarity::{ClarityInstance, Error as clarity_error}; +use crate::clarity_vm::clarity::{ClarityError, ClarityInstance}; use crate::core::mempool::*; use crate::core::*; use crate::monitoring::{ @@ -657,7 +657,7 @@ impl TransactionResult { } // recover original ClarityError ClarityRuntimeTxError::Acceptable { error, .. } => { - if let clarity_error::Parse(ref parse_err) = error { + if let ClarityError::Parse(ref parse_err) = error { info!("Parse error: {}", parse_err; "txid" => %tx.txid()); match *parse_err.err { ParseErrors::ExpressionStackDepthTooDeep @@ -671,10 +671,10 @@ impl TransactionResult { Error::ClarityError(error) } ClarityRuntimeTxError::CostError(cost, budget) => { - Error::ClarityError(clarity_error::CostError(cost, budget)) + Error::ClarityError(ClarityError::CostError(cost, budget)) } ClarityRuntimeTxError::AnalysisError(e) => { - let clarity_err = Error::ClarityError(clarity_error::Interpreter( + let clarity_err = Error::ClarityError(ClarityError::Interpreter( InterpreterError::Unchecked(e), )); if epoch_id < StacksEpochId::Epoch21 { @@ -690,7 +690,7 @@ impl TransactionResult { assets_modified, tx_events, reason, - } => Error::ClarityError(clarity_error::AbortedByCallback { + } => Error::ClarityError(ClarityError::AbortedByCallback { output: output.map(Box::new), assets_modified: Box::new(assets_modified), tx_events, diff --git a/stackslib/src/chainstate/stacks/mod.rs b/stackslib/src/chainstate/stacks/mod.rs index 7bf4d87c5d..447bcd7b36 100644 --- a/stackslib/src/chainstate/stacks/mod.rs +++ b/stackslib/src/chainstate/stacks/mod.rs @@ -43,7 +43,7 @@ use crate::chainstate::burn::ConsensusHash; use crate::chainstate::stacks::db::accounts::MinerReward; use crate::chainstate::stacks::db::{MinerRewardInfo, StacksHeaderInfo}; use crate::chainstate::stacks::index::Error as marf_error; -use crate::clarity_vm::clarity::Error as clarity_error; +use crate::clarity_vm::clarity::ClarityError; use crate::net::Error as net_error; use crate::util_lib::db::Error as db_error; use crate::util_lib::strings::StacksString; @@ -99,7 +99,7 @@ pub enum Error { MicroblockStreamTooLongError, IncompatibleSpendingConditionError, CostOverflowError(ExecutionCost, ExecutionCost, ExecutionCost), - ClarityError(clarity_error), + ClarityError(ClarityError), DBError(db_error), NetError(net_error), CodecError(codec_error), @@ -128,8 +128,8 @@ impl From for Error { } } -impl From for Error { - fn from(e: clarity_error) -> Error { +impl From for Error { + fn from(e: ClarityError) -> Error { Error::ClarityError(e) } } @@ -344,7 +344,7 @@ impl From for Error { impl From for Error { fn from(e: clarity_interpreter_error) -> Error { - Error::ClarityError(clarity_error::Interpreter(e)) + Error::ClarityError(ClarityError::Interpreter(e)) } } diff --git a/stackslib/src/clarity_vm/clarity.rs b/stackslib/src/clarity_vm/clarity.rs index 416c6e99ed..f35ca5f538 100644 --- a/stackslib/src/clarity_vm/clarity.rs +++ b/stackslib/src/clarity_vm/clarity.rs @@ -21,7 +21,7 @@ use clarity::consts::CHAIN_ID_TESTNET; use clarity::vm::analysis::AnalysisDatabase; use clarity::vm::ast::ASTRules; use clarity::vm::clarity::TransactionConnection; -pub use clarity::vm::clarity::{ClarityConnection, Error}; +pub use clarity::vm::clarity::{ClarityConnection, ClarityError}; use clarity::vm::contexts::{AssetMap, OwnedEnvironment}; use clarity::vm::costs::{CostTracker, ExecutionCost, LimitedCostTracker}; use clarity::vm::database::{ @@ -166,13 +166,15 @@ pub struct ClarityReadOnlyConnection<'a> { epoch: StacksEpochId, } -impl From for Error { +impl From for ClarityError { fn from(e: ChainstateError) -> Self { match e { - ChainstateError::InvalidStacksTransaction(msg, _) => Error::BadTransaction(msg), - ChainstateError::CostOverflowError(_, after, budget) => Error::CostError(after, budget), + ChainstateError::InvalidStacksTransaction(msg, _) => ClarityError::BadTransaction(msg), + ChainstateError::CostOverflowError(_, after, budget) => { + ClarityError::CostError(after, budget) + } ChainstateError::ClarityError(x) => x, - x => Error::BadTransaction(format!("{:?}", &x)), + x => ClarityError::BadTransaction(x.to_string()), } } } @@ -250,7 +252,7 @@ impl ClarityBlockConnection<'_, '_> { pub fn get_clarity_db_epoch_version( &mut self, burn_state_db: &dyn BurnStateDB, - ) -> Result { + ) -> Result { let mut db = self.datastore.as_clarity_db(self.header_db, burn_state_db); // NOTE: the begin/roll_back shouldn't be necessary with how this gets used in practice, // but is put here defensively. @@ -557,7 +559,7 @@ impl ClarityInstance { conn } - pub fn drop_unconfirmed_state(&mut self, block: &StacksBlockId) -> Result<(), Error> { + pub fn drop_unconfirmed_state(&mut self, block: &StacksBlockId) -> Result<(), ClarityError> { let datastore = self.datastore.begin_unconfirmed(block); datastore.rollback_unconfirmed()?; Ok(()) @@ -617,7 +619,7 @@ impl ClarityInstance { at_block: &StacksBlockId, header_db: &'a dyn HeadersDB, burn_state_db: &'a dyn BurnStateDB, - ) -> Result, Error> { + ) -> Result, ClarityError> { let mut datastore = self.datastore.begin_read_only_checked(Some(at_block))?; let epoch = { let mut db = datastore.as_clarity_db(header_db, burn_state_db); @@ -650,7 +652,7 @@ impl ClarityInstance { contract: &QualifiedContractIdentifier, program: &str, ast_rules: ASTRules, - ) -> Result { + ) -> Result { let mut read_only_conn = self.datastore.begin_read_only(Some(at_block)); let mut clarity_db = read_only_conn.as_clarity_db(header_db, burn_state_db); let epoch_id = { @@ -663,7 +665,7 @@ impl ClarityInstance { let mut env = OwnedEnvironment::new_free(self.mainnet, self.chain_id, clarity_db, epoch_id); env.eval_read_only_with_rules(contract, program, ast_rules) .map(|(x, _, _)| x) - .map_err(Error::from) + .map_err(ClarityError::from) } pub fn destroy(self) -> MarfedKV { @@ -808,7 +810,10 @@ impl<'a> ClarityBlockConnection<'a, '_> { /// before this saves, it updates the metadata headers in /// the sidestore so that they don't get stepped on after /// a miner re-executes a constructed block. - pub fn commit_mined_block(self, bhh: &StacksBlockId) -> Result { + pub fn commit_mined_block( + self, + bhh: &StacksBlockId, + ) -> Result { debug!("Commit mined Clarity datastore to {}", bhh); self.datastore.commit_mined_block(bhh)?; @@ -828,7 +833,7 @@ impl<'a> ClarityBlockConnection<'a, '_> { } /// Get the boot code account - fn get_boot_code_account(&mut self) -> Result { + fn get_boot_code_account(&mut self) -> Result { let boot_code_address = boot_code_addr(self.mainnet); let boot_code_nonce = self.with_clarity_db_readonly(|db| { db.get_account_nonce(&boot_code_address.clone().into()) @@ -838,7 +843,7 @@ impl<'a> ClarityBlockConnection<'a, '_> { Ok(boot_code_account) } - pub fn initialize_epoch_2_05(&mut self) -> Result { + pub fn initialize_epoch_2_05(&mut self) -> Result { // use the `using!` statement to ensure that the old cost_tracker is placed // back in all branches after initialization using!(self.cost_track, "cost tracker", |old_cost_tracker| { @@ -922,7 +927,7 @@ impl<'a> ClarityBlockConnection<'a, '_> { }) } - pub fn initialize_epoch_2_1(&mut self) -> Result, Error> { + pub fn initialize_epoch_2_1(&mut self) -> Result, ClarityError> { // use the `using!` statement to ensure that the old cost_tracker is placed // back in all branches after initialization using!(self.cost_track, "cost tracker", |old_cost_tracker| { @@ -1110,7 +1115,7 @@ impl<'a> ClarityBlockConnection<'a, '_> { }) } - pub fn initialize_epoch_2_2(&mut self) -> Result, Error> { + pub fn initialize_epoch_2_2(&mut self) -> Result, ClarityError> { // use the `using!` statement to ensure that the old cost_tracker is placed // back in all branches after initialization using!(self.cost_track, "cost tracker", |old_cost_tracker| { @@ -1137,7 +1142,7 @@ impl<'a> ClarityBlockConnection<'a, '_> { }) } - pub fn initialize_epoch_2_3(&mut self) -> Result, Error> { + pub fn initialize_epoch_2_3(&mut self) -> Result, ClarityError> { // use the `using!` statement to ensure that the old cost_tracker is placed // back in all branches after initialization using!(self.cost_track, "cost tracker", |old_cost_tracker| { @@ -1166,7 +1171,7 @@ impl<'a> ClarityBlockConnection<'a, '_> { }) } - pub fn initialize_epoch_2_4(&mut self) -> Result, Error> { + pub fn initialize_epoch_2_4(&mut self) -> Result, ClarityError> { // use the `using!` statement to ensure that the old cost_tracker is placed // back in all branches after initialization using!(self.cost_track, "cost tracker", |old_cost_tracker| { @@ -1297,7 +1302,7 @@ impl<'a> ClarityBlockConnection<'a, '_> { }) } - pub fn initialize_epoch_2_5(&mut self) -> Result, Error> { + pub fn initialize_epoch_2_5(&mut self) -> Result, ClarityError> { // use the `using!` statement to ensure that the old cost_tracker is placed // back in all branches after initialization using!(self.cost_track, "cost tracker", |old_cost_tracker| { @@ -1540,7 +1545,7 @@ impl<'a> ClarityBlockConnection<'a, '_> { }) } - pub fn initialize_epoch_3_0(&mut self) -> Result, Error> { + pub fn initialize_epoch_3_0(&mut self) -> Result, ClarityError> { // use the `using!` statement to ensure that the old cost_tracker is placed // back in all branches after initialization using!(self.cost_track, "cost tracker", |old_cost_tracker| { @@ -1566,7 +1571,7 @@ impl<'a> ClarityBlockConnection<'a, '_> { }) } - pub fn initialize_epoch_3_1(&mut self) -> Result, Error> { + pub fn initialize_epoch_3_1(&mut self) -> Result, ClarityError> { // use the `using!` statement to ensure that the old cost_tracker is placed // back in all branches after initialization using!(self.cost_track, "cost tracker", |old_cost_tracker| { @@ -1592,7 +1597,7 @@ impl<'a> ClarityBlockConnection<'a, '_> { }) } - pub fn initialize_epoch_3_2(&mut self) -> Result, Error> { + pub fn initialize_epoch_3_2(&mut self) -> Result, ClarityError> { // use the `using!` statement to ensure that the old cost_tracker is placed // back in all branches after initialization using!(self.cost_track, "cost tracker", |old_cost_tracker| { @@ -1698,7 +1703,7 @@ impl<'a> ClarityBlockConnection<'a, '_> { }) } - pub fn initialize_epoch_3_3(&mut self) -> Result, Error> { + pub fn initialize_epoch_3_3(&mut self) -> Result, ClarityError> { // use the `using!` statement to ensure that the old cost_tracker is placed // back in all branches after initialization using!(self.cost_track, "cost tracker", |old_cost_tracker| { @@ -1990,9 +1995,9 @@ impl TransactionConnection for ClarityTransactionConnection<'_, '_> { impl ClarityTransactionConnection<'_, '_> { /// Do something to the underlying DB that involves writing. - pub fn with_clarity_db(&mut self, to_do: F) -> Result + pub fn with_clarity_db(&mut self, to_do: F) -> Result where - F: FnOnce(&mut ClarityDatabase) -> Result, + F: FnOnce(&mut ClarityDatabase) -> Result, { using!(self.log, "log", |log| { let rollback_wrapper = RollbackWrapper::from_persisted_log(self.store, log); @@ -2033,7 +2038,7 @@ impl ClarityTransactionConnection<'_, '_> { sender: &PrincipalData, mblock_header_1: &StacksMicroblockHeader, mblock_header_2: &StacksMicroblockHeader, - ) -> Result { + ) -> Result { self.with_abort_callback( |vm_env| { vm_env @@ -2046,7 +2051,7 @@ impl ClarityTransactionConnection<'_, '_> { ) }) }) - .map_err(Error::from) + .map_err(ClarityError::from) }, |_, _| None, ) @@ -2059,7 +2064,7 @@ impl ClarityTransactionConnection<'_, '_> { /// Commit the changes from the edit log. /// panics if there is more than one open savepoint - pub fn commit(mut self) -> Result<(), Error> { + pub fn commit(mut self) -> Result<(), ClarityError> { let log = self .log .take() @@ -2095,7 +2100,7 @@ impl ClarityTransactionConnection<'_, '_> { contract: &QualifiedContractIdentifier, method: &str, args: &[SymbolicExpression], - ) -> Result { + ) -> Result { let (result, _, _, _) = self.with_abort_callback( |vm_env| { vm_env @@ -2106,7 +2111,7 @@ impl ClarityTransactionConnection<'_, '_> { method, args, ) - .map_err(Error::from) + .map_err(ClarityError::from) }, |_, _| Some("read-only".to_string()), )?; @@ -2115,9 +2120,9 @@ impl ClarityTransactionConnection<'_, '_> { /// Evaluate a raw Clarity snippit #[cfg(test)] - pub fn clarity_eval_raw(&mut self, code: &str) -> Result { + pub fn clarity_eval_raw(&mut self, code: &str) -> Result { let (result, _, _, _) = self.with_abort_callback( - |vm_env| vm_env.eval_raw(code).map_err(Error::from), + |vm_env| vm_env.eval_raw(code).map_err(ClarityError::from), |_, _| None, )?; Ok(result) @@ -2128,9 +2133,13 @@ impl ClarityTransactionConnection<'_, '_> { &mut self, contract: &QualifiedContractIdentifier, code: &str, - ) -> Result { + ) -> Result { let (result, _, _, _) = self.with_abort_callback( - |vm_env| vm_env.eval_read_only(contract, code).map_err(Error::from), + |vm_env| { + vm_env + .eval_read_only(contract, code) + .map_err(ClarityError::from) + }, |_, _| None, )?; Ok(result) @@ -2812,7 +2821,7 @@ mod tests { ) }) .unwrap_err(); - let result_value = if let Error::AbortedByCallback { output, .. } = e { + let result_value = if let ClarityError::AbortedByCallback { output, .. } = e { output.unwrap() } else { panic!("Expects a AbortedByCallback error") @@ -3183,7 +3192,7 @@ mod tests { )) .unwrap_err() { - Error::CostError(total, limit) => { + ClarityError::CostError(total, limit) => { eprintln!("{}, {}", total, limit); limit.runtime == 100 && total.runtime > 100 } diff --git a/stackslib/src/clarity_vm/tests/analysis_costs.rs b/stackslib/src/clarity_vm/tests/analysis_costs.rs index 601fd7e78e..2b4569876e 100644 --- a/stackslib/src/clarity_vm/tests/analysis_costs.rs +++ b/stackslib/src/clarity_vm/tests/analysis_costs.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . use clarity::vm::ast::ASTRules; -use clarity::vm::clarity::{Error as ClarityError, TransactionConnection}; +use clarity::vm::clarity::{ClarityError, TransactionConnection}; use clarity::vm::costs::ExecutionCost; use clarity::vm::errors::CheckErrors; use clarity::vm::functions::NativeFunctions; diff --git a/stackslib/src/clarity_vm/tests/contracts.rs b/stackslib/src/clarity_vm/tests/contracts.rs index 27a9023e46..d9e0e21244 100644 --- a/stackslib/src/clarity_vm/tests/contracts.rs +++ b/stackslib/src/clarity_vm/tests/contracts.rs @@ -16,7 +16,7 @@ use clarity::types::StacksEpochId; use clarity::vm::ast::ASTRules; -use clarity::vm::clarity::Error as ClarityError; +use clarity::vm::clarity::ClarityError; use clarity::vm::errors::{CheckErrors, Error}; use clarity::vm::types::SequenceData::Buffer; use clarity::vm::types::{ @@ -304,7 +304,7 @@ fn publish_contract( contract_id: &QualifiedContractIdentifier, contract: &str, version: ClarityVersion, -) -> Result<(), clarity::vm::clarity::Error> { +) -> Result<(), ClarityError> { bc.as_transaction(|tx| { let (ast, analysis) = tx.analyze_smart_contract(contract_id, version, contract, ASTRules::PrecheckSize)?; diff --git a/stackslib/src/clarity_vm/tests/large_contract.rs b/stackslib/src/clarity_vm/tests/large_contract.rs index b90216bd96..287590b8d9 100644 --- a/stackslib/src/clarity_vm/tests/large_contract.rs +++ b/stackslib/src/clarity_vm/tests/large_contract.rs @@ -36,7 +36,7 @@ use stacks_common::types::StacksEpochId; use crate::chainstate::stacks::boot::{BOOT_CODE_COSTS_2, BOOT_CODE_COSTS_3, BOOT_CODE_COSTS_4}; use crate::chainstate::stacks::index::ClarityMarfTrieId; -use crate::clarity_vm::clarity::{ClarityBlockConnection, ClarityInstance, Error as ClarityError}; +use crate::clarity_vm::clarity::{ClarityBlockConnection, ClarityError, ClarityInstance}; use crate::clarity_vm::database::marf::MarfedKV; use crate::clarity_vm::database::MemoryBackingStore; use crate::util_lib::boot::boot_code_id; diff --git a/stackslib/src/net/api/postblock_proposal.rs b/stackslib/src/net/api/postblock_proposal.rs index 5447956f49..f04e371a13 100644 --- a/stackslib/src/net/api/postblock_proposal.rs +++ b/stackslib/src/net/api/postblock_proposal.rs @@ -46,7 +46,7 @@ use crate::chainstate::stacks::miner::{ use crate::chainstate::stacks::{ Error as ChainError, StacksTransaction, TenureChangeCause, TransactionPayload, }; -use crate::clarity_vm::clarity::Error as ClarityError; +use crate::clarity_vm::clarity::ClarityError; use crate::core::mempool::ProposalCallbackReceiver; use crate::net::http::{ http_reason, parse_json, Error, HttpContentType, HttpRequest, HttpRequestContents, diff --git a/stackslib/src/net/mod.rs b/stackslib/src/net/mod.rs index 1dd559c0cf..4523415c93 100644 --- a/stackslib/src/net/mod.rs +++ b/stackslib/src/net/mod.rs @@ -48,7 +48,7 @@ use crate::chainstate::stacks::{ Error as chainstate_error, Error as chain_error, StacksBlock, StacksMicroblock, StacksPublicKey, StacksTransaction, }; -use crate::clarity_vm::clarity::Error as clarity_error; +use crate::clarity_vm::clarity::ClarityError; use crate::core::mempool::*; use crate::cost_estimates::metrics::CostMetric; use crate::cost_estimates::{CostEstimator, FeeEstimator}; @@ -203,7 +203,7 @@ pub enum Error { /// MARF error, percolated up from chainstate MARFError(marf_error), /// Clarity VM error, percolated up from chainstate - ClarityError(clarity_error), + ClarityError(ClarityError), /// Catch-all for chainstate errors that don't map cleanly into network errors ChainstateError(String), /// Coordinator hung up @@ -527,8 +527,8 @@ impl From for Error { } } -impl From for Error { - fn from(e: clarity_error) -> Self { +impl From for Error { + fn from(e: ClarityError) -> Self { Error::ClarityError(e) } } From 9dfc5b4990933586ff8ce11664991065ba8b12e6 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 14:21:26 -0700 Subject: [PATCH 18/34] Add descriptions to ClarityError and its variants Signed-off-by: Jacinta Ferrant --- clarity/src/vm/clarity.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/clarity/src/vm/clarity.rs b/clarity/src/vm/clarity.rs index 47d9876996..7a274301c0 100644 --- a/clarity/src/vm/clarity.rs +++ b/clarity/src/vm/clarity.rs @@ -13,13 +13,22 @@ use crate::vm::events::StacksTransactionEvent; use crate::vm::types::{BuffData, PrincipalData, QualifiedContractIdentifier}; use crate::vm::{analysis, ast, ClarityVersion, ContractContext, SymbolicExpression, Value}; +/// Top-level error type for Clarity contract processing, encompassing errors from parsing, +/// type-checking, runtime evaluation, and transaction execution. #[derive(Debug)] pub enum ClarityError { + /// Error during static type-checking and semantic analysis. Analysis(CheckError), + /// Error during lexical or syntactic parsing. Parse(ParseError), + /// Error during runtime evaluation of Clarity code. Interpreter(InterpreterError), + /// Transaction is malformed or invalid due to blockchain-level issues (e.g., incorrect + /// format, invalid signatures). BadTransaction(String), + /// Transaction exceeds the allocated cost budget. Contains the actual and maximum allowed costs. CostError(ExecutionCost, ExecutionCost), + /// Transaction aborted by a callback (e.g., post-condition check or custom logic). AbortedByCallback { /// What the output value of the transaction would have been. /// This will be a Some for contract-calls, and None for contract initialization txs. From e92b92ed30c96eed6a6835854b141bb2cc72b35f Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 15:58:53 -0700 Subject: [PATCH 19/34] Rename vm::errors::Error to VmExecutionError Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/mod.rs | 79 ++++++++++--------- clarity-types/src/lib.rs | 2 +- clarity-types/src/tests/types/mod.rs | 56 ++++++------- .../src/tests/types/serialization.rs | 6 +- clarity/src/vm/ast/mod.rs | 3 +- clarity/src/vm/callables.rs | 6 +- clarity/src/vm/clarity.rs | 20 ++--- clarity/src/vm/contexts.rs | 42 +++++----- clarity/src/vm/costs/cost_functions.rs | 6 +- clarity/src/vm/costs/mod.rs | 3 +- clarity/src/vm/coverage.rs | 2 +- clarity/src/vm/database/clarity_db.rs | 11 ++- clarity/src/vm/database/structures.rs | 79 ++++++++++--------- clarity/src/vm/docs/contracts.rs | 2 +- clarity/src/vm/errors.rs | 4 +- clarity/src/vm/functions/assets.rs | 20 ++--- clarity/src/vm/functions/mod.rs | 6 +- clarity/src/vm/mod.rs | 12 +-- clarity/src/vm/tests/assets.rs | 12 +-- clarity/src/vm/tests/contracts.rs | 14 ++-- clarity/src/vm/tests/datamaps.rs | 17 ++-- clarity/src/vm/tests/defines.rs | 29 ++++--- clarity/src/vm/tests/sequences.rs | 18 ++--- clarity/src/vm/tests/simple_apply_eval.rs | 34 ++++---- clarity/src/vm/tests/traits.rs | 14 ++-- clarity/src/vm/tests/variables.rs | 20 +++-- clarity/src/vm/types/serialization.rs | 4 +- clarity/src/vm/version.rs | 6 +- pox-locking/src/events.rs | 8 +- pox-locking/src/events_24.rs | 6 +- pox-locking/src/lib.rs | 16 ++-- pox-locking/src/pox_1.rs | 8 +- pox-locking/src/pox_2.rs | 18 ++--- pox-locking/src/pox_3.rs | 18 ++--- pox-locking/src/pox_4.rs | 18 ++--- stacks-signer/src/client/mod.rs | 4 +- stackslib/src/blockstack_cli.rs | 8 +- stackslib/src/chainstate/coordinator/tests.rs | 4 +- .../chainstate/stacks/boot/contract_tests.rs | 4 +- stackslib/src/chainstate/stacks/boot/mod.rs | 6 +- stackslib/src/chainstate/stacks/db/blocks.rs | 28 +++---- .../src/chainstate/stacks/db/contracts.rs | 6 +- .../src/chainstate/stacks/db/transactions.rs | 36 ++++----- stackslib/src/chainstate/stacks/miner.rs | 4 +- stackslib/src/chainstate/stacks/mod.rs | 6 +- stackslib/src/clarity_cli.rs | 36 +++++---- stackslib/src/clarity_vm/clarity.rs | 6 +- stackslib/src/clarity_vm/special.rs | 4 +- stackslib/src/clarity_vm/tests/contracts.rs | 6 +- stackslib/src/clarity_vm/tests/costs.rs | 4 +- stackslib/src/clarity_vm/tests/forking.rs | 6 +- .../src/clarity_vm/tests/large_contract.rs | 8 +- .../src/clarity_vm/tests/simple_tests.rs | 4 +- stackslib/src/net/api/callreadonly.rs | 2 +- stackslib/src/net/api/fastcallreadonly.rs | 2 +- stackslib/src/net/mod.rs | 6 +- 56 files changed, 421 insertions(+), 388 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 58b42b8a99..8037ed7f7b 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -39,7 +39,7 @@ pub struct IncomparableError { } #[derive(Debug)] -pub enum Error { +pub enum VmExecutionError { /// UncheckedErrors are errors that *should* be caught by the /// TypeChecker and other check passes. Test executions may /// trigger these errors. @@ -109,7 +109,7 @@ pub enum ShortReturnType { AssertionFailed(Box), } -pub type InterpreterResult = Result; +pub type InterpreterResult = Result; impl PartialEq> for IncomparableError { fn eq(&self, _other: &IncomparableError) -> bool { @@ -117,22 +117,22 @@ impl PartialEq> for IncomparableError { } } -impl PartialEq for Error { - fn eq(&self, other: &Error) -> bool { +impl PartialEq for VmExecutionError { + fn eq(&self, other: &VmExecutionError) -> bool { match (self, other) { - (Error::Runtime(x, _), Error::Runtime(y, _)) => x == y, - (Error::Unchecked(x), Error::Unchecked(y)) => x == y, - (Error::ShortReturn(x), Error::ShortReturn(y)) => x == y, - (Error::Interpreter(x), Error::Interpreter(y)) => x == y, + (VmExecutionError::Runtime(x, _), VmExecutionError::Runtime(y, _)) => x == y, + (VmExecutionError::Unchecked(x), VmExecutionError::Unchecked(y)) => x == y, + (VmExecutionError::ShortReturn(x), VmExecutionError::ShortReturn(y)) => x == y, + (VmExecutionError::Interpreter(x), VmExecutionError::Interpreter(y)) => x == y, _ => false, } } } -impl fmt::Display for Error { +impl fmt::Display for VmExecutionError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Error::Runtime(err, stack) => { + VmExecutionError::Runtime(err, stack) => { write!(f, "{err}")?; if let Some(stack_trace) = stack { writeln!(f, "\n Stack Trace: ")?; @@ -153,7 +153,7 @@ impl fmt::Display for RuntimeErrorType { } } -impl error::Error for Error { +impl error::Error for VmExecutionError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { None } @@ -165,64 +165,64 @@ impl error::Error for RuntimeErrorType { } } -impl From for Error { +impl From for VmExecutionError { fn from(err: ParseError) -> Self { match *err.err { - ParseErrors::InterpreterFailure => Error::from(InterpreterError::Expect( + ParseErrors::InterpreterFailure => VmExecutionError::from(InterpreterError::Expect( "Unexpected interpreter failure during parsing".into(), )), - _ => Error::from(RuntimeErrorType::ASTError(Box::new(err))), + _ => VmExecutionError::from(RuntimeErrorType::ASTError(Box::new(err))), } } } -impl From for Error { +impl From for VmExecutionError { fn from(err: CostErrors) -> Self { match err { - CostErrors::InterpreterFailure => Error::from(InterpreterError::Expect( + CostErrors::InterpreterFailure => VmExecutionError::from(InterpreterError::Expect( "Interpreter failure during cost calculation".into(), )), - CostErrors::Expect(s) => Error::from(InterpreterError::Expect(format!( + CostErrors::Expect(s) => VmExecutionError::from(InterpreterError::Expect(format!( "Interpreter failure during cost calculation: {s}" ))), - other_err => Error::from(CheckErrors::from(other_err)), + other_err => VmExecutionError::from(CheckErrors::from(other_err)), } } } -impl From for Error { +impl From for VmExecutionError { fn from(err: RuntimeErrorType) -> Self { - Error::Runtime(err, None) + VmExecutionError::Runtime(err, None) } } -impl From for Error { +impl From for VmExecutionError { fn from(err: CheckErrors) -> Self { - Error::Unchecked(err) + VmExecutionError::Unchecked(err) } } -impl From<(CheckErrors, &SymbolicExpression)> for Error { +impl From<(CheckErrors, &SymbolicExpression)> for VmExecutionError { fn from(err: (CheckErrors, &SymbolicExpression)) -> Self { - Error::Unchecked(err.0) + VmExecutionError::Unchecked(err.0) } } -impl From for Error { +impl From for VmExecutionError { fn from(err: ShortReturnType) -> Self { - Error::ShortReturn(err) + VmExecutionError::ShortReturn(err) } } -impl From for Error { +impl From for VmExecutionError { fn from(err: InterpreterError) -> Self { - Error::Interpreter(err) + VmExecutionError::Interpreter(err) } } #[cfg(any(test, feature = "testing"))] -impl From for () { - fn from(_err: Error) -> Self {} +impl From for () { + fn from(_err: VmExecutionError) -> Self {} } impl From for Value { @@ -241,16 +241,23 @@ mod test { #[test] fn equality() { assert_eq!( - Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))), - Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))) + VmExecutionError::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool( + true + )))), + VmExecutionError::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool( + true + )))) ); assert_eq!( - Error::Interpreter(InterpreterError::InterpreterError("".to_string())), - Error::Interpreter(InterpreterError::InterpreterError("".to_string())) + VmExecutionError::Interpreter(InterpreterError::InterpreterError("".to_string())), + VmExecutionError::Interpreter(InterpreterError::InterpreterError("".to_string())) ); assert!( - Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))) - != Error::Interpreter(InterpreterError::InterpreterError("".to_string())) + VmExecutionError::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool( + true + )))) != VmExecutionError::Interpreter(InterpreterError::InterpreterError( + "".to_string() + )) ); } } diff --git a/clarity-types/src/lib.rs b/clarity-types/src/lib.rs index de51f53915..68cc269b47 100644 --- a/clarity-types/src/lib.rs +++ b/clarity-types/src/lib.rs @@ -31,7 +31,7 @@ pub mod representations; pub mod token; pub mod types; -pub use errors::Error; +pub use errors::VmExecutionError; pub use representations::{ClarityName, ContractName}; pub use types::Value; diff --git a/clarity-types/src/tests/types/mod.rs b/clarity-types/src/tests/types/mod.rs index 8c8d861c7c..c7c7297272 100644 --- a/clarity-types/src/tests/types/mod.rs +++ b/clarity-types/src/tests/types/mod.rs @@ -18,7 +18,7 @@ mod signatures; use rstest::rstest; use stacks_common::types::StacksEpochId; -use crate::Error; +use crate::VmExecutionError; use crate::errors::{CheckErrors, InterpreterError, RuntimeErrorType}; use crate::types::{ ASCIIData, BuffData, CharType, ListTypeData, MAX_VALUE_SIZE, PrincipalData, @@ -255,7 +255,7 @@ fn test_qualified_contract_identifier_local_returns_runtime_error() { let err = QualifiedContractIdentifier::local("1nvalid-name") .expect_err("Unexpected qualified contract identifier"); assert_eq!( - Error::from(RuntimeErrorType::BadNameValue( + VmExecutionError::from(RuntimeErrorType::BadNameValue( "ContractName", "1nvalid-name".into() )), @@ -279,7 +279,7 @@ fn test_principal_data_parse_standard_principal_returns_runtime_error( ) { let err = PrincipalData::parse_standard_principal(input).expect_err("Unexpected principal data"); - assert_eq!(Error::from(expected_err), err); + assert_eq!(VmExecutionError::from(expected_err), err); } #[rstest] @@ -295,7 +295,7 @@ fn test_qualified_contract_identifier_parse_returns_interpreter_error( ) { let err = QualifiedContractIdentifier::parse(input) .expect_err("Unexpected qualified contract identifier"); - assert_eq!(Error::from(expected_err), err); + assert_eq!(VmExecutionError::from(expected_err), err); } #[rstest] @@ -312,7 +312,7 @@ fn test_trait_identifier_parse_returns_runtime_error( #[case] input: &str, #[case] expected_err: RuntimeErrorType, ) { - let expected_err = Error::from(expected_err); + let expected_err = VmExecutionError::from(expected_err); let err = TraitIdentifier::parse(input).expect_err("Unexpected trait identifier"); assert_eq!(expected_err, err); @@ -333,7 +333,7 @@ fn test_trait_identifier_parse_fully_qualified_returns_runtime_error( ) { let err = TraitIdentifier::parse_fully_qualified(input).expect_err("Unexpected trait identifier"); - assert_eq!(Error::from(expected_err), err); + assert_eq!(VmExecutionError::from(expected_err), err); } /// The returned InterpreterError is consensus-critical. @@ -343,7 +343,7 @@ fn test_standard_principal_data_new_returns_interpreter_error_consensus_critical let err = result.expect_err("Unexpected principal data"); assert_eq!( - Error::from(InterpreterError::Expect("Unexpected principal data".into())), + VmExecutionError::from(InterpreterError::Expect("Unexpected principal data".into())), err.into(), ); } @@ -354,7 +354,7 @@ fn test_sequence_data_element_at_returns_interpreter_error_consensus_critical() let buff = SequenceData::String(CharType::ASCII(ASCIIData { data: vec![1] })); let err = buff.element_at(0).unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + VmExecutionError::from(InterpreterError::Expect( "BUG: failed to initialize single-byte ASCII buffer".into() )), err @@ -366,7 +366,7 @@ fn test_sequence_data_element_at_returns_interpreter_error_consensus_critical() fn test_ascii_data_to_value_returns_interpreter_error_consensus_critical() { let err = ASCIIData::to_value(&1).unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + VmExecutionError::from(InterpreterError::Expect( "ERROR: Invalid ASCII string successfully constructed".into() )), err @@ -378,7 +378,7 @@ fn test_ascii_data_to_value_returns_interpreter_error_consensus_critical() { fn test_utf8_data_to_value_returns_interpreter_error_consensus_critical() { let err = UTF8Data::to_value(&vec![0xED, 0xA0, 0x80]).unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + VmExecutionError::from(InterpreterError::Expect( "ERROR: Invalid UTF8 string successfully constructed".into() )), err @@ -397,7 +397,7 @@ fn test_tuple_data_from_data_typed_returns_interpreter_error_consensus_critical( ) .unwrap_err(); assert_eq!( - Error::from(InterpreterError::FailureConstructingTupleWithType), + VmExecutionError::from(InterpreterError::FailureConstructingTupleWithType), err ); } @@ -410,7 +410,7 @@ fn test_value_expect_ascii_returns_interpreter_error( #[case] expected_err: InterpreterError, ) { let err = value.expect_ascii().unwrap_err(); - assert_eq!(Error::from(expected_err), err); + assert_eq!(VmExecutionError::from(expected_err), err); } /// The returned InterpreterError is consensus-critical. @@ -418,7 +418,7 @@ fn test_value_expect_ascii_returns_interpreter_error( fn test_value_expect_u128_returns_interpreter_error_consensus_critical() { let err = Value::none().expect_u128().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected u128".to_string())), + VmExecutionError::from(InterpreterError::Expect("Expected u128".to_string())), err ); } @@ -427,7 +427,7 @@ fn test_value_expect_u128_returns_interpreter_error_consensus_critical() { fn test_value_expect_i128_returns_interpreter_error() { let err = Value::none().expect_i128().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected i128".to_string())), + VmExecutionError::from(InterpreterError::Expect("Expected i128".to_string())), err ); } @@ -440,14 +440,14 @@ fn test_value_expect_buff_returns_interpreter_error( #[case] expected_err: InterpreterError, ) { let err = value.expect_buff(1).unwrap_err(); - assert_eq!(Error::from(expected_err), err); + assert_eq!(VmExecutionError::from(expected_err), err); } #[test] fn test_value_expect_tuple_returns_interpreter_error() { let err = Value::none().expect_tuple().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected tuple".to_string())), + VmExecutionError::from(InterpreterError::Expect("Expected tuple".to_string())), err ); } @@ -456,7 +456,7 @@ fn test_value_expect_tuple_returns_interpreter_error() { fn test_value_expect_list_returns_interpreter_error() { let err = Value::none().expect_list().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected list".to_string())), + VmExecutionError::from(InterpreterError::Expect("Expected list".to_string())), err ); } @@ -465,7 +465,7 @@ fn test_value_expect_list_returns_interpreter_error() { fn test_value_expect_buff_padded_returns_interpreter_error() { let err = Value::none().expect_buff_padded(10, 0).unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected buff".to_string())), + VmExecutionError::from(InterpreterError::Expect("Expected buff".to_string())), err ); } @@ -474,7 +474,7 @@ fn test_value_expect_buff_padded_returns_interpreter_error() { fn test_value_expect_bool_returns_interpreter_error() { let err = Value::none().expect_bool().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected bool".to_string())), + VmExecutionError::from(InterpreterError::Expect("Expected bool".to_string())), err ); } @@ -484,7 +484,7 @@ fn test_value_expect_bool_returns_interpreter_error() { fn test_value_expect_optional_returns_interpreter_error_consensus_critical() { let err = Value::okay_true().expect_optional().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected optional".to_string())), + VmExecutionError::from(InterpreterError::Expect("Expected optional".to_string())), err ); } @@ -494,7 +494,7 @@ fn test_value_expect_optional_returns_interpreter_error_consensus_critical() { fn test_value_expect_principal_returns_interpreter_error_consensus_critical() { let err = Value::none().expect_principal().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected principal".to_string())), + VmExecutionError::from(InterpreterError::Expect("Expected principal".to_string())), err ); } @@ -504,7 +504,7 @@ fn test_value_expect_principal_returns_interpreter_error_consensus_critical() { fn test_value_expect_callable_returns_interpreter_error_consensus_critical() { let err = Value::none().expect_callable().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected callable".to_string())), + VmExecutionError::from(InterpreterError::Expect("Expected callable".to_string())), err ); } @@ -513,7 +513,7 @@ fn test_value_expect_callable_returns_interpreter_error_consensus_critical() { fn test_value_expect_result_returns_interpreter_error() { let err = Value::none().expect_result().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect("Expected response".to_string())), + VmExecutionError::from(InterpreterError::Expect("Expected response".to_string())), err ); } @@ -526,7 +526,7 @@ fn test_value_expect_result_ok_returns_interpreter_error( #[case] expected_err: InterpreterError, ) { let err = value.expect_result_ok().unwrap_err(); - assert_eq!(Error::from(expected_err), err); + assert_eq!(VmExecutionError::from(expected_err), err); } #[rstest] @@ -537,7 +537,7 @@ fn test_value_expect_result_err_returns_interpreter_error( #[case] expected_err: InterpreterError, ) { let err = value.expect_result_err().unwrap_err(); - assert_eq!(Error::from(expected_err), err); + assert_eq!(VmExecutionError::from(expected_err), err); } /// The returned InterpreterError is consensus-critical. @@ -549,7 +549,7 @@ fn test_buff_data_len_returns_interpreter_error_consensus_critical() { .len() .unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + VmExecutionError::from(InterpreterError::Expect( "Data length should be valid".into() )), err @@ -564,7 +564,7 @@ fn test_ascii_data_len_returns_interpreter_error() { .len() .unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + VmExecutionError::from(InterpreterError::Expect( "Data length should be valid".into() )), err @@ -579,7 +579,7 @@ fn test_utf8_data_len_returns_interpreter_error() { .len() .unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + VmExecutionError::from(InterpreterError::Expect( "Data length should be valid".into() )), err diff --git a/clarity-types/src/tests/types/serialization.rs b/clarity-types/src/tests/types/serialization.rs index 679befd351..e1bee07b2f 100644 --- a/clarity-types/src/tests/types/serialization.rs +++ b/clarity-types/src/tests/types/serialization.rs @@ -14,7 +14,7 @@ // along with this program. If not, see . use std::io::Write; -use crate::Error; +use crate::VmExecutionError; use crate::errors::{CheckErrors, InterpreterError}; use crate::types::serialization::SerializationError; use crate::types::{ @@ -424,7 +424,7 @@ fn test_serialize_to_vec_returns_interpreter_error_consensus_critical() { }))); let err = value.serialize_to_vec().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + VmExecutionError::from(InterpreterError::Expect( "IOError filling byte buffer.".into() )), err.into() @@ -439,7 +439,7 @@ fn test_serialize_to_hex_returns_interpreter_error_consensus_critical() { }))); let err = value.serialize_to_hex().unwrap_err(); assert_eq!( - Error::from(InterpreterError::Expect( + VmExecutionError::from(InterpreterError::Expect( "IOError filling byte buffer.".into() )), err.into() diff --git a/clarity/src/vm/ast/mod.rs b/clarity/src/vm/ast/mod.rs index ccb7853641..2ab93d70cf 100644 --- a/clarity/src/vm/ast/mod.rs +++ b/clarity/src/vm/ast/mod.rs @@ -49,7 +49,8 @@ pub fn parse( source_code: &str, version: ClarityVersion, epoch: StacksEpochId, -) -> Result, crate::vm::errors::Error> { +) -> Result, crate::vm::errors::VmExecutionError> +{ let ast = build_ast(contract_identifier, source_code, &mut (), version, epoch)?; Ok(ast.expressions) } diff --git a/clarity/src/vm/callables.rs b/clarity/src/vm/callables.rs index b697b3a095..ee9659bfec 100644 --- a/clarity/src/vm/callables.rs +++ b/clarity/src/vm/callables.rs @@ -28,7 +28,7 @@ use crate::vm::analysis::errors::CheckErrors; use crate::vm::contexts::ContractContext; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; -use crate::vm::errors::{check_argument_count, Error, InterpreterResult as Result}; +use crate::vm::errors::{check_argument_count, InterpreterResult as Result, VmExecutionError}; use crate::vm::representations::SymbolicExpression; use crate::vm::types::{ CallableData, ListData, ListTypeData, OptionalData, PrincipalData, ResponseData, SequenceData, @@ -116,7 +116,7 @@ pub fn cost_input_sized_vararg(args: &[Value]) -> Result { .map_err(|e| CostErrors::Expect(format!("{e:?}")))? as u64) .cost_overflow_add(sum) }) - .map_err(Error::from) + .map_err(VmExecutionError::from) } impl DefinedFunction { @@ -294,7 +294,7 @@ impl DefinedFunction { match result { Ok(r) => Ok(r), Err(e) => match e { - Error::ShortReturn(v) => Ok(v.into()), + VmExecutionError::ShortReturn(v) => Ok(v.into()), _ => Err(e), }, } diff --git a/clarity/src/vm/clarity.rs b/clarity/src/vm/clarity.rs index 979d815268..1d3ec45ebc 100644 --- a/clarity/src/vm/clarity.rs +++ b/clarity/src/vm/clarity.rs @@ -8,7 +8,7 @@ use crate::vm::ast::{ASTRules, ContractAST}; use crate::vm::contexts::{AssetMap, Environment, OwnedEnvironment}; use crate::vm::costs::{ExecutionCost, LimitedCostTracker}; use crate::vm::database::ClarityDatabase; -use crate::vm::errors::Error as InterpreterError; +use crate::vm::errors::VmExecutionError; use crate::vm::events::StacksTransactionEvent; use crate::vm::types::{BuffData, PrincipalData, QualifiedContractIdentifier}; use crate::vm::{analysis, ast, ClarityVersion, ContractContext, SymbolicExpression, Value}; @@ -17,7 +17,7 @@ use crate::vm::{analysis, ast, ClarityVersion, ContractContext, SymbolicExpressi pub enum Error { Analysis(CheckError), Parse(ParseError), - Interpreter(InterpreterError), + Interpreter(VmExecutionError), BadTransaction(String), CostError(ExecutionCost, ExecutionCost), AbortedByCallback { @@ -81,16 +81,16 @@ impl From for Error { } } -impl From for Error { - fn from(e: InterpreterError) -> Self { +impl From for Error { + fn from(e: VmExecutionError) -> Self { match &e { - InterpreterError::Unchecked(CheckErrors::CostBalanceExceeded(a, b)) => { + VmExecutionError::Unchecked(CheckErrors::CostBalanceExceeded(a, b)) => { Error::CostError(a.clone(), b.clone()) } - InterpreterError::Unchecked(CheckErrors::CostOverflow) => { + VmExecutionError::Unchecked(CheckErrors::CostOverflow) => { Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - InterpreterError::Unchecked(CheckErrors::ExecutionTimeExpired) => { + VmExecutionError::Unchecked(CheckErrors::ExecutionTimeExpired) => { Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } _ => Error::Interpreter(e), @@ -143,9 +143,9 @@ pub trait ClarityConnection { sponsor: Option, cost_track: LimitedCostTracker, to_do: F, - ) -> Result + ) -> Result where - F: FnOnce(&mut Environment) -> Result, + F: FnOnce(&mut Environment) -> Result, { let epoch_id = self.get_epoch(); let clarity_version = ClarityVersion::default_for_epoch(epoch_id); @@ -192,7 +192,7 @@ pub trait TransactionConnection: ClarityConnection { where A: FnOnce(&AssetMap, &mut ClarityDatabase) -> Option, F: FnOnce(&mut OwnedEnvironment) -> Result<(R, AssetMap, Vec), E>, - E: From; + E: From; /// Do something with the analysis database and cost tracker /// instance of this transaction connection. This is a low-level diff --git a/clarity/src/vm/contexts.rs b/clarity/src/vm/contexts.rs index 355a0e9d53..c319360438 100644 --- a/clarity/src/vm/contexts.rs +++ b/clarity/src/vm/contexts.rs @@ -21,6 +21,7 @@ use std::time::{Duration, Instant}; pub use clarity_types::errors::StackTrace; use clarity_types::representations::ClarityName; +use clarity_types::VmExecutionError; use serde::Serialize; use serde_json::json; use stacks_common::types::chainstate::StacksBlockId; @@ -605,7 +606,7 @@ impl<'a, 'hooks> OwnedEnvironment<'a, 'hooks> { f: F, ) -> std::result::Result<(A, AssetMap, Vec), E> where - E: From, + E: From, F: FnOnce(&mut Environment) -> std::result::Result, { assert!(self.context.is_top_level()); @@ -730,29 +731,24 @@ impl<'a, 'hooks> OwnedEnvironment<'a, 'hooks> { #[cfg(any(test, feature = "testing"))] pub fn stx_faucet(&mut self, recipient: &PrincipalData, amount: u128) { - self.execute_in_env::<_, _, crate::vm::errors::Error>( - recipient.clone(), - None, - None, - |env| { - let mut snapshot = env - .global_context - .database - .get_stx_balance_snapshot(recipient) - .unwrap(); + self.execute_in_env::<_, _, VmExecutionError>(recipient.clone(), None, None, |env| { + let mut snapshot = env + .global_context + .database + .get_stx_balance_snapshot(recipient) + .unwrap(); - snapshot.credit(amount).unwrap(); - snapshot.save().unwrap(); + snapshot.credit(amount).unwrap(); + snapshot.save().unwrap(); - env.global_context - .database - .increment_ustx_liquid_supply(amount) - .unwrap(); + env.global_context + .database + .increment_ustx_liquid_supply(amount) + .unwrap(); - let res: std::result::Result<(), crate::vm::errors::Error> = Ok(()); - res - }, - ) + let res: std::result::Result<(), VmExecutionError> = Ok(()); + res + }) .unwrap(); } @@ -1368,7 +1364,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { pub fn run_as_transaction(&mut self, f: F) -> std::result::Result where F: FnOnce(&mut Self) -> std::result::Result, - E: From, + E: From, { self.global_context.begin(); let result = f(self); @@ -1649,7 +1645,7 @@ impl<'a, 'hooks> GlobalContext<'a, 'hooks> { f: F, ) -> std::result::Result where - E: From, + E: From, F: FnOnce(&mut Environment) -> std::result::Result, { self.begin(); diff --git a/clarity/src/vm/costs/cost_functions.rs b/clarity/src/vm/costs/cost_functions.rs index 6abbaec555..729ee4b1f4 100644 --- a/clarity/src/vm/costs/cost_functions.rs +++ b/clarity/src/vm/costs/cost_functions.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +use clarity_types::VmExecutionError; + use super::ExecutionCost; use crate::vm::errors::{InterpreterResult, RuntimeErrorType}; @@ -169,7 +171,7 @@ pub fn linear(n: u64, a: u64, b: u64) -> u64 { } pub fn logn(n: u64, a: u64, b: u64) -> InterpreterResult { if n < 1 { - return Err(crate::vm::errors::Error::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::Arithmetic("log2 must be passed a positive integer".to_string()), Some(vec![]), )); @@ -179,7 +181,7 @@ pub fn logn(n: u64, a: u64, b: u64) -> InterpreterResult { } pub fn nlogn(n: u64, a: u64, b: u64) -> InterpreterResult { if n < 1 { - return Err(crate::vm::errors::Error::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::Arithmetic("log2 must be passed a positive integer".to_string()), Some(vec![]), )); diff --git a/clarity/src/vm/costs/mod.rs b/clarity/src/vm/costs/mod.rs index 669f6f483d..475ee3b908 100644 --- a/clarity/src/vm/costs/mod.rs +++ b/clarity/src/vm/costs/mod.rs @@ -19,6 +19,7 @@ use std::{cmp, fmt}; pub use clarity_types::errors::CostErrors; pub use clarity_types::execution_cost::{CostOverflowingMath, ExecutionCost}; +use clarity_types::VmExecutionError; use costs_1::Costs1; use costs_2::Costs2; use costs_2_testnet::Costs2Testnet; @@ -215,7 +216,7 @@ impl DefaultVersion { }; r.map_err(|e| { let e = match e { - crate::vm::errors::Error::Runtime(RuntimeErrorType::NotImplemented, _) => { + VmExecutionError::Runtime(RuntimeErrorType::NotImplemented, _) => { CheckErrors::UndefinedFunction(cost_function_ref.function_name.clone()).into() } other => other, diff --git a/clarity/src/vm/coverage.rs b/clarity/src/vm/coverage.rs index 15f41b6693..afbf45a87a 100644 --- a/clarity/src/vm/coverage.rs +++ b/clarity/src/vm/coverage.rs @@ -241,7 +241,7 @@ impl EvalHook for CoverageReporter { _env: &mut crate::vm::Environment, _context: &crate::vm::LocalContext, _expr: &SymbolicExpression, - _res: &core::result::Result, + _res: &core::result::Result, ) { } diff --git a/clarity/src/vm/database/clarity_db.rs b/clarity/src/vm/database/clarity_db.rs index a895b00ddb..ea9b2c3e20 100644 --- a/clarity/src/vm/database/clarity_db.rs +++ b/clarity/src/vm/database/clarity_db.rs @@ -38,7 +38,7 @@ use crate::vm::database::structures::{ }; use crate::vm::database::{ClarityBackingStore, RollbackWrapper}; use crate::vm::errors::{ - CheckErrors, Error, InterpreterError, InterpreterResult as Result, RuntimeErrorType, + CheckErrors, InterpreterError, InterpreterResult as Result, RuntimeErrorType, VmExecutionError, }; use crate::vm::representations::ClarityName; use crate::vm::types::serialization::NONE_SERIALIZATION_LEN; @@ -693,7 +693,10 @@ impl<'a> ClarityDatabase<'a> { data: &str, ) -> Result<()> { if self.store.has_metadata_entry(contract_identifier, key) { - Err(Error::Runtime(RuntimeErrorType::MetadataAlreadySet, None)) + Err(VmExecutionError::Runtime( + RuntimeErrorType::MetadataAlreadySet, + None, + )) } else { Ok(self.store.insert_metadata(contract_identifier, key, data)?) } @@ -984,7 +987,7 @@ impl<'a> ClarityDatabase<'a> { /// transactions in the block. pub fn set_tenure_height(&mut self, height: u32) -> Result<()> { if self.get_clarity_epoch_version()? < StacksEpochId::Epoch30 { - return Err(Error::Interpreter(InterpreterError::Expect( + return Err(VmExecutionError::Interpreter(InterpreterError::Expect( "Setting tenure height in Clarity state is not supported before epoch 3.0".into(), ))); } @@ -1485,7 +1488,7 @@ impl ClarityDatabase<'_> { // will throw NoSuchFoo errors instead of NoSuchContract errors. fn map_no_contract_as_none(res: Result>) -> Result> { res.or_else(|e| match e { - Error::Unchecked(CheckErrors::NoSuchContract(_)) => Ok(None), + VmExecutionError::Unchecked(CheckErrors::NoSuchContract(_)) => Ok(None), x => Err(x), }) } diff --git a/clarity/src/vm/database/structures.rs b/clarity/src/vm/database/structures.rs index c4fec9f382..05de5ae862 100644 --- a/clarity/src/vm/database/structures.rs +++ b/clarity/src/vm/database/structures.rs @@ -22,7 +22,7 @@ use stacks_common::util::hash::{hex_bytes, to_hex}; use crate::vm::analysis::ContractAnalysis; use crate::vm::contracts::Contract; use crate::vm::database::ClarityDatabase; -use crate::vm::errors::{Error, InterpreterError, RuntimeErrorType}; +use crate::vm::errors::{InterpreterError, RuntimeErrorType, VmExecutionError}; use crate::vm::types::{PrincipalData, TypeSignature}; pub trait ClaritySerializable { @@ -30,7 +30,7 @@ pub trait ClaritySerializable { } pub trait ClarityDeserializable { - fn deserialize(json: &str) -> Result; + fn deserialize(json: &str) -> Result; } impl ClaritySerializable for String { @@ -40,7 +40,7 @@ impl ClaritySerializable for String { } impl ClarityDeserializable for String { - fn deserialize(serialized: &str) -> Result { + fn deserialize(serialized: &str) -> Result { Ok(serialized.into()) } } @@ -54,7 +54,7 @@ macro_rules! clarity_serializable { } impl ClarityDeserializable<$Name> for $Name { #[cfg(not(target_family = "wasm"))] - fn deserialize(json: &str) -> Result { + fn deserialize(json: &str) -> Result { let mut deserializer = serde_json::Deserializer::from_str(&json); // serde's default 128 depth limit can be exhausted // by a 64-stack-depth AST, so disable the recursion limit @@ -67,7 +67,7 @@ macro_rules! clarity_serializable { }) } #[cfg(target_family = "wasm")] - fn deserialize(json: &str) -> Result { + fn deserialize(json: &str) -> Result { serde_json::from_str(json).map_err(|_| { InterpreterError::Expect("Failed to deserialize vm.Value".into()).into() }) @@ -257,7 +257,7 @@ impl ClaritySerializable for STXBalance { } impl ClarityDeserializable for STXBalance { - fn deserialize(input: &str) -> Result { + fn deserialize(input: &str) -> Result { let bytes = hex_bytes(input).map_err(|_| { InterpreterError::Expect("STXBalance deserialization: failed decoding bytes.".into()) })?; @@ -374,12 +374,16 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { &self.balance } - pub fn save(self) -> Result<(), Error> { + pub fn save(self) -> Result<(), VmExecutionError> { let key = ClarityDatabase::make_key_for_account_balance(&self.principal); self.db_ref.put_data(&key, &self.balance) } - pub fn transfer_to(mut self, recipient: &PrincipalData, amount: u128) -> Result<(), Error> { + pub fn transfer_to( + mut self, + recipient: &PrincipalData, + amount: u128, + ) -> Result<(), VmExecutionError> { if !self.can_transfer(amount)? { return Err(InterpreterError::InsufficientBalance.into()); } @@ -392,7 +396,10 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { recipient_balance .checked_add_unlocked_amount(amount) - .ok_or(Error::Runtime(RuntimeErrorType::ArithmeticOverflow, None))?; + .ok_or(VmExecutionError::Runtime( + RuntimeErrorType::ArithmeticOverflow, + None, + ))?; self.debit(amount)?; self.db_ref.put_data(&recipient_key, &recipient_balance)?; @@ -400,7 +407,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { Ok(()) } - pub fn get_available_balance(&mut self) -> Result { + pub fn get_available_balance(&mut self) -> Result { let v1_unlock_height = self.db_ref.get_v1_unlock_height(); let v2_unlock_height = self.db_ref.get_v2_unlock_height()?; let v3_unlock_height = self.db_ref.get_v3_unlock_height()?; @@ -412,7 +419,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { ) } - pub fn canonical_balance_repr(&mut self) -> Result { + pub fn canonical_balance_repr(&mut self) -> Result { let v1_unlock_height = self.db_ref.get_v1_unlock_height(); let v2_unlock_height = self.db_ref.get_v2_unlock_height()?; let v3_unlock_height = self.db_ref.get_v3_unlock_height()?; @@ -427,7 +434,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { .0) } - pub fn has_locked_tokens(&mut self) -> Result { + pub fn has_locked_tokens(&mut self) -> Result { let v1_unlock_height = self.db_ref.get_v1_unlock_height(); let v2_unlock_height = self.db_ref.get_v2_unlock_height()?; let v3_unlock_height = self.db_ref.get_v3_unlock_height()?; @@ -439,7 +446,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { )) } - pub fn has_unlockable_tokens(&mut self) -> Result { + pub fn has_unlockable_tokens(&mut self) -> Result { let v1_unlock_height = self.db_ref.get_v1_unlock_height(); let v2_unlock_height = self.db_ref.get_v2_unlock_height()?; let v3_unlock_height = self.db_ref.get_v3_unlock_height()?; @@ -451,11 +458,11 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { )) } - pub fn can_transfer(&mut self, amount: u128) -> Result { + pub fn can_transfer(&mut self, amount: u128) -> Result { Ok(self.get_available_balance()? >= amount) } - pub fn debit(&mut self, amount: u128) -> Result<(), Error> { + pub fn debit(&mut self, amount: u128) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after account-debit"); @@ -464,7 +471,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { self.balance.debit_unlocked_amount(amount) } - pub fn credit(&mut self, amount: u128) -> Result<(), Error> { + pub fn credit(&mut self, amount: u128) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after account-credit"); @@ -484,7 +491,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { &mut self, amount_to_lock: u128, unlock_burn_height: u64, - ) -> Result<(), Error> { + ) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after account-token-lock"); @@ -530,7 +537,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { /// Return true iff `self` represents a snapshot that has a lock /// created by PoX v2. - pub fn is_v2_locked(&mut self) -> Result { + pub fn is_v2_locked(&mut self) -> Result { match self.canonical_balance_repr()? { STXBalance::LockedPoxTwo { .. } => Ok(true), _ => Ok(false), @@ -539,7 +546,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { /// Increase the account's current lock to `new_total_locked`. /// Panics if `self` was not locked by V2 PoX. - pub fn increase_lock_v2(&mut self, new_total_locked: u128) -> Result<(), Error> { + pub fn increase_lock_v2(&mut self, new_total_locked: u128) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after extend-token-lock"); @@ -588,7 +595,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { /// Extend this account's current lock to `unlock_burn_height`. /// After calling, this method will set the balance to a "LockedPoxTwo" balance, /// because this method is only invoked as a result of PoX2 interactions - pub fn extend_lock_v2(&mut self, unlock_burn_height: u64) -> Result<(), Error> { + pub fn extend_lock_v2(&mut self, unlock_burn_height: u64) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after extend-token-lock"); @@ -625,7 +632,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { &mut self, amount_to_lock: u128, unlock_burn_height: u64, - ) -> Result<(), Error> { + ) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after account-token-lock"); @@ -678,7 +685,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { &mut self, amount_to_lock: u128, unlock_burn_height: u64, - ) -> Result<(), Error> { + ) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after account-token-lock"); @@ -728,7 +735,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { /// Extend this account's current lock to `unlock_burn_height`. /// After calling, this method will set the balance to a "LockedPoxThree" balance, /// because this method is only invoked as a result of PoX3 interactions - pub fn extend_lock_v3(&mut self, unlock_burn_height: u64) -> Result<(), Error> { + pub fn extend_lock_v3(&mut self, unlock_burn_height: u64) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after extend-token-lock"); @@ -760,7 +767,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { /// Increase the account's current lock to `new_total_locked`. /// Panics if `self` was not locked by V3 PoX. - pub fn increase_lock_v3(&mut self, new_total_locked: u128) -> Result<(), Error> { + pub fn increase_lock_v3(&mut self, new_total_locked: u128) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after extend-token-lock"); @@ -805,7 +812,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { /// Return true iff `self` represents a snapshot that has a lock /// created by PoX v3. - pub fn is_v3_locked(&mut self) -> Result { + pub fn is_v3_locked(&mut self) -> Result { match self.canonical_balance_repr()? { STXBalance::LockedPoxThree { .. } => Ok(true), _ => Ok(false), @@ -821,7 +828,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { &mut self, amount_to_lock: u128, unlock_burn_height: u64, - ) -> Result<(), Error> { + ) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after account-token-lock"); @@ -860,7 +867,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { /// Extend this account's current lock to `unlock_burn_height`. /// After calling, this method will set the balance to a "LockedPoxFour" balance, /// because this method is only invoked as a result of PoX3 interactions - pub fn extend_lock_v4(&mut self, unlock_burn_height: u64) -> Result<(), Error> { + pub fn extend_lock_v4(&mut self, unlock_burn_height: u64) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after extend-token-lock"); @@ -886,7 +893,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { /// Increase the account's current lock to `new_total_locked`. /// Panics if `self` was not locked by V3 PoX. - pub fn increase_lock_v4(&mut self, new_total_locked: u128) -> Result<(), Error> { + pub fn increase_lock_v4(&mut self, new_total_locked: u128) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after extend-token-lock"); @@ -926,7 +933,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { /// Return true iff `self` represents a snapshot that has a lock /// created by PoX v3. - pub fn is_v4_locked(&mut self) -> Result { + pub fn is_v4_locked(&mut self) -> Result { match self.canonical_balance_repr()? { STXBalance::LockedPoxFour { .. } => Ok(true), _ => Ok(false), @@ -937,7 +944,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { /// If this snapshot is locked, then alter the lock height to be /// the next burn block (i.e., `self.burn_block_height + 1`) - pub fn accelerate_unlock(&mut self) -> Result<(), Error> { + pub fn accelerate_unlock(&mut self) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { debug!("Consolidated after account-token-lock"); @@ -985,7 +992,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { /// Unlock any tokens that are unlockable at the current /// burn block height, and return the amount newly unlocked - fn unlock_available_tokens_if_any(&mut self) -> Result { + fn unlock_available_tokens_if_any(&mut self) -> Result { let (new_balance, unlocked) = self.balance.canonical_repr_at_block( self.burn_block_height, self.db_ref.get_v1_unlock_height(), @@ -1102,7 +1109,7 @@ impl STXBalance { } } - fn debit_unlocked_amount(&mut self, delta: u128) -> Result<(), Error> { + fn debit_unlocked_amount(&mut self, delta: u128) -> Result<(), VmExecutionError> { match self { STXBalance::Unlocked { amount: amount_unlocked, @@ -1164,7 +1171,7 @@ impl STXBalance { v1_unlock_height: u32, v2_unlock_height: u32, v3_unlock_height: u32, - ) -> Result<(STXBalance, u128), Error> { + ) -> Result<(STXBalance, u128), VmExecutionError> { if self.has_unlockable_tokens_at_burn_block( burn_block_height, v1_unlock_height, @@ -1188,7 +1195,7 @@ impl STXBalance { v1_unlock_height: u32, v2_unlock_height: u32, v3_unlock_height: u32, - ) -> Result { + ) -> Result { if self.has_unlockable_tokens_at_burn_block( burn_block_height, v1_unlock_height, @@ -1257,7 +1264,7 @@ impl STXBalance { } } - pub fn get_total_balance(&self) -> Result { + pub fn get_total_balance(&self) -> Result { let (unlocked, locked) = match self { STXBalance::Unlocked { amount } => (*amount, 0), STXBalance::LockedPoxOne { @@ -1462,7 +1469,7 @@ impl STXBalance { v1_unlock_height: u32, v2_unlock_height: u32, v3_unlock_height: u32, - ) -> Result { + ) -> Result { Ok(self.get_available_balance_at_burn_block( burn_block_height, v1_unlock_height, diff --git a/clarity/src/vm/docs/contracts.rs b/clarity/src/vm/docs/contracts.rs index 2cb8b2c403..2438ba6765 100644 --- a/clarity/src/vm/docs/contracts.rs +++ b/clarity/src/vm/docs/contracts.rs @@ -67,7 +67,7 @@ fn get_constant_value(var_name: &str, contract_content: &str) -> Value { .expect("BUG: failed to return constant value") } -fn doc_execute(program: &str) -> Result, vm::Error> { +fn doc_execute(program: &str) -> Result, vm::VmExecutionError> { let contract_id = QualifiedContractIdentifier::transient(); let mut contract_context = ContractContext::new(contract_id.clone(), ClarityVersion::Clarity2); let mut marf = MemoryBackingStore::new(); diff --git a/clarity/src/vm/errors.rs b/clarity/src/vm/errors.rs index 764ac466e5..1a7740ce3d 100644 --- a/clarity/src/vm/errors.rs +++ b/clarity/src/vm/errors.rs @@ -15,8 +15,8 @@ // along with this program. If not, see . pub use clarity_types::errors::{ - Error, IncomparableError, InterpreterError, InterpreterResult, RuntimeErrorType, - ShortReturnType, + IncomparableError, InterpreterError, InterpreterResult, RuntimeErrorType, ShortReturnType, + VmExecutionError, }; pub use crate::vm::analysis::errors::{ diff --git a/clarity/src/vm/functions/assets.rs b/clarity/src/vm/functions/assets.rs index 62763fa3fc..a42b39bc34 100644 --- a/clarity/src/vm/functions/assets.rs +++ b/clarity/src/vm/functions/assets.rs @@ -20,8 +20,8 @@ use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostTracker}; use crate::vm::database::STXBalance; use crate::vm::errors::{ - check_argument_count, CheckErrors, Error, InterpreterError, InterpreterResult as Result, - RuntimeErrorType, + check_argument_count, CheckErrors, InterpreterError, InterpreterResult as Result, + RuntimeErrorType, VmExecutionError, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::{ @@ -418,7 +418,7 @@ pub fn special_mint_asset_v200( &asset, expected_asset_type, ) { - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(()), + Err(VmExecutionError::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(()), Ok(_owner) => return clarity_ecode!(MintAssetErrorCodes::ALREADY_EXIST), Err(e) => Err(e), }?; @@ -492,7 +492,7 @@ pub fn special_mint_asset_v205( &asset, expected_asset_type, ) { - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(()), + Err(VmExecutionError::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(()), Ok(_owner) => return clarity_ecode!(MintAssetErrorCodes::ALREADY_EXIST), Err(e) => Err(e), }?; @@ -571,7 +571,7 @@ pub fn special_transfer_asset_v200( expected_asset_type, ) { Ok(owner) => Ok(owner), - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => { + Err(VmExecutionError::Runtime(RuntimeErrorType::NoSuchToken, _)) => { return clarity_ecode!(TransferAssetErrorCodes::DOES_NOT_EXIST) } Err(e) => Err(e), @@ -665,7 +665,7 @@ pub fn special_transfer_asset_v205( expected_asset_type, ) { Ok(owner) => Ok(owner), - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => { + Err(VmExecutionError::Runtime(RuntimeErrorType::NoSuchToken, _)) => { return clarity_ecode!(TransferAssetErrorCodes::DOES_NOT_EXIST) } Err(e) => Err(e), @@ -889,7 +889,7 @@ pub fn special_get_owner_v200( Ok(owner) => Ok(Value::some(Value::Principal(owner)).map_err(|_| { InterpreterError::Expect("Principal should always fit in optional.".into()) })?), - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(Value::none()), + Err(VmExecutionError::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(Value::none()), Err(e) => Err(e), } } @@ -936,7 +936,7 @@ pub fn special_get_owner_v205( Ok(owner) => Ok(Value::some(Value::Principal(owner)).map_err(|_| { InterpreterError::Expect("Principal should always fit in optional.".into()) })?), - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(Value::none()), + Err(VmExecutionError::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(Value::none()), Err(e) => Err(e), } } @@ -1068,7 +1068,7 @@ pub fn special_burn_asset_v200( &asset, expected_asset_type, ) { - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => { + Err(VmExecutionError::Runtime(RuntimeErrorType::NoSuchToken, _)) => { return clarity_ecode!(BurnAssetErrorCodes::DOES_NOT_EXIST) } Ok(owner) => Ok(owner), @@ -1156,7 +1156,7 @@ pub fn special_burn_asset_v205( &asset, expected_asset_type, ) { - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => { + Err(VmExecutionError::Runtime(RuntimeErrorType::NoSuchToken, _)) => { return clarity_ecode!(BurnAssetErrorCodes::DOES_NOT_EXIST) } Ok(owner) => Ok(owner), diff --git a/clarity/src/vm/functions/mod.rs b/clarity/src/vm/functions/mod.rs index f458c282e6..d9b76f9935 100644 --- a/clarity/src/vm/functions/mod.rs +++ b/clarity/src/vm/functions/mod.rs @@ -20,8 +20,8 @@ use crate::vm::callables::{cost_input_sized_vararg, CallableType, NativeHandle}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{constants as cost_constants, runtime_cost, CostTracker, MemoryConsumer}; use crate::vm::errors::{ - check_argument_count, check_arguments_at_least, CheckErrors, Error, - InterpreterResult as Result, ShortReturnType, SyntaxBindingError, SyntaxBindingErrorType, + check_argument_count, check_arguments_at_least, CheckErrors, InterpreterResult as Result, + ShortReturnType, SyntaxBindingError, SyntaxBindingErrorType, VmExecutionError, }; pub use crate::vm::functions::assets::stx_transfer_consolidated; use crate::vm::representations::{ClarityName, SymbolicExpression, SymbolicExpressionType}; @@ -749,7 +749,7 @@ fn special_let( let mut memory_use = 0; finally_drop_memory!( env, memory_use; { - handle_binding_list::<_, Error>(bindings, SyntaxBindingErrorType::Let, |binding_name, var_sexp| { + handle_binding_list::<_, VmExecutionError>(bindings, SyntaxBindingErrorType::Let, |binding_name, var_sexp| { if is_reserved(binding_name, env.contract_context.get_clarity_version()) || env.contract_context.lookup_function(binding_name).is_some() || inner_context.lookup_variable(binding_name).is_some() { diff --git a/clarity/src/vm/mod.rs b/clarity/src/vm/mod.rs index 781c7d4d7b..18452fd2e4 100644 --- a/clarity/src/vm/mod.rs +++ b/clarity/src/vm/mod.rs @@ -73,7 +73,7 @@ use crate::vm::costs::{ // publish the non-generic StacksEpoch form for use throughout module pub use crate::vm::database::clarity_db::StacksEpoch; use crate::vm::errors::{ - CheckErrors, Error, InterpreterError, InterpreterResult as Result, RuntimeErrorType, + CheckErrors, InterpreterError, InterpreterResult as Result, RuntimeErrorType, VmExecutionError, }; use crate::vm::events::StacksTransactionEvent; use crate::vm::functions::define::DefineResult; @@ -155,7 +155,7 @@ pub trait EvalHook { _env: &mut Environment, _context: &LocalContext, _expr: &SymbolicExpression, - _res: &core::result::Result, + _res: &core::result::Result, ); // Called upon completion of the execution @@ -214,7 +214,7 @@ pub fn lookup_function(name: &str, env: &mut Environment) -> Result, env: &Environment) { - if let Err(Error::Runtime(_, ref mut stack_trace)) = result { + if let Err(VmExecutionError::Runtime(_, ref mut stack_trace)) = result { if stack_trace.is_none() { stack_trace.replace(env.call_stack.make_stack_trace()); } @@ -266,7 +266,7 @@ pub fn apply( Err(e) => { env.drop_memory(used_memory)?; env.call_stack.decr_apply_depth(); - return Err(Error::from(e)); + return Err(VmExecutionError::from(e)); } }; used_memory += arg_value.get_memory_use()?; @@ -278,7 +278,7 @@ pub fn apply( let mut resp = match function { CallableType::NativeFunction(_, function, cost_function) => { runtime_cost(cost_function.clone(), env, evaluated_args.len()) - .map_err(Error::from) + .map_err(VmExecutionError::from) .and_then(|_| function.apply(evaluated_args, env)) } CallableType::NativeFunction205(_, function, cost_function, cost_input_handle) => { @@ -288,7 +288,7 @@ pub fn apply( evaluated_args.len() as u64 }; runtime_cost(cost_function.clone(), env, cost_input) - .map_err(Error::from) + .map_err(VmExecutionError::from) .and_then(|_| function.apply(evaluated_args, env)) } CallableType::UserFunction(function) => function.apply(&evaluated_args, env), diff --git a/clarity/src/vm/tests/assets.rs b/clarity/src/vm/tests/assets.rs index 0cfeebfb27..c41cd85ef1 100644 --- a/clarity/src/vm/tests/assets.rs +++ b/clarity/src/vm/tests/assets.rs @@ -17,7 +17,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::contexts::{AssetMap, OwnedEnvironment}; -use crate::vm::errors::Error; +use crate::vm::errors::VmExecutionError; use crate::vm::events::StacksTransactionEvent; use crate::vm::representations::SymbolicExpression; use crate::vm::tests::{test_clarity_versions, test_epochs}; @@ -137,7 +137,7 @@ fn execute_transaction( contract_identifier: &QualifiedContractIdentifier, tx: &str, args: &[SymbolicExpression], -) -> Result<(Value, AssetMap, Vec), Error> { +) -> Result<(Value, AssetMap, Vec), VmExecutionError> { env.execute_transaction(issuer, None, contract_identifier.clone(), tx, args) } @@ -622,7 +622,7 @@ fn test_simple_token_system( assert!(matches!( err, - Error::Unchecked(CheckErrors::TypeValueError(_, _)) + VmExecutionError::Unchecked(CheckErrors::TypeValueError(_, _)) )); let (result, asset_map, _events) = execute_transaction( @@ -856,7 +856,7 @@ fn test_total_supply(epoch: StacksEpochId, mut env_factory: TopLevelMemoryEnviro .unwrap_err(); assert!(matches!( err, - Error::Unchecked(CheckErrors::TypeValueError(_, _)) + VmExecutionError::Unchecked(CheckErrors::TypeValueError(_, _)) )); let err = owned_env @@ -869,7 +869,7 @@ fn test_total_supply(epoch: StacksEpochId, mut env_factory: TopLevelMemoryEnviro .unwrap_err(); assert!(matches!( err, - Error::Unchecked(CheckErrors::TypeValueError(_, _)) + VmExecutionError::Unchecked(CheckErrors::TypeValueError(_, _)) )); owned_env @@ -921,7 +921,7 @@ fn test_total_supply(epoch: StacksEpochId, mut env_factory: TopLevelMemoryEnviro .unwrap_err(); println!("{err}"); assert!(match err { - Error::Runtime(RuntimeErrorType::SupplyOverflow(x, y), _) => (x, y) == (6, 5), + VmExecutionError::Runtime(RuntimeErrorType::SupplyOverflow(x, y), _) => (x, y) == (6, 5), _ => false, }); } diff --git a/clarity/src/vm/tests/contracts.rs b/clarity/src/vm/tests/contracts.rs index da9d4f3731..3cfdecf823 100644 --- a/clarity/src/vm/tests/contracts.rs +++ b/clarity/src/vm/tests/contracts.rs @@ -27,7 +27,7 @@ use crate::vm::types::{PrincipalData, QualifiedContractIdentifier, StandardPrinc #[cfg(test)] use crate::vm::{ ast::{errors::ParseErrors, ASTRules}, - errors::{CheckErrors, Error, RuntimeErrorType}, + errors::{CheckErrors, RuntimeErrorType, VmExecutionError}, tests::{ env_factory, execute, is_committed, is_err_code_i128 as is_err_code, symbols_from_values, tl_env_factory, MemoryEnvironmentGenerator, TopLevelMemoryEnvironmentGenerator, @@ -972,7 +972,7 @@ fn test_factorial_contract(epoch: StacksEpochId, mut env_factory: MemoryEnvironm .unwrap_err(); assert!(matches!( err_result, - Error::Unchecked(CheckErrors::NoSuchPublicFunction(_, _)) + VmExecutionError::Unchecked(CheckErrors::NoSuchPublicFunction(_, _)) )); let err_result = env @@ -985,7 +985,7 @@ fn test_factorial_contract(epoch: StacksEpochId, mut env_factory: MemoryEnvironm .unwrap_err(); assert!(matches!( err_result, - Error::Unchecked(CheckErrors::TypeValueError(_, _)) + VmExecutionError::Unchecked(CheckErrors::TypeValueError(_, _)) )); } @@ -1008,7 +1008,7 @@ fn test_at_unknown_block( .unwrap_err(); eprintln!("{err}"); match err { - Error::Runtime(x, _) => assert_eq!( + VmExecutionError::Runtime(x, _) => assert_eq!( x, RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash::from( vec![2_u8; 32].as_slice() @@ -1180,7 +1180,7 @@ fn test_eval_with_non_existing_contract( ); assert_eq!( result.as_ref().unwrap_err(), - &Error::Unchecked(CheckErrors::NoSuchContract( + &VmExecutionError::Unchecked(CheckErrors::NoSuchContract( QualifiedContractIdentifier::local("absent") .unwrap() .to_string() @@ -1382,7 +1382,7 @@ fn test_contract_hash_type_check( .unwrap_err(); assert_eq!( err, - Error::Unchecked(CheckErrors::ExpectedContractPrincipalValue(Box::new( + VmExecutionError::Unchecked(CheckErrors::ExpectedContractPrincipalValue(Box::new( Value::UInt(123) ))) ); @@ -1440,6 +1440,6 @@ fn test_contract_hash_pre_clarity4( assert_eq!( err, - Error::Unchecked(CheckErrors::UndefinedFunction("contract-hash?".to_string())) + VmExecutionError::Unchecked(CheckErrors::UndefinedFunction("contract-hash?".to_string())) ); } diff --git a/clarity/src/vm/tests/datamaps.rs b/clarity/src/vm/tests/datamaps.rs index 83fef9ab76..6f2be1c01c 100644 --- a/clarity/src/vm/tests/datamaps.rs +++ b/clarity/src/vm/tests/datamaps.rs @@ -19,9 +19,9 @@ use crate::vm::{ errors::{CheckErrors, ShortReturnType, SyntaxBindingError}, types::{ListData, SequenceData, TupleTypeSignature, TypeSignature}, }; -use crate::vm::{execute, ClarityName, Error}; +use crate::vm::{execute, ClarityName, VmExecutionError}; -fn assert_executes(expected: Result, input: &str) { +fn assert_executes(expected: Result, input: &str) { assert_eq!(expected.unwrap(), execute(input).unwrap().unwrap()); } @@ -495,7 +495,7 @@ fn lists_system_2() { matches!( execute(test), - Err(Error::Unchecked(CheckErrors::TypeError(_, _))) + Err(VmExecutionError::Unchecked(CheckErrors::TypeError(_, _))) ); } @@ -560,7 +560,10 @@ fn lists_system() { println!("{test:#?}"); assert!(matches!( test, - Err(Error::Unchecked(CheckErrors::TypeValueError(_, _))) + Err(VmExecutionError::Unchecked(CheckErrors::TypeValueError( + _, + _ + ))) )); } } @@ -623,7 +626,7 @@ fn tuples_system() { for test in type_error_tests.iter() { let expected_type_error = match execute(test) { - Err(Error::Unchecked(CheckErrors::TypeValueError(_, _))) => true, + Err(VmExecutionError::Unchecked(CheckErrors::TypeValueError(_, _))) => true, _ => { println!("{:?}", execute(test)); false @@ -643,7 +646,7 @@ fn bad_define_maps() { "(define-map lists { name: int } contents 5)", "(define-map lists { name: int } { contents: (list 5 0 int) })", ]; - let expected: Vec = vec![ + let expected: Vec = vec![ CheckErrors::BadSyntaxBinding(SyntaxBindingError::tuple_cons_invalid_length(0)).into(), CheckErrors::UnknownTypeName("contents".to_string()).into(), CheckErrors::ExpectedName.into(), @@ -769,7 +772,7 @@ fn test_non_tuple_map_get_set() { for test in type_error_tests.iter() { let expected_type_error = match execute(test) { - Err(Error::Unchecked(CheckErrors::TypeValueError(_, _))) => true, + Err(VmExecutionError::Unchecked(CheckErrors::TypeValueError(_, _))) => true, _ => { println!("{:?}", execute(test)); false diff --git a/clarity/src/vm/tests/defines.rs b/clarity/src/vm/tests/defines.rs index 2cd874f2c3..71639778ab 100644 --- a/clarity/src/vm/tests/defines.rs +++ b/clarity/src/vm/tests/defines.rs @@ -21,7 +21,7 @@ use rstest_reuse::{self, *}; #[cfg(test)] use stacks_common::types::StacksEpochId; -use crate::vm::errors::{CheckErrors, Error}; +use crate::vm::errors::{CheckErrors, VmExecutionError}; use crate::vm::tests::test_clarity_versions; #[cfg(test)] use crate::vm::{ @@ -32,8 +32,8 @@ use crate::vm::{ {execute, ClarityVersion}, }; -fn assert_eq_err(e1: CheckErrors, e2: Error) { - let e1: Error = e1.into(); +fn assert_eq_err(e1: CheckErrors, e2: VmExecutionError) { + let e1: VmExecutionError = e1.into(); assert_eq!(e1, e2) } @@ -67,7 +67,7 @@ fn test_accept_options(#[case] version: ClarityVersion, #[case] epoch: StacksEpo format!("{defun} (f (some 1))"), format!("{defun} (f (some true))"), ]; - let expectations: &[Result<_, Error>] = &[ + let expectations: &[Result<_, VmExecutionError>] = &[ Ok(Some(Value::Int(0))), Ok(Some(Value::Int(10))), Err(CheckErrors::TypeValueError( @@ -187,7 +187,10 @@ fn test_stack_depth() { assert_eq!(Ok(Some(Value::Int(64))), execute(&test0)); assert!(matches!( execute(&test1), - Err(Error::Runtime(RuntimeErrorType::MaxStackDepthReached, _)) + Err(VmExecutionError::Runtime( + RuntimeErrorType::MaxStackDepthReached, + _ + )) )) } @@ -474,18 +477,18 @@ fn test_define_trait_arg_count() { // These errors are hit in the trait resolver, before reaching the type-checker match execute(test0).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + VmExecutionError::Runtime(RuntimeErrorType::ASTError(parse_err), _) if *parse_err.err == ParseErrors::DefineTraitBadSignature => {} e => panic!("{e:?}"), }; match execute(test1).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + VmExecutionError::Runtime(RuntimeErrorType::ASTError(parse_err), _) if *parse_err.err == ParseErrors::DefineTraitBadSignature => {} e => panic!("{e}"), }; execute(test2).unwrap(); match execute(test3).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + VmExecutionError::Runtime(RuntimeErrorType::ASTError(parse_err), _) if *parse_err.err == ParseErrors::DefineTraitBadSignature => {} e => panic!("{e}"), }; @@ -500,18 +503,18 @@ fn test_use_trait_arg_count() { // These errors are hit in the trait resolver, before reaching the type-checker match execute(test0).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + VmExecutionError::Runtime(RuntimeErrorType::ASTError(parse_err), _) if *parse_err.err == ParseErrors::ImportTraitBadSignature => {} e => panic!("{e:?}"), }; match execute(test1).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + VmExecutionError::Runtime(RuntimeErrorType::ASTError(parse_err), _) if *parse_err.err == ParseErrors::ImportTraitBadSignature => {} e => panic!("{e}"), }; execute(test2).unwrap(); match execute(test3).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + VmExecutionError::Runtime(RuntimeErrorType::ASTError(parse_err), _) if *parse_err.err == ParseErrors::ImportTraitBadSignature => {} e => panic!("{e}"), }; @@ -525,13 +528,13 @@ fn test_impl_trait_arg_count() { // These errors are hit in the trait resolver, before reaching the type-checker match execute(test0).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + VmExecutionError::Runtime(RuntimeErrorType::ASTError(parse_err), _) if *parse_err.err == ParseErrors::ImplTraitBadSignature => {} e => panic!("{e:?}"), }; execute(test1).unwrap(); match execute(test2).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + VmExecutionError::Runtime(RuntimeErrorType::ASTError(parse_err), _) if *parse_err.err == ParseErrors::ImplTraitBadSignature => {} e => panic!("{e}"), }; diff --git a/clarity/src/vm/tests/sequences.rs b/clarity/src/vm/tests/sequences.rs index 3ea779b7d6..d6e84aaa7b 100644 --- a/clarity/src/vm/tests/sequences.rs +++ b/clarity/src/vm/tests/sequences.rs @@ -22,7 +22,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::tests::test_clarity_versions; #[cfg(test)] use crate::vm::{ - errors::{CheckErrors, Error, RuntimeErrorType}, + errors::{CheckErrors, RuntimeErrorType, VmExecutionError}, execute, execute_v2, types::{ signatures::{ @@ -59,7 +59,7 @@ fn test_simple_list_admission() { ); let err = execute(&t3).unwrap_err(); assert!(match err { - Error::Unchecked(CheckErrors::TypeValueError(_, _)) => true, + VmExecutionError::Unchecked(CheckErrors::TypeValueError(_, _)) => true, _ => { eprintln!("Expected TypeError, but found: {err:?}"); false @@ -129,7 +129,7 @@ fn test_index_of() { for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { match execute(bad_test).unwrap_err() { - Error::Unchecked(check_error) => { + VmExecutionError::Unchecked(check_error) => { assert_eq!(&check_error, expected); } _ => unreachable!("Should have raised unchecked errors"), @@ -179,7 +179,7 @@ fn test_element_at() { for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { match execute(bad_test).unwrap_err() { - Error::Unchecked(check_error) => { + VmExecutionError::Unchecked(check_error) => { assert_eq!(&check_error, expected); } _ => unreachable!("Should have raised unchecked errors"), @@ -1205,23 +1205,23 @@ fn test_construct_bad_list(#[case] version: ClarityVersion, #[case] epoch: Stack #[test] fn test_eval_func_arg_panic() { let test1 = "(fold (lambda (x y) (* x y)) (list 1 2 3 4) 1)"; - let e: Error = CheckErrors::ExpectedName.into(); + let e: VmExecutionError = CheckErrors::ExpectedName.into(); assert_eq!(e, execute(test1).unwrap_err()); let test2 = "(map (lambda (x) (* x x)) (list 1 2 3 4))"; - let e: Error = CheckErrors::ExpectedName.into(); + let e: VmExecutionError = CheckErrors::ExpectedName.into(); assert_eq!(e, execute(test2).unwrap_err()); let test3 = "(map square (list 1 2 3 4) 2)"; - let e: Error = CheckErrors::UndefinedFunction("square".to_string()).into(); + let e: VmExecutionError = CheckErrors::UndefinedFunction("square".to_string()).into(); assert_eq!(e, execute(test3).unwrap_err()); let test4 = "(define-private (multiply-all (x int) (acc int)) (* x acc)) (fold multiply-all (list 1 2 3 4))"; - let e: Error = CheckErrors::IncorrectArgumentCount(3, 2).into(); + let e: VmExecutionError = CheckErrors::IncorrectArgumentCount(3, 2).into(); assert_eq!(e, execute(test4).unwrap_err()); let test5 = "(map + (list 1 2 3 4) 2)"; - let e: Error = CheckErrors::ExpectedSequence(Box::new(IntType)).into(); + let e: VmExecutionError = CheckErrors::ExpectedSequence(Box::new(IntType)).into(); assert_eq!(e, execute(test5).unwrap_err()); } diff --git a/clarity/src/vm/tests/simple_apply_eval.rs b/clarity/src/vm/tests/simple_apply_eval.rs index 53558e3548..368ea21175 100644 --- a/clarity/src/vm/tests/simple_apply_eval.rs +++ b/clarity/src/vm/tests/simple_apply_eval.rs @@ -31,7 +31,7 @@ use crate::vm::callables::DefinedFunction; use crate::vm::contexts::OwnedEnvironment; use crate::vm::costs::LimitedCostTracker; use crate::vm::database::MemoryBackingStore; -use crate::vm::errors::{CheckErrors, Error, RuntimeErrorType, ShortReturnType}; +use crate::vm::errors::{CheckErrors, RuntimeErrorType, ShortReturnType, VmExecutionError}; use crate::vm::tests::{execute, test_clarity_versions}; use crate::vm::types::signatures::*; use crate::vm::types::{ @@ -580,7 +580,7 @@ fn test_secp256k1_errors() { "(principal-of?)", ]; - let expectations: &[Error] = &[ + let expectations: &[VmExecutionError] = &[ CheckErrors::TypeValueError(Box::new(BUFF_32.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("de5b9eb9e7c5592930eb2e30a01369c36586d872082ed8181ee83d2a0ec20f").unwrap() })))).into(), CheckErrors::TypeValueError(Box::new(BUFF_65.clone()), Box::new(Value::Sequence(SequenceData::Buffer(BuffData { data: hex_bytes("8738487ebe69b93d8e51583be8eee50bb4213fc49c767d329632730cc193b873554428fc936ca3569afc15f1c9365f6591d6251a89fee9c9ac661116824d3a130100").unwrap() })))).into(), CheckErrors::IncorrectArgumentCount(2, 1).into(), @@ -877,7 +877,7 @@ fn test_sequence_comparisons_clarity1() { "(>= \"baa\" \"aaa\")", "(<= \"baa\" \"aaa\")", ]; - let error_expectations: &[Error] = &[ + let error_expectations: &[VmExecutionError] = &[ CheckErrors::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(Value::Sequence(SequenceData::String(CharType::ASCII( @@ -988,7 +988,7 @@ fn test_sequence_comparisons_clarity2() { fn test_sequence_comparisons_mismatched_types() { // Tests that comparing objects of different types results in an error in Clarity1. let error_tests = ["(> 0 u1)", "(< 0 u1)"]; - let v1_error_expectations: &[Error] = &[ + let v1_error_expectations: &[VmExecutionError] = &[ CheckErrors::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(Value::Int(0)), @@ -1009,7 +1009,7 @@ fn test_sequence_comparisons_mismatched_types() { assert_eq!(*expectation, vm_execute(program).unwrap_err()) }); - let v2_error_expectations: &[Error] = &[ + let v2_error_expectations: &[VmExecutionError] = &[ CheckErrors::UnionTypeValueError( vec![ TypeSignature::IntType, @@ -1043,7 +1043,7 @@ fn test_sequence_comparisons_mismatched_types() { // Tests that comparing objects of different types results in an error in Clarity2. let error_tests = ["(> \"baa\" u\"aaa\")", "(> \"baa\" 0x0001)"]; - let error_expectations: &[Error] = &[ + let error_expectations: &[VmExecutionError] = &[ CheckErrors::UnionTypeValueError( vec![ TypeSignature::IntType, @@ -1112,7 +1112,7 @@ fn test_simple_arithmetic_errors(#[case] version: ClarityVersion, #[case] epoch: "(is-eq (some 1) (some true))", ]; - let expectations: &[Error] = &[ + let expectations: &[VmExecutionError] = &[ CheckErrors::IncorrectArgumentCount(2, 1).into(), CheckErrors::TypeValueError( Box::new(TypeSignature::IntType), @@ -1167,7 +1167,7 @@ fn test_unsigned_arithmetic() { "(to-int (pow u2 u127))", ]; - let expectations: &[Error] = &[ + let expectations: &[VmExecutionError] = &[ RuntimeErrorType::ArithmeticUnderflow.into(), RuntimeErrorType::ArithmeticUnderflow.into(), CheckErrors::UnionTypeValueError( @@ -1206,7 +1206,7 @@ fn test_options_errors() { "(get field-0 1)", ]; - let expectations: &[Error] = &[ + let expectations: &[VmExecutionError] = &[ CheckErrors::IncorrectArgumentCount(1, 2).into(), CheckErrors::ExpectedOptionalValue(Box::new(Value::Bool(true))).into(), CheckErrors::IncorrectArgumentCount(1, 2).into(), @@ -1244,7 +1244,7 @@ fn test_stx_ops_errors() { "(stx-burn? 4 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR)", ]; - let expectations: &[Error] = &[ + let expectations: &[VmExecutionError] = &[ CheckErrors::IncorrectArgumentCount(3, 2).into(), CheckErrors::BadTransferSTXArguments.into(), CheckErrors::BadTransferSTXArguments.into(), @@ -1318,7 +1318,7 @@ fn test_bitwise() { "(bit-shift-left -64 u121)", // -170141183460469231731687303715884105728 ]; - let expectations: &[Result] = &[ + let expectations: &[Result] = &[ Ok(Value::Int(16)), // (bit-and 24 16) Ok(Value::UInt(16)), // (bit-and u24 u16) Ok(Value::Int(28)), // (bit-xor 24 4)y @@ -1423,7 +1423,7 @@ fn test_option_destructs() { "(try! 1)", ]; - let expectations: &[Result] = &[ + let expectations: &[Result] = &[ Ok(Value::Int(1)), Ok(Value::Int(1)), Err( @@ -1472,7 +1472,7 @@ fn test_hash_errors() { "(sha512/256 1 2)", ]; - let expectations: &[Error] = &[ + let expectations: &[VmExecutionError] = &[ CheckErrors::IncorrectArgumentCount(1, 2).into(), CheckErrors::IncorrectArgumentCount(1, 2).into(), CheckErrors::IncorrectArgumentCount(1, 2).into(), @@ -1573,7 +1573,7 @@ fn test_bad_lets() { "(let ((false 1)) false)", ]; - let expectations: &[Error] = &[ + let expectations: &[VmExecutionError] = &[ CheckErrors::NameAlreadyUsed("tx-sender".to_string()).into(), CheckErrors::NameAlreadyUsed("*".to_string()).into(), CheckErrors::NameAlreadyUsed("a".to_string()).into(), @@ -1674,11 +1674,11 @@ fn test_asserts_short_circuit() { "(begin (asserts! (is-eq 1 1) (err 0)) (asserts! (is-eq 2 1) (err 1)) (ok 2))", ]; - let expectations: &[Error] = &[ - Error::ShortReturn(ShortReturnType::AssertionFailed(Box::new( + let expectations: &[VmExecutionError] = &[ + VmExecutionError::ShortReturn(ShortReturnType::AssertionFailed(Box::new( Value::error(Value::Int(0)).unwrap(), ))), - Error::ShortReturn(ShortReturnType::AssertionFailed(Box::new( + VmExecutionError::ShortReturn(ShortReturnType::AssertionFailed(Box::new( Value::error(Value::Int(1)).unwrap(), ))), ]; diff --git a/clarity/src/vm/tests/traits.rs b/clarity/src/vm/tests/traits.rs index 09c95cdbcc..cc7f3e54f9 100644 --- a/clarity/src/vm/tests/traits.rs +++ b/clarity/src/vm/tests/traits.rs @@ -22,7 +22,7 @@ use crate::vm::tests::{test_clarity_versions, test_epochs}; #[cfg(test)] use crate::vm::{ ast::ASTRules, - errors::{CheckErrors, Error}, + errors::{CheckErrors, VmExecutionError}, tests::{env_factory, execute, symbols_from_values}, types::{PrincipalData, QualifiedContractIdentifier, Value}, version::ClarityVersion, @@ -251,7 +251,7 @@ fn test_dynamic_dispatch_intra_contract_call( ) .unwrap_err(); match err_result { - Error::Unchecked(CheckErrors::CircularReference(_)) => {} + VmExecutionError::Unchecked(CheckErrors::CircularReference(_)) => {} _ => panic!("{err_result:?}"), } } @@ -582,7 +582,7 @@ fn test_dynamic_dispatch_mismatched_args( ) .unwrap_err(); match err_result { - Error::Unchecked(CheckErrors::BadTraitImplementation(_, _)) => {} + VmExecutionError::Unchecked(CheckErrors::BadTraitImplementation(_, _)) => {} _ => panic!("{err_result:?}"), } } @@ -639,7 +639,7 @@ fn test_dynamic_dispatch_mismatched_returned( ) .unwrap_err(); match err_result { - Error::Unchecked(CheckErrors::ReturnTypesMustMatch(_, _)) => {} + VmExecutionError::Unchecked(CheckErrors::ReturnTypesMustMatch(_, _)) => {} _ => panic!("{err_result:?}"), } } @@ -699,7 +699,7 @@ fn test_reentrant_dynamic_dispatch( ) .unwrap_err(); match err_result { - Error::Unchecked(CheckErrors::CircularReference(_)) => {} + VmExecutionError::Unchecked(CheckErrors::CircularReference(_)) => {} _ => panic!("{err_result:?}"), } } @@ -756,7 +756,7 @@ fn test_readwrite_dynamic_dispatch( ) .unwrap_err(); match err_result { - Error::Unchecked(CheckErrors::TraitBasedContractCallInReadOnly) => {} + VmExecutionError::Unchecked(CheckErrors::TraitBasedContractCallInReadOnly) => {} _ => panic!("{err_result:?}"), } } @@ -813,7 +813,7 @@ fn test_readwrite_violation_dynamic_dispatch( ) .unwrap_err(); match err_result { - Error::Unchecked(CheckErrors::TraitBasedContractCallInReadOnly) => {} + VmExecutionError::Unchecked(CheckErrors::TraitBasedContractCallInReadOnly) => {} _ => panic!("{err_result:?}"), } } diff --git a/clarity/src/vm/tests/variables.rs b/clarity/src/vm/tests/variables.rs index f1a0f16e13..bd737abde7 100644 --- a/clarity/src/vm/tests/variables.rs +++ b/clarity/src/vm/tests/variables.rs @@ -25,7 +25,7 @@ use crate::vm::{ analysis::type_checker::v2_1::tests::contracts::type_check_version, ast::{parse, ASTRules}, database::MemoryBackingStore, - errors::{CheckErrors, Error}, + errors::{CheckErrors, VmExecutionError}, tests::{tl_env_factory, TopLevelMemoryEnvironmentGenerator}, types::{PrincipalData, QualifiedContractIdentifier, Value}, ClarityVersion, ContractContext, @@ -81,7 +81,9 @@ fn test_block_height( if version >= ClarityVersion::Clarity3 { let err = eval_result.unwrap_err(); assert_eq!( - Error::Unchecked(CheckErrors::UndefinedVariable("block-height".to_string(),)), + VmExecutionError::Unchecked( + CheckErrors::UndefinedVariable("block-height".to_string(),) + ), err ); } else { @@ -139,7 +141,7 @@ fn test_stacks_block_height( if version < ClarityVersion::Clarity3 { let err = eval_result.unwrap_err(); assert_eq!( - Error::Unchecked(CheckErrors::UndefinedVariable( + VmExecutionError::Unchecked(CheckErrors::UndefinedVariable( "stacks-block-height".to_string(), )), err @@ -199,7 +201,9 @@ fn test_tenure_height( if version < ClarityVersion::Clarity3 { let err = eval_result.unwrap_err(); assert_eq!( - Error::Unchecked(CheckErrors::UndefinedVariable("tenure-height".to_string(),)), + VmExecutionError::Unchecked(CheckErrors::UndefinedVariable( + "tenure-height".to_string(), + )), err ); } else { @@ -273,7 +277,7 @@ fn expect_contract_error( for (when, err_condition, expected_error) in expected_errors { if *when == WhenError::Initialization && err_condition(version, epoch) { let err = init_result.unwrap_err(); - if let Error::Unchecked(inner_err) = &err { + if let VmExecutionError::Unchecked(inner_err) = &err { assert_eq!(expected_error, inner_err); } else { panic!("Expected an Unchecked error, but got a different error"); @@ -292,7 +296,7 @@ fn expect_contract_error( for (when, err_condition, expected_error) in expected_errors { if *when == WhenError::Runtime && err_condition(version, epoch) { let err = eval_result.unwrap_err(); - if let Error::Unchecked(inner_err) = &err { + if let VmExecutionError::Unchecked(inner_err) = &err { assert_eq!(expected_error, inner_err); } else { panic!("Expected an Unchecked error, but got a different error"); @@ -1161,7 +1165,7 @@ fn test_block_time( if version < ClarityVersion::Clarity4 { let err = eval_result.unwrap_err(); assert_eq!( - Error::Unchecked(CheckErrors::UndefinedVariable("block-time".to_string(),)), + VmExecutionError::Unchecked(CheckErrors::UndefinedVariable("block-time".to_string(),)), err ); } else { @@ -1287,7 +1291,7 @@ fn test_current_contract( if version < ClarityVersion::Clarity4 { let err = eval_result.unwrap_err(); assert_eq!( - Error::Unchecked(CheckErrors::UndefinedVariable( + VmExecutionError::Unchecked(CheckErrors::UndefinedVariable( "current-contract".to_string(), )), err diff --git a/clarity/src/vm/types/serialization.rs b/clarity/src/vm/types/serialization.rs index 16e62f2409..79d413f0da 100644 --- a/clarity/src/vm/types/serialization.rs +++ b/clarity/src/vm/types/serialization.rs @@ -22,7 +22,7 @@ pub use clarity_types::types::serialization::{ use stacks_common::util::hash::{hex_bytes, to_hex}; use crate::vm::database::{ClarityDeserializable, ClaritySerializable}; -use crate::vm::errors::{Error as ClarityError, InterpreterError}; +use crate::vm::errors::{InterpreterError, VmExecutionError}; impl ClaritySerializable for u32 { fn serialize(&self) -> String { @@ -31,7 +31,7 @@ impl ClaritySerializable for u32 { } impl ClarityDeserializable for u32 { - fn deserialize(input: &str) -> Result { + fn deserialize(input: &str) -> Result { let bytes = hex_bytes(input).map_err(|_| { InterpreterError::Expect("u32 deserialization: failed decoding bytes.".into()) })?; diff --git a/clarity/src/vm/version.rs b/clarity/src/vm/version.rs index 41226cfad9..604cfce90d 100644 --- a/clarity/src/vm/version.rs +++ b/clarity/src/vm/version.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use stacks_common::types::StacksEpochId; -use crate::vm::errors::{Error, RuntimeErrorType}; +use crate::vm::errors::{RuntimeErrorType, VmExecutionError}; #[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, PartialOrd)] pub enum ClarityVersion { @@ -51,9 +51,9 @@ impl ClarityVersion { } impl FromStr for ClarityVersion { - type Err = Error; + type Err = VmExecutionError; - fn from_str(version: &str) -> Result { + fn from_str(version: &str) -> Result { let s = version.to_string().to_lowercase(); if s == "clarity1" { Ok(ClarityVersion::Clarity1) diff --git a/pox-locking/src/events.rs b/pox-locking/src/events.rs index 3a71083673..986447b0d1 100644 --- a/pox-locking/src/events.rs +++ b/pox-locking/src/events.rs @@ -17,7 +17,7 @@ use clarity::vm::ast::ASTRules; use clarity::vm::contexts::GlobalContext; use clarity::vm::costs::LimitedCostTracker; -use clarity::vm::errors::Error as ClarityError; +use clarity::vm::errors::VmExecutionError; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier, ResponseData, TupleData}; use clarity::vm::Value; #[cfg(any(test, feature = "testing"))] @@ -566,7 +566,7 @@ pub fn synthesize_pox_event_info( function_name: &str, args: &[Value], response: &ResponseData, -) -> Result, ClarityError> { +) -> Result, VmExecutionError> { // the first thing we do is check the current epoch. In Epochs <= 2.4, // synthesizing PoX events was an assessed cost, so event generation // must remain identical. @@ -611,7 +611,7 @@ fn inner_synthesize_pox_event_info( function_name: &str, args: &[Value], response: &ResponseData, -) -> Result, ClarityError> { +) -> Result, VmExecutionError> { let sender = match sender_opt { Some(sender) => sender, None => { @@ -690,7 +690,7 @@ fn inner_synthesize_pox_event_info( Ok(Value::Tuple(event_tuple)) }, ) - .map_err(|e: ClarityError| { + .map_err(|e: VmExecutionError| { error!("Failed to synthesize PoX event: {:?}", &e); e })?; diff --git a/pox-locking/src/events_24.rs b/pox-locking/src/events_24.rs index 40c10de905..c8017d6f96 100644 --- a/pox-locking/src/events_24.rs +++ b/pox-locking/src/events_24.rs @@ -16,7 +16,7 @@ use clarity::vm::ast::ASTRules; use clarity::vm::contexts::GlobalContext; -use clarity::vm::errors::Error as ClarityError; +use clarity::vm::errors::VmExecutionError; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier, TupleData}; use clarity::vm::Value; #[cfg(any(test, feature = "testing"))] @@ -344,7 +344,7 @@ pub fn synthesize_pox_2_or_3_event_info( sender_opt: Option<&PrincipalData>, function_name: &str, args: &[Value], -) -> Result, ClarityError> { +) -> Result, VmExecutionError> { let sender = match sender_opt { Some(sender) => sender, None => { @@ -422,7 +422,7 @@ pub fn synthesize_pox_2_or_3_event_info( Ok(Value::Tuple(event_tuple)) }, ) - .map_err(|e: ClarityError| { + .map_err(|e: VmExecutionError| { error!("Failed to synthesize PoX event: {:?}", &e); e })?; diff --git a/pox-locking/src/lib.rs b/pox-locking/src/lib.rs index 16c11c8af2..3b3ab9bb92 100644 --- a/pox-locking/src/lib.rs +++ b/pox-locking/src/lib.rs @@ -26,7 +26,7 @@ //! invoked. If so, it updates the PoX lock. use clarity::boot_util::boot_code_id; use clarity::vm::contexts::GlobalContext; -use clarity::vm::errors::{Error as ClarityError, RuntimeErrorType}; +use clarity::vm::errors::{RuntimeErrorType, VmExecutionError}; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use clarity::vm::Value; use stacks_common::types::StacksEpochId; @@ -48,11 +48,11 @@ pub enum LockingError { PoxExtendNotLocked, PoxIncreaseOnV1, PoxInvalidIncrease, - Clarity(ClarityError), + Clarity(VmExecutionError), } -impl From for LockingError { - fn from(e: ClarityError) -> LockingError { +impl From for LockingError { + fn from(e: VmExecutionError) -> LockingError { LockingError::Clarity(e) } } @@ -71,7 +71,7 @@ pub fn handle_contract_call_special_cases( function_name: &str, args: &[Value], result: &Value, -) -> Result<(), ClarityError> { +) -> Result<(), VmExecutionError> { if *contract_id == boot_code_id(POX_1_NAME, global_context.mainnet) { if !pox_1::is_read_only(function_name) && global_context.database.get_v1_unlock_height() @@ -86,7 +86,7 @@ pub fn handle_contract_call_special_cases( "function_name" => function_name, "contract_id" => %contract_id ); - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )); @@ -101,7 +101,7 @@ pub fn handle_contract_call_special_cases( "function_name" => function_name, "contract_id" => %contract_id ); - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )); @@ -124,7 +124,7 @@ pub fn handle_contract_call_special_cases( "function_name" => function_name, "contract_id" => %contract_id ); - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )); diff --git a/pox-locking/src/pox_1.rs b/pox-locking/src/pox_1.rs index 4cc7ffe0ea..c55f134cee 100644 --- a/pox-locking/src/pox_1.rs +++ b/pox-locking/src/pox_1.rs @@ -19,7 +19,7 @@ use clarity::vm::contexts::GlobalContext; use clarity::vm::costs::cost_functions::ClarityCostFunction; use clarity::vm::costs::runtime_cost; use clarity::vm::database::ClarityDatabase; -use clarity::vm::errors::{Error as ClarityError, RuntimeErrorType}; +use clarity::vm::errors::{RuntimeErrorType, VmExecutionError}; use clarity::vm::events::{STXEventType, STXLockEventData, StacksTransactionEvent}; use clarity::vm::types::PrincipalData; use clarity::vm::Value; @@ -131,7 +131,7 @@ pub fn handle_contract_call( _sender_opt: Option<&PrincipalData>, function_name: &str, value: &Value, -) -> Result<(), ClarityError> { +) -> Result<(), VmExecutionError> { if !(function_name == "stack-stx" || function_name == "delegate-stack-stx") { // only have work to do if the function is `stack-stx` or `delegate-stack-stx` return Ok(()); @@ -181,14 +181,14 @@ pub fn handle_contract_call( return Ok(()); } Err(LockingError::DefunctPoxContract) => { - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )); } Err(LockingError::PoxAlreadyLocked) => { // the caller tried to lock tokens into both pox-1 and pox-2 - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::PoxAlreadyLocked, None, )); diff --git a/pox-locking/src/pox_2.rs b/pox-locking/src/pox_2.rs index 1cbb1cd772..5249fe726c 100644 --- a/pox-locking/src/pox_2.rs +++ b/pox-locking/src/pox_2.rs @@ -19,7 +19,7 @@ use clarity::vm::contexts::GlobalContext; use clarity::vm::costs::cost_functions::ClarityCostFunction; use clarity::vm::costs::runtime_cost; use clarity::vm::database::{ClarityDatabase, STXBalance}; -use clarity::vm::errors::{Error as ClarityError, RuntimeErrorType}; +use clarity::vm::errors::{RuntimeErrorType, VmExecutionError}; use clarity::vm::events::{STXEventType, STXLockEventData, StacksTransactionEvent}; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use clarity::vm::{Environment, Value}; @@ -295,7 +295,7 @@ fn handle_stack_lockup_pox_v2( global_context: &mut GlobalContext, function_name: &str, value: &Value, -) -> Result, ClarityError> { +) -> Result, VmExecutionError> { debug!( "Handle special-case contract-call to {:?} {} (which returned {:?})", "PoX-2 contract", function_name, value @@ -332,14 +332,14 @@ fn handle_stack_lockup_pox_v2( return Ok(Some(event)); } Err(LockingError::DefunctPoxContract) => { - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )); } Err(LockingError::PoxAlreadyLocked) => { // the caller tried to lock tokens into both pox-1 and pox-2 - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::PoxAlreadyLocked, None, )); @@ -360,7 +360,7 @@ fn handle_stack_lockup_extension_pox_v2( global_context: &mut GlobalContext, function_name: &str, value: &Value, -) -> Result, ClarityError> { +) -> Result, VmExecutionError> { // in this branch case, the PoX-2 contract has stored the extension information // and performed the extension checks. Now, the VM needs to update the account locks // (because the locks cannot be applied directly from the Clarity code itself) @@ -400,7 +400,7 @@ fn handle_stack_lockup_extension_pox_v2( return Ok(Some(event)); } Err(LockingError::DefunctPoxContract) => { - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )); @@ -424,7 +424,7 @@ fn handle_stack_lockup_increase_pox_v2( global_context: &mut GlobalContext, function_name: &str, value: &Value, -) -> Result, ClarityError> { +) -> Result, VmExecutionError> { // in this branch case, the PoX-2 contract has stored the increase information // and performed the increase checks. Now, the VM needs to update the account locks // (because the locks cannot be applied directly from the Clarity code itself) @@ -463,7 +463,7 @@ fn handle_stack_lockup_increase_pox_v2( return Ok(Some(event)); } Err(LockingError::DefunctPoxContract) => { - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )); @@ -488,7 +488,7 @@ pub fn handle_contract_call( function_name: &str, args: &[Value], value: &Value, -) -> Result<(), ClarityError> { +) -> Result<(), VmExecutionError> { // Generate a synthetic print event for all functions that alter stacking state let print_event_opt = if let Value::Response(response) = value { if response.committed { diff --git a/pox-locking/src/pox_3.rs b/pox-locking/src/pox_3.rs index 265ec59208..4ee474edb2 100644 --- a/pox-locking/src/pox_3.rs +++ b/pox-locking/src/pox_3.rs @@ -19,7 +19,7 @@ use clarity::vm::contexts::GlobalContext; use clarity::vm::costs::cost_functions::ClarityCostFunction; use clarity::vm::costs::runtime_cost; use clarity::vm::database::{ClarityDatabase, STXBalance}; -use clarity::vm::errors::{Error as ClarityError, RuntimeErrorType}; +use clarity::vm::errors::{RuntimeErrorType, VmExecutionError}; use clarity::vm::events::{STXEventType, STXLockEventData, StacksTransactionEvent}; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use clarity::vm::{Environment, Value}; @@ -184,7 +184,7 @@ fn handle_stack_lockup_pox_v3( global_context: &mut GlobalContext, function_name: &str, value: &Value, -) -> Result, ClarityError> { +) -> Result, VmExecutionError> { debug!( "Handle special-case contract-call to {:?} {} (which returned {:?})", boot_code_id(POX_3_NAME, global_context.mainnet), @@ -223,14 +223,14 @@ fn handle_stack_lockup_pox_v3( return Ok(Some(event)); } Err(LockingError::DefunctPoxContract) => { - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )); } Err(LockingError::PoxAlreadyLocked) => { // the caller tried to lock tokens into multiple pox contracts - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::PoxAlreadyLocked, None, )); @@ -251,7 +251,7 @@ fn handle_stack_lockup_extension_pox_v3( global_context: &mut GlobalContext, function_name: &str, value: &Value, -) -> Result, ClarityError> { +) -> Result, VmExecutionError> { // in this branch case, the PoX-3 contract has stored the extension information // and performed the extension checks. Now, the VM needs to update the account locks // (because the locks cannot be applied directly from the Clarity code itself) @@ -291,7 +291,7 @@ fn handle_stack_lockup_extension_pox_v3( return Ok(Some(event)); } Err(LockingError::DefunctPoxContract) => { - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )); @@ -315,7 +315,7 @@ fn handle_stack_lockup_increase_pox_v3( global_context: &mut GlobalContext, function_name: &str, value: &Value, -) -> Result, ClarityError> { +) -> Result, VmExecutionError> { // in this branch case, the PoX-3 contract has stored the increase information // and performed the increase checks. Now, the VM needs to update the account locks // (because the locks cannot be applied directly from the Clarity code itself) @@ -353,7 +353,7 @@ fn handle_stack_lockup_increase_pox_v3( return Ok(Some(event)); } Err(LockingError::DefunctPoxContract) => { - return Err(ClarityError::Runtime( + return Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )); @@ -378,7 +378,7 @@ pub fn handle_contract_call( function_name: &str, args: &[Value], value: &Value, -) -> Result<(), ClarityError> { +) -> Result<(), VmExecutionError> { // Generate a synthetic print event for all functions that alter stacking state let print_event_opt = if let Value::Response(response) = value { if response.committed { diff --git a/pox-locking/src/pox_4.rs b/pox-locking/src/pox_4.rs index 733d6d6c54..134cdfcc7e 100644 --- a/pox-locking/src/pox_4.rs +++ b/pox-locking/src/pox_4.rs @@ -19,7 +19,7 @@ use clarity::vm::contexts::GlobalContext; use clarity::vm::costs::cost_functions::ClarityCostFunction; use clarity::vm::costs::runtime_cost; use clarity::vm::database::{ClarityDatabase, STXBalance}; -use clarity::vm::errors::{Error as ClarityError, RuntimeErrorType}; +use clarity::vm::errors::{RuntimeErrorType, VmExecutionError}; use clarity::vm::events::{STXEventType, STXLockEventData, StacksTransactionEvent}; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use clarity::vm::{Environment, Value}; @@ -154,7 +154,7 @@ fn handle_stack_lockup_pox_v4( global_context: &mut GlobalContext, function_name: &str, value: &Value, -) -> Result, ClarityError> { +) -> Result, VmExecutionError> { debug!( "Handle special-case contract-call to {:?} {function_name} (which returned {value:?})", boot_code_id(POX_4_NAME, global_context.mainnet) @@ -190,13 +190,13 @@ fn handle_stack_lockup_pox_v4( })); Ok(Some(event)) } - Err(LockingError::DefunctPoxContract) => Err(ClarityError::Runtime( + Err(LockingError::DefunctPoxContract) => Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )), Err(LockingError::PoxAlreadyLocked) => { // the caller tried to lock tokens into multiple pox contracts - Err(ClarityError::Runtime( + Err(VmExecutionError::Runtime( RuntimeErrorType::PoxAlreadyLocked, None, )) @@ -215,7 +215,7 @@ fn handle_stack_lockup_extension_pox_v4( global_context: &mut GlobalContext, function_name: &str, value: &Value, -) -> Result, ClarityError> { +) -> Result, VmExecutionError> { // in this branch case, the PoX-4 contract has stored the extension information // and performed the extension checks. Now, the VM needs to update the account locks // (because the locks cannot be applied directly from the Clarity code itself) @@ -252,7 +252,7 @@ fn handle_stack_lockup_extension_pox_v4( })); Ok(Some(event)) } - Err(LockingError::DefunctPoxContract) => Err(ClarityError::Runtime( + Err(LockingError::DefunctPoxContract) => Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )), @@ -271,7 +271,7 @@ fn handle_stack_lockup_increase_pox_v4( global_context: &mut GlobalContext, function_name: &str, value: &Value, -) -> Result, ClarityError> { +) -> Result, VmExecutionError> { // in this branch case, the PoX-4 contract has stored the increase information // and performed the increase checks. Now, the VM needs to update the account locks // (because the locks cannot be applied directly from the Clarity code itself) @@ -308,7 +308,7 @@ fn handle_stack_lockup_increase_pox_v4( Ok(Some(event)) } - Err(LockingError::DefunctPoxContract) => Err(ClarityError::Runtime( + Err(LockingError::DefunctPoxContract) => Err(VmExecutionError::Runtime( RuntimeErrorType::DefunctPoxContract, None, )), @@ -329,7 +329,7 @@ pub fn handle_contract_call( function_name: &str, args: &[Value], value: &Value, -) -> Result<(), ClarityError> { +) -> Result<(), VmExecutionError> { // Generate a synthetic print event for all functions that alter stacking state let print_event_opt = if let Value::Response(response) = value { if response.committed { diff --git a/stacks-signer/src/client/mod.rs b/stacks-signer/src/client/mod.rs index e518ff4a7b..50bd7bbe35 100644 --- a/stacks-signer/src/client/mod.rs +++ b/stacks-signer/src/client/mod.rs @@ -21,7 +21,7 @@ pub(crate) mod stacks_client; use std::time::Duration; -use clarity::vm::errors::Error as ClarityError; +use clarity::vm::errors::VmExecutionError; use clarity::vm::types::serialization::SerializationError; use libsigner::RPCError; use libstackerdb::Error as StackerDBError; @@ -81,7 +81,7 @@ pub enum ClientError { NotConnected, /// Clarity interpreter error #[error("Clarity interpreter error: {0}")] - ClarityError(#[from] ClarityError), + ClarityError(#[from] VmExecutionError), /// Malformed reward set #[error("Malformed contract data: {0}")] MalformedContractData(String), diff --git a/stackslib/src/blockstack_cli.rs b/stackslib/src/blockstack_cli.rs index bcf23757e7..93847ccd01 100644 --- a/stackslib/src/blockstack_cli.rs +++ b/stackslib/src/blockstack_cli.rs @@ -42,7 +42,7 @@ use blockstack_lib::clarity_cli::vm_execute; use blockstack_lib::core::{CHAIN_ID_MAINNET, CHAIN_ID_TESTNET}; use blockstack_lib::net::Error as NetError; use blockstack_lib::util_lib::strings::StacksString; -use clarity::vm::errors::{Error as ClarityError, RuntimeErrorType}; +use clarity::vm::errors::{RuntimeErrorType, VmExecutionError}; use clarity::vm::types::PrincipalData; use clarity::vm::{ClarityName, ClarityVersion, ContractName, Value}; use stacks_common::address::{b58, AddressHashMode}; @@ -190,7 +190,7 @@ block's sqlite database."; #[derive(Debug)] enum CliError { ClarityRuntimeError(RuntimeErrorType), - ClarityGeneralError(ClarityError), + ClarityGeneralError(VmExecutionError), Message(String), Usage, InvalidChainId(std::num::ParseIntError), @@ -230,8 +230,8 @@ impl From for CliError { } } -impl From for CliError { - fn from(value: ClarityError) -> Self { +impl From for CliError { + fn from(value: VmExecutionError) -> Self { CliError::ClarityGeneralError(value) } } diff --git a/stackslib/src/chainstate/coordinator/tests.rs b/stackslib/src/chainstate/coordinator/tests.rs index d948f08a55..1ce3b3afbc 100644 --- a/stackslib/src/chainstate/coordinator/tests.rs +++ b/stackslib/src/chainstate/coordinator/tests.rs @@ -23,7 +23,7 @@ use std::sync::Arc; use clarity::vm::clarity::TransactionConnection; use clarity::vm::costs::{ExecutionCost, LimitedCostTracker}; use clarity::vm::database::BurnStateDB; -use clarity::vm::errors::Error as InterpreterError; +use clarity::vm::errors::VmExecutionError; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use clarity::vm::Value; use lazy_static::lazy_static; @@ -4834,7 +4834,7 @@ fn get_total_stacked_info( parent_tip: &StacksBlockId, reward_cycle: u64, is_pox_2: bool, -) -> Result { +) -> Result { chainstate .with_read_only_clarity_tx(burn_dbconn, parent_tip, |conn| { conn.with_readonly_clarity_env( diff --git a/stackslib/src/chainstate/stacks/boot/contract_tests.rs b/stackslib/src/chainstate/stacks/boot/contract_tests.rs index 7514ba3632..b29b0806c0 100644 --- a/stackslib/src/chainstate/stacks/boot/contract_tests.rs +++ b/stackslib/src/chainstate/stacks/boot/contract_tests.rs @@ -7,7 +7,7 @@ use clarity::vm::ast::ASTRules; use clarity::vm::clarity::TransactionConnection; use clarity::vm::contexts::OwnedEnvironment; use clarity::vm::database::*; -use clarity::vm::errors::{CheckErrors, Error}; +use clarity::vm::errors::{CheckErrors, VmExecutionError}; use clarity::vm::test_util::{execute, symbols_from_values, TEST_BURN_STATE_DB, TEST_HEADER_DB}; use clarity::vm::types::{ OptionalData, PrincipalData, QualifiedContractIdentifier, ResponseData, StandardPrincipalData, @@ -1746,7 +1746,7 @@ fn simple_epoch21_test() { ClarityError::Interpreter(e) => { assert_eq!( e, - Error::Unchecked(CheckErrors::NameAlreadyUsed("stx-account".into())) + VmExecutionError::Unchecked(CheckErrors::NameAlreadyUsed("stx-account".into())) ); } e => panic!("Should have caused an Interpreter error: {:#?}", e), diff --git a/stackslib/src/chainstate/stacks/boot/mod.rs b/stackslib/src/chainstate/stacks/boot/mod.rs index 83afc46301..d58526fc14 100644 --- a/stackslib/src/chainstate/stacks/boot/mod.rs +++ b/stackslib/src/chainstate/stacks/boot/mod.rs @@ -24,7 +24,7 @@ use clarity::vm::ast::ASTRules; use clarity::vm::clarity::{Error as ClarityError, TransactionConnection}; use clarity::vm::costs::LimitedCostTracker; use clarity::vm::database::{ClarityDatabase, NULL_BURN_STATE_DB, NULL_HEADER_DB}; -use clarity::vm::errors::Error as VmError; +use clarity::vm::errors::VmExecutionError; use clarity::vm::events::StacksTransactionEvent; use clarity::vm::representations::ContractName; use clarity::vm::types::{ @@ -366,7 +366,7 @@ impl StacksChainState { fn mark_pox_cycle_handled( db: &mut ClarityDatabase, cycle_number: u64, - ) -> Result<(), clarity::vm::errors::Error> { + ) -> Result<(), VmExecutionError> { let db_key = Self::handled_pox_cycle_start_key(cycle_number); db.put_data(&db_key, &POX_CYCLE_START_HANDLED_VALUE.to_string())?; Ok(()) @@ -1362,7 +1362,7 @@ impl StacksChainState { // Catch the epoch boundary edge case where burn height >= pox 3 activation height, but // there hasn't yet been a Stacks block. match result { - Err(Error::ClarityError(ClarityError::Interpreter(VmError::Unchecked( + Err(Error::ClarityError(ClarityError::Interpreter(VmExecutionError::Unchecked( CheckErrors::NoSuchContract(_), )))) => { warn!("Reward cycle attempted to calculate rewards before the PoX contract was instantiated"); diff --git a/stackslib/src/chainstate/stacks/db/blocks.rs b/stackslib/src/chainstate/stacks/db/blocks.rs index 061fba56bc..84dff43b46 100644 --- a/stackslib/src/chainstate/stacks/db/blocks.rs +++ b/stackslib/src/chainstate/stacks/db/blocks.rs @@ -24,6 +24,7 @@ use clarity::vm::ast::ASTRules; use clarity::vm::clarity::TransactionConnection; use clarity::vm::costs::LimitedCostTracker; use clarity::vm::database::BurnStateDB; +use clarity::vm::errors::VmExecutionError; use clarity::vm::types::{ BuffData, PrincipalData, QualifiedContractIdentifier, SequenceData, StacksAddressExtensions as ClarityStacksAddressExtensions, StandardPrincipalData, TupleData, @@ -307,8 +308,8 @@ impl From for MemPoolRejection { } } -impl From for MemPoolRejection { - fn from(e: clarity::vm::errors::Error) -> MemPoolRejection { +impl From for MemPoolRejection { + fn from(e: VmExecutionError) -> MemPoolRejection { MemPoolRejection::Other(e.to_string()) } } @@ -3929,7 +3930,7 @@ impl StacksChainState { ) -> Result<(bool, Vec), Error> { // is this stacks block the first of a new epoch? let (stacks_parent_epoch, sortition_epoch) = clarity_tx - .with_clarity_db_readonly::<_, Result<_, clarity::vm::errors::Error>>(|db| { + .with_clarity_db_readonly::<_, Result<_, VmExecutionError>>(|db| { Ok(( db.get_clarity_epoch_version()?, db.get_stacks_epoch(chain_tip_burn_header_height), @@ -6628,17 +6629,16 @@ impl StacksChainState { } let (block_height, v1_unlock_height, v2_unlock_height, v3_unlock_height) = - clarity_connection - .with_clarity_db_readonly::<_, Result<_, clarity::vm::errors::Error>>( - |ref mut db| { - Ok(( - db.get_current_burnchain_block_height()? as u64, - db.get_v1_unlock_height(), - db.get_v2_unlock_height()?, - db.get_v3_unlock_height()?, - )) - }, - )?; + clarity_connection.with_clarity_db_readonly::<_, Result<_, VmExecutionError>>( + |ref mut db| { + Ok(( + db.get_current_burnchain_block_height()? as u64, + db.get_v1_unlock_height(), + db.get_v2_unlock_height()?, + db.get_v3_unlock_height()?, + )) + }, + )?; // 6: the paying account must have enough funds if !payer.stx_balance.can_transfer_at_burn_block( diff --git a/stackslib/src/chainstate/stacks/db/contracts.rs b/stackslib/src/chainstate/stacks/db/contracts.rs index 11b2ee0d02..6569dbd9eb 100644 --- a/stackslib/src/chainstate/stacks/db/contracts.rs +++ b/stackslib/src/chainstate/stacks/db/contracts.rs @@ -16,7 +16,7 @@ pub use clarity::vm::analysis::errors::CheckErrors; use clarity::vm::contracts::Contract; -use clarity::vm::errors::Error as clarity_vm_error; +use clarity::vm::errors::VmExecutionError; use clarity::vm::types::{QualifiedContractIdentifier, Value}; use crate::chainstate::stacks::db::*; @@ -31,7 +31,7 @@ impl StacksChainState { clarity_tx .with_clarity_db_readonly(|ref mut db| match db.get_contract(contract_id) { Ok(c) => Ok(Some(c)), - Err(clarity_vm_error::Unchecked(CheckErrors::NoSuchContract(_))) => Ok(None), + Err(VmExecutionError::Unchecked(CheckErrors::NoSuchContract(_))) => Ok(None), Err(e) => Err(clarity_error::Interpreter(e)), }) .map_err(Error::ClarityError) @@ -47,7 +47,7 @@ impl StacksChainState { .with_clarity_db_readonly(|ref mut db| { match db.lookup_variable_unknown_descriptor(contract_id, data_var, &epoch) { Ok(c) => Ok(Some(c)), - Err(clarity_vm_error::Unchecked(CheckErrors::NoSuchDataVariable(_))) => { + Err(VmExecutionError::Unchecked(CheckErrors::NoSuchDataVariable(_))) => { Ok(None) } Err(e) => Err(clarity_error::Interpreter(e)), diff --git a/stackslib/src/chainstate/stacks/db/transactions.rs b/stackslib/src/chainstate/stacks/db/transactions.rs index 2deee7b642..526af55cbb 100644 --- a/stackslib/src/chainstate/stacks/db/transactions.rs +++ b/stackslib/src/chainstate/stacks/db/transactions.rs @@ -23,7 +23,7 @@ use clarity::vm::clarity::TransactionConnection; use clarity::vm::contexts::{AssetMap, AssetMapEntry, Environment}; use clarity::vm::costs::cost_functions::ClarityCostFunction; use clarity::vm::costs::{runtime_cost, CostTracker, ExecutionCost}; -use clarity::vm::errors::Error as InterpreterError; +use clarity::vm::errors::{InterpreterError, VmExecutionError}; use clarity::vm::representations::ClarityName; use clarity::vm::types::{ AssetIdentifier, BuffData, PrincipalData, QualifiedContractIdentifier, SequenceData, @@ -44,12 +44,12 @@ use crate::util_lib::strings::VecDisplay; struct HashableClarityValue(Value); impl TryFrom for HashableClarityValue { - type Error = InterpreterError; + type Error = VmExecutionError; fn try_from(value: Value) -> Result { // check that serialization _will_ be successful when hashed let _bytes = value.serialize_to_vec().map_err(|_| { - InterpreterError::Interpreter(clarity::vm::errors::InterpreterError::Expect( + VmExecutionError::Interpreter(InterpreterError::Expect( "Failed to serialize asset in NFT during post-condition checks".into(), )) })?; @@ -376,22 +376,22 @@ pub enum ClarityRuntimeTxError { pub fn handle_clarity_runtime_error(error: clarity_error) -> ClarityRuntimeTxError { match error { // runtime errors are okay - clarity_error::Interpreter(InterpreterError::Runtime(_, _)) => { + clarity_error::Interpreter(VmExecutionError::Runtime(_, _)) => { ClarityRuntimeTxError::Acceptable { error, err_type: "runtime error", } } - clarity_error::Interpreter(InterpreterError::ShortReturn(_)) => { + clarity_error::Interpreter(VmExecutionError::ShortReturn(_)) => { ClarityRuntimeTxError::Acceptable { error, err_type: "short return/panic", } } - clarity_error::Interpreter(InterpreterError::Unchecked(check_error)) => { + clarity_error::Interpreter(VmExecutionError::Unchecked(check_error)) => { if check_error.rejectable() { ClarityRuntimeTxError::Rejectable(clarity_error::Interpreter( - InterpreterError::Unchecked(check_error), + VmExecutionError::Unchecked(check_error), )) } else { ClarityRuntimeTxError::AnalysisError(check_error) @@ -633,7 +633,7 @@ impl StacksChainState { origin_account: &StacksAccount, asset_map: &AssetMap, txid: Txid, - ) -> Result, InterpreterError> { + ) -> Result, VmExecutionError> { let mut checked_fungible_assets: HashMap> = HashMap::new(); let mut checked_nonfungible_assets: HashMap< @@ -962,7 +962,7 @@ impl StacksChainState { env.add_memory(u64::from( TypeSignature::PrincipalType .size() - .map_err(InterpreterError::from)?, + .map_err(VmExecutionError::from)?, )) .map_err(|e| Error::from_cost_error(e, cost_before.clone(), env.global_context))?; @@ -1213,7 +1213,7 @@ impl StacksChainState { "function_args" => %VecDisplay(&contract_call.function_args), "error" => %check_error); return Err(Error::ClarityError(clarity_error::Interpreter( - InterpreterError::Unchecked(check_error), + VmExecutionError::Unchecked(check_error), ))); } } @@ -1455,7 +1455,7 @@ impl StacksChainState { "contract" => %contract_id, "error" => %check_error); return Err(Error::ClarityError(clarity_error::Interpreter( - InterpreterError::Unchecked(check_error), + VmExecutionError::Unchecked(check_error), ))); } } @@ -9814,7 +9814,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(clarity_error::Interpreter(VmExecutionError::Unchecked( _check_error, ))) = err { @@ -9871,7 +9871,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(clarity_error::Interpreter(VmExecutionError::Unchecked( _check_error, ))) = err { @@ -9926,7 +9926,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(clarity_error::Interpreter(VmExecutionError::Unchecked( _check_error, ))) = err { @@ -9982,7 +9982,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(clarity_error::Interpreter(VmExecutionError::Unchecked( _check_error, ))) = err { @@ -10506,7 +10506,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(clarity_error::Interpreter(VmExecutionError::Unchecked( check_error, ))) = err { @@ -10980,7 +10980,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(clarity_error::Interpreter(VmExecutionError::Unchecked( check_error, ))) = err { @@ -11095,7 +11095,7 @@ pub mod test { ASTRules::PrecheckSize, ) .unwrap_err(); - if let Error::ClarityError(clarity_error::Interpreter(InterpreterError::Unchecked( + if let Error::ClarityError(clarity_error::Interpreter(VmExecutionError::Unchecked( check_error, ))) = err { diff --git a/stackslib/src/chainstate/stacks/miner.rs b/stackslib/src/chainstate/stacks/miner.rs index a6837e5c4f..8675075746 100644 --- a/stackslib/src/chainstate/stacks/miner.rs +++ b/stackslib/src/chainstate/stacks/miner.rs @@ -25,7 +25,7 @@ use std::time::Instant; use clarity::vm::ast::errors::ParseErrors; use clarity::vm::ast::ASTRules; use clarity::vm::database::BurnStateDB; -use clarity::vm::errors::Error as InterpreterError; +use clarity::vm::errors::VmExecutionError; use serde::Deserialize; use stacks_common::codec::StacksMessageCodec; use stacks_common::types::chainstate::{ @@ -675,7 +675,7 @@ impl TransactionResult { } ClarityRuntimeTxError::AnalysisError(e) => { let clarity_err = Error::ClarityError(clarity_error::Interpreter( - InterpreterError::Unchecked(e), + VmExecutionError::Unchecked(e), )); if epoch_id < StacksEpochId::Epoch21 { // this would invalidate the block, so it's problematic diff --git a/stackslib/src/chainstate/stacks/mod.rs b/stackslib/src/chainstate/stacks/mod.rs index 7bf4d87c5d..9a0f43b890 100644 --- a/stackslib/src/chainstate/stacks/mod.rs +++ b/stackslib/src/chainstate/stacks/mod.rs @@ -19,7 +19,7 @@ use std::{error, fmt, io}; use clarity::vm::contexts::GlobalContext; use clarity::vm::costs::{CostErrors, ExecutionCost}; -use clarity::vm::errors::Error as clarity_interpreter_error; +use clarity::vm::errors::VmExecutionError; use clarity::vm::representations::{ClarityName, ContractName}; use clarity::vm::types::{ PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, Value, @@ -342,8 +342,8 @@ impl From for Error { } } -impl From for Error { - fn from(e: clarity_interpreter_error) -> Error { +impl From for Error { + fn from(e: VmExecutionError) -> Error { Error::ClarityError(clarity_error::Interpreter(e)) } } diff --git a/stackslib/src/clarity_cli.rs b/stackslib/src/clarity_cli.rs index 1ae8f648de..c54db47e15 100644 --- a/stackslib/src/clarity_cli.rs +++ b/stackslib/src/clarity_cli.rs @@ -51,7 +51,7 @@ use crate::clarity::vm::costs::{ExecutionCost, LimitedCostTracker}; use crate::clarity::vm::database::{ BurnStateDB, ClarityDatabase, HeadersDB, STXBalance, NULL_BURN_STATE_DB, }; -use crate::clarity::vm::errors::{Error, InterpreterResult, RuntimeErrorType}; +use crate::clarity::vm::errors::{InterpreterResult, RuntimeErrorType, VmExecutionError}; use crate::clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use crate::clarity::vm::{ analysis, ast, eval_all, ClarityVersion, ContractContext, ContractName, SymbolicExpression, @@ -149,7 +149,7 @@ fn parse( contract_identifier: &QualifiedContractIdentifier, source_code: &str, clarity_version: ClarityVersion, -) -> Result, Error> { +) -> Result, VmExecutionError> { let ast = build_ast_with_rules( contract_identifier, source_code, @@ -442,7 +442,10 @@ where /// Execute program in a transient environment. To be used only by CLI tools /// for program evaluation, not by consensus critical code. -pub fn vm_execute(program: &str, clarity_version: ClarityVersion) -> Result, Error> { +pub fn vm_execute( + program: &str, + clarity_version: ClarityVersion, +) -> Result, VmExecutionError> { let contract_id = QualifiedContractIdentifier::transient(); let mut contract_context = ContractContext::new(contract_id.clone(), clarity_version); let mut marf = MemoryBackingStore::new(); @@ -784,13 +787,13 @@ fn get_eval_input(invoked_by: &str, args: &[String]) -> EvalInput { let mut buffer = String::new(); friendly_expect( io::stdin().read_to_string(&mut buffer), - "Error reading from stdin.", + "VmExecutionError reading from stdin.", ); buffer } else { friendly_expect( fs::read_to_string(&args[2]), - &format!("Error reading file: {}", args[2]), + &format!("VmExecutionError reading file: {}", args[2]), ) } }; @@ -1004,13 +1007,13 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option = @@ -1121,7 +1124,10 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option (i32, Option (i32, Option buffer, Err(error) => { - eprintln!("Error reading from stdin:\n{error}"); + eprintln!("VmExecutionError reading from stdin:\n{error}"); panic_test!(); } } @@ -1310,7 +1316,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option (i32, Option (i32, Option (i32, Option { where A: FnOnce(&AssetMap, &mut ClarityDatabase) -> Option, F: FnOnce(&mut OwnedEnvironment) -> Result<(R, AssetMap, Vec), E>, - E: From, + E: From, { using!(self.log, "log", |log| { using!(self.cost_track, "cost tracker", |cost_track| { @@ -2071,7 +2071,7 @@ impl ClarityTransactionConnection<'_, '_> { rollback_wrapper.depth() ); } - rollback_wrapper.commit().map_err(InterpreterError::from)?; + rollback_wrapper.commit().map_err(VmExecutionError::from)?; // now we can reset the memory usage for the edit-log self.cost_track .as_mut() diff --git a/stackslib/src/clarity_vm/special.rs b/stackslib/src/clarity_vm/special.rs index 64e4188128..9f01c8526e 100644 --- a/stackslib/src/clarity_vm/special.rs +++ b/stackslib/src/clarity_vm/special.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . use clarity::vm::contexts::GlobalContext; -use clarity::vm::errors::Error as ClarityError; +use clarity::vm::errors::VmExecutionError; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier, Value}; /// Handle special cases of contract-calls -- namely, those into PoX that should lock up STX @@ -27,7 +27,7 @@ pub fn handle_contract_call_special_cases( function_name: &str, args: &[Value], result: &Value, -) -> Result<(), ClarityError> { +) -> Result<(), VmExecutionError> { pox_locking::handle_contract_call_special_cases( global_context, sender, diff --git a/stackslib/src/clarity_vm/tests/contracts.rs b/stackslib/src/clarity_vm/tests/contracts.rs index 27a9023e46..72cfc25453 100644 --- a/stackslib/src/clarity_vm/tests/contracts.rs +++ b/stackslib/src/clarity_vm/tests/contracts.rs @@ -17,7 +17,7 @@ use clarity::types::StacksEpochId; use clarity::vm::ast::ASTRules; use clarity::vm::clarity::Error as ClarityError; -use clarity::vm::errors::{CheckErrors, Error}; +use clarity::vm::errors::{CheckErrors, VmExecutionError}; use clarity::vm::types::SequenceData::Buffer; use clarity::vm::types::{ BuffData, OptionalData, PrincipalData, QualifiedContractIdentifier, TupleData, TypeSignature, @@ -461,7 +461,7 @@ fn trait_invocation_cross_epoch() { ) .unwrap_err(); - if let ClarityError::Interpreter(Error::Unchecked(CheckErrors::TypeValueError(trait_ref_type, value))) = error { + if let ClarityError::Interpreter(VmExecutionError::Unchecked(CheckErrors::TypeValueError(trait_ref_type, value))) = error { assert!(matches!(*trait_ref_type, TypeSignature::TraitReferenceType(_))); } else { panic!("Expected an Interpreter(UncheckedError(TypeValue(TraitReferenceType, Principal))) during Epoch-2.2"); @@ -485,7 +485,7 @@ fn trait_invocation_cross_epoch() { ) .unwrap_err(); - if let ClarityError::Interpreter(Error::Unchecked(CheckErrors::TypeValueError(trait_ref_type, value))) = error { + if let ClarityError::Interpreter(VmExecutionError::Unchecked(CheckErrors::TypeValueError(trait_ref_type, value))) = error { assert!(matches!(*trait_ref_type, TypeSignature::TraitReferenceType(_))); } else { panic!("Expected an Interpreter(UncheckedError(TypeValue(TraitReferenceType, Principal))) during Epoch-2.2"); diff --git a/stackslib/src/clarity_vm/tests/costs.rs b/stackslib/src/clarity_vm/tests/costs.rs index d710a799fc..dfd39fd1e2 100644 --- a/stackslib/src/clarity_vm/tests/costs.rs +++ b/stackslib/src/clarity_vm/tests/costs.rs @@ -23,7 +23,7 @@ use clarity::vm::costs::{ DefaultVersion, ExecutionCost, LimitedCostTracker, COSTS_1_NAME, COSTS_2_NAME, COSTS_3_NAME, COSTS_4_NAME, }; -use clarity::vm::errors::Error; +use clarity::vm::errors::VmExecutionError; use clarity::vm::events::StacksTransactionEvent; use clarity::vm::functions::NativeFunctions; use clarity::vm::representations::SymbolicExpression; @@ -175,7 +175,7 @@ fn execute_transaction( contract_identifier: &QualifiedContractIdentifier, tx: &str, args: &[SymbolicExpression], -) -> Result<(Value, AssetMap, Vec), Error> { +) -> Result<(Value, AssetMap, Vec), VmExecutionError> { env.execute_transaction(issuer, None, contract_identifier.clone(), tx, args) } diff --git a/stackslib/src/clarity_vm/tests/forking.rs b/stackslib/src/clarity_vm/tests/forking.rs index 6dc3305562..bd6d96924e 100644 --- a/stackslib/src/clarity_vm/tests/forking.rs +++ b/stackslib/src/clarity_vm/tests/forking.rs @@ -17,7 +17,7 @@ use clarity::vm::analysis::errors::CheckErrors; use clarity::vm::ast::ASTRules; use clarity::vm::contexts::OwnedEnvironment; -use clarity::vm::errors::{Error, InterpreterResult as Result, RuntimeErrorType}; +use clarity::vm::errors::{InterpreterResult as Result, RuntimeErrorType, VmExecutionError}; use clarity::vm::test_util::{ execute, is_committed, is_err_code, symbols_from_values, TEST_BURN_STATE_DB, TEST_HEADER_DB, }; @@ -189,7 +189,7 @@ fn test_at_block_good(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc let resp = branch(x, version, 1, "reset").unwrap_err(); eprintln!("{}", resp); match resp { - Error::Runtime(x, _) => assert_eq!( + VmExecutionError::Runtime(x, _) => assert_eq!( x, RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash::from( vec![2; 32].as_slice() @@ -225,7 +225,7 @@ fn test_at_block_missing_defines(#[case] version: ClarityVersion, #[case] epoch: .unwrap(); } - fn initialize_2(owned_env: &mut OwnedEnvironment) -> Error { + fn initialize_2(owned_env: &mut OwnedEnvironment) -> VmExecutionError { let c_b = QualifiedContractIdentifier::local("contract-b").unwrap(); let contract = "(define-private (problematic-cc) diff --git a/stackslib/src/clarity_vm/tests/large_contract.rs b/stackslib/src/clarity_vm/tests/large_contract.rs index b90216bd96..dc5dff0074 100644 --- a/stackslib/src/clarity_vm/tests/large_contract.rs +++ b/stackslib/src/clarity_vm/tests/large_contract.rs @@ -20,7 +20,7 @@ use clarity::vm::ast::{self, ASTRules}; use clarity::vm::clarity::{ClarityConnection, TransactionConnection}; use clarity::vm::contexts::OwnedEnvironment; use clarity::vm::database::HeadersDB; -use clarity::vm::errors::Error as InterpreterError; +use clarity::vm::errors::VmExecutionError; use clarity::vm::test_util::*; use clarity::vm::tests::{test_clarity_versions, BurnStateDB}; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier, Value}; @@ -1255,7 +1255,7 @@ fn test_deep_tuples() { }); match error { - ClarityError::Interpreter(InterpreterError::Runtime(r_e, _)) => { + ClarityError::Interpreter(VmExecutionError::Runtime(r_e, _)) => { eprintln!("Runtime error: {:?}", r_e); } other => { @@ -1324,7 +1324,7 @@ fn test_deep_tuples_ast_precheck() { }); match error { - ClarityError::Interpreter(InterpreterError::Runtime(r_e, _)) => { + ClarityError::Interpreter(VmExecutionError::Runtime(r_e, _)) => { eprintln!("Runtime error: {:?}", r_e); } other => { @@ -1399,7 +1399,7 @@ fn test_deep_type_nesting() { }); match error { - ClarityError::Interpreter(InterpreterError::Runtime(r_e, _)) => { + ClarityError::Interpreter(VmExecutionError::Runtime(r_e, _)) => { eprintln!("Runtime error: {:?}", r_e); } other => { diff --git a/stackslib/src/clarity_vm/tests/simple_tests.rs b/stackslib/src/clarity_vm/tests/simple_tests.rs index 0fb38cdf9e..053f378e3c 100644 --- a/stackslib/src/clarity_vm/tests/simple_tests.rs +++ b/stackslib/src/clarity_vm/tests/simple_tests.rs @@ -1,5 +1,5 @@ use clarity::vm::contexts::OwnedEnvironment; -use clarity::vm::errors::{Error, RuntimeErrorType}; +use clarity::vm::errors::{RuntimeErrorType, VmExecutionError}; use clarity::vm::test_util::{TEST_BURN_STATE_DB, TEST_HEADER_DB}; use clarity::vm::types::QualifiedContractIdentifier; use stacks_common::consts::{FIRST_BURNCHAIN_CONSENSUS_HASH, FIRST_STACKS_BLOCK_HASH}; @@ -62,7 +62,7 @@ fn test_at_unknown_block() { .unwrap_err(); eprintln!("{}", err); match err { - Error::Runtime(x, _) => assert_eq!( + VmExecutionError::Runtime(x, _) => assert_eq!( x, RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash::from( vec![2; 32].as_slice() diff --git a/stackslib/src/net/api/callreadonly.rs b/stackslib/src/net/api/callreadonly.rs index cc9715b172..96f5c089a1 100644 --- a/stackslib/src/net/api/callreadonly.rs +++ b/stackslib/src/net/api/callreadonly.rs @@ -18,7 +18,7 @@ use clarity::vm::analysis::CheckErrors; use clarity::vm::ast::parser::v1::CLARITY_NAME_REGEX; use clarity::vm::clarity::ClarityConnection; use clarity::vm::costs::{ExecutionCost, LimitedCostTracker}; -use clarity::vm::errors::Error::Unchecked; +use clarity::vm::errors::VmExecutionError::Unchecked; use clarity::vm::representations::{CONTRACT_NAME_REGEX_STRING, STANDARD_PRINCIPAL_REGEX_STRING}; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use clarity::vm::{ClarityName, ContractName, SymbolicExpression, Value}; diff --git a/stackslib/src/net/api/fastcallreadonly.rs b/stackslib/src/net/api/fastcallreadonly.rs index cabd8c9db2..1f5a2902ad 100644 --- a/stackslib/src/net/api/fastcallreadonly.rs +++ b/stackslib/src/net/api/fastcallreadonly.rs @@ -19,7 +19,7 @@ use clarity::vm::analysis::CheckErrors; use clarity::vm::ast::parser::v1::CLARITY_NAME_REGEX; use clarity::vm::clarity::ClarityConnection; use clarity::vm::costs::{ExecutionCost, LimitedCostTracker}; -use clarity::vm::errors::Error::Unchecked; +use clarity::vm::errors::VmExecutionError::Unchecked; use clarity::vm::representations::{CONTRACT_NAME_REGEX_STRING, STANDARD_PRINCIPAL_REGEX_STRING}; use clarity::vm::types::PrincipalData; use clarity::vm::{ClarityName, ContractName, SymbolicExpression, Value}; diff --git a/stackslib/src/net/mod.rs b/stackslib/src/net/mod.rs index 1dd559c0cf..bdb8116d08 100644 --- a/stackslib/src/net/mod.rs +++ b/stackslib/src/net/mod.rs @@ -19,7 +19,7 @@ use std::io::{Read, Write}; use std::net::{IpAddr, SocketAddr}; use std::{error, fmt, io}; -use clarity::vm::errors::Error as InterpreterError; +use clarity::vm::errors::VmExecutionError; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use libstackerdb::{Error as libstackerdb_error, StackerDBChunkData}; use p2p::{DropReason, DropSource}; @@ -533,8 +533,8 @@ impl From for Error { } } -impl From for Error { - fn from(e: InterpreterError) -> Self { +impl From for Error { + fn from(e: VmExecutionError) -> Self { Error::ClarityError(e.into()) } } From 4b9257cc4b358461bfe0aa6f3330ecc19ac8bd60 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 16:07:39 -0700 Subject: [PATCH 20/34] Add descriptions to VmExecutionError and its variants Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/mod.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 8037ed7f7b..fd66681c22 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -39,13 +39,19 @@ pub struct IncomparableError { } #[derive(Debug)] +/// Errors that can occur during the runtime execution, including type-checking +/// failures, interpreter issues, runtime errors, and premature returns. pub enum VmExecutionError { /// UncheckedErrors are errors that *should* be caught by the - /// TypeChecker and other check passes. Test executions may - /// trigger these errors. + /// TypeChecker and other check passes. Test executions may + /// trigger these errors. Unchecked(CheckErrors), + /// Errors originating from the interpreter during program execution. + /// These *should never* occur. Test executions may trigger these errors Interpreter(InterpreterError), + /// Errors that occur during runtime execution, with an optional stack trace. Runtime(RuntimeErrorType, Option), + /// Errors triggered during Clarity contract evaluation that cause early termination. ShortReturn(ShortReturnType), } From a54136f44fa7a7a50ed868304188e09a9e2a5cfc Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 16:20:40 -0700 Subject: [PATCH 21/34] Rename RuntimeErrorType to RuntimeError Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/mod.rs | 14 ++--- clarity-types/src/representations.rs | 10 ++-- clarity-types/src/tests/representations.rs | 6 +-- clarity-types/src/tests/types/mod.rs | 34 ++++++------ clarity-types/src/types/mod.rs | 18 +++---- clarity/src/vm/contexts.rs | 16 +++--- clarity/src/vm/costs/cost_functions.rs | 8 +-- clarity/src/vm/costs/costs_1.rs | 54 +++++++++---------- clarity/src/vm/costs/costs_2.rs | 54 +++++++++---------- clarity/src/vm/costs/costs_2_testnet.rs | 54 +++++++++---------- clarity/src/vm/costs/costs_3.rs | 6 +-- clarity/src/vm/costs/mod.rs | 4 +- clarity/src/vm/database/clarity_db.rs | 20 +++---- clarity/src/vm/database/sqlite.rs | 6 +-- clarity/src/vm/database/structures.rs | 4 +- clarity/src/vm/errors.rs | 3 +- clarity/src/vm/functions/arithmetic.rs | 27 +++++----- clarity/src/vm/functions/assets.rs | 20 +++---- clarity/src/vm/functions/database.rs | 4 +- clarity/src/vm/functions/options.rs | 6 +-- clarity/src/vm/functions/sequences.rs | 8 +-- clarity/src/vm/mod.rs | 4 +- clarity/src/vm/tests/assets.rs | 6 +-- clarity/src/vm/tests/contracts.rs | 14 +++-- clarity/src/vm/tests/defines.rs | 20 +++---- clarity/src/vm/tests/representations.rs | 6 +-- clarity/src/vm/tests/sequences.rs | 10 ++-- clarity/src/vm/tests/simple_apply_eval.rs | 44 +++++++-------- clarity/src/vm/variables.rs | 12 ++--- clarity/src/vm/version.rs | 4 +- pox-locking/src/lib.rs | 8 +-- pox-locking/src/pox_1.rs | 9 ++-- pox-locking/src/pox_2.rs | 13 ++--- pox-locking/src/pox_3.rs | 13 ++--- pox-locking/src/pox_4.rs | 13 ++--- stackslib/src/blockstack_cli.rs | 8 +-- stackslib/src/clarity_cli.rs | 4 +- stackslib/src/clarity_vm/database/marf.rs | 12 ++--- stackslib/src/clarity_vm/database/mod.rs | 4 +- stackslib/src/clarity_vm/tests/forking.rs | 4 +- .../src/clarity_vm/tests/simple_tests.rs | 6 +-- stackslib/src/util_lib/strings.rs | 6 +-- 42 files changed, 282 insertions(+), 314 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 58b42b8a99..1ec676d102 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -45,7 +45,7 @@ pub enum Error { /// trigger these errors. Unchecked(CheckErrors), Interpreter(InterpreterError), - Runtime(RuntimeErrorType, Option), + Runtime(RuntimeError, Option), ShortReturn(ShortReturnType), } @@ -72,7 +72,7 @@ pub enum InterpreterError { /// RuntimeErrors are errors that smart contracts are expected /// to be able to trigger during execution (e.g., arithmetic errors) #[derive(Debug, PartialEq)] -pub enum RuntimeErrorType { +pub enum RuntimeError { Arithmetic(String), ArithmeticOverflow, ArithmeticUnderflow, @@ -147,7 +147,7 @@ impl fmt::Display for Error { } } -impl fmt::Display for RuntimeErrorType { +impl fmt::Display for RuntimeError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{self:?}") } @@ -159,7 +159,7 @@ impl error::Error for Error { } } -impl error::Error for RuntimeErrorType { +impl error::Error for RuntimeError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { None } @@ -171,7 +171,7 @@ impl From for Error { ParseErrors::InterpreterFailure => Error::from(InterpreterError::Expect( "Unexpected interpreter failure during parsing".into(), )), - _ => Error::from(RuntimeErrorType::ASTError(Box::new(err))), + _ => Error::from(RuntimeError::ASTError(Box::new(err))), } } } @@ -190,8 +190,8 @@ impl From for Error { } } -impl From for Error { - fn from(err: RuntimeErrorType) -> Self { +impl From for Error { + fn from(err: RuntimeError) -> Self { Error::Runtime(err, None) } } diff --git a/clarity-types/src/representations.rs b/clarity-types/src/representations.rs index e941e9b7ec..a6e2fe8263 100644 --- a/clarity-types/src/representations.rs +++ b/clarity-types/src/representations.rs @@ -23,7 +23,7 @@ use regex::Regex; use stacks_common::codec::{Error as codec_error, StacksMessageCodec, read_next, write_next}; use crate::Value; -use crate::errors::RuntimeErrorType; +use crate::errors::RuntimeError; use crate::types::TraitIdentifier; pub const CONTRACT_MIN_NAME_LENGTH: usize = 1; @@ -66,8 +66,8 @@ guarded_string!( "ClarityName", CLARITY_NAME_REGEX, MAX_STRING_LEN, - RuntimeErrorType, - RuntimeErrorType::BadNameValue + RuntimeError, + RuntimeError::BadNameValue ); guarded_string!( @@ -75,8 +75,8 @@ guarded_string!( "ContractName", CONTRACT_NAME_REGEX, MAX_STRING_LEN, - RuntimeErrorType, - RuntimeErrorType::BadNameValue + RuntimeError, + RuntimeError::BadNameValue ); impl StacksMessageCodec for ClarityName { diff --git a/clarity-types/src/tests/representations.rs b/clarity-types/src/tests/representations.rs index ac395809c7..0d00f7bc87 100644 --- a/clarity-types/src/tests/representations.rs +++ b/clarity-types/src/tests/representations.rs @@ -15,7 +15,7 @@ use rstest::rstest; -use crate::errors::RuntimeErrorType; +use crate::errors::RuntimeError; use crate::representations::{ CONTRACT_MAX_NAME_LENGTH, CONTRACT_MIN_NAME_LENGTH, ClarityName, ContractName, MAX_STRING_LEN, }; @@ -73,7 +73,7 @@ fn test_clarity_name_invalid(#[case] name: &str) { assert!(result.is_err()); assert!(matches!( result.unwrap_err(), - RuntimeErrorType::BadNameValue(_, _) + RuntimeError::BadNameValue(_, _) )); } @@ -157,7 +157,7 @@ fn test_contract_name_invalid(#[case] name: &str) { assert!(result.is_err()); assert!(matches!( result.unwrap_err(), - RuntimeErrorType::BadNameValue(_, _) + RuntimeError::BadNameValue(_, _) )); } diff --git a/clarity-types/src/tests/types/mod.rs b/clarity-types/src/tests/types/mod.rs index 8c8d861c7c..b4ed2b2504 100644 --- a/clarity-types/src/tests/types/mod.rs +++ b/clarity-types/src/tests/types/mod.rs @@ -19,7 +19,7 @@ use rstest::rstest; use stacks_common::types::StacksEpochId; use crate::Error; -use crate::errors::{CheckErrors, InterpreterError, RuntimeErrorType}; +use crate::errors::{CheckErrors, InterpreterError, RuntimeError}; use crate::types::{ ASCIIData, BuffData, CharType, ListTypeData, MAX_VALUE_SIZE, PrincipalData, QualifiedContractIdentifier, SequenceData, SequencedValue as _, StandardPrincipalData, @@ -255,7 +255,7 @@ fn test_qualified_contract_identifier_local_returns_runtime_error() { let err = QualifiedContractIdentifier::local("1nvalid-name") .expect_err("Unexpected qualified contract identifier"); assert_eq!( - Error::from(RuntimeErrorType::BadNameValue( + Error::from(RuntimeError::BadNameValue( "ContractName", "1nvalid-name".into() )), @@ -264,18 +264,18 @@ fn test_qualified_contract_identifier_local_returns_runtime_error() { } #[rstest] -#[case::too_short("S162RK3CHJPCSSK6BM757FW", RuntimeErrorType::ParseError( +#[case::too_short("S162RK3CHJPCSSK6BM757FW", RuntimeError::ParseError( "Invalid principal literal: Expected 20 data bytes.".to_string(), ))] -#[case::too_long("S1C5H66S35CSKK6CK1C9HP8SB6CWSK4RB2CDJK8HY4", RuntimeErrorType::ParseError( +#[case::too_long("S1C5H66S35CSKK6CK1C9HP8SB6CWSK4RB2CDJK8HY4", RuntimeError::ParseError( "Invalid principal literal: Expected 20 data bytes.".to_string(), ))] -#[case::invalid_c32("II2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0G", RuntimeErrorType::ParseError( +#[case::invalid_c32("II2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0G", RuntimeError::ParseError( "Invalid principal literal: base58ck checksum 0x1074d4f7 does not match expected 0xae29c6e0".to_string(), ))] fn test_principal_data_parse_standard_principal_returns_runtime_error( #[case] input: &str, - #[case] expected_err: RuntimeErrorType, + #[case] expected_err: RuntimeError, ) { let err = PrincipalData::parse_standard_principal(input).expect_err("Unexpected principal data"); @@ -283,15 +283,15 @@ fn test_principal_data_parse_standard_principal_returns_runtime_error( } #[rstest] -#[case::no_dot("SM2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0Gcontract-name", RuntimeErrorType::ParseError( +#[case::no_dot("SM2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0Gcontract-name", RuntimeError::ParseError( "Invalid principal literal: expected a `.` in a qualified contract name" .to_string(), ))] -#[case::invalid_contract_name("SM2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0G.1nvalid-name", RuntimeErrorType::BadNameValue("ContractName", "1nvalid-name".into()))] +#[case::invalid_contract_name("SM2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0G.1nvalid-name", RuntimeError::BadNameValue("ContractName", "1nvalid-name".into()))] fn test_qualified_contract_identifier_parse_returns_interpreter_error( #[case] input: &str, - #[case] expected_err: RuntimeErrorType, + #[case] expected_err: RuntimeError, ) { let err = QualifiedContractIdentifier::parse(input) .expect_err("Unexpected qualified contract identifier"); @@ -299,18 +299,18 @@ fn test_qualified_contract_identifier_parse_returns_interpreter_error( } #[rstest] -#[case::no_dot("SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-traitnft-trait", RuntimeErrorType::ParseError( +#[case::no_dot("SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-traitnft-trait", RuntimeError::ParseError( "Invalid principal literal: expected a `.` in a qualified contract name" .to_string(), ))] -#[case::invalid_contract_name("SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.1nvalid-contract.valid-trait", RuntimeErrorType::BadNameValue("ContractName", "1nvalid-contract".into()))] -#[case::invalid_trait_name("SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.valid-contract.1nvalid-trait", RuntimeErrorType::BadNameValue("ClarityName", "1nvalid-trait".into()))] -#[case::invalid_standard_principal("S162RK3CHJPCSSK6BM757FW.valid-contract.valid-trait", RuntimeErrorType::ParseError( +#[case::invalid_contract_name("SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.1nvalid-contract.valid-trait", RuntimeError::BadNameValue("ContractName", "1nvalid-contract".into()))] +#[case::invalid_trait_name("SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.valid-contract.1nvalid-trait", RuntimeError::BadNameValue("ClarityName", "1nvalid-trait".into()))] +#[case::invalid_standard_principal("S162RK3CHJPCSSK6BM757FW.valid-contract.valid-trait", RuntimeError::ParseError( "Invalid principal literal: Expected 20 data bytes.".to_string(), ))] fn test_trait_identifier_parse_returns_runtime_error( #[case] input: &str, - #[case] expected_err: RuntimeErrorType, + #[case] expected_err: RuntimeError, ) { let expected_err = Error::from(expected_err); @@ -323,13 +323,13 @@ fn test_trait_identifier_parse_returns_runtime_error( } #[rstest] -#[case::bad_type_construction(".valid-contract.valid-trait", RuntimeErrorType::BadTypeConstruction)] -#[case::forwards_parse_errors("S162RK3CHJPCSSK6BM757FW.valid-contract.valid-trait", RuntimeErrorType::ParseError( +#[case::bad_type_construction(".valid-contract.valid-trait", RuntimeError::BadTypeConstruction)] +#[case::forwards_parse_errors("S162RK3CHJPCSSK6BM757FW.valid-contract.valid-trait", RuntimeError::ParseError( "Invalid principal literal: Expected 20 data bytes.".to_string(), ))] fn test_trait_identifier_parse_fully_qualified_returns_runtime_error( #[case] input: &str, - #[case] expected_err: RuntimeErrorType, + #[case] expected_err: RuntimeError, ) { let err = TraitIdentifier::parse_fully_qualified(input).expect_err("Unexpected trait identifier"); diff --git a/clarity-types/src/types/mod.rs b/clarity-types/src/types/mod.rs index c28dc0c275..285524b520 100644 --- a/clarity-types/src/types/mod.rs +++ b/clarity-types/src/types/mod.rs @@ -37,7 +37,7 @@ pub use self::signatures::{ ListTypeData, SequenceSubtype, StringSubtype, StringUTF8Length, TupleTypeSignature, TypeSignature, }; -use crate::errors::{CheckErrors, InterpreterError, InterpreterResult as Result, RuntimeErrorType}; +use crate::errors::{CheckErrors, InterpreterError, InterpreterResult as Result, RuntimeError}; use crate::representations::{ClarityName, ContractName, SymbolicExpression}; // use crate::vm::ClarityVersion; @@ -187,7 +187,7 @@ impl QualifiedContractIdentifier { pub fn parse(literal: &str) -> Result { let split: Vec<_> = literal.splitn(2, '.').collect(); if split.len() != 2 { - return Err(RuntimeErrorType::ParseError( + return Err(RuntimeError::ParseError( "Invalid principal literal: expected a `.` in a qualified contract name" .to_string(), ) @@ -275,7 +275,7 @@ impl TraitIdentifier { pub fn parse_fully_qualified(literal: &str) -> Result { let (issuer, contract_name, name) = Self::parse(literal)?; - let issuer = issuer.ok_or(RuntimeErrorType::BadTypeConstruction)?; + let issuer = issuer.ok_or(RuntimeError::BadTypeConstruction)?; Ok(TraitIdentifier::new(issuer, contract_name, name)) } @@ -289,7 +289,7 @@ impl TraitIdentifier { ) -> Result<(Option, ContractName, ClarityName)> { let split: Vec<_> = literal.splitn(3, '.').collect(); if split.len() != 3 { - return Err(RuntimeErrorType::ParseError( + return Err(RuntimeError::ParseError( "Invalid principal literal: expected a `.` in a qualified contract name" .to_string(), ) @@ -396,10 +396,10 @@ impl SequenceData { if let Value::Sequence(data) = &element { let elem_length = data.len(); if elem_length != 1 { - return Err(RuntimeErrorType::BadTypeConstruction.into()); + return Err(RuntimeError::BadTypeConstruction.into()); } } else { - return Err(RuntimeErrorType::BadTypeConstruction.into()); + return Err(RuntimeError::BadTypeConstruction.into()); } } if index >= seq_length { @@ -573,7 +573,7 @@ impl SequenceData { SequenceData::String(CharType::UTF8(inner_data)), SequenceData::String(CharType::UTF8(ref mut other_inner_data)), ) => inner_data.append(other_inner_data), - _ => Err(RuntimeErrorType::BadTypeConstruction.into()), + _ => Err(RuntimeError::BadTypeConstruction.into()), }?; Ok(()) } @@ -1405,9 +1405,9 @@ impl PrincipalData { pub fn parse_standard_principal(literal: &str) -> Result { let (version, data) = c32::c32_address_decode(literal) - .map_err(|x| RuntimeErrorType::ParseError(format!("Invalid principal literal: {x}")))?; + .map_err(|x| RuntimeError::ParseError(format!("Invalid principal literal: {x}")))?; if data.len() != 20 { - return Err(RuntimeErrorType::ParseError( + return Err(RuntimeError::ParseError( "Invalid principal literal: Expected 20 data bytes.".to_string(), ) .into()); diff --git a/clarity/src/vm/contexts.rs b/clarity/src/vm/contexts.rs index 355a0e9d53..9865fc1659 100644 --- a/clarity/src/vm/contexts.rs +++ b/clarity/src/vm/contexts.rs @@ -36,9 +36,7 @@ use crate::vm::database::{ ClarityDatabase, DataMapMetadata, DataVariableMetadata, FungibleTokenMetadata, NonFungibleTokenMetadata, }; -use crate::vm::errors::{ - CheckErrors, InterpreterError, InterpreterResult as Result, RuntimeErrorType, -}; +use crate::vm::errors::{CheckErrors, InterpreterError, InterpreterResult as Result, RuntimeError}; use crate::vm::events::*; use crate::vm::representations::SymbolicExpression; use crate::vm::types::signatures::FunctionSignature; @@ -272,7 +270,7 @@ impl AssetMap { let current_amount = self.stx_map.get(principal).unwrap_or(&0); current_amount .checked_add(amount) - .ok_or(RuntimeErrorType::ArithmeticOverflow.into()) + .ok_or(RuntimeError::ArithmeticOverflow.into()) } // This will get the next amount for a (principal, stx) entry in the burn table. @@ -280,7 +278,7 @@ impl AssetMap { let current_amount = self.burn_map.get(principal).unwrap_or(&0); current_amount .checked_add(amount) - .ok_or(RuntimeErrorType::ArithmeticOverflow.into()) + .ok_or(RuntimeError::ArithmeticOverflow.into()) } // This will get the next amount for a (principal, asset) entry in the asset table. @@ -297,7 +295,7 @@ impl AssetMap { .unwrap_or(&0); current_amount .checked_add(amount) - .ok_or(RuntimeErrorType::ArithmeticOverflow.into()) + .ok_or(RuntimeError::ArithmeticOverflow.into()) } pub fn add_stx_transfer(&mut self, principal: &PrincipalData, amount: u128) -> Result<()> { @@ -968,7 +966,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { .expressions; if parsed.is_empty() { - return Err(RuntimeErrorType::ParseError( + return Err(RuntimeError::ParseError( "Expected a program of at least length 1".to_string(), ) .into()); @@ -1027,7 +1025,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { .expressions; if parsed.is_empty() { - return Err(RuntimeErrorType::ParseError( + return Err(RuntimeError::ParseError( "Expected a program of at least length 1".to_string(), ) .into()); @@ -1887,7 +1885,7 @@ impl<'a> LocalContext<'a> { pub fn extend(&'a self) -> Result> { if self.depth >= MAX_CONTEXT_DEPTH { - Err(RuntimeErrorType::MaxContextDepthReached.into()) + Err(RuntimeError::MaxContextDepthReached.into()) } else { Ok(LocalContext { function_context: Some(self.function_context()), diff --git a/clarity/src/vm/costs/cost_functions.rs b/clarity/src/vm/costs/cost_functions.rs index 6abbaec555..968162b801 100644 --- a/clarity/src/vm/costs/cost_functions.rs +++ b/clarity/src/vm/costs/cost_functions.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . use super::ExecutionCost; -use crate::vm::errors::{InterpreterResult, RuntimeErrorType}; +use crate::vm::errors::{InterpreterResult, RuntimeError}; define_named_enum!(ClarityCostFunction { AnalysisTypeAnnotate("cost_analysis_type_annotate"), @@ -170,7 +170,7 @@ pub fn linear(n: u64, a: u64, b: u64) -> u64 { pub fn logn(n: u64, a: u64, b: u64) -> InterpreterResult { if n < 1 { return Err(crate::vm::errors::Error::Runtime( - RuntimeErrorType::Arithmetic("log2 must be passed a positive integer".to_string()), + RuntimeError::Arithmetic("log2 must be passed a positive integer".to_string()), Some(vec![]), )); } @@ -180,7 +180,7 @@ pub fn logn(n: u64, a: u64, b: u64) -> InterpreterResult { pub fn nlogn(n: u64, a: u64, b: u64) -> InterpreterResult { if n < 1 { return Err(crate::vm::errors::Error::Runtime( - RuntimeErrorType::Arithmetic("log2 must be passed a positive integer".to_string()), + RuntimeError::Arithmetic("log2 must be passed a positive integer".to_string()), Some(vec![]), )); } @@ -484,7 +484,7 @@ impl ClarityCostFunction { ClarityCostFunction::BitwiseRShift => C::cost_bitwise_right_shift(n), ClarityCostFunction::ContractHash => C::cost_contract_hash(n), ClarityCostFunction::ToAscii => C::cost_to_ascii(n), - ClarityCostFunction::Unimplemented => Err(RuntimeErrorType::NotImplemented.into()), + ClarityCostFunction::Unimplemented => Err(RuntimeError::NotImplemented.into()), } } } diff --git a/clarity/src/vm/costs/costs_1.rs b/clarity/src/vm/costs/costs_1.rs index 1e400f56bd..2292052a12 100644 --- a/clarity/src/vm/costs/costs_1.rs +++ b/clarity/src/vm/costs/costs_1.rs @@ -16,7 +16,7 @@ /// This file implements the cost functions from costs.clar in Rust. use super::cost_functions::{linear, logn, nlogn, CostValues}; use super::ExecutionCost; -use crate::vm::errors::{InterpreterResult, RuntimeErrorType}; +use crate::vm::errors::{InterpreterResult, RuntimeError}; pub struct Costs1; @@ -651,106 +651,106 @@ impl CostValues for Costs1 { } fn cost_buff_to_int_le(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_buff_to_uint_le(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_buff_to_int_be(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_buff_to_uint_be(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_is_standard(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_principal_destruct(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_principal_construct(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_string_to_int(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_string_to_uint(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_int_to_ascii(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_int_to_utf8(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_burn_block_info(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_stx_account(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_slice(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_to_consensus_buff(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_from_consensus_buff(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_stx_transfer_memo(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_replace_at(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_as_contract(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_and(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_or(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_not(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_left_shift(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_right_shift(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_contract_hash(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_to_ascii(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } } diff --git a/clarity/src/vm/costs/costs_2.rs b/clarity/src/vm/costs/costs_2.rs index 451008bd1b..d964d8a0ca 100644 --- a/clarity/src/vm/costs/costs_2.rs +++ b/clarity/src/vm/costs/costs_2.rs @@ -16,7 +16,7 @@ /// This file implements the cost functions from costs-2.clar in Rust. use super::cost_functions::{linear, logn, nlogn, CostValues}; use super::ExecutionCost; -use crate::vm::errors::{InterpreterResult, RuntimeErrorType}; +use crate::vm::errors::{InterpreterResult, RuntimeError}; pub struct Costs2; @@ -651,106 +651,106 @@ impl CostValues for Costs2 { } fn cost_buff_to_int_le(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_buff_to_uint_le(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_buff_to_int_be(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_buff_to_uint_be(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_is_standard(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_principal_destruct(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_principal_construct(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_string_to_int(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_string_to_uint(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_int_to_ascii(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_int_to_utf8(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_burn_block_info(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_stx_account(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_slice(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_to_consensus_buff(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_from_consensus_buff(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_stx_transfer_memo(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_replace_at(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_as_contract(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_and(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_or(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_not(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_left_shift(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_right_shift(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_contract_hash(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_to_ascii(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } } diff --git a/clarity/src/vm/costs/costs_2_testnet.rs b/clarity/src/vm/costs/costs_2_testnet.rs index 647bafedb9..ea67fd9399 100644 --- a/clarity/src/vm/costs/costs_2_testnet.rs +++ b/clarity/src/vm/costs/costs_2_testnet.rs @@ -16,7 +16,7 @@ /// This file implements the cost functions from costs-2-testnet.clar in Rust. use super::cost_functions::{linear, logn, nlogn, CostValues}; use super::ExecutionCost; -use crate::vm::errors::{InterpreterResult, RuntimeErrorType}; +use crate::vm::errors::{InterpreterResult, RuntimeError}; pub struct Costs2Testnet; @@ -651,106 +651,106 @@ impl CostValues for Costs2Testnet { } fn cost_buff_to_int_le(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_buff_to_uint_le(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_buff_to_int_be(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_buff_to_uint_be(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_is_standard(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_principal_destruct(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_principal_construct(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_string_to_int(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_string_to_uint(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_int_to_ascii(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_int_to_utf8(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_burn_block_info(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_stx_account(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_slice(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_to_consensus_buff(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_from_consensus_buff(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_stx_transfer_memo(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_replace_at(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_as_contract(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_and(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_or(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_not(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_left_shift(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_bitwise_right_shift(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_contract_hash(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_to_ascii(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } } diff --git a/clarity/src/vm/costs/costs_3.rs b/clarity/src/vm/costs/costs_3.rs index b195303510..c64c68f719 100644 --- a/clarity/src/vm/costs/costs_3.rs +++ b/clarity/src/vm/costs/costs_3.rs @@ -16,7 +16,7 @@ /// This file implements the cost functions from costs-3.clar in Rust. use super::cost_functions::{linear, logn, nlogn, CostValues}; use super::ExecutionCost; -use crate::vm::errors::{InterpreterResult, RuntimeErrorType}; +use crate::vm::errors::{InterpreterResult, RuntimeError}; pub struct Costs3; @@ -765,10 +765,10 @@ impl CostValues for Costs3 { } fn cost_contract_hash(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } fn cost_to_ascii(n: u64) -> InterpreterResult { - Err(RuntimeErrorType::NotImplemented.into()) + Err(RuntimeError::NotImplemented.into()) } } diff --git a/clarity/src/vm/costs/mod.rs b/clarity/src/vm/costs/mod.rs index 669f6f483d..347470ce25 100644 --- a/clarity/src/vm/costs/mod.rs +++ b/clarity/src/vm/costs/mod.rs @@ -28,7 +28,7 @@ use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; use stacks_common::types::StacksEpochId; -use super::errors::{CheckErrors, RuntimeErrorType}; +use super::errors::{CheckErrors, RuntimeError}; use crate::boot_util::boot_code_id; use crate::vm::contexts::{ContractContext, GlobalContext}; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -215,7 +215,7 @@ impl DefaultVersion { }; r.map_err(|e| { let e = match e { - crate::vm::errors::Error::Runtime(RuntimeErrorType::NotImplemented, _) => { + crate::vm::errors::Error::Runtime(RuntimeError::NotImplemented, _) => { CheckErrors::UndefinedFunction(cost_function_ref.function_name.clone()).into() } other => other, diff --git a/clarity/src/vm/database/clarity_db.rs b/clarity/src/vm/database/clarity_db.rs index a895b00ddb..5f41cdab0f 100644 --- a/clarity/src/vm/database/clarity_db.rs +++ b/clarity/src/vm/database/clarity_db.rs @@ -38,7 +38,7 @@ use crate::vm::database::structures::{ }; use crate::vm::database::{ClarityBackingStore, RollbackWrapper}; use crate::vm::errors::{ - CheckErrors, Error, InterpreterError, InterpreterResult as Result, RuntimeErrorType, + CheckErrors, Error, InterpreterError, InterpreterResult as Result, RuntimeError, }; use crate::vm::representations::ClarityName; use crate::vm::types::serialization::NONE_SERIALIZATION_LEN; @@ -693,7 +693,7 @@ impl<'a> ClarityDatabase<'a> { data: &str, ) -> Result<()> { if self.store.has_metadata_entry(contract_identifier, key) { - Err(Error::Runtime(RuntimeErrorType::MetadataAlreadySet, None)) + Err(Error::Runtime(RuntimeError::MetadataAlreadySet, None)) } else { Ok(self.store.insert_metadata(contract_identifier, key, data)?) } @@ -904,7 +904,7 @@ impl<'a> ClarityDatabase<'a> { pub fn get_current_block_time(&mut self) -> Result { match self.get_data(CLARITY_STORAGE_BLOCK_TIME_KEY)? { Some(value) => Ok(value), - None => Err(RuntimeErrorType::BlockTimeNotAvailable.into()), + None => Err(RuntimeError::BlockTimeNotAvailable.into()), } } @@ -943,7 +943,7 @@ impl<'a> ClarityDatabase<'a> { let current = self.get_total_liquid_ustx()?; let next = current.checked_add(incr_by).ok_or_else(|| { error!("Overflowed `ustx-liquid-supply`"); - RuntimeErrorType::ArithmeticOverflow + RuntimeError::ArithmeticOverflow })?; self.set_ustx_liquid_supply(next)?; Ok(()) @@ -953,7 +953,7 @@ impl<'a> ClarityDatabase<'a> { let current = self.get_total_liquid_ustx()?; let next = current.checked_sub(decr_by).ok_or_else(|| { error!("`stx-burn?` accepted that reduces `ustx-liquid-supply` below 0"); - RuntimeErrorType::ArithmeticUnderflow + RuntimeError::ArithmeticUnderflow })?; self.set_ustx_liquid_supply(next)?; Ok(()) @@ -2057,11 +2057,11 @@ impl ClarityDatabase<'_> { let new_supply = current_supply .checked_add(amount) - .ok_or(RuntimeErrorType::ArithmeticOverflow)?; + .ok_or(RuntimeError::ArithmeticOverflow)?; if let Some(total_supply) = descriptor.total_supply { if new_supply > total_supply { - return Err(RuntimeErrorType::SupplyOverflow(new_supply, total_supply).into()); + return Err(RuntimeError::SupplyOverflow(new_supply, total_supply).into()); } } @@ -2084,7 +2084,7 @@ impl ClarityDatabase<'_> { })?; if amount > current_supply { - return Err(RuntimeErrorType::SupplyUnderflow(current_supply, amount).into()); + return Err(RuntimeError::SupplyUnderflow(current_supply, amount).into()); } let new_supply = current_supply - amount; @@ -2180,12 +2180,12 @@ impl ClarityDatabase<'_> { )?; let owner = match value { Some(owner) => owner.value.expect_optional()?, - None => return Err(RuntimeErrorType::NoSuchToken.into()), + None => return Err(RuntimeError::NoSuchToken.into()), }; let principal = match owner { Some(value) => value.expect_principal()?, - None => return Err(RuntimeErrorType::NoSuchToken.into()), + None => return Err(RuntimeError::NoSuchToken.into()), }; Ok(principal) diff --git a/clarity/src/vm/database/sqlite.rs b/clarity/src/vm/database/sqlite.rs index c1af553041..9d5a9611b3 100644 --- a/clarity/src/vm/database/sqlite.rs +++ b/clarity/src/vm/database/sqlite.rs @@ -27,7 +27,7 @@ use super::{ }; use crate::vm::analysis::{AnalysisDatabase, CheckErrors}; use crate::vm::errors::{ - IncomparableError, InterpreterError, InterpreterResult as Result, RuntimeErrorType, + IncomparableError, InterpreterError, InterpreterResult as Result, RuntimeError, }; use crate::vm::types::QualifiedContractIdentifier; @@ -125,7 +125,7 @@ pub fn sqlite_get_metadata_manual( ) -> Result> { let bhh = store.get_block_at_height(at_height).ok_or_else(|| { warn!("Unknown block height when manually querying metadata"; "block_height" => at_height); - RuntimeErrorType::BadBlockHeight(at_height.to_string()) + RuntimeError::BadBlockHeight(at_height.to_string()) })?; SqliteConnection::get_metadata(store.get_side_store(), &bhh, &contract.to_string(), key) } @@ -311,7 +311,7 @@ impl MemoryBackingStore { impl ClarityBackingStore for MemoryBackingStore { fn set_block_hash(&mut self, bhh: StacksBlockId) -> Result { - Err(RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)).into()) + Err(RuntimeError::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)).into()) } fn get_data(&mut self, key: &str) -> Result> { diff --git a/clarity/src/vm/database/structures.rs b/clarity/src/vm/database/structures.rs index c4fec9f382..20e5ee83da 100644 --- a/clarity/src/vm/database/structures.rs +++ b/clarity/src/vm/database/structures.rs @@ -22,7 +22,7 @@ use stacks_common::util::hash::{hex_bytes, to_hex}; use crate::vm::analysis::ContractAnalysis; use crate::vm::contracts::Contract; use crate::vm::database::ClarityDatabase; -use crate::vm::errors::{Error, InterpreterError, RuntimeErrorType}; +use crate::vm::errors::{Error, InterpreterError, RuntimeError}; use crate::vm::types::{PrincipalData, TypeSignature}; pub trait ClaritySerializable { @@ -392,7 +392,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { recipient_balance .checked_add_unlocked_amount(amount) - .ok_or(Error::Runtime(RuntimeErrorType::ArithmeticOverflow, None))?; + .ok_or(Error::Runtime(RuntimeError::ArithmeticOverflow, None))?; self.debit(amount)?; self.db_ref.put_data(&recipient_key, &recipient_balance)?; diff --git a/clarity/src/vm/errors.rs b/clarity/src/vm/errors.rs index 764ac466e5..c0bbde967c 100644 --- a/clarity/src/vm/errors.rs +++ b/clarity/src/vm/errors.rs @@ -15,8 +15,7 @@ // along with this program. If not, see . pub use clarity_types::errors::{ - Error, IncomparableError, InterpreterError, InterpreterResult, RuntimeErrorType, - ShortReturnType, + Error, IncomparableError, InterpreterError, InterpreterResult, RuntimeError, ShortReturnType, }; pub use crate::vm::analysis::errors::{ diff --git a/clarity/src/vm/functions/arithmetic.rs b/clarity/src/vm/functions/arithmetic.rs index 2d5c2aff3a..89aec970b9 100644 --- a/clarity/src/vm/functions/arithmetic.rs +++ b/clarity/src/vm/functions/arithmetic.rs @@ -21,7 +21,7 @@ use integer_sqrt::IntegerSquareRoot; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::errors::{ - check_argument_count, CheckErrors, InterpreterError, InterpreterResult, RuntimeErrorType, + check_argument_count, CheckErrors, InterpreterError, InterpreterResult, RuntimeError, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::{ @@ -248,7 +248,7 @@ macro_rules! make_arithmetic_ops { let result = args .iter() .try_fold(0, |acc: $type, x: &$type| acc.checked_add(*x)) - .ok_or(RuntimeErrorType::ArithmeticOverflow)?; + .ok_or(RuntimeError::ArithmeticOverflow)?; Self::make_value(result) } fn sub(args: &[$type]) -> InterpreterResult { @@ -260,21 +260,21 @@ macro_rules! make_arithmetic_ops { return Self::make_value( first .checked_neg() - .ok_or(RuntimeErrorType::ArithmeticUnderflow)?, + .ok_or(RuntimeError::ArithmeticUnderflow)?, ); } let result = rest .iter() .try_fold(*first, |acc: $type, x: &$type| acc.checked_sub(*x)) - .ok_or(RuntimeErrorType::ArithmeticUnderflow)?; + .ok_or(RuntimeError::ArithmeticUnderflow)?; Self::make_value(result) } fn mul(args: &[$type]) -> InterpreterResult { let result = args .iter() .try_fold(1, |acc: $type, x: &$type| acc.checked_mul(*x)) - .ok_or(RuntimeErrorType::ArithmeticOverflow)?; + .ok_or(RuntimeError::ArithmeticOverflow)?; Self::make_value(result) } fn div(args: &[$type]) -> InterpreterResult { @@ -284,13 +284,13 @@ macro_rules! make_arithmetic_ops { let result = rest .iter() .try_fold(*first, |acc: $type, x: &$type| acc.checked_div(*x)) - .ok_or(RuntimeErrorType::DivisionByZero)?; + .ok_or(RuntimeError::DivisionByZero)?; Self::make_value(result) } fn modulo(numerator: $type, denominator: $type) -> InterpreterResult { let result = numerator .checked_rem(denominator) - .ok_or(RuntimeErrorType::DivisionByZero)?; + .ok_or(RuntimeError::DivisionByZero)?; Self::make_value(result) } #[allow(unused_comparisons)] @@ -312,7 +312,7 @@ macro_rules! make_arithmetic_ops { } if power < 0 || power > (u32::MAX as $type) { - return Err(RuntimeErrorType::Arithmetic( + return Err(RuntimeError::Arithmetic( "Power argument to (pow ...) must be a u32 integer".to_string(), ) .into()); @@ -322,14 +322,14 @@ macro_rules! make_arithmetic_ops { let result = base .checked_pow(power_u32) - .ok_or(RuntimeErrorType::ArithmeticOverflow)?; + .ok_or(RuntimeError::ArithmeticOverflow)?; Self::make_value(result) } fn sqrti(n: $type) -> InterpreterResult { match n.integer_sqrt_checked() { Some(result) => Self::make_value(result), None => { - return Err(RuntimeErrorType::Arithmetic( + return Err(RuntimeError::Arithmetic( "sqrti must be passed a positive integer".to_string(), ) .into()) @@ -338,7 +338,7 @@ macro_rules! make_arithmetic_ops { } fn log2(n: $type) -> InterpreterResult { if n < 1 { - return Err(RuntimeErrorType::Arithmetic( + return Err(RuntimeError::Arithmetic( "log2 must be passed a positive integer".to_string(), ) .into()); @@ -637,8 +637,7 @@ pub fn native_bitwise_right_shift(input: Value, pos: Value) -> InterpreterResult pub fn native_to_uint(input: Value) -> InterpreterResult { if let Value::Int(int_val) = input { - let uint_val = - u128::try_from(int_val).map_err(|_| RuntimeErrorType::ArithmeticUnderflow)?; + let uint_val = u128::try_from(int_val).map_err(|_| RuntimeError::ArithmeticUnderflow)?; Ok(Value::UInt(uint_val)) } else { Err(CheckErrors::TypeValueError(Box::new(TypeSignature::IntType), Box::new(input)).into()) @@ -647,7 +646,7 @@ pub fn native_to_uint(input: Value) -> InterpreterResult { pub fn native_to_int(input: Value) -> InterpreterResult { if let Value::UInt(uint_val) = input { - let int_val = i128::try_from(uint_val).map_err(|_| RuntimeErrorType::ArithmeticOverflow)?; + let int_val = i128::try_from(uint_val).map_err(|_| RuntimeError::ArithmeticOverflow)?; Ok(Value::Int(int_val)) } else { Err(CheckErrors::TypeValueError(Box::new(TypeSignature::UIntType), Box::new(input)).into()) diff --git a/clarity/src/vm/functions/assets.rs b/clarity/src/vm/functions/assets.rs index 62763fa3fc..d055856172 100644 --- a/clarity/src/vm/functions/assets.rs +++ b/clarity/src/vm/functions/assets.rs @@ -21,7 +21,7 @@ use crate::vm::costs::{runtime_cost, CostTracker}; use crate::vm::database::STXBalance; use crate::vm::errors::{ check_argument_count, CheckErrors, Error, InterpreterError, InterpreterResult as Result, - RuntimeErrorType, + RuntimeError, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::{ @@ -418,7 +418,7 @@ pub fn special_mint_asset_v200( &asset, expected_asset_type, ) { - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(()), + Err(Error::Runtime(RuntimeError::NoSuchToken, _)) => Ok(()), Ok(_owner) => return clarity_ecode!(MintAssetErrorCodes::ALREADY_EXIST), Err(e) => Err(e), }?; @@ -492,7 +492,7 @@ pub fn special_mint_asset_v205( &asset, expected_asset_type, ) { - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(()), + Err(Error::Runtime(RuntimeError::NoSuchToken, _)) => Ok(()), Ok(_owner) => return clarity_ecode!(MintAssetErrorCodes::ALREADY_EXIST), Err(e) => Err(e), }?; @@ -571,7 +571,7 @@ pub fn special_transfer_asset_v200( expected_asset_type, ) { Ok(owner) => Ok(owner), - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => { + Err(Error::Runtime(RuntimeError::NoSuchToken, _)) => { return clarity_ecode!(TransferAssetErrorCodes::DOES_NOT_EXIST) } Err(e) => Err(e), @@ -665,7 +665,7 @@ pub fn special_transfer_asset_v205( expected_asset_type, ) { Ok(owner) => Ok(owner), - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => { + Err(Error::Runtime(RuntimeError::NoSuchToken, _)) => { return clarity_ecode!(TransferAssetErrorCodes::DOES_NOT_EXIST) } Err(e) => Err(e), @@ -769,7 +769,7 @@ pub fn special_transfer_token( let final_to_bal = to_bal .checked_add(amount) - .ok_or(RuntimeErrorType::ArithmeticOverflow)?; + .ok_or(RuntimeError::ArithmeticOverflow)?; env.add_memory(TypeSignature::PrincipalType.size()? as u64)?; env.add_memory(TypeSignature::PrincipalType.size()? as u64)?; @@ -889,7 +889,7 @@ pub fn special_get_owner_v200( Ok(owner) => Ok(Value::some(Value::Principal(owner)).map_err(|_| { InterpreterError::Expect("Principal should always fit in optional.".into()) })?), - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(Value::none()), + Err(Error::Runtime(RuntimeError::NoSuchToken, _)) => Ok(Value::none()), Err(e) => Err(e), } } @@ -936,7 +936,7 @@ pub fn special_get_owner_v205( Ok(owner) => Ok(Value::some(Value::Principal(owner)).map_err(|_| { InterpreterError::Expect("Principal should always fit in optional.".into()) })?), - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => Ok(Value::none()), + Err(Error::Runtime(RuntimeError::NoSuchToken, _)) => Ok(Value::none()), Err(e) => Err(e), } } @@ -1068,7 +1068,7 @@ pub fn special_burn_asset_v200( &asset, expected_asset_type, ) { - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => { + Err(Error::Runtime(RuntimeError::NoSuchToken, _)) => { return clarity_ecode!(BurnAssetErrorCodes::DOES_NOT_EXIST) } Ok(owner) => Ok(owner), @@ -1156,7 +1156,7 @@ pub fn special_burn_asset_v205( &asset, expected_asset_type, ) { - Err(Error::Runtime(RuntimeErrorType::NoSuchToken, _)) => { + Err(Error::Runtime(RuntimeError::NoSuchToken, _)) => { return clarity_ecode!(BurnAssetErrorCodes::DOES_NOT_EXIST) } Ok(owner) => Ok(owner), diff --git a/clarity/src/vm/functions/database.rs b/clarity/src/vm/functions/database.rs index 93fbef0258..9f3b5a37d7 100644 --- a/clarity/src/vm/functions/database.rs +++ b/clarity/src/vm/functions/database.rs @@ -23,7 +23,7 @@ use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{constants as cost_constants, runtime_cost, CostTracker, MemoryConsumer}; use crate::vm::errors::{ check_argument_count, check_arguments_at_least, CheckErrors, InterpreterError, - InterpreterResult as Result, RuntimeErrorType, + InterpreterResult as Result, RuntimeError, }; use crate::vm::representations::{SymbolicExpression, SymbolicExpressionType}; use crate::vm::types::{ @@ -446,7 +446,7 @@ pub fn special_at_block( let bhh = match eval(&args[0], env, context)? { Value::Sequence(SequenceData::Buffer(BuffData { data })) => { if data.len() != 32 { - return Err(RuntimeErrorType::BadBlockHash(data).into()); + return Err(RuntimeError::BadBlockHash(data).into()); } else { StacksBlockId::from(data.as_slice()) } diff --git a/clarity/src/vm/functions/options.rs b/clarity/src/vm/functions/options.rs index c47dae91cc..3871db3e5b 100644 --- a/clarity/src/vm/functions/options.rs +++ b/clarity/src/vm/functions/options.rs @@ -19,7 +19,7 @@ use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostTracker, MemoryConsumer}; use crate::vm::errors::{ check_arguments_at_least, CheckErrors, InterpreterError, InterpreterResult as Result, - RuntimeErrorType, ShortReturnType, + RuntimeError, ShortReturnType, }; use crate::vm::types::{CallableData, OptionalData, ResponseData, TypeSignature, Value}; use crate::vm::Value::CallableContract; @@ -59,7 +59,7 @@ fn inner_unwrap_err(to_unwrap: Value) -> Result> { pub fn native_unwrap(input: Value) -> Result { inner_unwrap(input).and_then(|opt_value| match opt_value { Some(v) => Ok(v), - None => Err(RuntimeErrorType::UnwrapFailure.into()), + None => Err(RuntimeError::UnwrapFailure.into()), }) } @@ -73,7 +73,7 @@ pub fn native_unwrap_or_ret(input: Value, thrown: Value) -> Result { pub fn native_unwrap_err(input: Value) -> Result { inner_unwrap_err(input).and_then(|opt_value| match opt_value { Some(v) => Ok(v), - None => Err(RuntimeErrorType::UnwrapFailure.into()), + None => Err(RuntimeError::UnwrapFailure.into()), }) } diff --git a/clarity/src/vm/functions/sequences.rs b/clarity/src/vm/functions/sequences.rs index cafc795d36..a43b9dcb7d 100644 --- a/clarity/src/vm/functions/sequences.rs +++ b/clarity/src/vm/functions/sequences.rs @@ -22,7 +22,7 @@ use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostOverflowingMath}; use crate::vm::errors::{ check_argument_count, check_arguments_at_least, CheckErrors, InterpreterResult as Result, - RuntimeErrorType, + RuntimeError, }; use crate::vm::representations::SymbolicExpression; use crate::vm::types::signatures::ListTypeData; @@ -248,7 +248,7 @@ pub fn special_concat_v200( (Value::Sequence(ref mut seq), Value::Sequence(other_seq)) => { seq.concat(env.epoch(), other_seq) } - _ => Err(RuntimeErrorType::BadTypeConstruction.into()), + _ => Err(RuntimeError::BadTypeConstruction.into()), }?; Ok(wrapped_seq) @@ -276,7 +276,7 @@ pub fn special_concat_v205( } _ => { runtime_cost(ClarityCostFunction::Concat, env, 1)?; - Err(RuntimeErrorType::BadTypeConstruction.into()) + Err(RuntimeError::BadTypeConstruction.into()) } }?; @@ -410,7 +410,7 @@ pub fn special_slice( seq.slice(env.epoch(), left_position as usize, right_position as usize)?; Value::some(seq_value) } - _ => Err(RuntimeErrorType::BadTypeConstruction.into()), + _ => Err(RuntimeError::BadTypeConstruction.into()), } })(); diff --git a/clarity/src/vm/mod.rs b/clarity/src/vm/mod.rs index 781c7d4d7b..cc55a06201 100644 --- a/clarity/src/vm/mod.rs +++ b/clarity/src/vm/mod.rs @@ -73,7 +73,7 @@ use crate::vm::costs::{ // publish the non-generic StacksEpoch form for use throughout module pub use crate::vm::database::clarity_db::StacksEpoch; use crate::vm::errors::{ - CheckErrors, Error, InterpreterError, InterpreterResult as Result, RuntimeErrorType, + CheckErrors, Error, InterpreterError, InterpreterResult as Result, RuntimeError, }; use crate::vm::events::StacksTransactionEvent; use crate::vm::functions::define::DefineResult; @@ -238,7 +238,7 @@ pub fn apply( } if env.call_stack.depth() >= MAX_CALL_STACK_DEPTH { - return Err(RuntimeErrorType::MaxStackDepthReached.into()); + return Err(RuntimeError::MaxStackDepthReached.into()); } if let CallableType::SpecialFunction(_, function) = function { diff --git a/clarity/src/vm/tests/assets.rs b/clarity/src/vm/tests/assets.rs index 0cfeebfb27..0f378b76ca 100644 --- a/clarity/src/vm/tests/assets.rs +++ b/clarity/src/vm/tests/assets.rs @@ -26,7 +26,7 @@ use crate::vm::types::{PrincipalData, QualifiedContractIdentifier, Value}; use crate::vm::{ ast::ASTRules, contexts::AssetMapEntry, - errors::{CheckErrors, RuntimeErrorType}, + errors::{CheckErrors, RuntimeError}, tests::{ execute, is_committed, is_err_code, symbols_from_values, tl_env_factory as env_factory, TopLevelMemoryEnvironmentGenerator, @@ -307,7 +307,7 @@ fn test_native_stx_ops(epoch: StacksEpochId, mut env_factory: TopLevelMemoryEnvi // &symbols_from_values(vec![Value::UInt(2), p2.clone(), p1.clone()]) // ) // .unwrap_err(), - // RuntimeErrorType::ArithmeticOverflow.into() + // RuntimeError::ArithmeticOverflow.into() // ); // test 6: check balance @@ -921,7 +921,7 @@ fn test_total_supply(epoch: StacksEpochId, mut env_factory: TopLevelMemoryEnviro .unwrap_err(); println!("{err}"); assert!(match err { - Error::Runtime(RuntimeErrorType::SupplyOverflow(x, y), _) => (x, y) == (6, 5), + Error::Runtime(RuntimeError::SupplyOverflow(x, y), _) => (x, y) == (6, 5), _ => false, }); } diff --git a/clarity/src/vm/tests/contracts.rs b/clarity/src/vm/tests/contracts.rs index da9d4f3731..c02a54ab90 100644 --- a/clarity/src/vm/tests/contracts.rs +++ b/clarity/src/vm/tests/contracts.rs @@ -27,7 +27,7 @@ use crate::vm::types::{PrincipalData, QualifiedContractIdentifier, StandardPrinc #[cfg(test)] use crate::vm::{ ast::{errors::ParseErrors, ASTRules}, - errors::{CheckErrors, Error, RuntimeErrorType}, + errors::{CheckErrors, Error, RuntimeError}, tests::{ env_factory, execute, is_committed, is_err_code_i128 as is_err_code, symbols_from_values, tl_env_factory, MemoryEnvironmentGenerator, TopLevelMemoryEnvironmentGenerator, @@ -1010,9 +1010,7 @@ fn test_at_unknown_block( match err { Error::Runtime(x, _) => assert_eq!( x, - RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash::from( - vec![2_u8; 32].as_slice() - )) + RuntimeError::UnknownBlockHeaderHash(BlockHeaderHash::from(vec![2_u8; 32].as_slice())) ), _ => panic!("Unexpected error"), } @@ -1051,7 +1049,7 @@ fn test_ast_stack_depth() { "; assert_eq!( vm_execute(program).unwrap_err(), - RuntimeErrorType::ASTError(Box::new( + RuntimeError::ASTError(Box::new( ParseErrors::VaryExpressionStackDepthTooDeep.into(), )) .into() @@ -1074,7 +1072,7 @@ fn test_arg_stack_depth() { "; assert_eq!( vm_execute(program).unwrap_err(), - RuntimeErrorType::MaxStackDepthReached.into() + RuntimeError::MaxStackDepthReached.into() ); } @@ -1111,7 +1109,7 @@ fn test_cc_stack_depth( assert_eq!( env.initialize_contract(contract_identifier, contract_two, ASTRules::PrecheckSize) .unwrap_err(), - RuntimeErrorType::MaxStackDepthReached.into() + RuntimeError::MaxStackDepthReached.into() ); } @@ -1152,7 +1150,7 @@ fn test_cc_trait_stack_depth( assert_eq!( env.initialize_contract(contract_identifier, contract_two, ASTRules::PrecheckSize) .unwrap_err(), - RuntimeErrorType::MaxStackDepthReached.into() + RuntimeError::MaxStackDepthReached.into() ); } diff --git a/clarity/src/vm/tests/defines.rs b/clarity/src/vm/tests/defines.rs index 2cd874f2c3..eabfc9b79e 100644 --- a/clarity/src/vm/tests/defines.rs +++ b/clarity/src/vm/tests/defines.rs @@ -27,7 +27,7 @@ use crate::vm::tests::test_clarity_versions; use crate::vm::{ analysis::errors::SyntaxBindingError, ast::{build_ast, errors::ParseErrors}, - errors::RuntimeErrorType, + errors::RuntimeError, types::{QualifiedContractIdentifier, TypeSignature, TypeSignatureExt as _, Value}, {execute, ClarityVersion}, }; @@ -187,7 +187,7 @@ fn test_stack_depth() { assert_eq!(Ok(Some(Value::Int(64))), execute(&test0)); assert!(matches!( execute(&test1), - Err(Error::Runtime(RuntimeErrorType::MaxStackDepthReached, _)) + Err(Error::Runtime(RuntimeError::MaxStackDepthReached, _)) )) } @@ -474,18 +474,18 @@ fn test_define_trait_arg_count() { // These errors are hit in the trait resolver, before reaching the type-checker match execute(test0).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + Error::Runtime(RuntimeError::ASTError(parse_err), _) if *parse_err.err == ParseErrors::DefineTraitBadSignature => {} e => panic!("{e:?}"), }; match execute(test1).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + Error::Runtime(RuntimeError::ASTError(parse_err), _) if *parse_err.err == ParseErrors::DefineTraitBadSignature => {} e => panic!("{e}"), }; execute(test2).unwrap(); match execute(test3).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + Error::Runtime(RuntimeError::ASTError(parse_err), _) if *parse_err.err == ParseErrors::DefineTraitBadSignature => {} e => panic!("{e}"), }; @@ -500,18 +500,18 @@ fn test_use_trait_arg_count() { // These errors are hit in the trait resolver, before reaching the type-checker match execute(test0).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + Error::Runtime(RuntimeError::ASTError(parse_err), _) if *parse_err.err == ParseErrors::ImportTraitBadSignature => {} e => panic!("{e:?}"), }; match execute(test1).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + Error::Runtime(RuntimeError::ASTError(parse_err), _) if *parse_err.err == ParseErrors::ImportTraitBadSignature => {} e => panic!("{e}"), }; execute(test2).unwrap(); match execute(test3).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + Error::Runtime(RuntimeError::ASTError(parse_err), _) if *parse_err.err == ParseErrors::ImportTraitBadSignature => {} e => panic!("{e}"), }; @@ -525,13 +525,13 @@ fn test_impl_trait_arg_count() { // These errors are hit in the trait resolver, before reaching the type-checker match execute(test0).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + Error::Runtime(RuntimeError::ASTError(parse_err), _) if *parse_err.err == ParseErrors::ImplTraitBadSignature => {} e => panic!("{e:?}"), }; execute(test1).unwrap(); match execute(test2).unwrap_err() { - Error::Runtime(RuntimeErrorType::ASTError(parse_err), _) + Error::Runtime(RuntimeError::ASTError(parse_err), _) if *parse_err.err == ParseErrors::ImplTraitBadSignature => {} e => panic!("{e}"), }; diff --git a/clarity/src/vm/tests/representations.rs b/clarity/src/vm/tests/representations.rs index bed3ba7849..e96db9ba73 100644 --- a/clarity/src/vm/tests/representations.rs +++ b/clarity/src/vm/tests/representations.rs @@ -17,7 +17,7 @@ use proptest::prelude::*; use proptest::string::string_regex; use stacks_common::codec::StacksMessageCodec; -use crate::vm::errors::RuntimeErrorType; +use crate::vm::errors::RuntimeError; use crate::vm::representations::{ CLARITY_NAME_REGEX_STRING, CONTRACT_MAX_NAME_LENGTH, CONTRACT_MIN_NAME_LENGTH, CONTRACT_NAME_REGEX_STRING, MAX_STRING_LEN, @@ -164,7 +164,7 @@ fn prop_clarity_name_invalid_patterns() { prop_assert!(result.is_err(), "Expected invalid name '{}' to be rejected", name); prop_assert!(matches!( result.unwrap_err(), - RuntimeErrorType::BadNameValue(_, _) + RuntimeError::BadNameValue(_, _) ), "Expected BadNameValue error for invalid name '{}'", name); }); } @@ -302,7 +302,7 @@ fn prop_contract_name_invalid_patterns() { prop_assert!(result.is_err(), "Expected invalid contract name '{}' to be rejected", name); prop_assert!(matches!( result.unwrap_err(), - RuntimeErrorType::BadNameValue(_, _) + RuntimeError::BadNameValue(_, _) ), "Expected BadNameValue error for invalid contract name '{}'", name); }); } diff --git a/clarity/src/vm/tests/sequences.rs b/clarity/src/vm/tests/sequences.rs index 3ea779b7d6..cfbfc62947 100644 --- a/clarity/src/vm/tests/sequences.rs +++ b/clarity/src/vm/tests/sequences.rs @@ -22,7 +22,7 @@ use stacks_common::types::StacksEpochId; use crate::vm::tests::test_clarity_versions; #[cfg(test)] use crate::vm::{ - errors::{CheckErrors, Error, RuntimeErrorType}, + errors::{CheckErrors, Error, RuntimeError}, execute, execute_v2, types::{ signatures::{ @@ -592,12 +592,12 @@ fn test_simple_list_concat() { assert_eq!( execute("(concat (list 1) 3)").unwrap_err(), - RuntimeErrorType::BadTypeConstruction.into() + RuntimeError::BadTypeConstruction.into() ); assert_eq!( execute("(concat (list 1) \"1\")").unwrap_err(), - RuntimeErrorType::BadTypeConstruction.into() + RuntimeError::BadTypeConstruction.into() ); } @@ -623,12 +623,12 @@ fn test_simple_buff_concat() { assert_eq!( execute("(concat 0x31 3)").unwrap_err(), - RuntimeErrorType::BadTypeConstruction.into() + RuntimeError::BadTypeConstruction.into() ); assert_eq!( execute("(concat 0x31 (list 1))").unwrap_err(), - RuntimeErrorType::BadTypeConstruction.into() + RuntimeError::BadTypeConstruction.into() ); } diff --git a/clarity/src/vm/tests/simple_apply_eval.rs b/clarity/src/vm/tests/simple_apply_eval.rs index 53558e3548..18af910de4 100644 --- a/clarity/src/vm/tests/simple_apply_eval.rs +++ b/clarity/src/vm/tests/simple_apply_eval.rs @@ -31,7 +31,7 @@ use crate::vm::callables::DefinedFunction; use crate::vm::contexts::OwnedEnvironment; use crate::vm::costs::LimitedCostTracker; use crate::vm::database::MemoryBackingStore; -use crate::vm::errors::{CheckErrors, Error, RuntimeErrorType, ShortReturnType}; +use crate::vm::errors::{CheckErrors, Error, RuntimeError, ShortReturnType}; use crate::vm::tests::{execute, test_clarity_versions}; use crate::vm::types::signatures::*; use crate::vm::types::{ @@ -1119,31 +1119,27 @@ fn test_simple_arithmetic_errors(#[case] version: ClarityVersion, #[case] epoch: Box::new(Value::Bool(true)), ) .into(), - RuntimeErrorType::DivisionByZero.into(), - RuntimeErrorType::DivisionByZero.into(), - RuntimeErrorType::ArithmeticOverflow.into(), - RuntimeErrorType::ArithmeticOverflow.into(), - RuntimeErrorType::ArithmeticOverflow.into(), - RuntimeErrorType::ArithmeticUnderflow.into(), + RuntimeError::DivisionByZero.into(), + RuntimeError::DivisionByZero.into(), + RuntimeError::ArithmeticOverflow.into(), + RuntimeError::ArithmeticOverflow.into(), + RuntimeError::ArithmeticOverflow.into(), + RuntimeError::ArithmeticUnderflow.into(), CheckErrors::IncorrectArgumentCount(1, 0).into(), CheckErrors::IncorrectArgumentCount(1, 0).into(), CheckErrors::IncorrectArgumentCount(2, 1).into(), CheckErrors::IncorrectArgumentCount(2, 1).into(), CheckErrors::IncorrectArgumentCount(1, 0).into(), CheckErrors::IncorrectArgumentCount(1, 2).into(), - RuntimeErrorType::Arithmetic("sqrti must be passed a positive integer".to_string()).into(), + RuntimeError::Arithmetic("sqrti must be passed a positive integer".to_string()).into(), CheckErrors::IncorrectArgumentCount(1, 0).into(), CheckErrors::IncorrectArgumentCount(1, 2).into(), - RuntimeErrorType::Arithmetic("log2 must be passed a positive integer".to_string()).into(), + RuntimeError::Arithmetic("log2 must be passed a positive integer".to_string()).into(), CheckErrors::IncorrectArgumentCount(2, 1).into(), - RuntimeErrorType::Arithmetic( - "Power argument to (pow ...) must be a u32 integer".to_string(), - ) - .into(), - RuntimeErrorType::Arithmetic( - "Power argument to (pow ...) must be a u32 integer".to_string(), - ) - .into(), + RuntimeError::Arithmetic("Power argument to (pow ...) must be a u32 integer".to_string()) + .into(), + RuntimeError::Arithmetic("Power argument to (pow ...) must be a u32 integer".to_string()) + .into(), CheckErrors::TypeError( Box::new(TypeSignature::from_string("bool", version, epoch)), Box::new(TypeSignature::from_string("int", version, epoch)), @@ -1168,8 +1164,8 @@ fn test_unsigned_arithmetic() { ]; let expectations: &[Error] = &[ - RuntimeErrorType::ArithmeticUnderflow.into(), - RuntimeErrorType::ArithmeticUnderflow.into(), + RuntimeError::ArithmeticUnderflow.into(), + RuntimeError::ArithmeticUnderflow.into(), CheckErrors::UnionTypeValueError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(Value::UInt(10)), @@ -1177,8 +1173,8 @@ fn test_unsigned_arithmetic() { .into(), CheckErrors::TypeValueError(Box::new(TypeSignature::UIntType), Box::new(Value::Int(80))) .into(), - RuntimeErrorType::ArithmeticUnderflow.into(), - RuntimeErrorType::ArithmeticOverflow.into(), + RuntimeError::ArithmeticUnderflow.into(), + RuntimeError::ArithmeticOverflow.into(), ]; for (program, expectation) in tests.iter().zip(expectations.iter()) { @@ -1435,9 +1431,9 @@ fn test_option_destructs() { Ok(Value::Int(3)), Ok(Value::Int(3)), Ok(Value::Int(3)), - Err(RuntimeErrorType::UnwrapFailure.into()), - Err(RuntimeErrorType::UnwrapFailure.into()), - Err(RuntimeErrorType::UnwrapFailure.into()), + Err(RuntimeError::UnwrapFailure.into()), + Err(RuntimeError::UnwrapFailure.into()), + Err(RuntimeError::UnwrapFailure.into()), Ok(Value::Int(2)), Ok(Value::Int(9)), Ok(Value::Int(2)), diff --git a/clarity/src/vm/variables.rs b/clarity/src/vm/variables.rs index cb84336dc9..64f4bb36b2 100644 --- a/clarity/src/vm/variables.rs +++ b/clarity/src/vm/variables.rs @@ -21,7 +21,7 @@ use super::errors::InterpreterError; use crate::vm::contexts::{Environment, LocalContext}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; -use crate::vm::errors::{InterpreterResult as Result, RuntimeErrorType}; +use crate::vm::errors::{InterpreterResult as Result, RuntimeError}; use crate::vm::types::Value; use crate::vm::ClarityVersion; @@ -58,17 +58,11 @@ pub fn lookup_reserved_variable( { match variable { NativeVariables::TxSender => { - let sender = env - .sender - .clone() - .ok_or(RuntimeErrorType::NoSenderInContext)?; + let sender = env.sender.clone().ok_or(RuntimeError::NoSenderInContext)?; Ok(Some(Value::Principal(sender))) } NativeVariables::ContractCaller => { - let caller = env - .caller - .clone() - .ok_or(RuntimeErrorType::NoCallerInContext)?; + let caller = env.caller.clone().ok_or(RuntimeError::NoCallerInContext)?; Ok(Some(Value::Principal(caller))) } NativeVariables::TxSponsor => { diff --git a/clarity/src/vm/version.rs b/clarity/src/vm/version.rs index 41226cfad9..b9e681e43f 100644 --- a/clarity/src/vm/version.rs +++ b/clarity/src/vm/version.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use stacks_common::types::StacksEpochId; -use crate::vm::errors::{Error, RuntimeErrorType}; +use crate::vm::errors::{Error, RuntimeError}; #[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, PartialOrd)] pub enum ClarityVersion { @@ -64,7 +64,7 @@ impl FromStr for ClarityVersion { } else if s == "clarity4" { Ok(ClarityVersion::Clarity4) } else { - Err(RuntimeErrorType::ParseError( + Err(RuntimeError::ParseError( "Invalid clarity version. Valid versions are: Clarity1, Clarity2, Clarity3." .to_string(), ) diff --git a/pox-locking/src/lib.rs b/pox-locking/src/lib.rs index 16c11c8af2..870ba8e446 100644 --- a/pox-locking/src/lib.rs +++ b/pox-locking/src/lib.rs @@ -26,7 +26,7 @@ //! invoked. If so, it updates the PoX lock. use clarity::boot_util::boot_code_id; use clarity::vm::contexts::GlobalContext; -use clarity::vm::errors::{Error as ClarityError, RuntimeErrorType}; +use clarity::vm::errors::{Error as ClarityError, RuntimeError}; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use clarity::vm::Value; use stacks_common::types::StacksEpochId; @@ -87,7 +87,7 @@ pub fn handle_contract_call_special_cases( "contract_id" => %contract_id ); return Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )); } @@ -102,7 +102,7 @@ pub fn handle_contract_call_special_cases( "contract_id" => %contract_id ); return Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )); } @@ -125,7 +125,7 @@ pub fn handle_contract_call_special_cases( "contract_id" => %contract_id ); return Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )); } diff --git a/pox-locking/src/pox_1.rs b/pox-locking/src/pox_1.rs index 4cc7ffe0ea..8dac69c3c8 100644 --- a/pox-locking/src/pox_1.rs +++ b/pox-locking/src/pox_1.rs @@ -19,7 +19,7 @@ use clarity::vm::contexts::GlobalContext; use clarity::vm::costs::cost_functions::ClarityCostFunction; use clarity::vm::costs::runtime_cost; use clarity::vm::database::ClarityDatabase; -use clarity::vm::errors::{Error as ClarityError, RuntimeErrorType}; +use clarity::vm::errors::{Error as ClarityError, RuntimeError}; use clarity::vm::events::{STXEventType, STXLockEventData, StacksTransactionEvent}; use clarity::vm::types::PrincipalData; use clarity::vm::Value; @@ -182,16 +182,13 @@ pub fn handle_contract_call( } Err(LockingError::DefunctPoxContract) => { return Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )); } Err(LockingError::PoxAlreadyLocked) => { // the caller tried to lock tokens into both pox-1 and pox-2 - return Err(ClarityError::Runtime( - RuntimeErrorType::PoxAlreadyLocked, - None, - )); + return Err(ClarityError::Runtime(RuntimeError::PoxAlreadyLocked, None)); } Err(e) => { panic!( diff --git a/pox-locking/src/pox_2.rs b/pox-locking/src/pox_2.rs index 1cbb1cd772..76b9c5b029 100644 --- a/pox-locking/src/pox_2.rs +++ b/pox-locking/src/pox_2.rs @@ -19,7 +19,7 @@ use clarity::vm::contexts::GlobalContext; use clarity::vm::costs::cost_functions::ClarityCostFunction; use clarity::vm::costs::runtime_cost; use clarity::vm::database::{ClarityDatabase, STXBalance}; -use clarity::vm::errors::{Error as ClarityError, RuntimeErrorType}; +use clarity::vm::errors::{Error as ClarityError, RuntimeError}; use clarity::vm::events::{STXEventType, STXLockEventData, StacksTransactionEvent}; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use clarity::vm::{Environment, Value}; @@ -333,16 +333,13 @@ fn handle_stack_lockup_pox_v2( } Err(LockingError::DefunctPoxContract) => { return Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )); } Err(LockingError::PoxAlreadyLocked) => { // the caller tried to lock tokens into both pox-1 and pox-2 - return Err(ClarityError::Runtime( - RuntimeErrorType::PoxAlreadyLocked, - None, - )); + return Err(ClarityError::Runtime(RuntimeError::PoxAlreadyLocked, None)); } Err(e) => { panic!( @@ -401,7 +398,7 @@ fn handle_stack_lockup_extension_pox_v2( } Err(LockingError::DefunctPoxContract) => { return Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )); } @@ -464,7 +461,7 @@ fn handle_stack_lockup_increase_pox_v2( } Err(LockingError::DefunctPoxContract) => { return Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )); } diff --git a/pox-locking/src/pox_3.rs b/pox-locking/src/pox_3.rs index 265ec59208..c2ec93c209 100644 --- a/pox-locking/src/pox_3.rs +++ b/pox-locking/src/pox_3.rs @@ -19,7 +19,7 @@ use clarity::vm::contexts::GlobalContext; use clarity::vm::costs::cost_functions::ClarityCostFunction; use clarity::vm::costs::runtime_cost; use clarity::vm::database::{ClarityDatabase, STXBalance}; -use clarity::vm::errors::{Error as ClarityError, RuntimeErrorType}; +use clarity::vm::errors::{Error as ClarityError, RuntimeError}; use clarity::vm::events::{STXEventType, STXLockEventData, StacksTransactionEvent}; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use clarity::vm::{Environment, Value}; @@ -224,16 +224,13 @@ fn handle_stack_lockup_pox_v3( } Err(LockingError::DefunctPoxContract) => { return Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )); } Err(LockingError::PoxAlreadyLocked) => { // the caller tried to lock tokens into multiple pox contracts - return Err(ClarityError::Runtime( - RuntimeErrorType::PoxAlreadyLocked, - None, - )); + return Err(ClarityError::Runtime(RuntimeError::PoxAlreadyLocked, None)); } Err(e) => { panic!( @@ -292,7 +289,7 @@ fn handle_stack_lockup_extension_pox_v3( } Err(LockingError::DefunctPoxContract) => { return Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )); } @@ -354,7 +351,7 @@ fn handle_stack_lockup_increase_pox_v3( } Err(LockingError::DefunctPoxContract) => { return Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )); } diff --git a/pox-locking/src/pox_4.rs b/pox-locking/src/pox_4.rs index 733d6d6c54..ed0d67925a 100644 --- a/pox-locking/src/pox_4.rs +++ b/pox-locking/src/pox_4.rs @@ -19,7 +19,7 @@ use clarity::vm::contexts::GlobalContext; use clarity::vm::costs::cost_functions::ClarityCostFunction; use clarity::vm::costs::runtime_cost; use clarity::vm::database::{ClarityDatabase, STXBalance}; -use clarity::vm::errors::{Error as ClarityError, RuntimeErrorType}; +use clarity::vm::errors::{Error as ClarityError, RuntimeError}; use clarity::vm::events::{STXEventType, STXLockEventData, StacksTransactionEvent}; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use clarity::vm::{Environment, Value}; @@ -191,15 +191,12 @@ fn handle_stack_lockup_pox_v4( Ok(Some(event)) } Err(LockingError::DefunctPoxContract) => Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )), Err(LockingError::PoxAlreadyLocked) => { // the caller tried to lock tokens into multiple pox contracts - Err(ClarityError::Runtime( - RuntimeErrorType::PoxAlreadyLocked, - None, - )) + Err(ClarityError::Runtime(RuntimeError::PoxAlreadyLocked, None)) } Err(e) => { panic!( @@ -253,7 +250,7 @@ fn handle_stack_lockup_extension_pox_v4( Ok(Some(event)) } Err(LockingError::DefunctPoxContract) => Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )), Err(e) => { @@ -309,7 +306,7 @@ fn handle_stack_lockup_increase_pox_v4( Ok(Some(event)) } Err(LockingError::DefunctPoxContract) => Err(ClarityError::Runtime( - RuntimeErrorType::DefunctPoxContract, + RuntimeError::DefunctPoxContract, None, )), Err(e) => { diff --git a/stackslib/src/blockstack_cli.rs b/stackslib/src/blockstack_cli.rs index bcf23757e7..43b84d383c 100644 --- a/stackslib/src/blockstack_cli.rs +++ b/stackslib/src/blockstack_cli.rs @@ -42,7 +42,7 @@ use blockstack_lib::clarity_cli::vm_execute; use blockstack_lib::core::{CHAIN_ID_MAINNET, CHAIN_ID_TESTNET}; use blockstack_lib::net::Error as NetError; use blockstack_lib::util_lib::strings::StacksString; -use clarity::vm::errors::{Error as ClarityError, RuntimeErrorType}; +use clarity::vm::errors::{Error as ClarityError, RuntimeError}; use clarity::vm::types::PrincipalData; use clarity::vm::{ClarityName, ClarityVersion, ContractName, Value}; use stacks_common::address::{b58, AddressHashMode}; @@ -189,7 +189,7 @@ block's sqlite database."; #[derive(Debug)] enum CliError { - ClarityRuntimeError(RuntimeErrorType), + ClarityRuntimeError(RuntimeError), ClarityGeneralError(ClarityError), Message(String), Usage, @@ -224,8 +224,8 @@ impl From<&str> for CliError { } } -impl From for CliError { - fn from(value: RuntimeErrorType) -> Self { +impl From for CliError { + fn from(value: RuntimeError) -> Self { CliError::ClarityRuntimeError(value) } } diff --git a/stackslib/src/clarity_cli.rs b/stackslib/src/clarity_cli.rs index 1ae8f648de..9d120b1122 100644 --- a/stackslib/src/clarity_cli.rs +++ b/stackslib/src/clarity_cli.rs @@ -51,7 +51,7 @@ use crate::clarity::vm::costs::{ExecutionCost, LimitedCostTracker}; use crate::clarity::vm::database::{ BurnStateDB, ClarityDatabase, HeadersDB, STXBalance, NULL_BURN_STATE_DB, }; -use crate::clarity::vm::errors::{Error, InterpreterResult, RuntimeErrorType}; +use crate::clarity::vm::errors::{Error, InterpreterResult, RuntimeError}; use crate::clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use crate::clarity::vm::{ analysis, ast, eval_all, ClarityVersion, ContractContext, ContractName, SymbolicExpression, @@ -158,7 +158,7 @@ fn parse( DEFAULT_CLI_EPOCH, ASTRules::PrecheckSize, ) - .map_err(|e| RuntimeErrorType::ASTError(Box::new(e)))?; + .map_err(|e| RuntimeError::ASTError(Box::new(e)))?; Ok(ast.expressions) } diff --git a/stackslib/src/clarity_vm/database/marf.rs b/stackslib/src/clarity_vm/database/marf.rs index b19ff76def..4a559edffb 100644 --- a/stackslib/src/clarity_vm/database/marf.rs +++ b/stackslib/src/clarity_vm/database/marf.rs @@ -11,9 +11,7 @@ use clarity::vm::database::{ BurnStateDB, ClarityBackingStore, ClarityDatabase, HeadersDB, SpecialCaseHandler, SqliteConnection, }; -use clarity::vm::errors::{ - IncomparableError, InterpreterError, InterpreterResult, RuntimeErrorType, -}; +use clarity::vm::errors::{IncomparableError, InterpreterError, InterpreterResult, RuntimeError}; use clarity::vm::types::QualifiedContractIdentifier; use rusqlite::Connection; use stacks_common::codec::StacksMessageCodec; @@ -307,7 +305,7 @@ impl ClarityBackingStore for ReadOnlyMarfStore<'_> { .map_err(|e| match e { Error::NotFoundError => { test_debug!("No such block {:?} (NotFoundError)", &bhh); - RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)) + RuntimeError::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)) } Error::NonMatchingForks(_bh1, _bh2) => { test_debug!( @@ -316,7 +314,7 @@ impl ClarityBackingStore for ReadOnlyMarfStore<'_> { BlockHeaderHash(_bh1), BlockHeaderHash(_bh2) ); - RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)) + RuntimeError::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)) } _ => panic!("ERROR: Unexpected MARF failure: {}", e), })?; @@ -622,7 +620,7 @@ impl ClarityBackingStore for WritableMarfStore<'_> { .map_err(|e| match e { Error::NotFoundError => { test_debug!("No such block {:?} (NotFoundError)", &bhh); - RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)) + RuntimeError::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)) } Error::NonMatchingForks(_bh1, _bh2) => { test_debug!( @@ -631,7 +629,7 @@ impl ClarityBackingStore for WritableMarfStore<'_> { BlockHeaderHash(_bh1), BlockHeaderHash(_bh2) ); - RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)) + RuntimeError::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)) } _ => panic!("ERROR: Unexpected MARF failure: {}", e), })?; diff --git a/stackslib/src/clarity_vm/database/mod.rs b/stackslib/src/clarity_vm/database/mod.rs index 966a422ba5..a3a083b840 100644 --- a/stackslib/src/clarity_vm/database/mod.rs +++ b/stackslib/src/clarity_vm/database/mod.rs @@ -11,7 +11,7 @@ use clarity::vm::database::{ BurnStateDB, ClarityBackingStore, ClarityDatabase, HeadersDB, SpecialCaseHandler, SqliteConnection, NULL_BURN_STATE_DB, NULL_HEADER_DB, }; -use clarity::vm::errors::{InterpreterResult, RuntimeErrorType}; +use clarity::vm::errors::{InterpreterResult, RuntimeError}; use clarity::vm::types::{QualifiedContractIdentifier, TupleData}; use rusqlite::{params, Connection, OptionalExtension, Row}; use stacks_common::types::chainstate::{ @@ -1219,7 +1219,7 @@ impl MemoryBackingStore { impl ClarityBackingStore for MemoryBackingStore { fn set_block_hash(&mut self, bhh: StacksBlockId) -> InterpreterResult { - Err(RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)).into()) + Err(RuntimeError::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)).into()) } fn get_data(&mut self, key: &str) -> InterpreterResult> { diff --git a/stackslib/src/clarity_vm/tests/forking.rs b/stackslib/src/clarity_vm/tests/forking.rs index 6dc3305562..cd4d08cd4e 100644 --- a/stackslib/src/clarity_vm/tests/forking.rs +++ b/stackslib/src/clarity_vm/tests/forking.rs @@ -17,7 +17,7 @@ use clarity::vm::analysis::errors::CheckErrors; use clarity::vm::ast::ASTRules; use clarity::vm::contexts::OwnedEnvironment; -use clarity::vm::errors::{Error, InterpreterResult as Result, RuntimeErrorType}; +use clarity::vm::errors::{Error, InterpreterResult as Result, RuntimeError}; use clarity::vm::test_util::{ execute, is_committed, is_err_code, symbols_from_values, TEST_BURN_STATE_DB, TEST_HEADER_DB, }; @@ -191,7 +191,7 @@ fn test_at_block_good(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc match resp { Error::Runtime(x, _) => assert_eq!( x, - RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash::from( + RuntimeError::UnknownBlockHeaderHash(BlockHeaderHash::from( vec![2; 32].as_slice() )) ), diff --git a/stackslib/src/clarity_vm/tests/simple_tests.rs b/stackslib/src/clarity_vm/tests/simple_tests.rs index 0fb38cdf9e..2001d3fee8 100644 --- a/stackslib/src/clarity_vm/tests/simple_tests.rs +++ b/stackslib/src/clarity_vm/tests/simple_tests.rs @@ -1,5 +1,5 @@ use clarity::vm::contexts::OwnedEnvironment; -use clarity::vm::errors::{Error, RuntimeErrorType}; +use clarity::vm::errors::{Error, RuntimeError}; use clarity::vm::test_util::{TEST_BURN_STATE_DB, TEST_HEADER_DB}; use clarity::vm::types::QualifiedContractIdentifier; use stacks_common::consts::{FIRST_BURNCHAIN_CONSENSUS_HASH, FIRST_STACKS_BLOCK_HASH}; @@ -64,9 +64,7 @@ fn test_at_unknown_block() { match err { Error::Runtime(x, _) => assert_eq!( x, - RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash::from( - vec![2; 32].as_slice() - )) + RuntimeError::UnknownBlockHeaderHash(BlockHeaderHash::from(vec![2; 32].as_slice())) ), _ => panic!("Unexpected error"), } diff --git a/stackslib/src/util_lib/strings.rs b/stackslib/src/util_lib/strings.rs index c76dbb6c61..86592ab5e3 100644 --- a/stackslib/src/util_lib/strings.rs +++ b/stackslib/src/util_lib/strings.rs @@ -19,7 +19,7 @@ use std::fmt; use std::io::{Read, Write}; use std::ops::{Deref, DerefMut}; -use clarity::vm::errors::RuntimeErrorType; +use clarity::vm::errors::RuntimeError; use clarity::vm::representations::{ ClarityName, ContractName, MAX_STRING_LEN as CLARITY_MAX_STRING_LENGTH, }; @@ -41,8 +41,8 @@ guarded_string!( "UrlString", URL_STRING_REGEX, CLARITY_MAX_STRING_LENGTH, - RuntimeErrorType, - RuntimeErrorType::BadNameValue + RuntimeError, + RuntimeError::BadNameValue ); /// printable-ASCII-only string, but encodable. From ce984318c4f58a4f41d7e06713e33b79d9cecdb2 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Wed, 17 Sep 2025 16:27:26 -0700 Subject: [PATCH 22/34] Add descriptions to RuntimeError and its variants Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/mod.rs | 35 +++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 1ec676d102..8e4d3d5ed0 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -73,33 +73,60 @@ pub enum InterpreterError { /// to be able to trigger during execution (e.g., arithmetic errors) #[derive(Debug, PartialEq)] pub enum RuntimeError { + /// A generic arithmetic error with a descriptive message. Arithmetic(String), + /// An arithmetic operation exceeded the maximum value for the data type (e.g., u128). ArithmeticOverflow, + /// An arithmetic operation resulted in a value below zero for an unsigned type. ArithmeticUnderflow, + /// Attempt to increase token supply beyond the maximum limit. + /// The parameters represent the current supply and the attempted increase. SupplyOverflow(u128, u128), + /// Attempt to decrease token supply below zero. + /// The parameters represent the current supply and the attempted decrease. SupplyUnderflow(u128, u128), + /// Attempt to divide or compute modulo by zero. DivisionByZero, - // error in parsing types + /// Failure to parse types dynamically during execution. + /// The string describes the specific parsing issue, such as invalid data formats. ParseError(String), - // error in parsing the AST + /// Failure to parse the abstract syntax tree (AST) during dynamic evaluation. + /// Wraps a detailed `ParseError` for issues in code interpretation. ASTError(Box), + /// The call stack exceeded the virtual machine's maximum depth. MaxStackDepthReached, + /// The execution context depth exceeded the virtual machine's limit. MaxContextDepthReached, + /// Attempt to construct an invalid or unsupported type at runtime. BadTypeConstruction, + /// Reference to an invalid or out-of-bounds block height. + /// The string details the issue, such as querying a future block. BadBlockHeight(String), + /// Attempt to interact with a non-existent token (e.g., in NFT or fungible token operations). NoSuchToken, + /// Feature or function not yet implemented in the virtual machine. NotImplemented, + /// No caller principal available in the current execution context. NoCallerInContext, + /// No sender principal available in the current execution context. NoSenderInContext, + /// Invalid name-value pair in contract data (e.g., map keys). + /// The static string specifies the name, and the dynamic string provides the offending value. BadNameValue(&'static str, String), + /// Reference to a non-existent block header hash. UnknownBlockHeaderHash(BlockHeaderHash), + /// Invalid block hash provided (e.g., incorrect format or length). + /// The byte vector contains the invalid hash data. BadBlockHash(Vec), + /// Failed to unwrap an `Optional` (`none`) or `Response` (`err` or `ok`) Clarity value. UnwrapFailure, + /// Attempt to set metadata already initialized (e.g., for NFTs or tokens). MetadataAlreadySet, - // pox-locking errors + /// Interaction with a deprecated or inactive Proof of Transfer (PoX) contract. DefunctPoxContract, + /// Attempt to lock STX for stacking when already locked in an active PoX cycle. PoxAlreadyLocked, - + /// Block time unavailable during execution. BlockTimeNotAvailable, } From 62857b734f420f85fb051cc7e5b543b2dd606e03 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Thu, 18 Sep 2025 09:11:39 -0700 Subject: [PATCH 23/34] Rename RuntimeError::ParseError to TypeParseFailure Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/mod.rs | 2 +- clarity-types/src/tests/types/mod.rs | 14 +++++++------- clarity-types/src/types/mod.rs | 11 ++++++----- clarity/src/vm/contexts.rs | 4 ++-- clarity/src/vm/version.rs | 2 +- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 8e4d3d5ed0..990025056a 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -89,7 +89,7 @@ pub enum RuntimeError { DivisionByZero, /// Failure to parse types dynamically during execution. /// The string describes the specific parsing issue, such as invalid data formats. - ParseError(String), + TypeParseFailure(String), /// Failure to parse the abstract syntax tree (AST) during dynamic evaluation. /// Wraps a detailed `ParseError` for issues in code interpretation. ASTError(Box), diff --git a/clarity-types/src/tests/types/mod.rs b/clarity-types/src/tests/types/mod.rs index b4ed2b2504..31dfb4c38d 100644 --- a/clarity-types/src/tests/types/mod.rs +++ b/clarity-types/src/tests/types/mod.rs @@ -264,13 +264,13 @@ fn test_qualified_contract_identifier_local_returns_runtime_error() { } #[rstest] -#[case::too_short("S162RK3CHJPCSSK6BM757FW", RuntimeError::ParseError( +#[case::too_short("S162RK3CHJPCSSK6BM757FW", RuntimeError::TypeParseFailure( "Invalid principal literal: Expected 20 data bytes.".to_string(), ))] -#[case::too_long("S1C5H66S35CSKK6CK1C9HP8SB6CWSK4RB2CDJK8HY4", RuntimeError::ParseError( +#[case::too_long("S1C5H66S35CSKK6CK1C9HP8SB6CWSK4RB2CDJK8HY4", RuntimeError::TypeParseFailure( "Invalid principal literal: Expected 20 data bytes.".to_string(), ))] -#[case::invalid_c32("II2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0G", RuntimeError::ParseError( +#[case::invalid_c32("II2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0G", RuntimeError::TypeParseFailure( "Invalid principal literal: base58ck checksum 0x1074d4f7 does not match expected 0xae29c6e0".to_string(), ))] fn test_principal_data_parse_standard_principal_returns_runtime_error( @@ -283,7 +283,7 @@ fn test_principal_data_parse_standard_principal_returns_runtime_error( } #[rstest] -#[case::no_dot("SM2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0Gcontract-name", RuntimeError::ParseError( +#[case::no_dot("SM2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0Gcontract-name", RuntimeError::TypeParseFailure( "Invalid principal literal: expected a `.` in a qualified contract name" .to_string(), ))] @@ -299,13 +299,13 @@ fn test_qualified_contract_identifier_parse_returns_interpreter_error( } #[rstest] -#[case::no_dot("SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-traitnft-trait", RuntimeError::ParseError( +#[case::no_dot("SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-traitnft-trait", RuntimeError::TypeParseFailure( "Invalid principal literal: expected a `.` in a qualified contract name" .to_string(), ))] #[case::invalid_contract_name("SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.1nvalid-contract.valid-trait", RuntimeError::BadNameValue("ContractName", "1nvalid-contract".into()))] #[case::invalid_trait_name("SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.valid-contract.1nvalid-trait", RuntimeError::BadNameValue("ClarityName", "1nvalid-trait".into()))] -#[case::invalid_standard_principal("S162RK3CHJPCSSK6BM757FW.valid-contract.valid-trait", RuntimeError::ParseError( +#[case::invalid_standard_principal("S162RK3CHJPCSSK6BM757FW.valid-contract.valid-trait", RuntimeError::TypeParseFailure( "Invalid principal literal: Expected 20 data bytes.".to_string(), ))] fn test_trait_identifier_parse_returns_runtime_error( @@ -324,7 +324,7 @@ fn test_trait_identifier_parse_returns_runtime_error( #[rstest] #[case::bad_type_construction(".valid-contract.valid-trait", RuntimeError::BadTypeConstruction)] -#[case::forwards_parse_errors("S162RK3CHJPCSSK6BM757FW.valid-contract.valid-trait", RuntimeError::ParseError( +#[case::forwards_parse_errors("S162RK3CHJPCSSK6BM757FW.valid-contract.valid-trait", RuntimeError::TypeParseFailure( "Invalid principal literal: Expected 20 data bytes.".to_string(), ))] fn test_trait_identifier_parse_fully_qualified_returns_runtime_error( diff --git a/clarity-types/src/types/mod.rs b/clarity-types/src/types/mod.rs index 285524b520..550d27ec11 100644 --- a/clarity-types/src/types/mod.rs +++ b/clarity-types/src/types/mod.rs @@ -187,7 +187,7 @@ impl QualifiedContractIdentifier { pub fn parse(literal: &str) -> Result { let split: Vec<_> = literal.splitn(2, '.').collect(); if split.len() != 2 { - return Err(RuntimeError::ParseError( + return Err(RuntimeError::TypeParseFailure( "Invalid principal literal: expected a `.` in a qualified contract name" .to_string(), ) @@ -289,7 +289,7 @@ impl TraitIdentifier { ) -> Result<(Option, ContractName, ClarityName)> { let split: Vec<_> = literal.splitn(3, '.').collect(); if split.len() != 3 { - return Err(RuntimeError::ParseError( + return Err(RuntimeError::TypeParseFailure( "Invalid principal literal: expected a `.` in a qualified contract name" .to_string(), ) @@ -1404,10 +1404,11 @@ impl PrincipalData { } pub fn parse_standard_principal(literal: &str) -> Result { - let (version, data) = c32::c32_address_decode(literal) - .map_err(|x| RuntimeError::ParseError(format!("Invalid principal literal: {x}")))?; + let (version, data) = c32::c32_address_decode(literal).map_err(|x| { + RuntimeError::TypeParseFailure(format!("Invalid principal literal: {x}")) + })?; if data.len() != 20 { - return Err(RuntimeError::ParseError( + return Err(RuntimeError::TypeParseFailure( "Invalid principal literal: Expected 20 data bytes.".to_string(), ) .into()); diff --git a/clarity/src/vm/contexts.rs b/clarity/src/vm/contexts.rs index 9865fc1659..8319a2617d 100644 --- a/clarity/src/vm/contexts.rs +++ b/clarity/src/vm/contexts.rs @@ -966,7 +966,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { .expressions; if parsed.is_empty() { - return Err(RuntimeError::ParseError( + return Err(RuntimeError::TypeParseFailure( "Expected a program of at least length 1".to_string(), ) .into()); @@ -1025,7 +1025,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { .expressions; if parsed.is_empty() { - return Err(RuntimeError::ParseError( + return Err(RuntimeError::TypeParseFailure( "Expected a program of at least length 1".to_string(), ) .into()); diff --git a/clarity/src/vm/version.rs b/clarity/src/vm/version.rs index b9e681e43f..539a801fdb 100644 --- a/clarity/src/vm/version.rs +++ b/clarity/src/vm/version.rs @@ -64,7 +64,7 @@ impl FromStr for ClarityVersion { } else if s == "clarity4" { Ok(ClarityVersion::Clarity4) } else { - Err(RuntimeError::ParseError( + Err(RuntimeError::TypeParseFailure( "Invalid clarity version. Valid versions are: Clarity1, Clarity2, Clarity3." .to_string(), ) From bdb5d9da50b90c24fa8d0eafc0ae66abc58e3e91 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Thu, 18 Sep 2025 09:50:01 -0700 Subject: [PATCH 24/34] CRC: fix bad comments Signed-off-by: Jacinta Ferrant --- stackslib/src/chainstate/stacks/events.rs | 2 +- stackslib/src/chainstate/stacks/tests/block_construction.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stackslib/src/chainstate/stacks/events.rs b/stackslib/src/chainstate/stacks/events.rs index b78c478c6d..daa4984e6b 100644 --- a/stackslib/src/chainstate/stacks/events.rs +++ b/stackslib/src/chainstate/stacks/events.rs @@ -52,7 +52,7 @@ pub struct StacksTransactionReceipt { pub execution_cost: ExecutionCost, pub microblock_header: Option, pub tx_index: u32, - /// This is really a string-formatted StaticCheckError (which can't be clone()'ed) + /// This is really a string-formatted CheckErrorKind or VmExecutionError (which can't be clone()'ed) pub vm_error: Option, } diff --git a/stackslib/src/chainstate/stacks/tests/block_construction.rs b/stackslib/src/chainstate/stacks/tests/block_construction.rs index 5fe5cf0f30..87faa6f604 100644 --- a/stackslib/src/chainstate/stacks/tests/block_construction.rs +++ b/stackslib/src/chainstate/stacks/tests/block_construction.rs @@ -3961,7 +3961,7 @@ fn test_is_tx_problematic() { expected_txids.push(contract_call_spends_too_much_tx.txid()); // for tenure_id == 4: - // make a contract that, when called, will result in a StaticCheckError at + // make a contract that, when called, will result in a CheckErrorKind at // runtime let runtime_checkerror_trait = " From 4774c6cf2cdecd68d777cf79cdb10047dc91d723 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Thu, 18 Sep 2025 10:22:42 -0700 Subject: [PATCH 25/34] CRC: annotate all parameters Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/analysis.rs | 78 ++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 9 deletions(-) diff --git a/clarity-types/src/errors/analysis.rs b/clarity-types/src/errors/analysis.rs index f845e87907..ee5c8b07d8 100644 --- a/clarity-types/src/errors/analysis.rs +++ b/clarity-types/src/errors/analysis.rs @@ -141,6 +141,7 @@ impl From for CheckErrorKind { Self::BadSyntaxBinding(e) } } + /// Errors encountered during type-checking and analysis of Clarity contract code, ensuring /// type safety, correct function signatures, and adherence to resource constraints. /// These errors prevent invalid contracts from being deployed or executed, @@ -151,10 +152,13 @@ pub enum CheckErrorKind { /// Arithmetic overflow in cost computation during type-checking, exceeding the maximum threshold. CostOverflow, /// Cumulative type-checking cost exceeds the allocated budget, indicating budget depletion. + /// The first `ExecutionCost` represents the total consumed cost, and the second represents the budget limit. CostBalanceExceeded(ExecutionCost, ExecutionCost), - /// Memory usage during type-checking exceeds the allocated memory budget. + /// Memory usage during type-checking exceeds the allocated budget. + /// The first `u64` represents the total consumed memory, and the second represents the memory limit. MemoryBalanceExceeded(u64, u64), - /// Failure in the cost-tracking mechanism due to an unexpected condition or invalid state. + /// Failure in cost-tracking due to an unexpected condition or invalid state. + /// The `String` wraps the specific reason for the failure. CostComputationFailed(String), // Time checker errors /// Type-checking time exceeds the allowed budget, halting analysis to ensure responsiveness. @@ -177,12 +181,15 @@ pub enum CheckErrorKind { /// This error indicates a transaction would invalidate a block if included. Expects(String), - // Match errors - /// Invalid syntax in an `option` match expression, wrapping the underlying error. + // Match expression errors + /// Invalid syntax in an `option` match expression. + /// The `Box` wraps the underlying error causing the syntax issue. BadMatchOptionSyntax(Box), - /// Invalid syntax in a `response` match expression, wrapping the underlying error. + /// Invalid syntax in a `response` match expression. + /// The `Box` wraps the underlying error causing the syntax issue. BadMatchResponseSyntax(Box), - /// Input to a match expression does not conform to the expected type. + /// Input to a `match` expression does not conform to the expected type (e.g., `Option` or `Response`). + /// The `Box` wraps the actual type of the provided input. BadMatchInput(Box), // List typing errors @@ -191,34 +198,45 @@ pub enum CheckErrorKind { /// Constructed list exceeds the maximum allowed length during type-checking. ConstructedListTooLarge, - // Simple type expectation mismatch + // Type mismatch errors /// Expected type does not match the actual type during analysis. + /// The first `Box` wraps the expected type, and the second wraps the actual type. TypeError(Box, Box), /// Value does not match the expected type during type-checking. + /// The `Box` wraps the expected type, and the `Box` wraps the invalid value. TypeValueError(Box, Box), /// Type description is invalid or malformed, preventing proper type-checking. InvalidTypeDescription, /// Referenced type name does not exist or is undefined. + /// The `String` wraps the non-existent type name. UnknownTypeName(String), // Union type mismatch /// Type does not belong to the expected union of types during analysis. + /// The `Vec` represents the expected types, and the `Box` wraps the actual type. UnionTypeError(Vec, Box), /// Value does not belong to the expected union of types during type-checking. + /// The `Vec` represents the expected types, and the `Box` wraps the invalid value. UnionTypeValueError(Vec, Box), /// Expected an optional type but found a different type. + /// The `Box` wraps the actual type provided. ExpectedOptionalType(Box), /// Expected a response type but found a different type. + /// The `Box` wraps the actual type provided. ExpectedResponseType(Box), /// Expected an optional or response type but found a different type. + /// The `Box` wraps the actual type provided. ExpectedOptionalOrResponseType(Box), /// Expected an optional value but found a different value. + /// The `Box` wraps the actual value provided. ExpectedOptionalValue(Box), /// Expected a response value but found a different value. + /// The `Box` wraps the actual value provided. ExpectedResponseValue(Box), /// Expected an optional or response value but found a different value. + /// The `Box` wraps the actual value provided. ExpectedOptionalOrResponseValue(Box), /// Could not determine the type of the `ok` branch in a response type. CouldNotDetermineResponseOkType, @@ -229,8 +247,10 @@ pub enum CheckErrorKind { /// Intermediary response types were not properly checked, risking type safety. UncheckedIntermediaryResponses, /// Expected a contract principal value but found a different value. + /// The `Box` wraps the actual value provided. ExpectedContractPrincipalValue(Box), + // Match type errors /// Could not determine the types for a match expression’s branches. CouldNotDetermineMatchTypes, /// Could not determine the type of an expression during analysis. @@ -243,15 +263,18 @@ pub enum CheckErrorKind { CheckerImplementationFailure, // Assets - /// Expected a token name as an argument + /// Expected a token name as an argument but found an invalid token. BadTokenName, /// Invalid or malformed signature in a `(define-non-fungible-token ...)` expression. DefineNFTBadSignature, /// Referenced non-fungible token (NFT) does not exist. + /// The `String` wraps the non-existent token name. NoSuchNFT(String), /// Referenced fungible token (FT) does not exist. + /// The `String` wraps the non-existent token name. NoSuchFT(String), + // Transfer and asset operation errors /// Invalid arguments provided to a `stx-transfer?` function. BadTransferSTXArguments, /// Invalid arguments provided to a fungible token transfer function. @@ -267,22 +290,27 @@ pub enum CheckErrorKind { /// Tuple field name is invalid or violates naming rules. BadTupleFieldName, /// Expected a tuple type but found a different type. + /// The `Box` wraps the actual type provided. ExpectedTuple(Box), /// Referenced tuple field does not exist in the tuple type. + /// The `String` wraps the requested field name, and the `TupleTypeSignature` wraps the tuple’s type. NoSuchTupleField(String, TupleTypeSignature), /// Empty tuple is not allowed in Clarity. EmptyTuplesNotAllowed, /// Invalid tuple construction due to malformed syntax or type mismatch. + /// The `String` wraps the specific error description. BadTupleConstruction(String), // Variables /// Referenced data variable does not exist in scope. + /// The `String` wraps the non-existent variable name. NoSuchDataVariable(String), // Data map /// Map name is invalid or violates naming rules. BadMapName, /// Referenced data map does not exist in scope. + /// The `String` wraps the non-existent map name. NoSuchMap(String), // Defines @@ -293,37 +321,49 @@ pub enum CheckErrorKind { /// Invalid or malformed map type definition in a `(define-map ...)` expression. BadMapTypeDefinition, /// Public function must return a response type, but found a different type. + /// The `Box` wraps the actual return type. PublicFunctionMustReturnResponse(Box), /// Invalid or malformed variable definition in a `(define-data-var ...)` expression. DefineVariableBadSignature, /// Return types of function branches do not match the expected type. + /// The first `Box` wraps the expected type, and the second wraps the actual type. ReturnTypesMustMatch(Box, Box), /// Circular reference detected in interdependent function definitions. + /// The `Vec` represents the list of referenced names forming the cycle. CircularReference(Vec), // Contract-call errors /// Referenced contract does not exist. + /// The `String` wraps the non-existent contract name. NoSuchContract(String), /// Referenced public function does not exist in the specified contract. + /// The first `String` wraps the contract name, and the second wraps the function name. NoSuchPublicFunction(String, String), /// Public function is not read-only when expected to be. + /// The first `String` wraps the contract name, and the second wraps the function name. PublicFunctionNotReadOnly(String, String), /// Attempt to define a contract with a name that already exists. + /// The `String` wraps the conflicting contract name. ContractAlreadyExists(String), /// Expected a contract name in a `contract-call?` expression but found an invalid token. ContractCallExpectName, /// Expected a callable type (e.g., function or trait) but found a different type. + /// The `Box` wraps the actual type provided. ExpectedCallableType(Box), // get-block-info? errors /// Referenced block info property does not exist. + /// The `String` wraps the non-existent property name. NoSuchBlockInfoProperty(String), /// Referenced burn block info property does not exist. + /// The `String` wraps the non-existent property name. NoSuchBurnBlockInfoProperty(String), /// Referenced Stacks block info property does not exist. + /// The `String` wraps the non-existent property name. NoSuchStacksBlockInfoProperty(String), /// Referenced tenure info property does not exist. + /// The `String` wraps the non-existent property name. NoSuchTenureInfoProperty(String), /// Expected a block info property name but found an invalid token. GetBlockInfoExpectPropertyName, @@ -335,8 +375,10 @@ pub enum CheckErrorKind { GetTenureInfoExpectPropertyName, /// Name (e.g., variable, function) is already in use within the same scope. + /// The `String` wraps the conflicting name. NameAlreadyUsed(String), /// Name is a reserved word in Clarity and cannot be used. + /// The `String` wraps the reserved name. ReservedWord(String), // Expect a function, or applying a function to a list @@ -345,6 +387,7 @@ pub enum CheckErrorKind { /// Expected a list application but found a different expression. ExpectedListApplication, /// Expected a sequence type (e.g., list, buffer) but found a different type. + /// The `Box` wraps the actual type provided. ExpectedSequence(Box), /// Sequence length exceeds the maximum allowed limit. MaxLengthOverflow, @@ -355,49 +398,65 @@ pub enum CheckErrorKind { // Generic binding syntax /// Invalid binding syntax in a generic construct (e.g., `let`, `match`). + /// The `SyntaxBindingError` wraps the specific binding error. BadSyntaxBinding(SyntaxBindingError), /// Maximum context depth for type-checking has been reached. MaxContextDepthReached, /// Referenced function is not defined in the current scope. + /// The `String` wraps the non-existent function name. UndefinedFunction(String), /// Referenced variable is not defined in the current scope. + /// The `String` wraps the non-existent variable name. UndefinedVariable(String), // Argument counts /// Function requires at least the specified number of arguments, but fewer were provided. + /// The first `usize` represents the minimum required, and the second represents the actual count. RequiresAtLeastArguments(usize, usize), /// Function requires at most the specified number of arguments, but more were provided. + /// The first `usize` represents the maximum allowed, and the second represents the actual count. RequiresAtMostArguments(usize, usize), /// Incorrect number of arguments provided to a function. + /// The first `usize` represents the expected count, and the second represents the actual count. IncorrectArgumentCount(usize, usize), /// `if` expression arms have mismatched return types. + /// The first `Box` wraps the type of one arm, and the second wraps the other. IfArmsMustMatch(Box, Box), /// `match` expression arms have mismatched return types. + /// The first `Box` wraps the type of one arm, and the second wraps the other. MatchArmsMustMatch(Box, Box), - /// 'default-to` expression types are mismatched. + /// `default-to` expression types are mismatched. + /// The first `Box` wraps the expected type, and the second wraps the actual type. DefaultTypesMustMatch(Box, Box), /// Application of an illegal or unknown function. + /// The `String` wraps the function name. IllegalOrUnknownFunctionApplication(String), /// Referenced function is unknown or not defined. + /// The `String` wraps the non-existent function name. UnknownFunction(String), // Traits /// Referenced trait does not exist in the specified contract. + /// The first `String` wraps the contract name, and the second wraps the trait name. NoSuchTrait(String, String), /// Referenced trait is not defined or cannot be found. + /// The `String` wraps the non-existent trait name. TraitReferenceUnknown(String), /// Referenced method does not exist in the specified trait. + /// The first `String` wraps the trait name, and the second wraps the method name. TraitMethodUnknown(String, String), /// Expected a trait identifier (e.g., `.trait-name`) but found an invalid token. ExpectedTraitIdentifier, /// Trait reference is not allowed in the current context (e.g., storage). TraitReferenceNotAllowed, /// Invalid implementation of a trait method. + /// The first `String` wraps the trait name, and the second wraps the method name. BadTraitImplementation(String, String), /// Invalid or malformed signature in a `(define-trait ...)` expression. DefineTraitBadSignature, /// Trait definition contains duplicate method names. + /// The `String` wraps the duplicate method name. DefineTraitDuplicateMethod(String), /// Unexpected use of a trait or field reference in a non-trait context. UnexpectedTraitOrFieldReference, @@ -406,6 +465,7 @@ pub enum CheckErrorKind { /// `contract-of` expects a trait type but found a different type. ContractOfExpectsTrait, /// Trait implementation is incompatible with the expected trait definition. + /// The first `Box` wraps the expected trait, and the second wraps the actual trait. IncompatibleTrait(Box, Box), // Strings From 93d5090b9e999201a6c5023aacf348a3c491e5e6 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Thu, 18 Sep 2025 11:11:27 -0700 Subject: [PATCH 26/34] CRC: annotate all parameters Signed-off-by: Jacinta Ferrant --- clarity/src/vm/clarity.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/clarity/src/vm/clarity.rs b/clarity/src/vm/clarity.rs index 7a274301c0..b3dd0c4e1e 100644 --- a/clarity/src/vm/clarity.rs +++ b/clarity/src/vm/clarity.rs @@ -17,16 +17,20 @@ use crate::vm::{analysis, ast, ClarityVersion, ContractContext, SymbolicExpressi /// type-checking, runtime evaluation, and transaction execution. #[derive(Debug)] pub enum ClarityError { - /// Error during static type-checking and semantic analysis. + /// Error during static type-checking or semantic analysis. + /// The `StaticCheckError` wraps the specific type-checking error, including diagnostic details. Analysis(CheckError), /// Error during lexical or syntactic parsing. + /// The `ParseError` wraps the specific parsing error, such as invalid syntax or tokens. Parse(ParseError), - /// Error during runtime evaluation of Clarity code. + /// Error during runtime evaluation in the virtual machine. + /// The `VmExecutionError` wraps the specific error, such as runtime errors or dynamic type-checking errors. Interpreter(InterpreterError), - /// Transaction is malformed or invalid due to blockchain-level issues (e.g., incorrect - /// format, invalid signatures). + /// Transaction is malformed or invalid due to blockchain-level issues. + /// The `String` wraps a human-readable description of the issue, such as incorrect format or invalid signatures. BadTransaction(String), - /// Transaction exceeds the allocated cost budget. Contains the actual and maximum allowed costs. + /// Transaction exceeds the allocated cost budget during execution. + /// The first `ExecutionCost` represents the total consumed cost, and the second represents the budget limit. CostError(ExecutionCost, ExecutionCost), /// Transaction aborted by a callback (e.g., post-condition check or custom logic). AbortedByCallback { From 71508f230c4a4a0b5891a861126899d6bf247112 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Thu, 18 Sep 2025 11:22:19 -0700 Subject: [PATCH 27/34] CRC: annotate all parameters Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/ast.rs | 54 +++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/clarity-types/src/errors/ast.rs b/clarity-types/src/errors/ast.rs index 75460a49fc..8c2a8c3537 100644 --- a/clarity-types/src/errors/ast.rs +++ b/clarity-types/src/errors/ast.rs @@ -23,19 +23,21 @@ use crate::representations::{PreSymbolicExpression, Span}; use crate::token::Token; pub type ParseResult = Result; - -#[derive(Debug, PartialEq)] /// Errors encountered during the lexical and syntactic analysis of Clarity source code /// when constructing the abstract syntax tree (AST). +#[derive(Debug, PartialEq)] pub enum ParseErrorKind { // Cost-related errors /// Arithmetic overflow in cost computation during AST construction, exceeding the maximum threshold. CostOverflow, - /// Cumulative parsing cost exceeds the allocated budget, indicating budget depletion rather than an overflow. + /// Cumulative parsing cost exceeds the allocated budget. + /// The first `ExecutionCost` represents the total consumed cost, and the second represents the budget limit. CostBalanceExceeded(ExecutionCost, ExecutionCost), - /// Memory usage during AST construction exceeds the allocated memory budget. + /// Memory usage during AST construction exceeds the allocated budget. + /// The first `u64` represents the total consumed memory, and the second represents the memory limit. MemoryBalanceExceeded(u64, u64), - /// Failure in the cost-tracking mechanism due to an unexpected condition or invalid state. + /// Failure in cost-tracking due to an unexpected condition or invalid state. + /// The `String` represents the specific reason for the failure. CostComputationFailed(String), /// Parsing time exceeds the allowed budget, halting AST construction to ensure responsiveness. ExecutionTimeExpired, @@ -43,19 +45,22 @@ pub enum ParseErrorKind { // Structural errors /// Number of expressions exceeds the maximum allowed limit. TooManyExpressions, - /// Nesting depth of expressions exceeds the allowed stack depth limit. + /// Nesting depth of expressions exceeds the maximum allowed stack depth. ExpressionStackDepthTooDeep, - /// Nesting depth of expressions exceeds the allowed stack depth limit. + /// Nesting depth of expressions exceeds the maximum allowed stack depth. VaryExpressionStackDepthTooDeep, // Semantic errors /// Failed to parse a string into an integer literal. + /// The `String` represents the invalid input string. FailedParsingIntValue(String), /// Circular reference detected in interdependent function definitions. + /// The `Vec` represents the list of function names forming the cycle. CircularReference(Vec), /// Variable name is already in use within the same scope. + /// The `String` represents the conflicting variable name. NameAlreadyUsed(String), - /// Attempt to store a trait reference, which is prohibited to ensure type safety and deterministic execution. + /// Attempt to store a trait reference, which is prohibited to ensure type safety. TraitReferenceNotAllowed, /// Invalid or malformed signature in a `(use-trait ...)` expression. ImportTraitBadSignature, @@ -64,28 +69,37 @@ pub enum ParseErrorKind { /// Invalid or malformed signature in a `(impl-trait ...)` expression. ImplTraitBadSignature, /// Referenced trait does not exist or cannot be found. + /// The `String` represents the non-existent trait name. TraitReferenceUnknown(String), // V1 Errors /// Failed to capture an expected substring or value during pattern matching in lexical analysis. FailedCapturingInput, - /// Expected a whitespace or a close parentheses but found an unexpected token or character. + /// Expected a whitespace or closing parenthesis but found an unexpected token or character. + /// The `String` represents the unexpected token or character found. SeparatorExpected(String), - /// Expected a whitespace after a colon, but found an unexpected token. + /// Expected a whitespace after a colon but found an unexpected token. + /// The `String` represents the unexpected token found. SeparatorExpectedAfterColon(String), /// Input program exceeds the maximum allowed number of lines. ProgramTooLarge, /// Variable name contains invalid characters or violates naming rules. + /// The `String` represents the invalid variable name. IllegalVariableName(String), /// Failed to parse a string into a buffer literal. + /// The `String` represents the invalid buffer string. FailedParsingBuffer(String), - /// Failed to parse a string into a hexadecimal value, with the input string and error details. + /// Failed to parse a string into a hexadecimal value. + /// The first `String` represents the invalid input string, and the second represents the error details. FailedParsingHexValue(String, String), /// Failed to parse a string into a principal literal (e.g., invalid principal format). + /// The `String` represents the invalid principal string. FailedParsingPrincipal(String), /// Failed to parse a string into a valid field literal. + /// The `String` represents the invalid field string. FailedParsingField(String), - /// Failed to parse the remaining input after processing a construct, leaving invalid or unexpected tokens. + /// Failed to parse the remaining input after processing a construct, leaving invalid tokens. + /// The `String` represents the unparsed remainder of the input. FailedParsingRemainder(String), /// Unexpected closing parenthesis encountered in the input. ClosingParenthesisUnexpected, @@ -96,10 +110,13 @@ pub enum ParseErrorKind { /// Expected a closing brace for a tuple literal but it was missing. ClosingTupleLiteralExpected, /// Expected a colon in a tuple literal at the specified position, but it was missing. + /// The `usize` represents the index where the colon was expected. TupleColonExpected(usize), /// Expected a comma in a tuple literal at the specified position, but it was missing. + /// The `usize` represents the index where the comma was expected. TupleCommaExpected(usize), /// Expected a tuple item (e.g., key-value pair) at the specified position, but it was missing or invalid. + /// The `usize` represents the index where the item was expected. TupleItemExpected(usize), /// Unexpected comma separator encountered outside a valid list or tuple context. CommaSeparatorUnexpected, @@ -112,10 +129,13 @@ pub enum ParseErrorKind { // V2 Errors /// Lexical analysis failed due to an underlying lexer error. + /// The `LexerError` represents the specific lexer error encountered. Lexer(LexerError), /// Contract name exceeds the maximum allowed length. + /// The `String` represents the overly long contract name. ContractNameTooLong(String), /// Expected a specific closing token (e.g., parenthesis or brace) but found another token. + /// The `Token` represents the expected closing token. ExpectedClosing(Token), /// Expected a contract identifier (e.g., `.contract-name`) but found an invalid or missing token. ExpectedContractIdentifier, @@ -124,16 +144,20 @@ pub enum ParseErrorKind { /// Expected whitespace to separate tokens but found an unexpected token or character. ExpectedWhitespace, /// Failed to parse a string into an unsigned integer literal. + /// The `String` represents the invalid unsigned integer string. FailedParsingUIntValue(String), /// Trait name contains invalid characters or violates naming rules. + /// The `String` represents the invalid trait name. IllegalTraitName(String), /// Invalid principal literal format, preventing parsing into a valid principal. InvalidPrincipalLiteral, /// Invalid buffer literal format, preventing parsing into a valid buffer. InvalidBuffer, /// Name (e.g., variable or function) exceeds the maximum allowed length. + /// The `String` represents the overly long name. NameTooLong(String), /// Encountered an unexpected token during parsing. + /// The `Token` represents the unexpected token found. UnexpectedToken(Token), /// Expected a colon in a tuple literal (version 2 syntax) but it was missing. TupleColonExpectedv2, @@ -142,14 +166,18 @@ pub enum ParseErrorKind { /// Expected a value in a tuple literal but it was missing or invalid. TupleValueExpected, /// Clarity name (e.g., variable, function, or trait) contains invalid characters or violates naming rules. + /// The `String` represents the invalid Clarity name. IllegalClarityName(String), /// ASCII string literal contains invalid characters or violates format rules. + /// The `String` represents the invalid ASCII string. IllegalASCIIString(String), /// Contract name contains invalid characters or violates naming rules. + /// The `String` represents the invalid contract name. IllegalContractName(String), // Notes - /// Indicates a token mismatch, used for internal parser diagnostics to match a specific token. + /// Indicates a token mismatch for internal parser diagnostics. + /// The `Token` represents the expected token to match. NoteToMatchThis(Token), /// Unreachable error indicating an unexpected parser failure; should never occur in valid execution. UnexpectedParserFailure, From 8952b53e2b4067be6288328697d47a9c9f166dcb Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Thu, 18 Sep 2025 11:43:50 -0700 Subject: [PATCH 28/34] CRC: add more detailed documentation. Leave interpreter to prevent conflicts with its rename Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/mod.rs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index fd66681c22..1d53dddb86 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -38,20 +38,30 @@ pub struct IncomparableError { pub err: T, } +/// Errors that can occur during the runtime execution of Clarity contracts in the virtual machine. +/// These encompass type-checking failures, interpreter issues, runtime errors, and premature returns. +/// Unlike static analysis errors in `ClarityError::StaticCheck(CheckError)` or `ClarityError::Parse(ParseError)`, +/// which are caught before execution during type-checking or parsing, these errors occur during dynamic +/// evaluation and may involve conditions not detectable statically, such as dynamically constructed expressions +/// (e.g., based on VRF seeds or runtime data). #[derive(Debug)] -/// Errors that can occur during the runtime execution, including type-checking -/// failures, interpreter issues, runtime errors, and premature returns. pub enum VmExecutionError { - /// UncheckedErrors are errors that *should* be caught by the - /// TypeChecker and other check passes. Test executions may - /// trigger these errors. + /// Type-checking errors caught during runtime analysis, which should typically be detected by + /// static type-checking passes before execution. These may occur in test executions or when + /// dynamic expression construction (e.g., using runtime data like VRF seeds) creates structures + /// violating type or resource constraints (e.g., excessive stack depth). + /// The `CheckErrorKind` wraps the specific type-checking error encountered at runtime. Unchecked(CheckErrors), - /// Errors originating from the interpreter during program execution. - /// These *should never* occur. Test executions may trigger these errors Interpreter(InterpreterError), - /// Errors that occur during runtime execution, with an optional stack trace. + /// Errors that occur during runtime execution of Clarity code, such as arithmetic errors or + /// invalid operations, expected as part of contract evaluation. + /// The `RuntimeErrorType` wraps the specific runtime error, and the `Option` provides + /// an optional stack trace for debugging, if available. Runtime(RuntimeErrorType, Option), - /// Errors triggered during Clarity contract evaluation that cause early termination. + /// Errors triggered during Clarity contract evaluation that cause early termination with + /// insufficient results (e.g., unwrapping an empty `Option`). + /// The `EarlyReturnError` wraps the specific early return condition, detailing the premature + /// termination cause. ShortReturn(ShortReturnType), } From dc9df983e5d13fecef3813d6dbbc32062b83f9e1 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Thu, 18 Sep 2025 12:29:24 -0700 Subject: [PATCH 29/34] CRC: annotate all parameters Signed-off-by: Jacinta Ferrant --- clarity-types/src/errors/mod.rs | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index 990025056a..c88c392256 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -69,38 +69,41 @@ pub enum InterpreterError { Expect(String), } -/// RuntimeErrors are errors that smart contracts are expected -/// to be able to trigger during execution (e.g., arithmetic errors) +/// Runtime errors that Clarity smart contracts are expected to trigger during execution in the virtual +/// machine, such as arithmetic errors, invalid operations, or blockchain-specific issues. These errors +/// are distinct from static analysis errors and occur during dynamic evaluation of contract code. #[derive(Debug, PartialEq)] pub enum RuntimeError { - /// A generic arithmetic error with a descriptive message. + /// A generic arithmetic error encountered during contract execution. + /// The `String` represents a descriptive message detailing the specific arithmetic issue. Arithmetic(String), - /// An arithmetic operation exceeded the maximum value for the data type (e.g., u128). + /// An arithmetic operation exceeded the maximum value for the data type (e.g., `u128`). ArithmeticOverflow, /// An arithmetic operation resulted in a value below zero for an unsigned type. ArithmeticUnderflow, /// Attempt to increase token supply beyond the maximum limit. - /// The parameters represent the current supply and the attempted increase. + /// The first u128 represents the attempted new supply (current supply plus increase), + /// and the second represents the maximum allowed supply. SupplyOverflow(u128, u128), /// Attempt to decrease token supply below zero. - /// The parameters represent the current supply and the attempted decrease. + /// The first `u128` represents the current token supply, and the second represents the attempted decrease amount. SupplyUnderflow(u128, u128), /// Attempt to divide or compute modulo by zero. DivisionByZero, - /// Failure to parse types dynamically during execution. - /// The string describes the specific parsing issue, such as invalid data formats. + /// Failure to parse types dynamically during contract execution. + /// The `String` represents the specific parsing issue, such as invalid data formats. TypeParseFailure(String), /// Failure to parse the abstract syntax tree (AST) during dynamic evaluation. - /// Wraps a detailed `ParseError` for issues in code interpretation. + /// The `Box` wraps the specific parsing error encountered, detailing code interpretation issues. ASTError(Box), /// The call stack exceeded the virtual machine's maximum depth. MaxStackDepthReached, /// The execution context depth exceeded the virtual machine's limit. MaxContextDepthReached, - /// Attempt to construct an invalid or unsupported type at runtime. + /// Attempt to construct an invalid or unsupported type at runtime (e.g., malformed data structure). BadTypeConstruction, /// Reference to an invalid or out-of-bounds block height. - /// The string details the issue, such as querying a future block. + /// The `String` represents the string representation of the queried block height that was invalid. BadBlockHeight(String), /// Attempt to interact with a non-existent token (e.g., in NFT or fungible token operations). NoSuchToken, @@ -111,16 +114,17 @@ pub enum RuntimeError { /// No sender principal available in the current execution context. NoSenderInContext, /// Invalid name-value pair in contract data (e.g., map keys). - /// The static string specifies the name, and the dynamic string provides the offending value. + /// The `&'static str` represents the name of the invalid pair, and the `String` represents the offending value. BadNameValue(&'static str, String), /// Reference to a non-existent block header hash. + /// The `BlockHeaderHash` represents the unknown block header hash. UnknownBlockHeaderHash(BlockHeaderHash), /// Invalid block hash provided (e.g., incorrect format or length). - /// The byte vector contains the invalid hash data. + /// The `Vec` represents the invalid block hash data. BadBlockHash(Vec), /// Failed to unwrap an `Optional` (`none`) or `Response` (`err` or `ok`) Clarity value. UnwrapFailure, - /// Attempt to set metadata already initialized (e.g., for NFTs or tokens). + /// Attempt to set metadata (e.g., for NFTs or tokens) that was already initialized. MetadataAlreadySet, /// Interaction with a deprecated or inactive Proof of Transfer (PoX) contract. DefunctPoxContract, From 78287226790b996a2457878610c5c7ac07891104 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Thu, 18 Sep 2025 12:35:01 -0700 Subject: [PATCH 30/34] CRC: remove accidental search replace in println and format Signed-off-by: Jacinta Ferrant --- stackslib/src/clarity_cli.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/stackslib/src/clarity_cli.rs b/stackslib/src/clarity_cli.rs index c54db47e15..a40c3774c6 100644 --- a/stackslib/src/clarity_cli.rs +++ b/stackslib/src/clarity_cli.rs @@ -787,13 +787,13 @@ fn get_eval_input(invoked_by: &str, args: &[String]) -> EvalInput { let mut buffer = String::new(); friendly_expect( io::stdin().read_to_string(&mut buffer), - "VmExecutionError reading from stdin.", + "Error reading from stdin.", ); buffer } else { friendly_expect( fs::read_to_string(&args[2]), - &format!("VmExecutionError reading file: {}", args[2]), + &format!("Error reading file: {}", args[2]), ) } }; @@ -1007,13 +1007,13 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option = @@ -1124,10 +1124,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option (i32, Option (i32, Option buffer, Err(error) => { - eprintln!("VmExecutionError reading from stdin:\n{error}"); + eprintln!("Error reading from stdin:\n{error}"); panic_test!(); } } @@ -1316,7 +1313,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option (i32, Option (i32, Option (i32, Option Date: Fri, 19 Sep 2025 10:42:02 +0200 Subject: [PATCH 31/34] add docstring for IncomparableError --- clarity-types/src/errors/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index ad7c19a03f..f020c0d126 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -33,8 +33,12 @@ use crate::types::{FunctionIdentifier, Value}; pub type StackTrace = Vec; +/// Wraps error types that do not implement [`PartialEq`], enabling their +/// use in enums that implement the trait. Any two `IncomparableError` values +/// are always considered unequal. #[derive(Debug)] pub struct IncomparableError { + /// The wrapped error value. pub err: T, } From bbead542d692fff734e679e572c28d235427d66f Mon Sep 17 00:00:00 2001 From: Francesco Leacche Date: Fri, 19 Sep 2025 10:42:45 +0200 Subject: [PATCH 32/34] document the variants' parameters --- clarity-types/src/errors/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/clarity-types/src/errors/mod.rs b/clarity-types/src/errors/mod.rs index f020c0d126..5953930208 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -70,11 +70,12 @@ pub enum Error { pub enum VmInternalError { /// Raised when the VM encounters an invalid or malformed `SymbolicExpression` /// e.g., bad variable name or missing argument. + /// The `String` provides a message describing the specific issue. BadSymbolicRepresentation(String), /// A generic, unexpected internal error, indicating a logic failure within /// the VM. - /// TODO: merge with VmInternalError::Expect - InvariantViolation(String), + /// The `String` provides a message describing the specific failure. + InvariantViolation(String), // TODO: merge with VmInternalError::Expect /// The VM failed to produce the final `AssetMap` when finalizing the /// execution environment for a transaction. FailedToConstructAssetTable, @@ -82,6 +83,7 @@ pub enum VmInternalError { /// execution environment for a transaction. FailedToConstructEventBatch, /// An error occurred during an interaction with the database. + /// The parameter contains the corresponding SQLite error. #[cfg(feature = "rusqlite")] SqliteError(IncomparableError), /// The file path provided for the MARF database is invalid because it @@ -91,6 +93,7 @@ pub enum VmInternalError { /// storage. Likely due to a file system permissions error or an invalid path FailedToCreateDataDirectory, /// A failure occurred within the MARF implementation. + /// The `String` provides a message describing the specific failure. MarfFailure(String), /// Failed to construct a tuple value from provided data because it did not /// match the expected type signature. @@ -101,10 +104,12 @@ pub enum VmInternalError { /// An STX transfer failed due to insufficient balance. InsufficientBalance, /// A generic error occurred during a database operation. + /// The `String` represents a descriptive message detailing the specific issue. DBError(String), /// An internal expectation or assertion failed. This is used for conditions /// that are believed to be unreachable but are handled gracefully to prevent /// a panic. + /// The `String` provides a message describing the failed expectation. Expect(String), } From adfc00b9734233005cab339a7578189ade1828da Mon Sep 17 00:00:00 2001 From: Francesco Leacche Date: Fri, 19 Sep 2025 11:29:38 +0200 Subject: [PATCH 33/34] add aac-client-breaking to clippy workflow branches --- .github/workflows/clippy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index ded23c7c6e..44d60b4d33 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -13,6 +13,7 @@ on: pull_request: branches: - develop + - aac-client-breaking # temp branch for aac work types: - opened - reopened From 4c8946179bd0c2d62ef59ed60191da23c13275df Mon Sep 17 00:00:00 2001 From: Francesco Leacche Date: Mon, 22 Sep 2025 12:42:25 +0100 Subject: [PATCH 34/34] cargo fmt --- clarity/src/vm/errors.rs | 4 ++-- clarity/src/vm/functions/options.rs | 4 ++-- stackslib/src/clarity_vm/database/ephemeral.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clarity/src/vm/errors.rs b/clarity/src/vm/errors.rs index 91edcdea0d..6c40c5bdb5 100644 --- a/clarity/src/vm/errors.rs +++ b/clarity/src/vm/errors.rs @@ -15,8 +15,8 @@ // along with this program. If not, see . pub use clarity_types::errors::{ - EarlyReturnError, Error, IncomparableError, VmInternalError, InterpreterResult, - RuntimeErrorType, + EarlyReturnError, Error, IncomparableError, InterpreterResult, RuntimeErrorType, + VmInternalError, }; pub use crate::vm::analysis::errors::{ diff --git a/clarity/src/vm/functions/options.rs b/clarity/src/vm/functions/options.rs index 6d1c1165ec..d418b472cf 100644 --- a/clarity/src/vm/functions/options.rs +++ b/clarity/src/vm/functions/options.rs @@ -18,8 +18,8 @@ use crate::vm::contexts::{Environment, LocalContext}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{runtime_cost, CostTracker, MemoryConsumer}; use crate::vm::errors::{ - check_arguments_at_least, CheckErrors, EarlyReturnError, VmInternalError, - InterpreterResult as Result, RuntimeErrorType, + check_arguments_at_least, CheckErrors, EarlyReturnError, InterpreterResult as Result, + RuntimeErrorType, VmInternalError, }; use crate::vm::types::{CallableData, OptionalData, ResponseData, TypeSignature, Value}; use crate::vm::Value::CallableContract; diff --git a/stackslib/src/clarity_vm/database/ephemeral.rs b/stackslib/src/clarity_vm/database/ephemeral.rs index e0f0bdc6b4..41ea4057a5 100644 --- a/stackslib/src/clarity_vm/database/ephemeral.rs +++ b/stackslib/src/clarity_vm/database/ephemeral.rs @@ -21,7 +21,7 @@ use clarity::vm::database::sqlite::{ sqlite_insert_metadata, }; use clarity::vm::database::{ClarityBackingStore, SpecialCaseHandler, SqliteConnection}; -use clarity::vm::errors::{VmInternalError, InterpreterResult, RuntimeErrorType}; +use clarity::vm::errors::{InterpreterResult, RuntimeErrorType, VmInternalError}; use clarity::vm::types::QualifiedContractIdentifier; use rusqlite; use rusqlite::Connection;