diff --git a/clarity-types/src/errors/analysis.rs b/clarity-types/src/errors/analysis.rs index 5116d0cab9c..a5d2a11362c 100644 --- a/clarity-types/src/errors/analysis.rs +++ b/clarity-types/src/errors/analysis.rs @@ -136,16 +136,440 @@ impl SyntaxBindingError { } } -impl From for CheckErrorKind { +/// Converts a [`SyntaxBindingError`] into a [`StaticCheckErrorKind`]. +/// Used for propagating binding errors from +/// [`crate::vm::analysis::read_only_checker::ReadOnlyChecker::check_each_expression_is_read_only`] +impl From for StaticCheckErrorKind { fn from(e: SyntaxBindingError) -> Self { 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. +/// Converts a [`SyntaxBindingError`] into a [`CommonCheckErrorKind`]. +/// Used for propagating binding errors from [`crate::vm::functions::handle_binding_list`], +/// which is utilized in both static and runtime analysis to ensure consistent error handling. +impl From for CommonCheckErrorKind { + fn from(e: SyntaxBindingError) -> Self { + CommonCheckErrorKind::BadSyntaxBinding(e) + } +} + +/// Internal set of error variants that are shared exclusively between static analysis (deployment) +// and runtime checking (execution), specifically for validation logic that is implemented in common +// code paths used by both. +/// +/// **This enum is strictly for internal use and is not a part of the public API.** +/// +/// All these variants represent errors that can arise *only* from code executed in both analysis and execution +/// contexts—such as argument count checks, type size limits, or shared cost tracking logic. If an error +/// may be triggered by either context via common logic, it lives here. +/// +/// Importantly, this enum does *not* cover all errors common to both analysis and execution. +/// There are other error shared error variants, but those are generated specifically by logic +/// that is unique to static analysis or unique to execution. These errors are defined separately +/// and do not pass through this enum. Only error cases that can possibly arise from a shared validation +/// flow will appear here. +/// +/// When a `CommonCheckErrorKind` is produced, it is always converted immediately into either a +/// [`StaticCheckErrorKind`] (when encountered during deployment analysis) *or* a +/// [`CheckErrorKind`] (when encountered at runtime). +#[derive(Debug, PartialEq)] +pub enum CommonCheckErrorKind { + // 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. + /// 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 budget. + /// The first `u64` represents the total consumed memory, and the second represents the memory limit. + MemoryBalanceExceeded(u64, u64), + /// 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. + 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 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), + + // 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), + + /// 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), + + /// Could not determine the serialization type for a value during analysis. + CouldNotDetermineSerializationType, + + /// Could not determine the type of an expression during analysis. + CouldNotDetermineType, + + /// Empty tuple is not allowed in Clarity. + EmptyTuplesNotAllowed, + + /// Invalid or malformed signature in a function definition. + DefineFunctionBadSignature, + + /// Name (e.g., variable, function) is already in use within the same scope. + /// The `String` wraps the conflicting name. + NameAlreadyUsed(String), + + /// Invalid binding syntax in a generic construct (e.g., `let`, `match`). + /// The `SyntaxBindingError` wraps the specific binding error. + BadSyntaxBinding(SyntaxBindingError), + + // 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), + + /// Expected a trait identifier (e.g., `.trait-name`) but found an invalid token. + ExpectedTraitIdentifier, + /// 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), +} + +/// An error detected during the static analysis of a smart contract at deployment time. +/// +/// These checks are performed once, before any contract execution occurs, to find issues +/// like type mismatches, invalid function signatures, or incorrect control flow. +#[derive(Debug, PartialEq)] +pub enum StaticCheckErrorKind { + // 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. + /// 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 budget. + /// The first `u64` represents the total consumed memory, and the second represents the memory limit. + MemoryBalanceExceeded(u64, u64), + /// 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. + 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 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 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. + /// The `Box` wraps the underlying error causing the syntax issue. + BadMatchResponseSyntax(Box), + /// 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), + + /// Constructed list exceeds the maximum allowed length during type-checking. + ConstructedListTooLarge, + + // 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), + + /// 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), + /// 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), + /// 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, + + // 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. + 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 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), + + // Tuples + /// 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 + /// 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. + /// 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), + + // 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), + /// 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 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, + /// 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. + /// 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 + /// 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. + /// The `Box` wraps the actual type provided. + ExpectedSequence(Box), + /// Sequence length exceeds the maximum allowed limit. + MaxLengthOverflow, + + // Let syntax + /// Invalid syntax in a `let` expression, violating binding or structure rules. + BadLetSyntax, + + // 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 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. + /// 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, + /// 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, + /// `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), + + /// Attempt to write to contract state in a read-only function. + WriteAttemptedInReadOnly, + /// `at-block` closure must be read-only but contains write operations. + AtBlockClosureMustBeReadOnly, + + // contract post-conditions + /// Post-condition expects a list of asset allowances but received invalid input. + /// The first `String` wraps the function name, and the second `i32` wraps the argument number. + ExpectedListOfAllowances(String, i32), + /// Allowance expressions are only allowed in specific contexts (`restrict-assets?` or `as-contract?`). + AllowanceExprNotAllowed, + /// Expected an allowance expression but found invalid input. + /// The `String` wraps the unexpected input. + ExpectedAllowanceExpr(String), + /// `with-all-assets-unsafe` is not allowed in this context. + WithAllAllowanceNotAllowed, + /// `with-all-assets-unsafe` cannot be used alongside other allowances. + WithAllAllowanceNotAlone, + /// `with-nft` allowance requires a list of asset identifiers. + WithNftExpectedListOfIdentifiers, + /// `with-nft` allowance identifiers list exceeds the maximum allowed length. + /// The first `u32` represents the maximum length, and the second represents the actual length. + MaxIdentifierLengthExceeded(u32, u32), + /// Too many allowances specified in post-condition. + /// The first `usize` represents the maximum allowed, and the second represents the actual count. + TooManyAllowances(usize, usize), +} + +/// An error that occurs during the runtime analysis of a smart contract at runtime. Could be returnd by: +/// - a contract initialization execution +/// - a contract call execution +/// +/// These errors are found when a contract is executed. They represent dynamic conditions +/// that cannot be determined by static analysis, such as: +/// - Failures based on runtime arguments or state changes. +/// - Value-level type mismatches. #[derive(Debug, PartialEq)] pub enum CheckErrorKind { // Cost checker errors @@ -195,8 +619,6 @@ pub enum CheckErrorKind { // List typing errors /// List elements have mismatched types, violating type consistency. ListTypesMustMatch, - /// Constructed list exceeds the maximum allowed length during type-checking. - ConstructedListTooLarge, // Type mismatch errors /// Expected type does not match the actual type during analysis. @@ -220,15 +642,6 @@ pub enum CheckErrorKind { /// 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), @@ -238,35 +651,19 @@ pub enum CheckErrorKind { /// 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, - /// 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. /// 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. 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 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), @@ -287,8 +684,6 @@ pub enum CheckErrorKind { BadBurnFTArguments, // Tuples - /// 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), @@ -297,9 +692,6 @@ pub enum CheckErrorKind { 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. @@ -307,8 +699,6 @@ pub enum CheckErrorKind { 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), @@ -318,13 +708,9 @@ pub enum CheckErrorKind { 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. /// 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), @@ -348,27 +734,16 @@ pub enum CheckErrorKind { 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, - /// 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. @@ -377,9 +752,6 @@ pub enum CheckErrorKind { /// 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 /// Attempt to apply a non-function value as a function. @@ -389,8 +761,6 @@ pub enum CheckErrorKind { /// 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, // Let syntax /// Invalid syntax in a `let` expression, violating binding or structure rules. @@ -401,8 +771,6 @@ pub enum CheckErrorKind { /// 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), @@ -420,26 +788,8 @@ pub enum CheckErrorKind { /// 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. - /// 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), @@ -448,8 +798,6 @@ pub enum CheckErrorKind { 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), @@ -458,15 +806,11 @@ pub enum CheckErrorKind { /// 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, + /// 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. - /// The first `Box` wraps the expected trait, and the second wraps the actual trait. - IncompatibleTrait(Box, Box), // Strings /// String contains invalid or disallowed characters (e.g., non-ASCII in ASCII strings). @@ -507,12 +851,15 @@ pub enum CheckErrorKind { } #[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. +/// A complete static analysis error, combining the error with diagnostic information. +/// +/// This struct wraps a [`StaticCheckErrorKind`] variant with its source location +/// (like line and column numbers) and the code expression that caused the error. +/// It provides the full context needed to report a clear, actionable error to a +/// developer during contract deployment. pub struct StaticCheckError { /// The specific type-checking or semantic error that occurred. - pub err: Box, + 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. @@ -530,8 +877,17 @@ impl CheckErrorKind { } } +impl StaticCheckErrorKind { + pub fn rejectable(&self) -> bool { + matches!( + self, + StaticCheckErrorKind::SupertypeTooLarge | StaticCheckErrorKind::Expects(_) + ) + } +} + impl StaticCheckError { - pub fn new(err: CheckErrorKind) -> StaticCheckError { + pub fn new(err: StaticCheckErrorKind) -> StaticCheckError { let diagnostic = Diagnostic::err(&err); StaticCheckError { err: Box::new(err), @@ -554,30 +910,40 @@ impl StaticCheckError { self.expressions.replace(exprs.to_vec()); } - pub fn with_expression(err: CheckErrorKind, expr: &SymbolicExpression) -> Self { + pub fn with_expression(err: StaticCheckErrorKind, expr: &SymbolicExpression) -> Self { let mut r = Self::new(err); r.set_expression(expr); r } } +impl From<(CommonCheckErrorKind, &SymbolicExpression)> for StaticCheckError { + fn from(e: (CommonCheckErrorKind, &SymbolicExpression)) -> Self { + Self::with_expression(e.0.into(), e.1) + } +} + impl From<(SyntaxBindingError, &SymbolicExpression)> for StaticCheckError { fn from(e: (SyntaxBindingError, &SymbolicExpression)) -> Self { - Self::with_expression(CheckErrorKind::BadSyntaxBinding(e.0), e.1) + Self::with_expression(StaticCheckErrorKind::BadSyntaxBinding(e.0), e.1) } } -impl From<(CheckErrorKind, &SymbolicExpression)> for StaticCheckError { - fn from(e: (CheckErrorKind, &SymbolicExpression)) -> Self { - let mut ce = Self::new(e.0); - ce.set_expression(e.1); - ce +impl From<(CommonCheckErrorKind, &SymbolicExpression)> for CommonCheckErrorKind { + fn from(e: (CommonCheckErrorKind, &SymbolicExpression)) -> Self { + e.0 } } -impl From<(CheckErrorKind, &SymbolicExpression)> for CheckErrorKind { - fn from(e: (CheckErrorKind, &SymbolicExpression)) -> Self { - e.0 +impl From<(CommonCheckErrorKind, &SymbolicExpression)> for CheckErrorKind { + fn from(e: (CommonCheckErrorKind, &SymbolicExpression)) -> Self { + e.0.into() + } +} + +impl fmt::Display for CommonCheckErrorKind { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{self:?}") } } @@ -587,6 +953,12 @@ impl fmt::Display for CheckErrorKind { } } +impl fmt::Display for StaticCheckErrorKind { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{self:?}") + } +} + impl fmt::Display for StaticCheckError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.err)?; @@ -601,7 +973,30 @@ impl fmt::Display for StaticCheckError { impl From for StaticCheckError { fn from(err: CostErrors) -> Self { - StaticCheckError::from(CheckErrorKind::from(err)) + StaticCheckError::from(StaticCheckErrorKind::from(err)) + } +} + +impl From for StaticCheckErrorKind { + fn from(err: CostErrors) -> Self { + match err { + CostErrors::CostOverflow => StaticCheckErrorKind::CostOverflow, + CostErrors::CostBalanceExceeded(a, b) => { + StaticCheckErrorKind::CostBalanceExceeded(a, b) + } + CostErrors::MemoryBalanceExceeded(a, b) => { + StaticCheckErrorKind::MemoryBalanceExceeded(a, b) + } + CostErrors::CostComputationFailed(s) => StaticCheckErrorKind::CostComputationFailed(s), + CostErrors::CostContractLoadFailure => { + StaticCheckErrorKind::CostComputationFailed("Failed to load cost contract".into()) + } + CostErrors::InterpreterFailure => StaticCheckErrorKind::Expects( + "Unexpected interpreter failure in cost computation".into(), + ), + CostErrors::Expect(s) => StaticCheckErrorKind::Expects(s), + CostErrors::ExecutionTimeExpired => StaticCheckErrorKind::ExecutionTimeExpired, + } } } @@ -624,6 +1019,35 @@ impl From for CheckErrorKind { } } +impl From for CommonCheckErrorKind { + fn from(err: CostErrors) -> Self { + match err { + CostErrors::CostOverflow => CommonCheckErrorKind::CostOverflow, + CostErrors::CostBalanceExceeded(a, b) => { + CommonCheckErrorKind::CostBalanceExceeded(a, b) + } + CostErrors::MemoryBalanceExceeded(a, b) => { + CommonCheckErrorKind::MemoryBalanceExceeded(a, b) + } + CostErrors::CostComputationFailed(s) => CommonCheckErrorKind::CostComputationFailed(s), + CostErrors::CostContractLoadFailure => { + CommonCheckErrorKind::CostComputationFailed("Failed to load cost contract".into()) + } + CostErrors::InterpreterFailure => CommonCheckErrorKind::Expects( + "Unexpected interpreter failure in cost computation".into(), + ), + CostErrors::Expect(s) => CommonCheckErrorKind::Expects(s), + CostErrors::ExecutionTimeExpired => CommonCheckErrorKind::ExecutionTimeExpired, + } + } +} + +impl error::Error for CommonCheckErrorKind { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + None + } +} + impl error::Error for StaticCheckError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { None @@ -636,30 +1060,166 @@ impl error::Error for CheckErrorKind { } } -impl From for StaticCheckError { - fn from(err: CheckErrorKind) -> Self { +impl From for StaticCheckError { + fn from(err: StaticCheckErrorKind) -> Self { StaticCheckError::new(err) } } +impl From for StaticCheckError { + fn from(err: CommonCheckErrorKind) -> Self { + StaticCheckError::new(StaticCheckErrorKind::from(err)) + } +} + +impl From for CheckErrorKind { + fn from(err: CommonCheckErrorKind) -> Self { + match err { + CommonCheckErrorKind::CostOverflow => CheckErrorKind::CostOverflow, + CommonCheckErrorKind::CostBalanceExceeded(a, b) => { + CheckErrorKind::CostBalanceExceeded(a, b) + } + CommonCheckErrorKind::MemoryBalanceExceeded(a, b) => { + CheckErrorKind::MemoryBalanceExceeded(a, b) + } + CommonCheckErrorKind::CostComputationFailed(s) => { + CheckErrorKind::CostComputationFailed(s) + } + CommonCheckErrorKind::ExecutionTimeExpired => CheckErrorKind::ExecutionTimeExpired, + CommonCheckErrorKind::IncorrectArgumentCount(expected, args) => { + CheckErrorKind::IncorrectArgumentCount(expected, args) + } + CommonCheckErrorKind::RequiresAtLeastArguments(expected, args) => { + CheckErrorKind::RequiresAtLeastArguments(expected, args) + } + CommonCheckErrorKind::RequiresAtMostArguments(expected, args) => { + CheckErrorKind::RequiresAtMostArguments(expected, args) + } + CommonCheckErrorKind::ExpectedName => CheckErrorKind::ExpectedName, + CommonCheckErrorKind::DefineFunctionBadSignature => { + CheckErrorKind::DefineFunctionBadSignature + } + CommonCheckErrorKind::ExpectedTraitIdentifier => { + CheckErrorKind::ExpectedTraitIdentifier + } + CommonCheckErrorKind::Expects(s) => CheckErrorKind::Expects(s), + CommonCheckErrorKind::CouldNotDetermineType => CheckErrorKind::CouldNotDetermineType, + CommonCheckErrorKind::ValueTooLarge => CheckErrorKind::ValueTooLarge, + CommonCheckErrorKind::TypeSignatureTooDeep => CheckErrorKind::TypeSignatureTooDeep, + CommonCheckErrorKind::DefineTraitDuplicateMethod(s) => { + CheckErrorKind::DefineTraitDuplicateMethod(s) + } + CommonCheckErrorKind::DefineTraitBadSignature => { + CheckErrorKind::DefineTraitBadSignature + } + CommonCheckErrorKind::InvalidTypeDescription => CheckErrorKind::InvalidTypeDescription, + CommonCheckErrorKind::SupertypeTooLarge => CheckErrorKind::SupertypeTooLarge, + CommonCheckErrorKind::TypeError(a, b) => CheckErrorKind::TypeError(a, b), + CommonCheckErrorKind::BadSyntaxBinding(e) => CheckErrorKind::BadSyntaxBinding(e), + CommonCheckErrorKind::ValueOutOfBounds => CheckErrorKind::ValueOutOfBounds, + CommonCheckErrorKind::CouldNotDetermineSerializationType => { + CheckErrorKind::CouldNotDetermineSerializationType + } + CommonCheckErrorKind::EmptyTuplesNotAllowed => CheckErrorKind::EmptyTuplesNotAllowed, + CommonCheckErrorKind::NameAlreadyUsed(name) => CheckErrorKind::NameAlreadyUsed(name), + CommonCheckErrorKind::UnknownTypeName(name) => CheckErrorKind::UnknownTypeName(name), + } + } +} + +impl From for StaticCheckErrorKind { + fn from(err: CommonCheckErrorKind) -> Self { + match err { + CommonCheckErrorKind::CostOverflow => StaticCheckErrorKind::CostOverflow, + CommonCheckErrorKind::CostBalanceExceeded(a, b) => { + StaticCheckErrorKind::CostBalanceExceeded(a, b) + } + CommonCheckErrorKind::MemoryBalanceExceeded(a, b) => { + StaticCheckErrorKind::MemoryBalanceExceeded(a, b) + } + CommonCheckErrorKind::CostComputationFailed(s) => { + StaticCheckErrorKind::CostComputationFailed(s) + } + CommonCheckErrorKind::ExecutionTimeExpired => { + StaticCheckErrorKind::ExecutionTimeExpired + } + CommonCheckErrorKind::IncorrectArgumentCount(expected, args) => { + StaticCheckErrorKind::IncorrectArgumentCount(expected, args) + } + CommonCheckErrorKind::RequiresAtLeastArguments(expected, args) => { + StaticCheckErrorKind::RequiresAtLeastArguments(expected, args) + } + CommonCheckErrorKind::RequiresAtMostArguments(expected, args) => { + StaticCheckErrorKind::RequiresAtMostArguments(expected, args) + } + CommonCheckErrorKind::ExpectedName => StaticCheckErrorKind::ExpectedName, + CommonCheckErrorKind::DefineFunctionBadSignature => { + StaticCheckErrorKind::DefineFunctionBadSignature + } + CommonCheckErrorKind::ExpectedTraitIdentifier => { + StaticCheckErrorKind::ExpectedTraitIdentifier + } + CommonCheckErrorKind::Expects(s) => StaticCheckErrorKind::Expects(s), + CommonCheckErrorKind::CouldNotDetermineType => { + StaticCheckErrorKind::CouldNotDetermineType + } + CommonCheckErrorKind::ValueTooLarge => StaticCheckErrorKind::ValueTooLarge, + CommonCheckErrorKind::TypeSignatureTooDeep => { + StaticCheckErrorKind::TypeSignatureTooDeep + } + CommonCheckErrorKind::DefineTraitDuplicateMethod(s) => { + StaticCheckErrorKind::DefineTraitDuplicateMethod(s) + } + CommonCheckErrorKind::DefineTraitBadSignature => { + StaticCheckErrorKind::DefineTraitBadSignature + } + CommonCheckErrorKind::InvalidTypeDescription => { + StaticCheckErrorKind::InvalidTypeDescription + } + CommonCheckErrorKind::SupertypeTooLarge => StaticCheckErrorKind::SupertypeTooLarge, + CommonCheckErrorKind::TypeError(a, b) => StaticCheckErrorKind::TypeError(a, b), + CommonCheckErrorKind::BadSyntaxBinding(e) => StaticCheckErrorKind::BadSyntaxBinding(e), + CommonCheckErrorKind::ValueOutOfBounds => StaticCheckErrorKind::ValueOutOfBounds, + CommonCheckErrorKind::CouldNotDetermineSerializationType => { + StaticCheckErrorKind::CouldNotDetermineSerializationType + } + CommonCheckErrorKind::EmptyTuplesNotAllowed => { + StaticCheckErrorKind::EmptyTuplesNotAllowed + } + CommonCheckErrorKind::NameAlreadyUsed(name) => { + StaticCheckErrorKind::NameAlreadyUsed(name) + } + CommonCheckErrorKind::UnknownTypeName(name) => { + StaticCheckErrorKind::UnknownTypeName(name) + } + } + } +} + #[cfg(any(test, feature = "testing"))] -impl From for String { - fn from(o: CheckErrorKind) -> Self { +impl From for String { + fn from(o: StaticCheckErrorKind) -> Self { o.to_string() } } -pub fn check_argument_count(expected: usize, args: &[T]) -> Result<(), CheckErrorKind> { +pub fn check_argument_count(expected: usize, args: &[T]) -> Result<(), CommonCheckErrorKind> { if args.len() != expected { - Err(CheckErrorKind::IncorrectArgumentCount(expected, args.len())) + Err(CommonCheckErrorKind::IncorrectArgumentCount( + expected, + args.len(), + )) } else { Ok(()) } } -pub fn check_arguments_at_least(expected: usize, args: &[T]) -> Result<(), CheckErrorKind> { +pub fn check_arguments_at_least( + expected: usize, + args: &[T], +) -> Result<(), CommonCheckErrorKind> { if args.len() < expected { - Err(CheckErrorKind::RequiresAtLeastArguments( + Err(CommonCheckErrorKind::RequiresAtLeastArguments( expected, args.len(), )) @@ -668,9 +1228,9 @@ pub fn check_arguments_at_least(expected: usize, args: &[T]) -> Result<(), Ch } } -pub fn check_arguments_at_most(expected: usize, args: &[T]) -> Result<(), CheckErrorKind> { +pub fn check_arguments_at_most(expected: usize, args: &[T]) -> Result<(), CommonCheckErrorKind> { if args.len() > expected { - Err(CheckErrorKind::RequiresAtMostArguments( + Err(CommonCheckErrorKind::RequiresAtMostArguments( expected, args.len(), )) @@ -694,6 +1254,134 @@ fn formatted_expected_types(expected_types: &[TypeSignature]) -> String { expected_types_joined } +impl DiagnosableError for StaticCheckErrorKind { + fn message(&self) -> String { + match &self { + StaticCheckErrorKind::SupertypeTooLarge => "supertype of two types is too large".into(), + StaticCheckErrorKind::Expects(s) => format!("unexpected interpreter behavior: {s}"), + StaticCheckErrorKind::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()), + StaticCheckErrorKind::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()), + StaticCheckErrorKind::BadMatchInput(t) => + format!("match requires an input of either a response or optional, found input: '{t}'"), + StaticCheckErrorKind::CostOverflow => "contract execution cost overflowed cost counter".into(), + StaticCheckErrorKind::CostBalanceExceeded(a, b) => format!("contract execution cost exceeded budget: {a:?} > {b:?}"), + StaticCheckErrorKind::MemoryBalanceExceeded(a, b) => format!("contract execution cost exceeded memory budget: {a:?} > {b:?}"), + StaticCheckErrorKind::CostComputationFailed(s) => format!("contract cost computation failed: {s}"), + StaticCheckErrorKind::ExecutionTimeExpired => "execution time expired".into(), + StaticCheckErrorKind::InvalidTypeDescription => "supplied type description is invalid".into(), + StaticCheckErrorKind::EmptyTuplesNotAllowed => "tuple types may not be empty".into(), + StaticCheckErrorKind::UnknownTypeName(name) => format!("failed to parse type: '{name}'"), + StaticCheckErrorKind::ValueTooLarge => "created a type which was greater than maximum allowed value size".into(), + StaticCheckErrorKind::ValueOutOfBounds => "created a type which value size was out of defined bounds".into(), + StaticCheckErrorKind::TypeSignatureTooDeep => "created a type which was deeper than maximum allowed type depth".into(), + StaticCheckErrorKind::ExpectedName => "expected a name argument to this function".into(), + StaticCheckErrorKind::ConstructedListTooLarge => "reached limit of elements in a sequence".into(), + StaticCheckErrorKind::TypeError(expected_type, found_type) => format!("expecting expression of type '{expected_type}', found '{found_type}'"), + StaticCheckErrorKind::UnionTypeError(expected_types, found_type) => format!("expecting expression of type {}, found '{}'", formatted_expected_types(expected_types), found_type), + StaticCheckErrorKind::ExpectedOptionalType(found_type) => format!("expecting expression of type 'optional', found '{found_type}'"), + StaticCheckErrorKind::ExpectedOptionalOrResponseType(found_type) => format!("expecting expression of type 'optional' or 'response', found '{found_type}'"), + StaticCheckErrorKind::ExpectedResponseType(found_type) => format!("expecting expression of type 'response', found '{found_type}'"), + StaticCheckErrorKind::CouldNotDetermineResponseOkType => "attempted to obtain 'ok' value from response, but 'ok' type is indeterminate".into(), + StaticCheckErrorKind::CouldNotDetermineResponseErrType => "attempted to obtain 'err' value from response, but 'err' type is indeterminate".into(), + StaticCheckErrorKind::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(), + StaticCheckErrorKind::CouldNotDetermineType => "type of expression cannot be determined".into(), + StaticCheckErrorKind::BadTupleFieldName => "invalid tuple field name".into(), + StaticCheckErrorKind::ExpectedTuple(type_signature) => format!("expecting tuple, found '{type_signature}'"), + StaticCheckErrorKind::NoSuchTupleField(field_name, tuple_signature) => format!("cannot find field '{field_name}' in tuple '{tuple_signature}'"), + StaticCheckErrorKind::BadTupleConstruction(message) => format!("invalid tuple syntax: {message}"), + StaticCheckErrorKind::NoSuchDataVariable(var_name) => format!("use of unresolved persisted variable '{var_name}'"), + StaticCheckErrorKind::BadMapName => "invalid map name".into(), + StaticCheckErrorKind::NoSuchMap(map_name) => format!("use of unresolved map '{map_name}'"), + StaticCheckErrorKind::DefineFunctionBadSignature => "invalid function definition".into(), + StaticCheckErrorKind::BadFunctionName => "invalid function name".into(), + StaticCheckErrorKind::BadMapTypeDefinition => "invalid map definition".into(), + StaticCheckErrorKind::PublicFunctionMustReturnResponse(found_type) => format!("public functions must return an expression of type 'response', found '{found_type}'"), + StaticCheckErrorKind::DefineVariableBadSignature => "invalid variable definition".into(), + StaticCheckErrorKind::ReturnTypesMustMatch(type_1, type_2) => format!("detected two execution paths, returning two different expression types (got '{type_1}' and '{type_2}')"), + StaticCheckErrorKind::NoSuchContract(contract_identifier) => format!("use of unresolved contract '{contract_identifier}'"), + StaticCheckErrorKind::NoSuchPublicFunction(contract_identifier, function_name) => format!("contract '{contract_identifier}' has no public function '{function_name}'"), + StaticCheckErrorKind::ContractAlreadyExists(contract_identifier) => format!("contract name '{contract_identifier}' conflicts with existing contract"), + StaticCheckErrorKind::ContractCallExpectName => "missing contract name for call".into(), + StaticCheckErrorKind::ExpectedCallableType(found_type) => format!("expected a callable contract, found {found_type}"), + StaticCheckErrorKind::NoSuchBlockInfoProperty(property_name) => format!("use of block unknown property '{property_name}'"), + StaticCheckErrorKind::NoSuchStacksBlockInfoProperty(property_name) => format!("use of unknown stacks block property '{property_name}'"), + StaticCheckErrorKind::NoSuchTenureInfoProperty(property_name) => format!("use of unknown tenure property '{property_name}'"), + StaticCheckErrorKind::GetBlockInfoExpectPropertyName => "missing property name for block info introspection".into(), + StaticCheckErrorKind::GetBurnBlockInfoExpectPropertyName => "missing property name for burn block info introspection".into(), + StaticCheckErrorKind::GetStacksBlockInfoExpectPropertyName => "missing property name for stacks block info introspection".into(), + StaticCheckErrorKind::GetTenureInfoExpectPropertyName => "missing property name for tenure info introspection".into(), + StaticCheckErrorKind::NameAlreadyUsed(name) => format!("defining '{name}' conflicts with previous value"), + StaticCheckErrorKind::ReservedWord(name) => format!("{name} is a reserved word"), + StaticCheckErrorKind::NonFunctionApplication => "expecting expression of type function".into(), + StaticCheckErrorKind::ExpectedListApplication => "expecting expression of type list".into(), + StaticCheckErrorKind::ExpectedSequence(found_type) => format!("expecting expression of type 'list', 'buff', 'string-ascii' or 'string-utf8' - found '{found_type}'"), + StaticCheckErrorKind::MaxLengthOverflow => format!("expecting a value <= {}", u32::MAX), + StaticCheckErrorKind::BadLetSyntax => "invalid syntax of 'let'".into(), + StaticCheckErrorKind::BadSyntaxBinding(binding_error) => format!("invalid syntax binding: {}", &binding_error.message()), + StaticCheckErrorKind::MaxContextDepthReached => "reached depth limit".into(), + StaticCheckErrorKind::UndefinedVariable(var_name) => format!("use of unresolved variable '{var_name}'"), + StaticCheckErrorKind::RequiresAtLeastArguments(expected, found) => format!("expecting >= {expected} arguments, got {found}"), + StaticCheckErrorKind::RequiresAtMostArguments(expected, found) => format!("expecting < {expected} arguments, got {found}"), + StaticCheckErrorKind::IncorrectArgumentCount(expected_count, found_count) => format!("expecting {expected_count} arguments, got {found_count}"), + StaticCheckErrorKind::IfArmsMustMatch(type_1, type_2) => format!("expression types returned by the arms of 'if' must match (got '{type_1}' and '{type_2}')"), + StaticCheckErrorKind::MatchArmsMustMatch(type_1, type_2) => format!("expression types returned by the arms of 'match' must match (got '{type_1}' and '{type_2}')"), + StaticCheckErrorKind::DefaultTypesMustMatch(type_1, type_2) => format!("expression types passed in 'default-to' must match (got '{type_1}' and '{type_2}')"), + StaticCheckErrorKind::IllegalOrUnknownFunctionApplication(function_name) => format!("use of illegal / unresolved function '{function_name}"), + StaticCheckErrorKind::UnknownFunction(function_name) => format!("use of unresolved function '{function_name}'"), + StaticCheckErrorKind::WriteAttemptedInReadOnly => "expecting read-only statements, detected a writing operation".into(), + StaticCheckErrorKind::AtBlockClosureMustBeReadOnly => "(at-block ...) closures expect read-only statements, but detected a writing operation".into(), + StaticCheckErrorKind::BadTokenName => "expecting an token name as an argument".into(), + StaticCheckErrorKind::DefineNFTBadSignature => "(define-asset ...) expects an asset name and an asset identifier type signature as arguments".into(), + StaticCheckErrorKind::NoSuchNFT(asset_name) => format!("tried to use asset function with a undefined asset ('{asset_name}')"), + StaticCheckErrorKind::NoSuchFT(asset_name) => format!("tried to use token function with a undefined token ('{asset_name}')"), + StaticCheckErrorKind::NoSuchTrait(contract_name, trait_name) => format!("use of unresolved trait {contract_name}.{trait_name}"), + StaticCheckErrorKind::TraitReferenceUnknown(trait_name) => format!("use of undeclared trait <{trait_name}>"), + StaticCheckErrorKind::TraitMethodUnknown(trait_name, func_name) => format!("method '{func_name}' unspecified in trait <{trait_name}>"), + StaticCheckErrorKind::BadTraitImplementation(trait_name, func_name) => format!("invalid signature for method '{func_name}' regarding trait's specification <{trait_name}>"), + StaticCheckErrorKind::ExpectedTraitIdentifier => "expecting expression of type trait identifier".into(), + StaticCheckErrorKind::UnexpectedTraitOrFieldReference => "unexpected use of trait reference or field".into(), + StaticCheckErrorKind::DefineTraitBadSignature => "invalid trait definition".into(), + StaticCheckErrorKind::DefineTraitDuplicateMethod(method_name) => format!("duplicate method name '{method_name}' in trait definition"), + StaticCheckErrorKind::ContractOfExpectsTrait => "trait reference expected".into(), + StaticCheckErrorKind::IncompatibleTrait(expected_trait, actual_trait) => format!("trait '{actual_trait}' is not a compatible with expected trait, '{expected_trait}'"), + StaticCheckErrorKind::TypeAlreadyAnnotatedFailure | StaticCheckErrorKind::CheckerImplementationFailure => { + "internal error - please file an issue on https://github.com/stacks-network/stacks-blockchain".into() + }, + StaticCheckErrorKind::UncheckedIntermediaryResponses => "intermediary responses in consecutive statements must be checked".into(), + StaticCheckErrorKind::CouldNotDetermineSerializationType => "could not determine the input type for the serialization function".into(), + StaticCheckErrorKind::ExpectedListOfAllowances(fn_name, arg_num) => format!("{fn_name} expects a list of asset allowances as argument {arg_num}"), + StaticCheckErrorKind::AllowanceExprNotAllowed => "allowance expressions are only allowed in the context of a `restrict-assets?` or `as-contract?`".into(), + StaticCheckErrorKind::ExpectedAllowanceExpr(got_name) => format!("expected an allowance expression, got: {got_name}"), + StaticCheckErrorKind::WithAllAllowanceNotAllowed => "with-all-assets-unsafe is not allowed here, only in the allowance list for `as-contract?`".into(), + StaticCheckErrorKind::WithAllAllowanceNotAlone => "with-all-assets-unsafe must not be used along with other allowances".into(), + StaticCheckErrorKind::WithNftExpectedListOfIdentifiers => "with-nft allowance must include a list of asset identifiers".into(), + StaticCheckErrorKind::MaxIdentifierLengthExceeded(max_len, len) => format!("with-nft allowance identifiers list must not exceed {max_len} elements, got {len}"), + StaticCheckErrorKind::TooManyAllowances(max_allowed, found) => format!("too many allowances specified, the maximum is {max_allowed}, found {found}"), + + } + } + + fn suggestion(&self) -> Option { + match &self { + StaticCheckErrorKind::BadLetSyntax => Some( + "'let' syntax example: (let ((supply 1000) (ttl 60)) )".into(), + ), + StaticCheckErrorKind::TraitReferenceUnknown(_) => Some( + "traits should be either defined, with define-trait, or imported, with use-trait." + .into(), + ), + StaticCheckErrorKind::NoSuchBlockInfoProperty(_) => Some( + "properties available: time, header-hash, burnchain-header-hash, vrf-seed".into(), + ), + _ => None, + } + } +} + impl DiagnosableError for CheckErrorKind { fn message(&self) -> String { match &self { @@ -710,6 +1398,8 @@ impl DiagnosableError for CheckErrorKind { 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::CostComputationFailed(s) => format!("contract cost computation failed: {s}"), + CheckErrorKind::ExecutionTimeExpired => "execution time expired".into(), 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}'"), @@ -718,102 +1408,67 @@ impl DiagnosableError for CheckErrorKind { 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() - }, - 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(), CheckErrorKind::ExpectedListOfAllowances(fn_name, arg_num) => format!("{fn_name} expects a list of asset allowances as argument {arg_num}"), CheckErrorKind::AllowanceExprNotAllowed => "allowance expressions are only allowed in the context of a `restrict-assets?` or `as-contract?`".into(), CheckErrorKind::ExpectedAllowanceExpr(got_name) => format!("expected an allowance expression, got: {got_name}"), @@ -834,9 +1489,6 @@ impl DiagnosableError for CheckErrorKind { "traits should be either defined, with define-trait, or imported, with use-trait." .into(), ), - 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 5d63336ca13..a4586953245 100644 --- a/clarity-types/src/errors/mod.rs +++ b/clarity-types/src/errors/mod.rs @@ -20,6 +20,7 @@ pub mod lexer; use std::{error, fmt}; +use analysis::CommonCheckErrorKind; pub use analysis::{CheckErrorKind, StaticCheckError}; pub use ast::{ParseError, ParseErrorKind, ParseResult}; pub use cost::CostErrors; @@ -294,15 +295,25 @@ impl From for VmExecutionError { } } +// TODO: remove. CommonCheckErrorKind shouldn't be used in the public API. +// So there shouldn't be any need to convert it to a VmExecutionError. +impl From for VmExecutionError { + fn from(err: CommonCheckErrorKind) -> Self { + VmExecutionError::Unchecked(err.into()) + } +} + impl From for VmExecutionError { fn from(err: CheckErrorKind) -> Self { VmExecutionError::Unchecked(err) } } -impl From<(CheckErrorKind, &SymbolicExpression)> for VmExecutionError { - fn from(err: (CheckErrorKind, &SymbolicExpression)) -> Self { - VmExecutionError::Unchecked(err.0) +// TODO: remove. CommonCheckErrorKind shouldn't be used in the public API. +// So there shouldn't be any need to convert it to a VmExecutionError. +impl From<(CommonCheckErrorKind, &SymbolicExpression)> for VmExecutionError { + fn from(err: (CommonCheckErrorKind, &SymbolicExpression)) -> Self { + VmExecutionError::Unchecked(err.0.into()) } } diff --git a/clarity-types/src/tests/types/mod.rs b/clarity-types/src/tests/types/mod.rs index ef0a023a60b..0b9329d93ed 100644 --- a/clarity-types/src/tests/types/mod.rs +++ b/clarity-types/src/tests/types/mod.rs @@ -19,6 +19,7 @@ use rstest::rstest; use stacks_common::types::StacksEpochId; use crate::VmExecutionError; +use crate::errors::analysis::CommonCheckErrorKind; use crate::errors::{CheckErrorKind, RuntimeError, VmInternalError}; use crate::types::{ ASCIIData, BuffData, CharType, ListTypeData, MAX_VALUE_SIZE, PrincipalData, @@ -38,7 +39,7 @@ fn test_constructors() { ); assert_eq!( ListTypeData::new_list(TypeSignature::IntType, MAX_VALUE_SIZE), - Err(CheckErrorKind::ValueTooLarge) + Err(CommonCheckErrorKind::ValueTooLarge) ); assert_eq!( diff --git a/clarity-types/src/tests/types/signatures.rs b/clarity-types/src/tests/types/signatures.rs index 6fecdd77767..a41dbf6ed38 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::CheckErrorKind; +use crate::errors::analysis::CommonCheckErrorKind; use crate::representations::CONTRACT_MAX_NAME_LENGTH; use crate::types::TypeSignature::{BoolType, IntType, ListUnionType, UIntType}; use crate::types::signatures::{CallableSubtype, TypeSignature}; @@ -43,7 +43,7 @@ fn test_buffer_length_try_from_u32_trait() { assert_eq!(MAX_VALUE_SIZE, buffer.get_value()); let err = BufferLength::try_from(MAX_VALUE_SIZE + 1).unwrap_err(); - assert_eq!(CheckErrorKind::ValueTooLarge, err); + assert_eq!(CommonCheckErrorKind::ValueTooLarge, err); } #[test] @@ -55,7 +55,7 @@ fn test_buffer_length_try_from_usize_trait() { assert_eq!(MAX_VALUE_SIZE, buffer.get_value()); let err = BufferLength::try_from(MAX_VALUE_SIZE as usize + 1).unwrap_err(); - assert_eq!(CheckErrorKind::ValueTooLarge, err); + assert_eq!(CommonCheckErrorKind::ValueTooLarge, err); } #[test] @@ -67,10 +67,10 @@ fn test_buffer_length_try_from_i128_trait() { assert_eq!(MAX_VALUE_SIZE, buffer.get_value()); let err = BufferLength::try_from(MAX_VALUE_SIZE as i128 + 1).unwrap_err(); - assert_eq!(CheckErrorKind::ValueTooLarge, err); + assert_eq!(CommonCheckErrorKind::ValueTooLarge, err); let err = BufferLength::try_from(-1_i128).unwrap_err(); - assert_eq!(CheckErrorKind::ValueOutOfBounds, err); + assert_eq!(CommonCheckErrorKind::ValueOutOfBounds, err); } #[test] @@ -229,7 +229,7 @@ fn test_string_utf8_length_try_from_u32_trait() { assert_eq!(MAX_UTF8_VALUE_SIZE, string.get_value()); let err = StringUTF8Length::try_from(MAX_UTF8_VALUE_SIZE + 1).unwrap_err(); - assert_eq!(CheckErrorKind::ValueTooLarge, err); + assert_eq!(CommonCheckErrorKind::ValueTooLarge, err); } #[test] @@ -244,7 +244,7 @@ fn test_string_utf8_length_try_from_usize_trait() { assert_eq!(MAX_UTF8_VALUE_SIZE, string.get_value()); let err = StringUTF8Length::try_from(MAX_UTF8_VALUE_SIZE as usize + 1).unwrap_err(); - assert_eq!(CheckErrorKind::ValueTooLarge, err); + assert_eq!(CommonCheckErrorKind::ValueTooLarge, err); } #[test] @@ -259,10 +259,10 @@ fn test_string_utf8_length_try_from_i128_trait() { assert_eq!(MAX_UTF8_VALUE_SIZE, string.get_value()); let err = StringUTF8Length::try_from(MAX_UTF8_VALUE_SIZE as i128 + 1).unwrap_err(); - assert_eq!(CheckErrorKind::ValueTooLarge, err); + assert_eq!(CommonCheckErrorKind::ValueTooLarge, err); let err = StringUTF8Length::try_from(-1_i128).unwrap_err(); - assert_eq!(CheckErrorKind::ValueOutOfBounds, err); + assert_eq!(CommonCheckErrorKind::ValueOutOfBounds, err); } #[test] @@ -826,11 +826,11 @@ fn test_least_supertype() { for pair in bad_pairs { matches!( TypeSignature::least_supertype_v2_1(&pair.0, &pair.1).unwrap_err(), - CheckErrorKind::TypeError(..) + CommonCheckErrorKind::TypeError(..) ); matches!( TypeSignature::least_supertype_v2_1(&pair.1, &pair.0).unwrap_err(), - CheckErrorKind::TypeError(..) + CommonCheckErrorKind::TypeError(..) ); } } diff --git a/clarity-types/src/types/mod.rs b/clarity-types/src/types/mod.rs index 04902d51b66..294bee4131b 100644 --- a/clarity-types/src/types/mod.rs +++ b/clarity-types/src/types/mod.rs @@ -36,6 +36,7 @@ pub use self::signatures::{ AssetIdentifier, BufferLength, ListTypeData, SequenceSubtype, StringSubtype, StringUTF8Length, TupleTypeSignature, TypeSignature, }; +use crate::errors::analysis::CommonCheckErrorKind; use crate::errors::{CheckErrorKind, InterpreterResult as Result, RuntimeError, VmInternalError}; use crate::representations::{ClarityName, ContractName, SymbolicExpression}; @@ -700,7 +701,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; @@ -725,7 +726,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(), ))) @@ -745,9 +746,11 @@ 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(|_| { - CheckErrorKind::Expects("ERROR: Too large of a buffer successfully constructed.".into()) + CommonCheckErrorKind::Expects( + "ERROR: Too large of a buffer successfully constructed.".into(), + ) })?; Ok(TypeSignature::SequenceType(SequenceSubtype::BufferType( buff_length, @@ -768,9 +771,11 @@ 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(|_| { - CheckErrorKind::Expects("ERROR: Too large of a buffer successfully constructed.".into()) + CommonCheckErrorKind::Expects( + "ERROR: Too large of a buffer successfully constructed.".into(), + ) })?; Ok(TypeSignature::SequenceType(SequenceSubtype::StringType( StringSubtype::ASCII(buff_length), @@ -794,9 +799,11 @@ 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(|_| { - CheckErrorKind::Expects("ERROR: Too large of a buffer successfully constructed.".into()) + CommonCheckErrorKind::Expects( + "ERROR: Too large of a buffer successfully constructed.".into(), + ) })?; Ok(TypeSignature::SequenceType(SequenceSubtype::StringType( StringSubtype::UTF8(str_len), @@ -812,19 +819,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(|_| { - CheckErrorKind::Expects("Should not have constructed too large of a type.".into()) + CommonCheckErrorKind::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)?, @@ -836,7 +843,7 @@ impl ResponseData { ), }; type_result.map_err(|_| { - CheckErrorKind::Expects("Should not have constructed too large of a type.".into()) + CommonCheckErrorKind::Expects("Should not have constructed too large of a type.".into()) }) } } diff --git a/clarity-types/src/types/serialization.rs b/clarity-types/src/types/serialization.rs index 929b2e43136..9747aca13de 100644 --- a/clarity-types/src/types/serialization.rs +++ b/clarity-types/src/types/serialization.rs @@ -23,6 +23,7 @@ use stacks_common::util::hash::{hex_bytes, to_hex}; use stacks_common::util::retry::BoundReader; use super::{ListTypeData, TupleTypeSignature}; +use crate::errors::analysis::StaticCheckErrorKind; use crate::errors::{CheckErrorKind, IncomparableError, VmInternalError}; use crate::representations::{ClarityName, ContractName, MAX_STRING_LEN}; use crate::types::{ @@ -394,7 +395,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 +406,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(CheckErrorKind::CouldNotDetermineSerializationType); + return Err(StaticCheckErrorKind::CouldNotDetermineSerializationType); } TypeSignature::IntType => 16, TypeSignature::UIntType => 16, @@ -417,14 +418,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(|| CheckErrorKind::ValueTooLarge)? + .ok_or_else(|| StaticCheckErrorKind::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(|| CheckErrorKind::ValueTooLarge)? + .ok_or_else(|| StaticCheckErrorKind::ValueTooLarge)? } TypeSignature::SequenceType(SequenceSubtype::StringType(StringSubtype::ASCII( length, @@ -434,7 +435,7 @@ impl TypeSignature { // ascii is 1-byte per character u32::from(length) .checked_add(str_length_encode) - .ok_or_else(|| CheckErrorKind::ValueTooLarge)? + .ok_or_else(|| StaticCheckErrorKind::ValueTooLarge)? } TypeSignature::SequenceType(SequenceSubtype::StringType(StringSubtype::UTF8( length, @@ -445,7 +446,7 @@ impl TypeSignature { u32::from(length) .checked_mul(4) .and_then(|x| x.checked_add(str_length_encode)) - .ok_or_else(|| CheckErrorKind::ValueTooLarge)? + .ok_or_else(|| StaticCheckErrorKind::ValueTooLarge)? } TypeSignature::PrincipalType | TypeSignature::CallableType(_) @@ -468,7 +469,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(|| CheckErrorKind::ValueTooLarge)?; + .ok_or_else(|| StaticCheckErrorKind::ValueTooLarge)?; } total_size } @@ -477,7 +478,7 @@ impl TypeSignature { Ok(size) => size, // if NoType, then this is just serializing a none // value, which is only the type prefix - Err(CheckErrorKind::CouldNotDetermineSerializationType) => 0, + Err(StaticCheckErrorKind::CouldNotDetermineSerializationType) => 0, Err(e) => return Err(e), } } @@ -485,17 +486,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(CheckErrorKind::CouldNotDetermineSerializationType) => (0, true), + Err(StaticCheckErrorKind::CouldNotDetermineSerializationType) => (0, true), Err(e) => return Err(e), }; let err_type_max_size = match err_type.max_serialized_size() { Ok(size) => size, - Err(CheckErrorKind::CouldNotDetermineSerializationType) => { + Err(StaticCheckErrorKind::CouldNotDetermineSerializationType) => { if no_ok_type { // if both the ok type and the error type are NoType, - // throw a CheckErrorKind. This should not be possible, but the check + // throw a StaticCheckErrorKind. This should not be possible, but the check // is done out of caution. - return Err(CheckErrorKind::CouldNotDetermineSerializationType); + return Err(StaticCheckErrorKind::CouldNotDetermineSerializationType); } else { 0 } @@ -505,13 +506,13 @@ impl TypeSignature { cmp::max(ok_type_max_size, err_type_max_size) } TypeSignature::ListUnionType(_) => { - return Err(CheckErrorKind::CouldNotDetermineSerializationType); + return Err(StaticCheckErrorKind::CouldNotDetermineSerializationType); } }; max_output_size .checked_add(type_prefix_size) - .ok_or_else(|| CheckErrorKind::ValueTooLarge) + .ok_or_else(|| StaticCheckErrorKind::ValueTooLarge) } } @@ -612,8 +613,8 @@ impl Value { TypePrefix::Buffer => { let mut buffer_len = [0; 4]; r.read_exact(&mut buffer_len)?; - let buffer_len = BufferLength::try_from(u32::from_be_bytes(buffer_len))?; - + let buffer_len = BufferLength::try_from(u32::from_be_bytes(buffer_len)) + .map_err(CheckErrorKind::from)?; if let Some(x) = &expected_type { let passed_test = match x { TypeSignature::SequenceType(SequenceSubtype::BufferType( @@ -844,7 +845,8 @@ impl Value { TypePrefix::StringASCII => { let mut buffer_len = [0; 4]; r.read_exact(&mut buffer_len)?; - let buffer_len = BufferLength::try_from(u32::from_be_bytes(buffer_len))?; + let buffer_len = BufferLength::try_from(u32::from_be_bytes(buffer_len)) + .map_err(CheckErrorKind::from)?; if let Some(x) = &expected_type { let passed_test = match x { @@ -869,7 +871,8 @@ impl Value { TypePrefix::StringUTF8 => { let mut total_len = [0; 4]; r.read_exact(&mut total_len)?; - let total_len = BufferLength::try_from(u32::from_be_bytes(total_len))?; + let total_len = BufferLength::try_from(u32::from_be_bytes(total_len)) + .map_err(CheckErrorKind::from)?; let mut data: Vec = vec![0; u32::from(total_len) as usize]; diff --git a/clarity-types/src/types/signatures.rs b/clarity-types/src/types/signatures.rs index dd68701210a..13ce2becc0a 100644 --- a/clarity-types/src/types/signatures.rs +++ b/clarity-types/src/types/signatures.rs @@ -23,6 +23,7 @@ use serde::{Deserialize, Serialize}; use stacks_common::types::StacksEpochId; use crate::errors::CheckErrorKind; +use crate::errors::analysis::{CommonCheckErrorKind, StaticCheckErrorKind}; use crate::representations::{CONTRACT_MAX_NAME_LENGTH, ClarityName, ContractName}; use crate::types::{ CharType, MAX_TO_ASCII_BUFFER_LEN, MAX_TO_ASCII_RESULT_LEN, MAX_TYPE_DEPTH, @@ -121,11 +122,11 @@ impl BufferLength { /// /// This function is primarily intended for internal runtime use, /// and serves as the central place for all integer validation logic. - fn try_from_i128(data: i128) -> Result { + fn try_from_i128(data: i128) -> Result { if data > (MAX_VALUE_SIZE as i128) { - Err(CheckErrorKind::ValueTooLarge) + Err(CommonCheckErrorKind::ValueTooLarge) } else if data < 0 { - Err(CheckErrorKind::ValueOutOfBounds) + Err(CommonCheckErrorKind::ValueOutOfBounds) } else { Ok(BufferLength(data as u32)) } @@ -161,22 +162,22 @@ impl From for u32 { } impl TryFrom for BufferLength { - type Error = CheckErrorKind; - fn try_from(data: u32) -> Result { + type Error = CommonCheckErrorKind; + fn try_from(data: u32) -> Result { Self::try_from(data as i128) } } impl TryFrom for BufferLength { - type Error = CheckErrorKind; - fn try_from(data: usize) -> Result { + type Error = CommonCheckErrorKind; + fn try_from(data: usize) -> Result { Self::try_from(data as i128) } } impl TryFrom for BufferLength { - type Error = CheckErrorKind; - fn try_from(data: i128) -> Result { + type Error = CommonCheckErrorKind; + fn try_from(data: i128) -> Result { Self::try_from_i128(data) } } @@ -202,11 +203,11 @@ impl StringUTF8Length { /// /// This function is primarily intended for internal runtime use, /// and serves as the central place for all integer validation logic. - fn try_from_i128(value: i128) -> Result { + fn try_from_i128(value: i128) -> Result { if value > MAX_UTF8_VALUE_SIZE as i128 { - Err(CheckErrorKind::ValueTooLarge) + Err(CommonCheckErrorKind::ValueTooLarge) } else if value < 0 { - Err(CheckErrorKind::ValueOutOfBounds) + Err(CommonCheckErrorKind::ValueOutOfBounds) } else { Ok(StringUTF8Length(value as u32)) } @@ -242,22 +243,22 @@ impl From for u32 { } impl TryFrom for StringUTF8Length { - type Error = CheckErrorKind; - fn try_from(data: u32) -> Result { + type Error = CommonCheckErrorKind; + fn try_from(data: u32) -> Result { Self::try_from(data as i128) } } impl TryFrom for StringUTF8Length { - type Error = CheckErrorKind; - fn try_from(data: usize) -> Result { + type Error = CommonCheckErrorKind; + fn try_from(data: usize) -> Result { Self::try_from(data as i128) } } impl TryFrom for StringUTF8Length { - type Error = CheckErrorKind; - fn try_from(data: i128) -> Result { + type Error = CommonCheckErrorKind; + fn try_from(data: i128) -> Result { Self::try_from_i128(data) } } @@ -358,10 +359,10 @@ impl ListTypeData { pub fn new_list( entry_type: TypeSignature, max_len: u32, - ) -> Result { + ) -> Result { let would_be_depth = 1 + entry_type.depth(); if would_be_depth > MAX_TYPE_DEPTH { - return Err(CheckErrorKind::TypeSignatureTooDeep); + return Err(CommonCheckErrorKind::TypeSignatureTooDeep); } let list_data = ListTypeData { @@ -370,9 +371,9 @@ impl ListTypeData { }; let would_be_size = list_data .inner_size()? - .ok_or_else(|| CheckErrorKind::ValueTooLarge)?; + .ok_or_else(|| CommonCheckErrorKind::ValueTooLarge)?; if would_be_size > MAX_VALUE_SIZE { - Err(CheckErrorKind::ValueTooLarge) + Err(CommonCheckErrorKind::ValueTooLarge) } else { Ok(list_data) } @@ -400,13 +401,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(CheckErrorKind::ValueTooLarge) + Err(CommonCheckErrorKind::ValueTooLarge) } else if new_depth > MAX_TYPE_DEPTH { - Err(CheckErrorKind::TypeSignatureTooDeep) + Err(CommonCheckErrorKind::TypeSignatureTooDeep) } else { Ok(OptionalType(Box::new(inner_type))) } @@ -415,14 +416,14 @@ 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(CheckErrorKind::ValueTooLarge) + Err(CommonCheckErrorKind::ValueTooLarge) } else if new_depth > MAX_TYPE_DEPTH { - Err(CheckErrorKind::TypeSignatureTooDeep) + Err(CommonCheckErrorKind::TypeSignatureTooDeep) } else { Ok(ResponseType(Box::new((ok_type, err_type)))) } @@ -436,7 +437,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) } @@ -445,7 +446,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 @@ -457,13 +458,13 @@ impl TypeSignature { | StacksEpochId::Epoch31 | StacksEpochId::Epoch32 | StacksEpochId::Epoch33 => self.admits_type_v2_1(other), - StacksEpochId::Epoch10 => { - Err(CheckErrorKind::Expects("epoch 1.0 not supported".into())) - } + StacksEpochId::Epoch10 => Err(CommonCheckErrorKind::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 { @@ -545,18 +546,18 @@ impl TypeSignature { Ok(false) } } - NoType => Err(CheckErrorKind::CouldNotDetermineType), - CallableType(_) => Err(CheckErrorKind::Expects( + NoType => Err(CommonCheckErrorKind::CouldNotDetermineType), + CallableType(_) => Err(CommonCheckErrorKind::Expects( "CallableType should not be used in epoch v2.0".into(), )), - ListUnionType(_) => Err(CheckErrorKind::Expects( + ListUnionType(_) => Err(CommonCheckErrorKind::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(_) => { @@ -645,7 +646,7 @@ impl TypeSignature { Ok(false) } } - NoType => Err(CheckErrorKind::CouldNotDetermineType), + NoType => Err(CommonCheckErrorKind::CouldNotDetermineType), _ => Ok(&other == self), } } @@ -702,7 +703,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; @@ -711,7 +712,7 @@ impl TypeSignature { match partial { CallableSubtype::Principal(_) => { if is_trait.is_some() { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::CallableType(partial.clone())), Box::new(TypeSignature::PrincipalType), )); @@ -721,7 +722,7 @@ impl TypeSignature { } CallableSubtype::Trait(t) => { if is_principal { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::CallableType(partial.clone())), )); @@ -744,12 +745,12 @@ impl TypeSignature { } impl TryFrom> for TupleTypeSignature { - type Error = CheckErrorKind; + type Error = CommonCheckErrorKind; fn try_from( type_data: Vec<(ClarityName, TypeSignature)>, - ) -> Result { + ) -> Result { if type_data.is_empty() { - return Err(CheckErrorKind::EmptyTuplesNotAllowed); + return Err(CommonCheckErrorKind::EmptyTuplesNotAllowed); } let mut type_map = BTreeMap::new(); @@ -757,7 +758,7 @@ impl TryFrom> for TupleTypeSignature { if let Entry::Vacant(e) = type_map.entry(name.clone()) { e.insert(type_info); } else { - return Err(CheckErrorKind::NameAlreadyUsed(name.into())); + return Err(CommonCheckErrorKind::NameAlreadyUsed(name.into())); } } TupleTypeSignature::try_from(type_map) @@ -765,25 +766,25 @@ impl TryFrom> for TupleTypeSignature { } impl TryFrom> for TupleTypeSignature { - type Error = CheckErrorKind; + type Error = CommonCheckErrorKind; fn try_from( type_map: BTreeMap, - ) -> Result { + ) -> Result { if type_map.is_empty() { - return Err(CheckErrorKind::EmptyTuplesNotAllowed); + return Err(CommonCheckErrorKind::EmptyTuplesNotAllowed); } for child_sig in type_map.values() { if (1 + child_sig.depth()) > MAX_TYPE_DEPTH { - return Err(CheckErrorKind::TypeSignatureTooDeep); + return Err(CommonCheckErrorKind::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(|| CheckErrorKind::ValueTooLarge)?; + .ok_or_else(|| CommonCheckErrorKind::ValueTooLarge)?; if would_be_size > MAX_VALUE_SIZE { - Err(CheckErrorKind::ValueTooLarge) + Err(CommonCheckErrorKind::ValueTooLarge) } else { Ok(result) } @@ -813,7 +814,7 @@ impl TupleTypeSignature { &self, epoch: &StacksEpochId, other: &TupleTypeSignature, - ) -> Result { + ) -> Result { if self.type_map.len() != other.type_map.len() { return Ok(false); } @@ -934,18 +935,18 @@ impl TypeSignature { /// Creates a string ASCII type with the specified length. /// Returns an error if the provided length is invalid. - pub fn new_ascii_type(len: i128) -> Result { + pub fn new_ascii_type(len: i128) -> Result { Ok(SequenceType(SequenceSubtype::StringType( StringSubtype::ASCII(BufferLength::try_from_i128(len)?), ))) } /// If one of the types is a NoType, return Ok(the other type), otherwise return least_supertype(a, b) - pub fn factor_out_no_type( + pub(crate) fn factor_out_no_type( epoch: &StacksEpochId, a: &TypeSignature, b: &TypeSignature, - ) -> Result { + ) -> Result { if a.is_no_type() { Ok(b.clone()) } else if b.is_no_type() { @@ -996,7 +997,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 @@ -1008,16 +1009,16 @@ impl TypeSignature { | StacksEpochId::Epoch31 | StacksEpochId::Epoch32 | StacksEpochId::Epoch33 => Self::least_supertype_v2_1(a, b), - StacksEpochId::Epoch10 => { - Err(CheckErrorKind::Expects("epoch 1.0 not supported".into())) - } + StacksEpochId::Epoch10 => Err(CommonCheckErrorKind::Expects( + "epoch 1.0 not supported".into(), + )), } } - pub fn least_supertype_v2_0( + fn least_supertype_v2_0( a: &TypeSignature, b: &TypeSignature, - ) -> Result { + ) -> Result { match (a, b) { ( TupleType(TupleTypeSignature { type_map: types_a }), @@ -1025,7 +1026,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(CheckErrorKind::TypeError( + let entry_b = types_b.get(name).ok_or(CommonCheckErrorKind::TypeError( Box::new(a.clone()), Box::new(b.clone()), ))?; @@ -1034,7 +1035,7 @@ impl TypeSignature { } Ok(TupleTypeSignature::try_from(type_map_out) .map(|x| x.into()) - .map_err(|_| CheckErrorKind::SupertypeTooLarge)?) + .map_err(|_| CommonCheckErrorKind::SupertypeTooLarge)?) } ( SequenceType(SequenceSubtype::ListType(ListTypeData { @@ -1055,7 +1056,7 @@ impl TypeSignature { }; let max_len = cmp::max(len_a, len_b); Ok(Self::list_of(entry_type, *max_len) - .map_err(|_| CheckErrorKind::SupertypeTooLarge)?) + .map_err(|_| CommonCheckErrorKind::SupertypeTooLarge)?) } (ResponseType(resp_a), ResponseType(resp_b)) => { let ok_type = @@ -1114,7 +1115,7 @@ impl TypeSignature { if x == y { Ok(x.clone()) } else { - Err(CheckErrorKind::TypeError( + Err(CommonCheckErrorKind::TypeError( Box::new(a.clone()), Box::new(b.clone()), )) @@ -1123,10 +1124,10 @@ impl TypeSignature { } } - pub fn least_supertype_v2_1( + pub(crate) fn least_supertype_v2_1( a: &TypeSignature, b: &TypeSignature, - ) -> Result { + ) -> Result { match (a, b) { ( TupleType(TupleTypeSignature { type_map: types_a }), @@ -1134,7 +1135,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(CheckErrorKind::TypeError( + let entry_b = types_b.get(name).ok_or(CommonCheckErrorKind::TypeError( Box::new(a.clone()), Box::new(b.clone()), ))?; @@ -1143,7 +1144,7 @@ impl TypeSignature { } Ok(TupleTypeSignature::try_from(type_map_out) .map(|x| x.into()) - .map_err(|_| CheckErrorKind::SupertypeTooLarge)?) + .map_err(|_| CommonCheckErrorKind::SupertypeTooLarge)?) } ( SequenceType(SequenceSubtype::ListType(ListTypeData { @@ -1164,7 +1165,7 @@ impl TypeSignature { }; let max_len = cmp::max(len_a, len_b); Ok(Self::list_of(entry_type, *max_len) - .map_err(|_| CheckErrorKind::SupertypeTooLarge)?) + .map_err(|_| CommonCheckErrorKind::SupertypeTooLarge)?) } (ResponseType(resp_a), ResponseType(resp_b)) => { let ok_type = @@ -1245,7 +1246,7 @@ impl TypeSignature { if all_principals { Ok(PrincipalType) } else { - Err(CheckErrorKind::TypeError( + Err(CommonCheckErrorKind::TypeError( Box::new(a.clone()), Box::new(b.clone()), )) @@ -1258,7 +1259,7 @@ impl TypeSignature { if x == y { Ok(x.clone()) } else { - Err(CheckErrorKind::TypeError( + Err(CommonCheckErrorKind::TypeError( Box::new(a.clone()), Box::new(b.clone()), )) @@ -1270,7 +1271,7 @@ impl TypeSignature { pub fn list_of( item_type: TypeSignature, max_len: u32, - ) -> Result { + ) -> Result { ListTypeData::new_list(item_type, max_len).map(|x| x.into()) } @@ -1281,7 +1282,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, @@ -1310,29 +1311,31 @@ 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()), )), - _ => Self::type_of(x), + _ => Self::type_of(x).map_err(StaticCheckErrorKind::from), } } // Checks if resulting type signature is of valid size. 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?) + let children_types: Result, _> = args.iter().map(TypeSignature::type_of).collect(); + Ok(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(|_| CheckErrorKind::ValueTooLarge)?; + let len = + u32::try_from(children.len()).map_err(|_| CommonCheckErrorKind::ValueTooLarge)?; ListTypeData::new_list(current_entry_type, len) } else { Ok(TypeSignature::empty_list()) @@ -1372,16 +1375,16 @@ impl TypeSignature { } } - pub fn size(&self) -> Result { + pub fn size(&self) -> Result { self.inner_size()?.ok_or_else(|| { - CheckErrorKind::Expects( + CommonCheckErrorKind::Expects( "FAIL: .size() overflowed on too large of a type. construction should have failed!" .into(), ) }) } - fn inner_size(&self) -> Result, CheckErrorKind> { + fn inner_size(&self) -> Result, CommonCheckErrorKind> { 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). @@ -1414,9 +1417,9 @@ impl TypeSignature { Ok(out) } - pub fn type_size(&self) -> Result { + pub fn type_size(&self) -> Result { self.inner_type_size() - .ok_or_else(|| CheckErrorKind::ValueTooLarge) + .ok_or_else(|| CommonCheckErrorKind::ValueTooLarge) } /// Returns the size of the _type signature_ @@ -1446,7 +1449,7 @@ impl TypeSignature { impl ListTypeData { /// List Size: type_signature_size + max_len * entry_type.size() - fn inner_size(&self) -> Result, CheckErrorKind> { + fn inner_size(&self) -> Result, CommonCheckErrorKind> { let total_size = self .entry_type .size()? @@ -1512,7 +1515,7 @@ impl TupleTypeSignature { /// Tuple Size: /// size( btreemap ) + type_size /// size( btreemap ) = 2*map.len() + sum(names) + sum(values) - fn inner_size(&self) -> Result, CheckErrorKind> { + fn inner_size(&self) -> Result, CommonCheckErrorKind> { let Some(mut total_size) = u32::try_from(self.type_map.len()) .ok() .and_then(|x| x.checked_mul(2)) diff --git a/clarity/src/vm/analysis/analysis_db.rs b/clarity/src/vm/analysis/analysis_db.rs index 62c28813ca0..ff7197249f6 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::{CheckErrorKind, StaticCheckError}; +use crate::vm::analysis::errors::{StaticCheckError, StaticCheckErrorKind}; 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| CheckErrorKind::Expects(format!("{e:?}")))?; + .map_err(|e| StaticCheckErrorKind::Expects(format!("{e:?}")))?; Err(e) })?; self.commit() - .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")))?; + .map_err(|e| StaticCheckErrorKind::Expects(format!("{e:?}")))?; Ok(result) } @@ -66,13 +66,13 @@ impl<'a> AnalysisDatabase<'a> { pub fn commit(&mut self) -> Result<(), StaticCheckError> { self.store .commit() - .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")).into()) + .map_err(|e| StaticCheckErrorKind::Expects(format!("{e:?}")).into()) } pub fn roll_back(&mut self) -> Result<(), StaticCheckError> { self.store .rollback() - .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")).into()) + .map_err(|e| StaticCheckErrorKind::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(|_| { - CheckErrorKind::Expects("Bad data deserialized from DB".into()).into() + StaticCheckErrorKind::Expects("Bad data deserialized from DB".into()).into() }) }) .transpose() @@ -127,8 +127,9 @@ impl<'a> AnalysisDatabase<'a> { .ok() .flatten() .map(|x| { - ContractAnalysis::deserialize(&x) - .map_err(|_| CheckErrorKind::Expects("Bad data deserialized from DB".into())) + ContractAnalysis::deserialize(&x).map_err(|_| { + StaticCheckErrorKind::Expects("Bad data deserialized from DB".into()) + }) }) .transpose()? .map(|mut x| { @@ -144,14 +145,15 @@ impl<'a> AnalysisDatabase<'a> { ) -> Result<(), StaticCheckError> { let key = AnalysisDatabase::storage_key(); if self.store.has_metadata_entry(contract_identifier, key) { - return Err( - CheckErrorKind::ContractAlreadyExists(contract_identifier.to_string()).into(), - ); + return Err(StaticCheckErrorKind::ContractAlreadyExists( + contract_identifier.to_string(), + ) + .into()); } self.store .insert_metadata(contract_identifier, key, &contract.serialize()) - .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")))?; + .map_err(|e| StaticCheckErrorKind::Expects(format!("{e:?}")))?; Ok(()) } @@ -165,7 +167,7 @@ impl<'a> AnalysisDatabase<'a> { // charges based on the function type size. let contract = self .load_contract_non_canonical(contract_identifier)? - .ok_or(CheckErrorKind::NoSuchContract( + .ok_or(StaticCheckErrorKind::NoSuchContract( contract_identifier.to_string(), ))?; Ok(contract.clarity_version) @@ -183,7 +185,7 @@ impl<'a> AnalysisDatabase<'a> { // charges based on the function type size. let contract = self .load_contract_non_canonical(contract_identifier)? - .ok_or(CheckErrorKind::NoSuchContract( + .ok_or(StaticCheckErrorKind::NoSuchContract( contract_identifier.to_string(), ))?; Ok(contract @@ -203,7 +205,7 @@ impl<'a> AnalysisDatabase<'a> { // charges based on the function type size. let contract = self .load_contract_non_canonical(contract_identifier)? - .ok_or(CheckErrorKind::NoSuchContract( + .ok_or(StaticCheckErrorKind::NoSuchContract( contract_identifier.to_string(), ))?; Ok(contract @@ -223,7 +225,7 @@ impl<'a> AnalysisDatabase<'a> { // charges based on the function type size. let contract = self .load_contract_non_canonical(contract_identifier)? - .ok_or(CheckErrorKind::NoSuchContract( + .ok_or(StaticCheckErrorKind::NoSuchContract( contract_identifier.to_string(), ))?; Ok(contract.get_defined_trait(trait_name).map(|trait_map| { @@ -240,7 +242,7 @@ impl<'a> AnalysisDatabase<'a> { ) -> Result, StaticCheckError> { let contract = self .load_contract_non_canonical(contract_identifier)? - .ok_or(CheckErrorKind::NoSuchContract( + .ok_or(StaticCheckErrorKind::NoSuchContract( contract_identifier.to_string(), ))?; Ok(contract.implemented_traits) diff --git a/clarity/src/vm/analysis/contract_interface_builder/mod.rs b/clarity/src/vm/analysis/contract_interface_builder/mod.rs index 5fc0169c5cb..54f1a161cf7 100644 --- a/clarity/src/vm/analysis/contract_interface_builder/mod.rs +++ b/clarity/src/vm/analysis/contract_interface_builder/mod.rs @@ -19,12 +19,12 @@ use std::collections::{BTreeMap, BTreeSet}; use stacks_common::types::StacksEpochId; use crate::vm::analysis::types::ContractAnalysis; -use crate::vm::analysis::StaticCheckError; +use crate::vm::analysis::{StaticCheckError, StaticCheckErrorKind}; use crate::vm::types::signatures::CallableSubtype; use crate::vm::types::{ FixedFunction, FunctionArg, FunctionType, TupleTypeSignature, TypeSignature, }; -use crate::vm::{CheckErrorKind, ClarityName, ClarityVersion}; +use crate::vm::{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(CheckErrorKind::Expects( + _ => return Err(StaticCheckErrorKind::Expects( "Contract functions should only have fixed function return types!" .into(), ) @@ -290,7 +290,7 @@ impl ContractInterfaceFunction { ContractInterfaceFunctionArg::from_function_args(args) } _ => { - return Err(CheckErrorKind::Expects( + return Err(StaticCheckErrorKind::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(|_| { - CheckErrorKind::Expects("Failed to serialize contract interface".into()).into() + StaticCheckErrorKind::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 7bf7faabc13..c7e326e6a6e 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, CheckErrorKind, - StaticCheckError, SyntaxBindingError, SyntaxBindingErrorType, + StaticCheckError, StaticCheckErrorKind, SyntaxBindingError, SyntaxBindingErrorType, }; diff --git a/clarity/src/vm/analysis/mod.rs b/clarity/src/vm/analysis/mod.rs index f25c0d4e732..9da98099d2e 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::{CheckErrorKind, StaticCheckError}; +pub use self::errors::{CheckErrorKind, StaticCheckError, StaticCheckErrorKind}; use self::read_only_checker::ReadOnlyChecker; use self::trait_checker::TraitChecker; use self::type_checker::v2_05::TypeChecker as TypeChecker2_05; @@ -54,9 +54,10 @@ pub fn mem_type_check( epoch: StacksEpochId, ) -> Result<(Option, ContractAnalysis), StaticCheckError> { let contract_identifier = QualifiedContractIdentifier::transient(); - let contract = build_ast(&contract_identifier, snippet, &mut (), version, epoch) - .map_err(|_| CheckErrorKind::Expects("Failed to build AST".into()))? - .expressions; + let contract: Vec = + build_ast(&contract_identifier, snippet, &mut (), version, epoch) + .map_err(|_| StaticCheckErrorKind::Expects("Failed to build AST".into()))? + .expressions; let mut marf = MemoryBackingStore::new(); let mut analysis_db = marf.as_analysis_db(); @@ -73,16 +74,15 @@ pub fn mem_type_check( ) { Ok(x) => { // return the first type result of the type checker - let first_type = x - .type_map - .as_ref() - .ok_or_else(|| CheckErrorKind::Expects("Should be non-empty".into()))? - .get_type_expected( - x.expressions - .last() - .ok_or_else(|| CheckErrorKind::Expects("Should be non-empty".into()))?, - ) - .cloned(); + + let first_type = + x.type_map + .as_ref() + .ok_or_else(|| StaticCheckErrorKind::Expects("Should be non-empty".into()))? + .get_type_expected(x.expressions.last().ok_or_else(|| { + StaticCheckErrorKind::Expects("Should be non-empty".into()) + })?) + .cloned(); Ok((first_type, x)) } Err(e) => Err(e.0), @@ -151,7 +151,7 @@ pub fn run_analysis( TypeChecker2_1::run_pass(&epoch, &mut contract_analysis, db, build_type_map) } StacksEpochId::Epoch10 => { - return Err(CheckErrorKind::Expects( + return Err(StaticCheckErrorKind::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 0c62c80e4dd..dd486172527 100644 --- a/clarity/src/vm/analysis/read_only_checker/mod.rs +++ b/clarity/src/vm/analysis/read_only_checker/mod.rs @@ -22,7 +22,7 @@ use stacks_common::types::StacksEpochId; pub use super::errors::{ check_argument_count, check_arguments_at_least, CheckErrorKind, StaticCheckError, - SyntaxBindingError, + StaticCheckErrorKind, SyntaxBindingError, }; use super::AnalysisDatabase; use crate::vm::analysis::types::{AnalysisPass, ContractAnalysis}; @@ -82,7 +82,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { /// Returns successfully iff this function is read-only correct. /// /// # Errors - /// - `CheckErrorKind::WriteAttemptedInReadOnly` + /// - `StaticCheckErrorKind::WriteAttemptedInReadOnly` /// - Contract parsing errors pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), StaticCheckError> { // Iterate over all the top-level statements in a contract. @@ -106,7 +106,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { /// Returns successfully iff this function is read-only correct. /// /// # Errors - /// - CheckErrorKind::WriteAttemptedInReadOnly + /// - StaticCheckErrorKind::WriteAttemptedInReadOnly /// - Contract parsing errors fn check_top_level_expression( &mut self, @@ -136,7 +136,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(CheckErrorKind::WriteAttemptedInReadOnly.into()); + return Err(StaticCheckErrorKind::WriteAttemptedInReadOnly.into()); } else { self.defined_functions.insert(function_name, is_read_only); } @@ -172,9 +172,9 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { ) -> Result<(ClarityName, bool), StaticCheckError> { let function_name = signature .first() - .ok_or(CheckErrorKind::DefineFunctionBadSignature)? + .ok_or(StaticCheckErrorKind::DefineFunctionBadSignature)? .match_atom() - .ok_or(CheckErrorKind::BadFunctionName)?; + .ok_or(StaticCheckErrorKind::BadFunctionName)?; let is_read_only = self.check_read_only(body)?; @@ -207,7 +207,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(CheckErrorKind::WriteAttemptedInReadOnly.into()); + return Err(StaticCheckErrorKind::WriteAttemptedInReadOnly.into()); } else { self.defined_functions.insert(f_name, is_read_only); } @@ -396,7 +396,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(CheckErrorKind::AtBlockClosureMustBeReadOnly.into()); + return Err(StaticCheckErrorKind::AtBlockClosureMustBeReadOnly.into()); } Ok(is_block_arg_read_only) } @@ -413,7 +413,9 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { Let => { check_arguments_at_least(2, args)?; - let binding_list = args[0].match_list().ok_or(CheckErrorKind::BadLetSyntax)?; + let binding_list = args[0] + .match_list() + .ok_or(StaticCheckErrorKind::BadLetSyntax)?; for (i, pair) in binding_list.iter().enumerate() { let pair_expression = pair.match_list().ok_or_else(|| { @@ -488,7 +490,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { let function_name = args[1] .match_atom() - .ok_or(CheckErrorKind::ContractCallExpectName)?; + .ok_or(StaticCheckErrorKind::ContractCallExpectName)?; let is_function_read_only = match &args[0].expr { SymbolicExpressionType::LiteralValue(Value::Principal( @@ -509,7 +511,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { } _ => { return Err(StaticCheckError::new( - CheckErrorKind::ContractCallExpectName, + StaticCheckErrorKind::ContractCallExpectName, )) } }; @@ -527,7 +529,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { let allowances = args[1] .match_list() - .ok_or(CheckErrorKind::ExpectedListOfAllowances( + .ok_or(StaticCheckErrorKind::ExpectedListOfAllowances( "restrict-assets?".into(), 2, ))?; @@ -545,7 +547,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { let allowances = args[0] .match_list() - .ok_or(CheckErrorKind::ExpectedListOfAllowances( + .ok_or(StaticCheckErrorKind::ExpectedListOfAllowances( "as-contract?".into(), 1, ))?; @@ -575,11 +577,11 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { ) -> Result { let (function_name, args) = expressions .split_first() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::NonFunctionApplication)?; let function_name = function_name .match_atom() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::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 { @@ -587,10 +589,9 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> { } result } else { - let is_function_read_only = *self - .defined_functions - .get(function_name) - .ok_or(CheckErrorKind::UnknownFunction(function_name.to_string()))?; + let is_function_read_only = *self.defined_functions.get(function_name).ok_or( + StaticCheckErrorKind::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 5b985b7b2f2..9e0f8b46aaa 100644 --- a/clarity/src/vm/analysis/read_only_checker/tests.rs +++ b/clarity/src/vm/analysis/read_only_checker/tests.rs @@ -20,10 +20,11 @@ use rstest::rstest; use rstest_reuse::{self, *}; use stacks_common::types::StacksEpochId; +use crate::vm::analysis::type_check; use crate::vm::analysis::type_checker::v2_1::tests::mem_type_check; -use crate::vm::analysis::{type_check, CheckErrorKind}; use crate::vm::ast::parse; use crate::vm::database::MemoryBackingStore; +use crate::vm::errors::StaticCheckErrorKind; use crate::vm::tests::test_clarity_versions; use crate::vm::types::QualifiedContractIdentifier; use crate::vm::ClarityVersion; @@ -34,11 +35,11 @@ fn test_argument_count_violations() { ( "(define-private (foo-bar) (at-block))", - CheckErrorKind::IncorrectArgumentCount(2, 0), + StaticCheckErrorKind::IncorrectArgumentCount(2, 0), ), ( "(define-private (foo-bar) (map-get?))", - CheckErrorKind::IncorrectArgumentCount(2, 0), + StaticCheckErrorKind::IncorrectArgumentCount(2, 0), ), ]; @@ -72,7 +73,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, CheckErrorKind::AtBlockClosureMustBeReadOnly) + assert_eq!(*err.err, StaticCheckErrorKind::AtBlockClosureMustBeReadOnly) } } @@ -163,7 +164,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, CheckErrorKind::WriteAttemptedInReadOnly) + assert_eq!(*err.err, StaticCheckErrorKind::WriteAttemptedInReadOnly) } } @@ -180,7 +181,7 @@ fn test_nested_writing_closure() { for contract in bad_contracts.iter() { let err = mem_type_check(contract).unwrap_err(); - assert_eq!(*err.err, CheckErrorKind::AtBlockClosureMustBeReadOnly) + assert_eq!(*err.err, StaticCheckErrorKind::AtBlockClosureMustBeReadOnly) } } @@ -231,7 +232,7 @@ fn test_contract_call_read_only_violations( ) }) .unwrap_err(); - assert_eq!(*err.err, CheckErrorKind::WriteAttemptedInReadOnly); + assert_eq!(*err.err, StaticCheckErrorKind::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 a2563de2d47..01396a64e25 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::{CheckErrorKind, StaticCheckError}; +use crate::vm::analysis::errors::{StaticCheckError, StaticCheckErrorKind}; 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(CheckErrorKind::TraitReferenceUnknown( + .ok_or(StaticCheckErrorKind::TraitReferenceUnknown( trait_identifier.name.to_string(), ))?; let trait_definition = contract_defining_trait .get_defined_trait(&trait_name) - .ok_or(CheckErrorKind::TraitReferenceUnknown( + .ok_or(StaticCheckErrorKind::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 c103f7a6eaa..a04ad00d8c9 100644 --- a/clarity/src/vm/analysis/trait_checker/tests.rs +++ b/clarity/src/vm/analysis/trait_checker/tests.rs @@ -20,8 +20,7 @@ use rstest::rstest; use rstest_reuse::{self, *}; use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::CheckErrorKind; -use crate::vm::analysis::{type_check, StaticCheckError}; +use crate::vm::analysis::{type_check, StaticCheckError, StaticCheckErrorKind}; use crate::vm::ast::errors::ParseErrorKind; use crate::vm::ast::{build_ast, parse}; use crate::vm::database::MemoryBackingStore; @@ -98,7 +97,7 @@ fn test_incomplete_impl_trait_1(#[case] version: ClarityVersion, #[case] epoch: }) .unwrap_err(); match *err.err { - CheckErrorKind::BadTraitImplementation(_, _) => {} + StaticCheckErrorKind::BadTraitImplementation(_, _) => {} _ => panic!("{err:?}"), } } @@ -125,7 +124,7 @@ fn test_incomplete_impl_trait_2(#[case] version: ClarityVersion, #[case] epoch: }) .unwrap_err(); match *err.err { - CheckErrorKind::BadTraitImplementation(_, _) => {} + StaticCheckErrorKind::BadTraitImplementation(_, _) => {} _ => panic!("{err:?}"), } } @@ -149,7 +148,7 @@ fn test_impl_trait_arg_admission_1(#[case] version: ClarityVersion, #[case] epoc }) .unwrap_err(); match *err.err { - CheckErrorKind::BadTraitImplementation(_, _) => {} + StaticCheckErrorKind::BadTraitImplementation(_, _) => {} _ => panic!("{err:?}"), } } @@ -289,7 +288,7 @@ fn test_get_trait_reference_from_tuple( }) .unwrap_err(); match *err.err { - CheckErrorKind::ContractCallExpectName => {} + StaticCheckErrorKind::ContractCallExpectName => {} _ => panic!("{err:?}"), } } @@ -332,7 +331,7 @@ fn test_dynamic_dispatch_by_defining_and_impl_trait( }) .unwrap_err(); match *err.err { - CheckErrorKind::TraitReferenceUnknown(_) => {} + StaticCheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err:?}"), } } @@ -434,7 +433,7 @@ fn test_cycle_in_traits_2_contracts(#[case] version: ClarityVersion, #[case] epo }) .unwrap_err(); match *err.err { - CheckErrorKind::NoSuchContract(_) => {} + StaticCheckErrorKind::NoSuchContract(_) => {} _ => panic!("{err:?}"), } } @@ -487,7 +486,7 @@ fn test_dynamic_dispatch_unknown_method( }) .unwrap_err(); match *err.err { - CheckErrorKind::TraitMethodUnknown(_, _) => {} + StaticCheckErrorKind::TraitMethodUnknown(_, _) => {} _ => panic!("{err:?}"), } } @@ -812,7 +811,7 @@ fn test_dynamic_dispatch_importing_non_existant_trait( }) .unwrap_err(); match *err.err { - CheckErrorKind::TraitReferenceUnknown(_) => {} + StaticCheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err:?}"), } } @@ -1099,13 +1098,13 @@ fn test_dynamic_dispatch_including_wrong_nested_trait( .unwrap_err(); match *err.err { - CheckErrorKind::TypeError(expected, actual) if epoch < StacksEpochId::Epoch21 => { + StaticCheckErrorKind::TypeError(expected, actual) if epoch < StacksEpochId::Epoch21 => { match (&*expected, &*actual) { (TypeSignature::TraitReferenceType(_), TypeSignature::TraitReferenceType(_)) => {} _ => panic!("unexpected TypeSignature: {expected:?} {actual:?}"), } } - CheckErrorKind::TypeError(expected, actual) + StaticCheckErrorKind::TypeError(expected, actual) if epoch >= StacksEpochId::Epoch21 && version < ClarityVersion::Clarity2 => { match (&*expected, &*actual) { @@ -1113,7 +1112,7 @@ fn test_dynamic_dispatch_including_wrong_nested_trait( _ => panic!("unexpected TypeSignature: {expected:?} {actual:?}"), } } - CheckErrorKind::TraitReferenceUnknown(name) => assert_eq!(name.as_str(), "trait-a"), + StaticCheckErrorKind::TraitReferenceUnknown(name) => assert_eq!(name.as_str(), "trait-a"), _ => panic!("{err:?}"), } } @@ -1167,7 +1166,7 @@ fn test_dynamic_dispatch_mismatched_args( }) .unwrap_err(); match *err.err { - CheckErrorKind::TypeError(_, _) => {} + StaticCheckErrorKind::TypeError(_, _) => {} _ => panic!("{err:?}"), } } @@ -1221,7 +1220,7 @@ fn test_dynamic_dispatch_mismatched_returns( }) .unwrap_err(); match *err.err { - CheckErrorKind::BadTraitImplementation(_, _) => {} + StaticCheckErrorKind::BadTraitImplementation(_, _) => {} _ => panic!("{err:?}"), } } @@ -1257,7 +1256,7 @@ fn test_bad_call_with_trait(#[case] version: ClarityVersion, #[case] epoch: Stac }) .unwrap_err(); match *err.err { - CheckErrorKind::TypeError(_, _) => {} + StaticCheckErrorKind::TypeError(_, _) => {} _ => panic!("{err:?}"), } } @@ -1466,7 +1465,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 { - CheckErrorKind::TypeError(_, _) => {} + StaticCheckErrorKind::TypeError(_, _) => {} _ => panic!("{err:?}"), }; } @@ -1560,7 +1559,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_principal.err { - CheckErrorKind::TraitReferenceUnknown(_) => {} + StaticCheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_principal:?}"), } let err_int = db @@ -1570,7 +1569,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_int.err { - CheckErrorKind::TraitReferenceUnknown(_) => {} + StaticCheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_int:?}"), } let err_uint = db @@ -1580,7 +1579,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_uint.err { - CheckErrorKind::TraitReferenceUnknown(_) => {} + StaticCheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_uint:?}"), } let err_bool = db @@ -1590,7 +1589,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_bool.err { - CheckErrorKind::TraitReferenceUnknown(_) => {} + StaticCheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_bool:?}"), } let err_list = db @@ -1600,7 +1599,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_list.err { - CheckErrorKind::TraitReferenceUnknown(_) => {} + StaticCheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_list:?}"), } let err_buff = db @@ -1610,7 +1609,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_buff.err { - CheckErrorKind::TraitReferenceUnknown(_) => {} + StaticCheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_buff:?}"), } let err_tuple = db @@ -1620,7 +1619,7 @@ fn test_contract_of_wrong_type(#[case] version: ClarityVersion, #[case] epoch: S }) .unwrap_err(); match *err_tuple.err { - CheckErrorKind::TraitReferenceUnknown(_) => {} + StaticCheckErrorKind::TraitReferenceUnknown(_) => {} _ => panic!("{err_tuple:?}"), } } @@ -1819,7 +1818,7 @@ fn test_trait_contract_not_found(#[case] version: ClarityVersion, #[case] epoch: ) }) { Err(StaticCheckError { err, .. }) if version < ClarityVersion::Clarity2 => match *err { - CheckErrorKind::NoSuchContract(contract) => { + StaticCheckErrorKind::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 50f8cd16104..8a350431b35 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::{CheckErrorKind, StaticCheckError}; +use crate::vm::analysis::errors::{StaticCheckError, StaticCheckErrorKind}; use crate::vm::types::signatures::CallableSubtype; use crate::vm::types::{TraitIdentifier, TypeSignature}; use crate::vm::{ClarityName, ClarityVersion, SymbolicExpression, MAX_CONTEXT_DEPTH}; @@ -69,7 +69,7 @@ impl TypeMap { TypeMapDataType::Map(ref mut map) => { if map.insert(expr.id, type_sig).is_some() { Err(StaticCheckError::new( - CheckErrorKind::TypeAlreadyAnnotatedFailure, + StaticCheckErrorKind::TypeAlreadyAnnotatedFailure, )) } else { Ok(()) @@ -78,7 +78,7 @@ impl TypeMap { TypeMapDataType::Set(ref mut map) => { if !map.insert(expr.id) { Err(StaticCheckError::new( - CheckErrorKind::TypeAlreadyAnnotatedFailure, + StaticCheckErrorKind::TypeAlreadyAnnotatedFailure, )) } else { Ok(()) @@ -110,7 +110,7 @@ impl TypingContext<'_> { pub fn extend(&self) -> Result, StaticCheckError> { if self.depth >= MAX_CONTEXT_DEPTH { Err(StaticCheckError::new( - CheckErrorKind::MaxContextDepthReached, + StaticCheckErrorKind::MaxContextDepthReached, )) } else { Ok(TypingContext { diff --git a/clarity/src/vm/analysis/type_checker/mod.rs b/clarity/src/vm/analysis/type_checker/mod.rs index 7305d63d08e..30db2e931ff 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::{CheckErrorKind, StaticCheckError}; +use super::errors::{StaticCheckError, StaticCheckErrorKind}; 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(CheckErrorKind::Expects("Epoch10 is not supported".into()).into()) + Err(StaticCheckErrorKind::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(CheckErrorKind::Expects("Epoch10 is not supported".into()).into()) + Err(StaticCheckErrorKind::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 684c7ff872b..ac08536c82b 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::{CheckErrorKind, StaticCheckError}; +use crate::vm::analysis::errors::{StaticCheckError, StaticCheckErrorKind}; use crate::vm::analysis::types::ContractAnalysis; use crate::vm::representations::ClarityName; use crate::vm::types::signatures::FunctionSignature; @@ -67,9 +67,9 @@ impl ContractContext { || self.traits.contains_key(name) || self.map_types.contains_key(name) { - Err(StaticCheckError::new(CheckErrorKind::NameAlreadyUsed( - name.to_string(), - ))) + Err(StaticCheckError::new( + StaticCheckErrorKind::NameAlreadyUsed(name.to_string()), + )) } else { 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 da3872048d9..8ccd89410bf 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,7 @@ 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, CheckErrorKind, StaticCheckError, + check_argument_count, check_arguments_at_least, StaticCheckError, StaticCheckErrorKind, SyntaxBindingErrorType, }; use crate::vm::analysis::AnalysisDatabase; @@ -147,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(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(found_type.clone()), ) @@ -165,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(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(found_type.clone()), ) @@ -183,10 +183,11 @@ impl FunctionType { return Ok(return_type.clone()); } } - Err( - CheckErrorKind::UnionTypeError(arg_types.clone(), Box::new(found_type.clone())) - .into(), + Err(StaticCheckErrorKind::UnionTypeError( + arg_types.clone(), + Box::new(found_type.clone()), ) + .into()) } FunctionType::ArithmeticVariadic | FunctionType::ArithmeticBinary @@ -197,14 +198,17 @@ impl FunctionType { if self == &FunctionType::ArithmeticBinary { check_argument_count(2, args)?; } - let (first, rest) = args - .split_first() - .ok_or(CheckErrorKind::RequiresAtLeastArguments(1, args.len()))?; + let (first, rest) = + args.split_first() + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::UnionTypeError( + _ => Err(StaticCheckErrorKind::UnionTypeError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(first.clone()), )), @@ -212,7 +216,7 @@ impl FunctionType { for found_type in rest.iter() { analysis_typecheck_cost(accounting, &TypeSignature::IntType, found_type)?; if found_type != &return_type { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(return_type), Box::new(found_type.clone()), ) @@ -228,7 +232,7 @@ impl FunctionType { analysis_typecheck_cost(accounting, &TypeSignature::IntType, second)?; if first != &TypeSignature::IntType && first != &TypeSignature::UIntType { - return Err(CheckErrorKind::UnionTypeError( + return Err(StaticCheckErrorKind::UnionTypeError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(first.clone()), ) @@ -236,7 +240,7 @@ impl FunctionType { } if first != second { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(first.clone()), Box::new(second.clone()), ) @@ -245,7 +249,7 @@ impl FunctionType { Ok(TypeSignature::BoolType) } - FunctionType::Binary(_, _, _) => Err(CheckErrorKind::Expects( + FunctionType::Binary(_, _, _) => Err(StaticCheckErrorKind::Expects( "Binary type should not be reached in 2.05".into(), ) .into()), @@ -259,7 +263,9 @@ impl FunctionType { ) -> Result { let (expected_args, returns) = match self { FunctionType::Fixed(FixedFunction { args, returns }) => (args, returns), - _ => return Err(CheckErrorKind::Expects("Unexpected function type".into()).into()), + _ => { + return Err(StaticCheckErrorKind::Expects("Unexpected function type".into()).into()) + } }; check_argument_count(expected_args.len(), func_args)?; @@ -271,7 +277,9 @@ impl FunctionType { ) => { let contract_to_check = db .load_contract(contract, &StacksEpochId::Epoch2_05)? - .ok_or_else(|| CheckErrorKind::NoSuchContract(contract.name.to_string()))?; + .ok_or_else(|| { + StaticCheckErrorKind::NoSuchContract(contract.name.to_string()) + })?; let trait_definition = db .get_defined_trait( &trait_id.contract_identifier, @@ -279,9 +287,11 @@ impl FunctionType { &StacksEpochId::Epoch2_05, ) .map_err(|_| { - CheckErrorKind::NoSuchContract(trait_id.contract_identifier.to_string()) + StaticCheckErrorKind::NoSuchContract( + trait_id.contract_identifier.to_string(), + ) })? - .ok_or(CheckErrorKind::NoSuchContract( + .ok_or(StaticCheckErrorKind::NoSuchContract( trait_id.contract_identifier.to_string(), ))?; contract_to_check.check_trait_compliance( @@ -293,7 +303,7 @@ impl FunctionType { (expected_type, value) => { if !expected_type.admits(&StacksEpochId::Epoch2_05, value)? { let actual_type = TypeSignature::type_of(value)?; - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type), ) @@ -327,13 +337,13 @@ fn type_reserved_variable(variable_name: &str) -> Result, BlockHeight => TypeSignature::UIntType, BurnBlockHeight => TypeSignature::UIntType, NativeNone => TypeSignature::new_option(no_type()) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, NativeTrue => TypeSignature::BoolType, NativeFalse => TypeSignature::BoolType, TotalLiquidMicroSTX => TypeSignature::UIntType, Regtest => TypeSignature::BoolType, TxSponsor | Mainnet | ChainId | StacksBlockHeight | TenureHeight | StacksBlockTime | CurrentContract => { - return Err(CheckErrorKind::Expects( + return Err(StaticCheckErrorKind::Expects( "tx-sponsor, mainnet, chain-id, stacks-block-height, tenure-height, stacks-block-time, and current-contract should not reach here in 2.05".into(), ) .into()) @@ -393,7 +403,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &return_type, ) .map_err(|_| { - CheckErrorKind::ReturnTypesMustMatch( + StaticCheckErrorKind::ReturnTypesMustMatch( Box::new(expected_type), Box::new(return_type), ) @@ -424,7 +434,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { } Err(e) => Err(e), })? - .ok_or_else(|| CheckErrorKind::Expects("Expected a depth result".into()))?; + .ok_or_else(|| StaticCheckErrorKind::Expects("Expected a depth result".into()))?; } runtime_cost(ClarityCostFunction::AnalysisStorage, self, size)?; @@ -463,7 +473,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { let contract_to_check = self .db .load_contract(contract_identifier, &StacksEpochId::Epoch2_05)? - .ok_or(CheckErrorKind::NoSuchContract( + .ok_or(StaticCheckErrorKind::NoSuchContract( contract_identifier.to_string(), ))?; @@ -473,13 +483,13 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &trait_identifier.contract_identifier, &StacksEpochId::Epoch2_05, )? - .ok_or(CheckErrorKind::NoSuchContract( + .ok_or(StaticCheckErrorKind::NoSuchContract( trait_identifier.contract_identifier.to_string(), ))?; let trait_definition = contract_defining_trait .get_defined_trait(&trait_identifier.name) - .ok_or(CheckErrorKind::NoSuchTrait( + .ok_or(StaticCheckErrorKind::NoSuchTrait( trait_identifier.contract_identifier.to_string(), trait_identifier.name.to_string(), ))?; @@ -496,9 +506,11 @@ 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: StaticCheckError = - CheckErrorKind::TypeError(Box::new(expected_type.clone()), Box::new(actual_type)) - .into(); + let mut err: StaticCheckError = StaticCheckErrorKind::TypeError( + Box::new(expected_type.clone()), + Box::new(actual_type), + ) + .into(); err.set_expression(expr); Err(err) } else { @@ -533,12 +545,12 @@ impl<'a, 'b> TypeChecker<'a, 'b> { let mut types_returned = self.type_check_all(args, context)?; let last_return = types_returned.pop().ok_or(StaticCheckError::new( - CheckErrorKind::CheckerImplementationFailure, + StaticCheckErrorKind::CheckerImplementationFailure, ))?; for type_return in types_returned.iter() { if type_return.is_response_type() { - return Err(CheckErrorKind::UncheckedIntermediaryResponses.into()); + return Err(StaticCheckErrorKind::UncheckedIntermediaryResponses.into()); } } Ok(last_return) @@ -581,10 +593,10 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result<(ClarityName, FixedFunction), StaticCheckError> { let (function_name, args) = signature .split_first() - .ok_or(CheckErrorKind::RequiresAtLeastArguments(1, 0))?; + .ok_or(StaticCheckErrorKind::RequiresAtLeastArguments(1, 0))?; let function_name = function_name .match_atom() - .ok_or(CheckErrorKind::BadFunctionName)?; + .ok_or(StaticCheckErrorKind::BadFunctionName)?; let args = parse_name_type_pairs::<(), StaticCheckError>( StacksEpochId::Epoch2_05, args, @@ -593,7 +605,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { )?; if self.function_return_tracker.is_some() { - return Err(CheckErrorKind::Expects( + return Err(StaticCheckErrorKind::Expects( "Interpreter error: Previous function define left dirty typecheck state.".into(), ) .into()); @@ -635,7 +647,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &return_type, ) .map_err(|_| { - CheckErrorKind::ReturnTypesMustMatch( + StaticCheckErrorKind::ReturnTypesMustMatch( Box::new(expected.clone()), Box::new(return_type), ) @@ -674,10 +686,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(|_| CheckErrorKind::BadMapTypeDefinition)?; + .map_err(|_| StaticCheckErrorKind::BadMapTypeDefinition)?; let value_type = TypeSignature::parse_type_repr(StacksEpochId::Epoch2_05, value_type, &mut ()) - .map_err(|_| CheckErrorKind::BadMapTypeDefinition)?; + .map_err(|_| StaticCheckErrorKind::BadMapTypeDefinition)?; Ok((map_name.clone(), (key_type, value_type))) } @@ -709,19 +721,21 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result { let (function_name, args) = expression .split_first() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::NonFunctionApplication)?; self.type_map.set_type(function_name, no_type())?; let function_name = function_name .match_atom() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::UnknownFunction(function_name.to_string())), + _ => Err(StaticCheckErrorKind::UnknownFunction( + function_name.to_string(), + )), }?; for (expected_type, found_type) in function.args.iter().map(|x| &x.signature).zip(args) @@ -751,7 +765,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(CheckErrorKind::UndefinedVariable(name.to_string()).into()); + return Err(StaticCheckErrorKind::UndefinedVariable(name.to_string()).into()); } runtime_cost( @@ -763,7 +777,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { if let Some(type_result) = context.lookup_variable_type(name) { Ok(type_result.clone()) } else { - Err(CheckErrorKind::UndefinedVariable(name.to_string()).into()) + Err(StaticCheckErrorKind::UndefinedVariable(name.to_string()).into()) } } } @@ -778,7 +792,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(CheckErrorKind::UnexpectedTraitOrFieldReference.into()); + return Err(StaticCheckErrorKind::UnexpectedTraitOrFieldReference.into()); } }; @@ -810,7 +824,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result<(ClarityName, TypeSignature), StaticCheckError> { let expected_type = TypeSignature::parse_type_repr::<()>(StacksEpochId::Epoch2_05, var_type, &mut ()) - .map_err(|_e| CheckErrorKind::DefineVariableBadSignature)?; + .map_err(|_e| StaticCheckErrorKind::DefineVariableBadSignature)?; self.type_check_expects(initial, context, &expected_type)?; @@ -838,7 +852,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result<(ClarityName, TypeSignature), StaticCheckError> { let asset_type = TypeSignature::parse_type_repr::<()>(StacksEpochId::Epoch2_05, nft_type, &mut ()) - .map_err(|_| CheckErrorKind::DefineNFTBadSignature)?; + .map_err(|_| StaticCheckErrorKind::DefineNFTBadSignature)?; Ok((asset_name.clone(), asset_type)) } @@ -902,9 +916,9 @@ impl<'a, 'b> TypeChecker<'a, 'b> { .add_public_function_type(f_name, FunctionType::Fixed(f_type))?; return Ok(Some(())); } else { - return Err(CheckErrorKind::PublicFunctionMustReturnResponse(Box::new( - f_type.returns, - )) + return Err(StaticCheckErrorKind::PublicFunctionMustReturnResponse( + Box::new(f_type.returns), + ) .into()); } } @@ -1009,9 +1023,10 @@ 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( - CheckErrorKind::TraitReferenceUnknown(name.to_string()).into() - ); + return Err(StaticCheckErrorKind::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 74680694340..d5a492d09a9 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, CheckErrorKind, StaticCheckError}; +use crate::vm::analysis::errors::{check_argument_count, StaticCheckError, StaticCheckErrorKind}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::representations::SymbolicExpression; @@ -28,13 +28,15 @@ pub fn check_special_get_owner( ) -> Result { check_argument_count(2, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_asset_type = checker .contract_context .get_nft_type(asset_name) .cloned() - .ok_or_else(|| CheckErrorKind::NoSuchNFT(asset_name.to_string()))?; + .ok_or_else(|| StaticCheckErrorKind::NoSuchNFT(asset_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -56,10 +58,12 @@ pub fn check_special_get_balance( ) -> Result { check_argument_count(2, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; if !checker.contract_context.ft_exists(asset_name) { - return Err(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); + return Err(StaticCheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } runtime_cost(ClarityCostFunction::AnalysisTypeLookup, checker, 1)?; @@ -77,13 +81,15 @@ pub fn check_special_mint_asset( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; let expected_asset_type = checker .contract_context .get_nft_type(asset_name) - .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))? + .ok_or(StaticCheckErrorKind::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 +114,9 @@ pub fn check_special_mint_token( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_amount: TypeSignature = TypeSignature::UIntType; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; @@ -119,7 +127,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(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); + return Err(StaticCheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } Ok(TypeSignature::ResponseType(Box::new(( @@ -135,13 +143,15 @@ pub fn check_special_transfer_asset( ) -> Result { check_argument_count(4, args)?; - let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let token_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; let expected_asset_type = checker .contract_context .get_nft_type(token_name) - .ok_or(CheckErrorKind::NoSuchNFT(token_name.to_string()))? + .ok_or(StaticCheckErrorKind::NoSuchNFT(token_name.to_string()))? .clone(); runtime_cost( @@ -167,7 +177,9 @@ pub fn check_special_transfer_token( ) -> Result { check_argument_count(4, args)?; - let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let token_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_amount: TypeSignature = TypeSignature::UIntType; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; @@ -179,7 +191,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(CheckErrorKind::NoSuchFT(token_name.to_string()).into()); + return Err(StaticCheckErrorKind::NoSuchFT(token_name.to_string()).into()); } Ok(TypeSignature::ResponseType(Box::new(( @@ -195,10 +207,12 @@ pub fn check_special_get_token_supply( ) -> Result { check_argument_count(1, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; if !checker.contract_context.ft_exists(asset_name) { - return Err(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); + return Err(StaticCheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } runtime_cost(ClarityCostFunction::AnalysisTypeLookup, checker, 1)?; @@ -213,13 +227,15 @@ pub fn check_special_burn_asset( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; let expected_asset_type = checker .contract_context .get_nft_type(asset_name) - .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))? + .ok_or(StaticCheckErrorKind::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 +260,9 @@ pub fn check_special_burn_token( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_amount: TypeSignature = TypeSignature::UIntType; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; @@ -255,7 +273,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(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); + return Err(StaticCheckErrorKind::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 e454e424f10..b9cb0122af1 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, CheckErrorKind, StaticCheckError, TypeChecker, TypingContext, + check_arguments_at_least, StaticCheckError, StaticCheckErrorKind, TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost}; @@ -31,14 +31,16 @@ pub fn check_special_fetch_entry( ) -> Result { check_arguments_at_least(2, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; + let map_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::NoSuchMap(map_name.to_string()))?; + .ok_or(StaticCheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -55,7 +57,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(StaticCheckError::new(CheckErrorKind::TypeError( + Err(StaticCheckError::new(StaticCheckErrorKind::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) @@ -71,14 +73,16 @@ pub fn check_special_delete_entry( ) -> Result { check_arguments_at_least(2, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; + let map_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadMapName)?; let key_type = checker.type_check(&args[1], context)?; let (expected_key_type, _) = checker .contract_context .get_map_type(map_name) - .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; + .ok_or(StaticCheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -88,7 +92,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(StaticCheckError::new(CheckErrorKind::TypeError( + Err(StaticCheckError::new(StaticCheckErrorKind::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) @@ -104,7 +108,9 @@ fn check_set_or_insert_entry( ) -> Result { check_arguments_at_least(3, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; + let map_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadMapName)?; let key_type = checker.type_check(&args[1], context)?; let value_type = checker.type_check(&args[2], context)?; @@ -112,7 +118,7 @@ fn check_set_or_insert_entry( let (expected_key_type, expected_value_type) = checker .contract_context .get_map_type(map_name) - .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; + .ok_or(StaticCheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -129,12 +135,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(StaticCheckError::new(CheckErrorKind::TypeError( + Err(StaticCheckError::new(StaticCheckErrorKind::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) } else if !expected_value_type.admits_type(&StacksEpochId::Epoch2_05, &value_type)? { - Err(StaticCheckError::new(CheckErrorKind::TypeError( + Err(StaticCheckError::new(StaticCheckErrorKind::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 3cbe844478e..1cc33db4554 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::{CheckErrorKind, StaticCheckError, SyntaxBindingErrorType}; +use crate::vm::analysis::errors::{StaticCheckError, StaticCheckErrorKind, SyntaxBindingErrorType}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost}; use crate::vm::diagnostic::DiagnosableError; @@ -117,10 +117,12 @@ fn inner_handle_tuple_get( let return_type = tuple_type_sig .field_type(field_to_get) - .ok_or(StaticCheckError::new(CheckErrorKind::NoSuchTupleField( - field_to_get.to_string(), - tuple_type_sig.clone(), - )))? + .ok_or(StaticCheckError::new( + StaticCheckErrorKind::NoSuchTupleField( + field_to_get.to_string(), + tuple_type_sig.clone(), + ), + ))? .clone(); Ok(return_type) } @@ -134,7 +136,7 @@ fn check_special_get( let field_to_get = args[0] .match_atom() - .ok_or(CheckErrorKind::BadTupleFieldName)?; + .ok_or(StaticCheckErrorKind::BadTupleFieldName)?; let argument_type = checker.type_check(&args[1], context)?; @@ -146,10 +148,10 @@ fn check_special_get( let option_type = TypeSignature::new_option(inner_type)?; Ok(option_type) } else { - Err(CheckErrorKind::ExpectedTuple(value_type_sig).into()) + Err(StaticCheckErrorKind::ExpectedTuple(value_type_sig).into()) } } else { - Err(CheckErrorKind::ExpectedTuple(Box::new(argument_type)).into()) + Err(StaticCheckErrorKind::ExpectedTuple(Box::new(argument_type)).into()) } } @@ -163,13 +165,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(CheckErrorKind::ExpectedTuple(Box::new(res.clone()))), + _ => Err(StaticCheckErrorKind::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(CheckErrorKind::ExpectedTuple(Box::new(res.clone()))), + _ => Err(StaticCheckErrorKind::ExpectedTuple(Box::new(res.clone()))), }?; runtime_cost( ClarityCostFunction::AnalysisCheckTupleMerge, @@ -209,8 +211,9 @@ pub fn check_special_tuple_cons( }, )?; - let tuple_signature = TupleTypeSignature::try_from(tuple_type_data) - .map_err(|e| CheckErrorKind::BadTupleConstruction(e.message()))?; + let tuple_signature = TupleTypeSignature::try_from(tuple_type_data).map_err(|e| { + StaticCheckErrorKind::BadTupleConstruction(StaticCheckErrorKind::from(e).message()) + })?; Ok(TypeSignature::TupleType(tuple_signature)) } @@ -224,7 +227,7 @@ fn check_special_let( let binding_list = args[0] .match_list() - .ok_or(StaticCheckError::new(CheckErrorKind::BadLetSyntax))?; + .ok_or(StaticCheckError::new(StaticCheckErrorKind::BadLetSyntax))?; let mut out_context = context.extend()?; @@ -236,9 +239,9 @@ 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(StaticCheckError::new(CheckErrorKind::NameAlreadyUsed( - var_name.to_string(), - ))); + return Err(StaticCheckError::new( + StaticCheckErrorKind::NameAlreadyUsed(var_name.to_string()), + )); } let typed_result = checker.type_check(var_sexp, &out_context)?; @@ -267,14 +270,14 @@ fn check_special_fetch_var( let var_name = args[0] .match_atom() - .ok_or(StaticCheckError::new(CheckErrorKind::BadMapName))?; + .ok_or(StaticCheckError::new(StaticCheckErrorKind::BadMapName))?; let value_type = checker .contract_context .get_persisted_variable_type(var_name) - .ok_or(StaticCheckError::new(CheckErrorKind::NoSuchDataVariable( - var_name.to_string(), - )))?; + .ok_or(StaticCheckError::new( + StaticCheckErrorKind::NoSuchDataVariable(var_name.to_string()), + ))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -292,14 +295,18 @@ fn check_special_set_var( ) -> Result { check_arguments_at_least(2, args)?; - let var_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; + let var_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::NoSuchDataVariable(var_name.to_string()))?; + .ok_or(StaticCheckErrorKind::NoSuchDataVariable( + var_name.to_string(), + ))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -309,7 +316,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(StaticCheckError::new(CheckErrorKind::TypeError( + Err(StaticCheckError::new(StaticCheckErrorKind::TypeError( Box::new(expected_value_type.clone()), Box::new(value_type), ))) @@ -331,7 +338,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(|_| CheckErrorKind::TypeError(Box::new(x_type), Box::new(arg_type)))?; + .map_err(|_| StaticCheckErrorKind::TypeError(Box::new(x_type), Box::new(arg_type)))?; } Ok(TypeSignature::BoolType) @@ -354,7 +361,8 @@ fn check_special_if( analysis_typecheck_cost(checker, expr1, expr2)?; TypeSignature::least_supertype(&StacksEpochId::Epoch2_05, expr1, expr2).map_err(|_| { - CheckErrorKind::IfArmsMustMatch(Box::new(expr1.clone()), Box::new(expr2.clone())).into() + StaticCheckErrorKind::IfArmsMustMatch(Box::new(expr1.clone()), Box::new(expr2.clone())) + .into() }) } @@ -366,7 +374,7 @@ fn check_contract_call( check_arguments_at_least(2, args)?; let func_name = args[1].match_atom().ok_or(StaticCheckError::new( - CheckErrorKind::ContractCallExpectName, + StaticCheckErrorKind::ContractCallExpectName, ))?; checker.type_map.set_type(&args[1], no_type())?; @@ -391,10 +399,12 @@ fn check_contract_call( { Ok(function) } else { - Err(StaticCheckError::new(CheckErrorKind::NoSuchPublicFunction( - contract_identifier.to_string(), - func_name.to_string(), - ))) + Err(StaticCheckError::new( + StaticCheckErrorKind::NoSuchPublicFunction( + contract_identifier.to_string(), + func_name.to_string(), + ), + )) } }?; @@ -413,21 +423,22 @@ fn check_contract_call( let trait_id = match context.lookup_trait_reference_type(trait_instance) { Some(trait_id) => trait_id, _ => { - return Err( - CheckErrorKind::TraitReferenceUnknown(trait_instance.to_string()).into(), - ); + return Err(StaticCheckErrorKind::TraitReferenceUnknown( + trait_instance.to_string(), + ) + .into()); } }; runtime_cost(ClarityCostFunction::AnalysisLookupFunction, checker, 0)?; let trait_signature = checker.contract_context.get_trait(&trait_id.name).ok_or( - CheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()), + StaticCheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()), )?; let func_signature = trait_signature .get(func_name) - .ok_or(CheckErrorKind::TraitMethodUnknown( + .ok_or(StaticCheckErrorKind::TraitMethodUnknown( trait_id.name.to_string(), func_name.to_string(), ))?; @@ -442,7 +453,7 @@ fn check_contract_call( } _ => { return Err(StaticCheckError::new( - CheckErrorKind::ContractCallExpectName, + StaticCheckErrorKind::ContractCallExpectName, )) } }; @@ -466,14 +477,18 @@ fn check_contract_of( SymbolicExpressionType::Atom(trait_instance) => trait_instance, _ => { return Err(StaticCheckError::new( - CheckErrorKind::ContractOfExpectsTrait, + StaticCheckErrorKind::ContractOfExpectsTrait, )) } }; let trait_id = match context.lookup_trait_reference_type(trait_instance) { Some(trait_id) => trait_id, - _ => return Err(CheckErrorKind::TraitReferenceUnknown(trait_instance.to_string()).into()), + _ => { + return Err( + StaticCheckErrorKind::TraitReferenceUnknown(trait_instance.to_string()).into(), + ) + } }; runtime_cost(ClarityCostFunction::ContractOf, checker, 1)?; @@ -481,7 +496,7 @@ fn check_contract_of( checker .contract_context .get_trait(&trait_id.name) - .ok_or_else(|| CheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()))?; + .ok_or_else(|| StaticCheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()))?; Ok(TypeSignature::PrincipalType) } @@ -495,7 +510,7 @@ fn check_principal_of( checker.type_check_expects(&args[0], context, &TypeSignature::BUFFER_33)?; Ok( TypeSignature::new_response(TypeSignature::PrincipalType, TypeSignature::UIntType) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, ) } @@ -509,7 +524,7 @@ fn check_secp256k1_recover( checker.type_check_expects(&args[1], context, &TypeSignature::BUFFER_65)?; Ok( TypeSignature::new_response(TypeSignature::BUFFER_33, TypeSignature::UIntType) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, ) } @@ -533,7 +548,7 @@ fn check_get_block_info( check_arguments_at_least(2, args)?; let block_info_prop_str = args[0].match_atom().ok_or(StaticCheckError::new( - CheckErrorKind::GetBlockInfoExpectPropertyName, + StaticCheckErrorKind::GetBlockInfoExpectPropertyName, ))?; let block_info_prop = BlockInfoProperty::lookup_by_name_at_version( @@ -541,7 +556,7 @@ fn check_get_block_info( &ClarityVersion::Clarity1, ) .ok_or(StaticCheckError::new( - CheckErrorKind::NoSuchBlockInfoProperty(block_info_prop_str.to_string()), + StaticCheckErrorKind::NoSuchBlockInfoProperty(block_info_prop_str.to_string()), ))?; checker.type_check_expects(&args[1], context, &TypeSignature::UIntType)?; @@ -567,7 +582,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 { @@ -589,7 +604,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::IntType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -600,7 +615,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::UIntType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -611,7 +626,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::BoolType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -664,7 +679,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("owner".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -676,7 +691,7 @@ impl TypedNativeFunction { FunctionArg::new( TypeSignature::UIntType, ClarityName::try_from("amount".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -684,7 +699,7 @@ impl TypedNativeFunction { FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("sender".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -692,7 +707,7 @@ impl TypedNativeFunction { FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("recipient".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -702,14 +717,14 @@ impl TypedNativeFunction { TypeSignature::BoolType, TypeSignature::UIntType, ) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, }))), StxBurn => Simple(SimpleNativeFunction(FunctionType::Fixed(FixedFunction { args: vec![ FunctionArg::new( TypeSignature::UIntType, ClarityName::try_from("amount".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -717,7 +732,7 @@ impl TypedNativeFunction { FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("sender".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -727,7 +742,7 @@ impl TypedNativeFunction { TypeSignature::BoolType, TypeSignature::UIntType, ) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, }))), GetTokenBalance => Special(SpecialNativeFunction(&assets::check_special_get_balance)), GetAssetOwner => Special(SpecialNativeFunction(&assets::check_special_get_owner)), @@ -825,7 +840,7 @@ impl TypedNativeFunction { | AllowanceWithStacking | AllowanceAll | Secp256r1Verify => { - return Err(CheckErrorKind::Expects( + return Err(StaticCheckErrorKind::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 73a4d87f649..75c931428c3 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, CheckErrorKind, StaticCheckError, - TypeChecker, TypingContext, + check_argument_count, check_arguments_at_least, no_type, StaticCheckError, + StaticCheckErrorKind, 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(CheckErrorKind::ExpectedResponseType(Box::new(input)).into()) + Err(StaticCheckErrorKind::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(CheckErrorKind::ExpectedOptionalType(Box::new(input)).into()) + Err(StaticCheckErrorKind::ExpectedOptionalType(Box::new(input)).into()) } } @@ -120,11 +120,14 @@ pub fn check_special_default_to( let contained_type = *input_type; TypeSignature::least_supertype(&StacksEpochId::Epoch2_05, &default, &contained_type) .map_err(|_| { - CheckErrorKind::DefaultTypesMustMatch(Box::new(default), Box::new(contained_type)) - .into() + StaticCheckErrorKind::DefaultTypesMustMatch( + Box::new(default), + Box::new(contained_type), + ) + .into() }) } else { - Err(CheckErrorKind::ExpectedOptionalType(Box::new(input)).into()) + Err(StaticCheckErrorKind::ExpectedOptionalType(Box::new(input)).into()) } } @@ -152,7 +155,7 @@ fn inner_unwrap( match input { TypeSignature::OptionalType(input_type) => { if input_type.is_no_type() { - Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) + Err(StaticCheckErrorKind::CouldNotDetermineResponseOkType.into()) } else { Ok(*input_type) } @@ -160,12 +163,12 @@ fn inner_unwrap( TypeSignature::ResponseType(response_type) => { let ok_type = response_type.0; if ok_type.is_no_type() { - Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) + Err(StaticCheckErrorKind::CouldNotDetermineResponseOkType.into()) } else { Ok(ok_type) } } - _ => Err(CheckErrorKind::ExpectedOptionalOrResponseType(Box::new(input)).into()), + _ => Err(StaticCheckErrorKind::ExpectedOptionalOrResponseType(Box::new(input)).into()), } } @@ -178,12 +181,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(CheckErrorKind::CouldNotDetermineResponseErrType.into()) + Err(StaticCheckErrorKind::CouldNotDetermineResponseErrType.into()) } else { Ok(err_type) } } else { - Err(CheckErrorKind::ExpectedResponseType(Box::new(input)).into()) + Err(StaticCheckErrorKind::ExpectedResponseType(Box::new(input)).into()) } } @@ -231,7 +234,7 @@ pub fn check_special_try_ret( match input { TypeSignature::OptionalType(input_type) => { if input_type.is_no_type() { - Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) + Err(StaticCheckErrorKind::CouldNotDetermineResponseOkType.into()) } else { checker.track_return_type(TypeSignature::new_option(TypeSignature::NoType)?)?; Ok(*input_type) @@ -240,9 +243,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(CheckErrorKind::CouldNotDetermineResponseOkType.into()) + Err(StaticCheckErrorKind::CouldNotDetermineResponseOkType.into()) } else if err_type.is_no_type() { - Err(CheckErrorKind::CouldNotDetermineResponseErrType.into()) + Err(StaticCheckErrorKind::CouldNotDetermineResponseErrType.into()) } else { checker.track_return_type(TypeSignature::new_response( TypeSignature::NoType, @@ -251,7 +254,7 @@ pub fn check_special_try_ret( Ok(ok_type) } } - _ => Err(CheckErrorKind::ExpectedOptionalOrResponseType(Box::new(input)).into()), + _ => Err(StaticCheckErrorKind::ExpectedOptionalOrResponseType(Box::new(input)).into()), } } @@ -297,7 +300,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(CheckErrorKind::NameAlreadyUsed(bind_name.into()).into()); + return Err(StaticCheckErrorKind::NameAlreadyUsed(bind_name.into()).into()); } inner_context.variable_types.insert(bind_name, bind_type); @@ -312,22 +315,22 @@ fn check_special_match_opt( context: &TypingContext, ) -> Result { if args.len() != 3 { - Err(CheckErrorKind::BadMatchOptionSyntax(Box::new( - CheckErrorKind::IncorrectArgumentCount(4, args.len() + 1), + Err(StaticCheckErrorKind::BadMatchOptionSyntax(Box::new( + StaticCheckErrorKind::IncorrectArgumentCount(4, args.len() + 1), )))?; } let bind_name = args[0] .match_atom() .ok_or_else(|| { - CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::ExpectedName)) + StaticCheckErrorKind::BadMatchOptionSyntax(Box::new(StaticCheckErrorKind::ExpectedName)) })? .clone(); let some_branch = &args[1]; let none_branch = &args[2]; if option_type.is_no_type() { - return Err(CheckErrorKind::CouldNotDetermineMatchTypes.into()); + return Err(StaticCheckErrorKind::CouldNotDetermineMatchTypes.into()); } let some_branch_type = @@ -342,8 +345,11 @@ fn check_special_match_opt( &none_branch_type, ) .map_err(|_| { - CheckErrorKind::MatchArmsMustMatch(Box::new(some_branch_type), Box::new(none_branch_type)) - .into() + StaticCheckErrorKind::MatchArmsMustMatch( + Box::new(some_branch_type), + Box::new(none_branch_type), + ) + .into() }) } @@ -354,22 +360,26 @@ fn check_special_match_resp( context: &TypingContext, ) -> Result { if args.len() != 4 { - Err(CheckErrorKind::BadMatchResponseSyntax(Box::new( - CheckErrorKind::IncorrectArgumentCount(5, args.len() + 1), + Err(StaticCheckErrorKind::BadMatchResponseSyntax(Box::new( + StaticCheckErrorKind::IncorrectArgumentCount(5, args.len() + 1), )))?; } let ok_bind_name = args[0] .match_atom() .ok_or_else(|| { - CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)) + StaticCheckErrorKind::BadMatchResponseSyntax(Box::new( + StaticCheckErrorKind::ExpectedName, + )) })? .clone(); let ok_branch = &args[1]; let err_bind_name = args[2] .match_atom() .ok_or_else(|| { - CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)) + StaticCheckErrorKind::BadMatchResponseSyntax(Box::new( + StaticCheckErrorKind::ExpectedName, + )) })? .clone(); let err_branch = &args[3]; @@ -377,7 +387,7 @@ fn check_special_match_resp( let (ok_type, err_type) = resp_type; if ok_type.is_no_type() || err_type.is_no_type() { - return Err(CheckErrorKind::CouldNotDetermineMatchTypes.into()); + return Err(StaticCheckErrorKind::CouldNotDetermineMatchTypes.into()); } let ok_branch_type = eval_with_new_binding(ok_branch, ok_bind_name, ok_type, checker, context)?; @@ -388,8 +398,11 @@ fn check_special_match_resp( TypeSignature::least_supertype(&StacksEpochId::Epoch2_05, &ok_branch_type, &err_branch_type) .map_err(|_| { - CheckErrorKind::MatchArmsMustMatch(Box::new(ok_branch_type), Box::new(err_branch_type)) - .into() + StaticCheckErrorKind::MatchArmsMustMatch( + Box::new(ok_branch_type), + Box::new(err_branch_type), + ) + .into() }) } @@ -409,6 +422,6 @@ pub fn check_special_match( TypeSignature::ResponseType(resp_type) => { check_special_match_resp(*resp_type, checker, &args[1..], context) } - _ => Err(CheckErrorKind::BadMatchInput(Box::new(input)).into()), + _ => Err(StaticCheckErrorKind::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 8b03807c7a9..37f3d83b837 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,8 +18,8 @@ use stacks_common::types::StacksEpochId; use super::{SimpleNativeFunction, TypedNativeFunction}; use crate::vm::analysis::type_checker::v2_05::{ - check_argument_count, check_arguments_at_least, CheckErrorKind, StaticCheckError, TypeChecker, - TypingContext, + check_argument_count, check_arguments_at_least, StaticCheckError, StaticCheckErrorKind, + TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost}; @@ -44,14 +44,15 @@ fn get_simple_native_or_user_define( { Ok(function_type) } else { - Err( - CheckErrorKind::IllegalOrUnknownFunctionApplication(function_name.to_string()) - .into(), + Err(StaticCheckErrorKind::IllegalOrUnknownFunctionApplication( + function_name.to_string(), ) + .into()) } } else { checker.get_function_type(function_name).ok_or( - CheckErrorKind::IllegalOrUnknownFunctionApplication(function_name.to_string()).into(), + StaticCheckErrorKind::IllegalOrUnknownFunctionApplication(function_name.to_string()) + .into(), ) } } @@ -65,7 +66,7 @@ pub fn check_special_map( let function_name = args[0] .match_atom() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::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)?; @@ -101,7 +102,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(CheckErrorKind::ExpectedSequence(Box::new(argument_type)).into()); + return Err(StaticCheckErrorKind::ExpectedSequence(Box::new(argument_type)).into()); } }; func_args.push(entry_type); @@ -110,7 +111,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(|_| CheckErrorKind::ConstructedListTooLarge.into()) + .map_err(|_| StaticCheckErrorKind::ConstructedListTooLarge.into()) } pub fn check_special_filter( @@ -122,7 +123,7 @@ pub fn check_special_filter( let function_name = args[0] .match_atom() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::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)?; @@ -133,7 +134,7 @@ pub fn check_special_filter( { let input_type = match argument_type { TypeSignature::SequenceType(ref sequence_type) => Ok(sequence_type.unit_type()), - _ => Err(CheckErrorKind::ExpectedSequence(Box::new( + _ => Err(StaticCheckErrorKind::ExpectedSequence(Box::new( argument_type.clone(), ))), }?; @@ -146,7 +147,7 @@ pub fn check_special_filter( )?; if TypeSignature::BoolType != filter_type { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BoolType), Box::new(filter_type), ) @@ -166,7 +167,7 @@ pub fn check_special_fold( let function_name = args[0] .match_atom() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::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)?; @@ -176,7 +177,9 @@ pub fn check_special_fold( let input_type = match argument_type { TypeSignature::SequenceType(sequence_type) => Ok(sequence_type.unit_type()), - _ => Err(CheckErrorKind::ExpectedSequence(Box::new(argument_type))), + _ => Err(StaticCheckErrorKind::ExpectedSequence(Box::new( + argument_type, + ))), }?; let initial_value_type = checker.type_check(&args[2], context)?; @@ -234,29 +237,29 @@ pub fn check_special_concat( )?; let new_len = lhs_max_len .checked_add(rhs_max_len) - .ok_or(CheckErrorKind::MaxLengthOverflow)?; + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::MaxLengthOverflow)?; + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::MaxLengthOverflow)?; + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::MaxLengthOverflow)?; + .ok_or(StaticCheckErrorKind::MaxLengthOverflow)?; TypeSignature::SequenceType(StringType(UTF8(size.try_into()?))) } (_, _) => { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(lhs_type.clone()), Box::new(rhs_type.clone()), ) @@ -264,7 +267,7 @@ pub fn check_special_concat( } } } - _ => return Err(CheckErrorKind::ExpectedSequence(Box::new(lhs_type.clone())).into()), + _ => return Err(StaticCheckErrorKind::ExpectedSequence(Box::new(lhs_type.clone())).into()), }; Ok(res) } @@ -293,11 +296,11 @@ pub fn check_special_append( )?; let new_len = lhs_max_len .checked_add(1) - .ok_or(CheckErrorKind::MaxLengthOverflow)?; + .ok_or(StaticCheckErrorKind::MaxLengthOverflow)?; let return_type = TypeSignature::list_of(list_entry_type, new_len)?; Ok(return_type) } - _ => Err(CheckErrorKind::ExpectedListApplication.into()), + _ => Err(StaticCheckErrorKind::ExpectedListApplication.into()), } } @@ -312,7 +315,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(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(expected_len_type), ) @@ -329,7 +332,7 @@ pub fn check_special_as_max_len( .set_type(&args[1], TypeSignature::UIntType)?; let expected_len = - u32::try_from(expected_len).map_err(|_e| CheckErrorKind::MaxLengthOverflow)?; + u32::try_from(expected_len).map_err(|_e| StaticCheckErrorKind::MaxLengthOverflow)?; let sequence = checker.type_check(&args[0], context)?; runtime_cost(ClarityCostFunction::AnalysisIterableFunc, checker, 0)?; @@ -355,7 +358,7 @@ pub fn check_special_as_max_len( StringUTF8Length::try_from(expected_len)?, )))), )), - _ => Err(CheckErrorKind::ExpectedSequence(Box::new(sequence)).into()), + _ => Err(StaticCheckErrorKind::ExpectedSequence(Box::new(sequence)).into()), } } @@ -371,7 +374,9 @@ pub fn check_special_len( match collection_type { TypeSignature::SequenceType(_) => Ok(()), - _ => Err(CheckErrorKind::ExpectedSequence(Box::new(collection_type))), + _ => Err(StaticCheckErrorKind::ExpectedSequence(Box::new( + collection_type, + ))), }?; Ok(TypeSignature::UIntType) @@ -400,16 +405,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(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, )))), )), TypeSignature::SequenceType(StringType(UTF8(_))) => Ok(TypeSignature::OptionalType( Box::new(TypeSignature::SequenceType(StringType(UTF8( StringUTF8Length::try_from(1u32) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, )))), )), - _ => Err(CheckErrorKind::ExpectedSequence(Box::new(collection_type)).into()), + _ => Err(StaticCheckErrorKind::ExpectedSequence(Box::new(collection_type)).into()), } } @@ -425,7 +430,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(CheckErrorKind::ExpectedSequence(Box::new(list_type))), + _ => Err(StaticCheckErrorKind::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 39e52b274d2..22272d7e435 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::CheckErrorKind; +use crate::vm::analysis::errors::StaticCheckErrorKind; 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 = [ - CheckErrorKind::NoSuchFT("stackoos".to_string()), - CheckErrorKind::BadTokenName, - CheckErrorKind::BadTokenName, - CheckErrorKind::TypeError( + StaticCheckErrorKind::NoSuchFT("stackoos".to_string()), + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::IntType), ), - CheckErrorKind::BadTokenName, - CheckErrorKind::NoSuchNFT("stackoos".to_string()), - CheckErrorKind::TypeError( + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::NoSuchNFT("stackoos".to_string()), + StaticCheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(string_ascii_type(15)), ), - CheckErrorKind::BadTokenName, - CheckErrorKind::NoSuchNFT("stackoos".to_string()), - CheckErrorKind::TypeError( + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::NoSuchNFT("stackoos".to_string()), + StaticCheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(string_ascii_type(15)), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::NoSuchFT("stackoos".to_string()), - CheckErrorKind::BadTokenName, - CheckErrorKind::TypeError( + StaticCheckErrorKind::NoSuchFT("stackoos".to_string()), + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::BoolType), ), - CheckErrorKind::BadTokenName, - CheckErrorKind::NoSuchNFT("stackoos".to_string()), - CheckErrorKind::TypeError( + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::NoSuchNFT("stackoos".to_string()), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::BadTokenName, - CheckErrorKind::TypeError( + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::NoSuchFT("stackoos".to_string()), - CheckErrorKind::BadTokenName, - CheckErrorKind::TypeError( + StaticCheckErrorKind::NoSuchFT("stackoos".to_string()), + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::BoolType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::BoolType), ), - CheckErrorKind::DefineNFTBadSignature, - CheckErrorKind::TypeError( + StaticCheckErrorKind::DefineNFTBadSignature, + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrorKind::NoSuchFT("stackoos".to_string()), - CheckErrorKind::NoSuchFT("stackoos".to_string()), - CheckErrorKind::TypeError( + StaticCheckErrorKind::NoSuchFT("stackoos".to_string()), + StaticCheckErrorKind::NoSuchFT("stackoos".to_string()), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::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 6b6c5137276..3ff400d42ee 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,10 +19,10 @@ 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::CheckErrorKind; use crate::vm::analysis::{mem_type_check, type_check}; use crate::vm::ast::parse; use crate::vm::database::MemoryBackingStore; +use crate::vm::errors::StaticCheckErrorKind; use crate::vm::types::QualifiedContractIdentifier; use crate::vm::ClarityVersion; @@ -492,7 +492,7 @@ fn test_names_tokens_contracts_bad() { ) }) .unwrap_err(); - assert!(matches!(*err.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*err.err, StaticCheckErrorKind::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, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*err.err, StaticCheckErrorKind::TypeError(_, _))); } assert!(matches!( @@ -545,7 +545,7 @@ fn test_bad_map_usage() { ) .unwrap_err() .err, - CheckErrorKind::UnionTypeError(_, _) + StaticCheckErrorKind::UnionTypeError(_, _) )); } @@ -665,7 +665,7 @@ fn test_expects() { eprintln!("unmatched_return_types returned check error: {err}"); assert!(matches!( *err.err, - CheckErrorKind::ReturnTypesMustMatch(_, _) + StaticCheckErrorKind::ReturnTypesMustMatch(_, _) )); } @@ -678,7 +678,7 @@ fn test_expects() { eprintln!("bad_default_types returned check error: {err}"); assert!(matches!( *err.err, - CheckErrorKind::DefaultTypesMustMatch(_, _) + StaticCheckErrorKind::DefaultTypesMustMatch(_, _) )); let err = mem_type_check( @@ -690,7 +690,7 @@ fn test_expects() { eprintln!("notype_response_type returned check error: {err}"); assert!(matches!( *err.err, - CheckErrorKind::CouldNotDetermineResponseErrType + StaticCheckErrorKind::CouldNotDetermineResponseErrType )); let err = mem_type_check( @@ -702,6 +702,6 @@ fn test_expects() { eprintln!("notype_response_type_2 returned check error: {err}"); assert!(matches!( *err.err, - CheckErrorKind::CouldNotDetermineResponseOkType + StaticCheckErrorKind::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 db7cdf7810f..6a130dd6537 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::{CheckErrorKind, StaticCheckError, SyntaxBindingError}; +use crate::vm::analysis::errors::{StaticCheckError, StaticCheckErrorKind, SyntaxBindingError}; use crate::vm::analysis::mem_type_check; use crate::vm::ast::build_ast; use crate::vm::ast::errors::ParseErrorKind; @@ -69,10 +69,10 @@ fn test_get_block_info() { "(get-block-info? time)", ]; let bad_expected = [ - 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), + StaticCheckErrorKind::NoSuchBlockInfoProperty("none".to_string()), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::RequiresAtLeastArguments(2, 1), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -113,10 +113,10 @@ fn test_define_trait() { "(define-trait)", ]; let bad_expected = [ - CheckErrorKind::InvalidTypeDescription, - CheckErrorKind::DefineTraitBadSignature, - CheckErrorKind::DefineTraitBadSignature, - CheckErrorKind::InvalidTypeDescription, + StaticCheckErrorKind::InvalidTypeDescription, + StaticCheckErrorKind::DefineTraitBadSignature, + StaticCheckErrorKind::DefineTraitBadSignature, + StaticCheckErrorKind::InvalidTypeDescription, ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -216,16 +216,16 @@ fn test_stx_ops() { "(stx-get-balance 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR)" ]; let bad_expected = [ - 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), + StaticCheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(UIntType)), + StaticCheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -291,7 +291,7 @@ fn test_destructuring_opts() { let bad = [ ( "(unwrap-err! (some 2) 2)", - CheckErrorKind::ExpectedResponseType(Box::new(TypeSignature::from_string( + StaticCheckErrorKind::ExpectedResponseType(Box::new(TypeSignature::from_string( "(optional int)", ClarityVersion::Clarity1, StacksEpochId::Epoch2_05, @@ -299,90 +299,99 @@ fn test_destructuring_opts() { ), ( "(unwrap! (err 3) 2)", - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(unwrap-err-panic (ok 3))", - CheckErrorKind::CouldNotDetermineResponseErrType, + StaticCheckErrorKind::CouldNotDetermineResponseErrType, ), ( "(unwrap-panic none)", - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(define-private (foo) (if (> 1 0) none none)) (unwrap-panic (foo))", - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(unwrap-panic (err 3))", - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(match none inner-value (/ 1 0) (+ 1 8))", - CheckErrorKind::CouldNotDetermineMatchTypes, + StaticCheckErrorKind::CouldNotDetermineMatchTypes, ), ( "(match (ok 1) ok-val (/ ok-val 0) err-val (+ err-val 7))", - CheckErrorKind::CouldNotDetermineMatchTypes, + StaticCheckErrorKind::CouldNotDetermineMatchTypes, ), ( "(match (err 1) ok-val (/ ok-val 0) err-val (+ err-val 7))", - CheckErrorKind::CouldNotDetermineMatchTypes, + StaticCheckErrorKind::CouldNotDetermineMatchTypes, ), ( "(define-private (foo) (if (> 1 0) (ok 1) (err u8))) (match (foo) ok-val (+ 1 ok-val) err-val (/ err-val u0))", - CheckErrorKind::MatchArmsMustMatch( + StaticCheckErrorKind::MatchArmsMustMatch( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), ), ( "(match (some 1) inner-value (+ 1 inner-value) (> 1 28))", - CheckErrorKind::MatchArmsMustMatch( + StaticCheckErrorKind::MatchArmsMustMatch( Box::new(TypeSignature::IntType), Box::new(TypeSignature::BoolType), ), ), ( "(match (some 1) inner-value (+ 1 inner-value))", - CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::IncorrectArgumentCount( - 4, 3, - ))), + StaticCheckErrorKind::BadMatchOptionSyntax(Box::new( + StaticCheckErrorKind::IncorrectArgumentCount(4, 3), + )), ), ( "(match (ok 1) inner-value (+ 1 inner-value))", - CheckErrorKind::BadMatchResponseSyntax(Box::new( - CheckErrorKind::IncorrectArgumentCount(5, 3), + StaticCheckErrorKind::BadMatchResponseSyntax(Box::new( + StaticCheckErrorKind::IncorrectArgumentCount(5, 3), )), ), ( "(match (ok 1) 1 (+ 1 1) err-val (+ 2 err-val))", - CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)), + StaticCheckErrorKind::BadMatchResponseSyntax(Box::new( + StaticCheckErrorKind::ExpectedName, + )), ), ( "(match (ok 1) ok-val (+ 1 1) (+ 3 4) (+ 2 err-val))", - CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)), + StaticCheckErrorKind::BadMatchResponseSyntax(Box::new( + StaticCheckErrorKind::ExpectedName, + )), ), ( "(match (some 1) 2 (+ 1 1) (+ 3 4))", - CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::ExpectedName)), + StaticCheckErrorKind::BadMatchOptionSyntax(Box::new( + StaticCheckErrorKind::ExpectedName, + )), + ), + ( + "(match)", + StaticCheckErrorKind::RequiresAtLeastArguments(1, 0), ), - ("(match)", CheckErrorKind::RequiresAtLeastArguments(1, 0)), ( "(match 1 ok-val (/ ok-val 0) err-val (+ err-val 7))", - CheckErrorKind::BadMatchInput(Box::new(TypeSignature::IntType)), + StaticCheckErrorKind::BadMatchInput(Box::new(TypeSignature::IntType)), ), ( "(default-to 3 5)", - CheckErrorKind::ExpectedOptionalType(Box::new(TypeSignature::IntType)), + StaticCheckErrorKind::ExpectedOptionalType(Box::new(TypeSignature::IntType)), ), ( "(define-private (foo (x int)) (match (some 3) x (+ x 2) 5))", - CheckErrorKind::NameAlreadyUsed("x".to_string()), + StaticCheckErrorKind::NameAlreadyUsed("x".to_string()), ), ( "(define-private (t1 (x uint)) (if (> x u1) (ok x) (err false))) @@ -390,7 +399,7 @@ fn test_destructuring_opts() { (if (> x u4) (err u3) (ok (+ u2 (try! (t1 x))))))", - CheckErrorKind::ReturnTypesMustMatch( + StaticCheckErrorKind::ReturnTypesMustMatch( Box::new( TypeSignature::new_response(TypeSignature::NoType, TypeSignature::BoolType) .unwrap(), @@ -405,7 +414,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))))", - CheckErrorKind::ReturnTypesMustMatch( + StaticCheckErrorKind::ReturnTypesMustMatch( Box::new( TypeSignature::new_response(TypeSignature::NoType, TypeSignature::BoolType) .unwrap(), @@ -415,23 +424,23 @@ fn test_destructuring_opts() { ), ( "(try! (ok 3))", - CheckErrorKind::CouldNotDetermineResponseErrType, + StaticCheckErrorKind::CouldNotDetermineResponseErrType, ), ( "(try! none)", - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(try! (err 3))", - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(try! 3)", - CheckErrorKind::ExpectedOptionalOrResponseType(Box::new(TypeSignature::IntType)), + StaticCheckErrorKind::ExpectedOptionalOrResponseType(Box::new(TypeSignature::IntType)), ), ( "(try! (ok 3) 4)", - CheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), ), ]; @@ -459,14 +468,14 @@ fn test_at_block() { let bad = [ ( "(at-block (sha512 u0) u1)", - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_32), Box::new(TypeSignature::BUFFER_64), ), ), ( "(at-block (sha256 u0) u1 u2)", - CheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), ), ]; @@ -507,7 +516,7 @@ fn test_trait_reference_unknown() { fn test_unexpected_use_of_field_or_trait_reference() { let bad = [( "(+ 1 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR.contract.field)", - CheckErrorKind::UnexpectedTraitOrFieldReference, + StaticCheckErrorKind::UnexpectedTraitOrFieldReference, )]; for (bad_test, expected) in bad.iter() { @@ -532,12 +541,12 @@ fn test_simple_arithmetic_checks() { "(and (or true false) (+ 1 2 3))", ]; let bad_expected = [ - 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)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::RequiresAtLeastArguments(1, 0), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::UndefinedVariable("x".to_string()), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -598,14 +607,14 @@ fn test_simple_hash_checks() { for bad_test in bad_types.iter() { assert!(matches!( *type_check_helper(bad_test).unwrap_err().err, - CheckErrorKind::UnionTypeError(_, _) + StaticCheckErrorKind::UnionTypeError(_, _) )); } for bad_test in invalid_args.iter() { assert!(matches!( *type_check_helper(bad_test).unwrap_err().err, - CheckErrorKind::IncorrectArgumentCount(_, _) + StaticCheckErrorKind::IncorrectArgumentCount(_, _) )); } } @@ -628,10 +637,10 @@ fn test_simple_ifs() { ]; let bad_expected = [ - 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)), + StaticCheckErrorKind::IfArmsMustMatch(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::IfArmsMustMatch(Box::new(ascii_type(1)), Box::new(BoolType)), + StaticCheckErrorKind::IncorrectArgumentCount(3, 0), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -664,9 +673,9 @@ fn test_simple_lets() { ]; let bad_expected = [ - CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_invalid_length(0)), - CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_not_atom(0)), - CheckErrorKind::TypeError( + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_invalid_length(0)), + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_not_atom(0)), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), @@ -721,26 +730,26 @@ fn test_index_of() { ]; let bad_expected = [ - CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), - CheckErrorKind::TypeError( + StaticCheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_MIN), Box::new(TypeSignature::STRING_ASCII_MIN), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::STRING_UTF8_MIN), Box::new(TypeSignature::STRING_ASCII_MIN), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::STRING_ASCII_MIN), Box::new(TypeSignature::STRING_UTF8_MIN), ), - CheckErrorKind::CouldNotDetermineType, - CheckErrorKind::CouldNotDetermineType, - CheckErrorKind::CouldNotDetermineType, + StaticCheckErrorKind::CouldNotDetermineType, + StaticCheckErrorKind::CouldNotDetermineType, + StaticCheckErrorKind::CouldNotDetermineType, ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -769,11 +778,11 @@ fn test_element_at() { let bad = ["(element-at (list 1 2 3 4 5) 100)", "(element-at 3 u100)"]; let bad_expected = [ - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), + StaticCheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -805,12 +814,12 @@ fn test_eqs() { ]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::list_of(IntType, 1).unwrap()), Box::new(IntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::from_string( "(optional bool)", ClarityVersion::Clarity1, @@ -852,9 +861,9 @@ fn test_asserts() { ]; let bad_expected = [ - CheckErrorKind::IncorrectArgumentCount(2, 1), - CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -918,23 +927,23 @@ fn test_lists() { "(map + (list 1 2 3 4 5) (list true true true true true))", ]; let bad_expected = [ - 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)), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(buff_type(20))), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(buff_type(20))), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::UnknownFunction("ynot".to_string()), + StaticCheckErrorKind::IllegalOrUnknownFunctionApplication("if".to_string()), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), + StaticCheckErrorKind::ExpectedSequence(Box::new(UIntType)), + StaticCheckErrorKind::ExpectedSequence(Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -975,20 +984,20 @@ fn test_buff() { "(len 1)", ]; let bad_expected = [ - 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)), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(buff_type(20))), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::UnknownFunction("ynot".to_string()), + StaticCheckErrorKind::IllegalOrUnknownFunctionApplication("if".to_string()), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), + StaticCheckErrorKind::ExpectedSequence(Box::new(UIntType)), + StaticCheckErrorKind::ExpectedSequence(Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1063,9 +1072,9 @@ fn test_native_as_max_len() { "(as-max-len? 0x01 u1048577)", ]; let bad_expected = [ - CheckErrorKind::ValueTooLarge, - CheckErrorKind::ValueTooLarge, - CheckErrorKind::ValueTooLarge, + StaticCheckErrorKind::ValueTooLarge, + StaticCheckErrorKind::ValueTooLarge, + StaticCheckErrorKind::ValueTooLarge, ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { assert_eq!(*expected, *type_check_helper(bad_test).unwrap_err().err); @@ -1109,9 +1118,9 @@ fn test_native_append() { ]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::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); @@ -1137,9 +1146,9 @@ fn test_native_concat() { ]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::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); @@ -1235,8 +1244,8 @@ fn test_tuples() { ]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1266,7 +1275,7 @@ fn test_empty_tuple_should_fail() { ) .unwrap_err() .err, - CheckErrorKind::EmptyTuplesNotAllowed + StaticCheckErrorKind::EmptyTuplesNotAllowed ); } @@ -1362,9 +1371,9 @@ fn test_simple_uints() { let bad = ["(> u1 1)", "(to-uint true)", "(to-int false)"]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(BoolType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1425,7 +1434,7 @@ fn test_response_inference() { ]; let bad_expected = [ - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::from_string( "(response bool int)", ClarityVersion::Clarity1, @@ -1433,8 +1442,8 @@ fn test_response_inference() { )), Box::new(BoolType), ), - CheckErrorKind::ReturnTypesMustMatch(Box::new(IntType), Box::new(BoolType)), - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::ReturnTypesMustMatch(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1572,7 +1581,7 @@ fn test_options() { .unwrap_err() .err { - CheckErrorKind::TypeError(t1, t2) => { + StaticCheckErrorKind::TypeError(t1, t2) => { *t1 == TypeSignature::from_string( "(optional bool)", ClarityVersion::Clarity1, @@ -1724,7 +1733,7 @@ fn test_missing_value_on_declaration_should_fail() { .unwrap_err(); assert!(matches!( *res.err, - CheckErrorKind::IncorrectArgumentCount(_, _) + StaticCheckErrorKind::IncorrectArgumentCount(_, _) )); } @@ -1740,7 +1749,7 @@ fn test_mismatching_type_on_declaration_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*res.err, StaticCheckErrorKind::TypeError(_, _))); } #[test] @@ -1761,7 +1770,7 @@ fn test_mismatching_type_on_update_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*res.err, StaticCheckErrorKind::TypeError(_, _))); } #[test] @@ -1778,7 +1787,10 @@ fn test_direct_access_to_persisted_var_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::UndefinedVariable(_) + )); } #[test] @@ -1798,7 +1810,7 @@ fn test_data_var_shadowed_by_let_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); + assert!(matches!(*res.err, StaticCheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -1816,7 +1828,10 @@ fn test_mutating_unknown_data_var_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NoSuchDataVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::NoSuchDataVariable(_) + )); } #[test] @@ -1832,7 +1847,10 @@ fn test_accessing_unknown_data_var_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NoSuchDataVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::NoSuchDataVariable(_) + )); } #[test] @@ -1848,7 +1866,7 @@ fn test_let_shadowed_by_let_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); + assert!(matches!(*res.err, StaticCheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -1865,7 +1883,7 @@ fn test_let_shadowed_by_nested_let_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); + assert!(matches!(*res.err, StaticCheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -1883,7 +1901,7 @@ fn test_define_constant_shadowed_by_let_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); + assert!(matches!(*res.err, StaticCheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -1900,7 +1918,7 @@ fn test_define_constant_shadowed_by_argument_should_fail() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); + assert!(matches!(*res.err, StaticCheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -2122,7 +2140,7 @@ fn test_fetch_entry_mismatching_type_signatures() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*res.err, StaticCheckErrorKind::TypeError(_, _))); } } @@ -2142,7 +2160,10 @@ fn test_fetch_entry_unbound_variables() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::UndefinedVariable(_) + )); } } @@ -2194,7 +2215,7 @@ fn test_insert_entry_mismatching_type_signatures() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*res.err, StaticCheckErrorKind::TypeError(_, _))); } } @@ -2217,7 +2238,10 @@ fn test_insert_entry_unbound_variables() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::UndefinedVariable(_) + )); } } @@ -2267,7 +2291,7 @@ fn test_delete_entry_mismatching_type_signatures() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*res.err, StaticCheckErrorKind::TypeError(_, _))); } } @@ -2287,7 +2311,10 @@ fn test_delete_entry_unbound_variables() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::UndefinedVariable(_) + )); } } @@ -2341,7 +2368,7 @@ fn test_set_entry_mismatching_type_signatures() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*res.err, StaticCheckErrorKind::TypeError(_, _))); } } @@ -2364,7 +2391,10 @@ fn test_set_entry_unbound_variables() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::UndefinedVariable(_) + )); } } @@ -2499,7 +2529,7 @@ fn test_buff_negative_len() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert_eq!(*res.err, CheckErrorKind::ValueOutOfBounds); + assert_eq!(*res.err, StaticCheckErrorKind::ValueOutOfBounds); } #[test] @@ -2513,7 +2543,7 @@ fn test_string_ascii_negative_len() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert_eq!(*res.err, CheckErrorKind::ValueOutOfBounds); + assert_eq!(*res.err, StaticCheckErrorKind::ValueOutOfBounds); } #[test] @@ -2527,5 +2557,5 @@ fn test_string_utf8_negative_len() { StacksEpochId::Epoch2_05, ) .unwrap_err(); - assert_eq!(*res.err, CheckErrorKind::ValueOutOfBounds); + assert_eq!(*res.err, StaticCheckErrorKind::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 7632ea305bb..c8998b90190 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::{CheckErrorKind, StaticCheckError}; +use crate::vm::analysis::errors::{StaticCheckError, StaticCheckErrorKind}; use crate::vm::analysis::type_checker::is_reserved_word; use crate::vm::analysis::types::ContractAnalysis; use crate::vm::representations::ClarityName; @@ -169,7 +169,7 @@ impl ContractContext { pub fn check_name_used(&self, name: &str) -> Result<(), StaticCheckError> { if is_reserved_word(name, self.clarity_version) { - return Err(StaticCheckError::new(CheckErrorKind::ReservedWord( + return Err(StaticCheckError::new(StaticCheckErrorKind::ReservedWord( name.to_string(), ))); } @@ -183,9 +183,9 @@ impl ContractContext { || self.traits.is_name_used(name) || self.map_types.contains_key(name) { - Err(StaticCheckError::new(CheckErrorKind::NameAlreadyUsed( - name.to_string(), - ))) + Err(StaticCheckError::new( + StaticCheckErrorKind::NameAlreadyUsed(name.to_string()), + )) } else { 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 a257bd07790..448cd41cb2f 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, CheckErrorKind, - StaticCheckError, SyntaxBindingErrorType, + check_argument_count, check_arguments_at_least, check_arguments_at_most, StaticCheckError, + StaticCheckErrorKind, SyntaxBindingErrorType, }; use crate::vm::analysis::AnalysisDatabase; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -161,14 +161,6 @@ pub fn compute_typecheck_cost( ) } -pub fn check_argument_len(expected: usize, args_len: usize) -> Result<(), CheckErrorKind> { - if args_len != expected { - Err(CheckErrorKind::IncorrectArgumentCount(expected, args_len)) - } else { - Ok(()) - } -} - impl FunctionType { #[allow(clippy::type_complexity)] pub fn check_args_visitor_2_1( @@ -192,7 +184,7 @@ impl FunctionType { if !admitted { return ( cost, - Err(CheckErrorKind::TypeError( + Err(StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(arg_type.clone()), ) @@ -211,7 +203,7 @@ impl FunctionType { let return_type = match arg_type { TypeSignature::IntType => Ok(Some(TypeSignature::IntType)), TypeSignature::UIntType => Ok(Some(TypeSignature::UIntType)), - _ => Err(CheckErrorKind::UnionTypeError( + _ => Err(StaticCheckErrorKind::UnionTypeError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(arg_type.clone()), ) @@ -220,10 +212,10 @@ impl FunctionType { (cost, return_type) } else { let return_type = accumulated_type - .ok_or_else(|| CheckErrorKind::Expects("Failed to set accumulated type for arg indices >= 1 in variadic arithmetic".into()).into()); + .ok_or_else(|| StaticCheckErrorKind::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(CheckErrorKind::TypeError( + Err(StaticCheckErrorKind::TypeError( Box::new(return_type.clone()), Box::new(arg_type.clone()), ) @@ -246,10 +238,11 @@ impl FunctionType { // note: argument count will be wrong? return ( None, - Err( - CheckErrorKind::IncorrectArgumentCount(arg_types.len(), arg_index) - .into(), - ), + Err(StaticCheckErrorKind::IncorrectArgumentCount( + arg_types.len(), + arg_index, + ) + .into()), ); } (None, Ok(None)) @@ -262,7 +255,7 @@ impl FunctionType { if arg_index >= 1 { return ( None, - Err(CheckErrorKind::IncorrectArgumentCount(1, arg_index).into()), + Err(StaticCheckErrorKind::IncorrectArgumentCount(1, arg_index).into()), ); } (None, Ok(None)) @@ -273,7 +266,7 @@ impl FunctionType { if arg_index >= 2 { return ( None, - Err(CheckErrorKind::IncorrectArgumentCount(2, arg_index).into()), + Err(StaticCheckErrorKind::IncorrectArgumentCount(2, arg_index).into()), ); } (None, Ok(None)) @@ -293,7 +286,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(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(found_type.clone()), ) @@ -311,7 +304,7 @@ impl FunctionType { { analysis_typecheck_cost(accounting, expected_type, found_type)?; if !expected_type.admits_type(&StacksEpochId::Epoch21, found_type)? { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(found_type.clone()), ) @@ -329,10 +322,11 @@ impl FunctionType { return Ok(return_type.clone()); } } - Err( - CheckErrorKind::UnionTypeError(arg_types.clone(), Box::new(found_type.clone())) - .into(), + Err(StaticCheckErrorKind::UnionTypeError( + arg_types.clone(), + Box::new(found_type.clone()), ) + .into()) } FunctionType::Binary(left_arg_sig, right_arg_sig, return_sig) => { check_argument_count(2, args)?; @@ -357,14 +351,17 @@ impl FunctionType { if self == &FunctionType::ArithmeticBinary { check_argument_count(2, args)?; } - let (first, rest) = args - .split_first() - .ok_or(CheckErrorKind::RequiresAtLeastArguments(1, args.len()))?; + let (first, rest) = + args.split_first() + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::UnionTypeError( + _ => Err(StaticCheckErrorKind::UnionTypeError( vec![TypeSignature::IntType, TypeSignature::UIntType], Box::new(first.clone()), )), @@ -372,7 +369,7 @@ impl FunctionType { for found_type in rest.iter() { analysis_typecheck_cost(accounting, &TypeSignature::IntType, found_type)?; if found_type != &return_type { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(return_type.clone()), Box::new(found_type.clone()), ) @@ -406,7 +403,7 @@ impl FunctionType { }; if !first_type_supported { - return Err(CheckErrorKind::UnionTypeError( + return Err(StaticCheckErrorKind::UnionTypeError( vec![ TypeSignature::IntType, TypeSignature::UIntType, @@ -448,7 +445,7 @@ impl FunctionType { }; if !pair_of_types_matches { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(first.clone()), Box::new(second.clone()), ) @@ -493,7 +490,7 @@ impl FunctionType { depth: u8, ) -> Result { if depth > MAX_TYPE_DEPTH { - return Err(CheckErrorKind::TypeSignatureTooDeep.into()); + return Err(StaticCheckErrorKind::TypeSignatureTooDeep.into()); } Ok(match value { @@ -563,7 +560,9 @@ impl FunctionType { ) -> Result { let (expected_args, returns) = match self { FunctionType::Fixed(FixedFunction { args, returns }) => (args, returns), - _ => return Err(CheckErrorKind::Expects("Unexpected function type".into()).into()), + _ => { + return Err(StaticCheckErrorKind::Expects("Unexpected function type".into()).into()) + } }; check_argument_count(expected_args.len(), func_args)?; @@ -577,7 +576,7 @@ impl FunctionType { let contract_to_check = db .load_contract(contract, &StacksEpochId::Epoch21)? .ok_or_else(|| { - CheckErrorKind::NoSuchContract(contract.name.to_string()) + StaticCheckErrorKind::NoSuchContract(contract.name.to_string()) })?; let trait_definition = db .get_defined_trait( @@ -585,8 +584,10 @@ impl FunctionType { &trait_id.name, &StacksEpochId::Epoch21, ) - .map_err(|_| CheckErrorKind::Expects("Failed to get trait".into()))? - .ok_or(CheckErrorKind::NoSuchContract( + .map_err(|_| { + StaticCheckErrorKind::Expects("Failed to get trait".into()) + })? + .ok_or(StaticCheckErrorKind::NoSuchContract( trait_id.contract_identifier.to_string(), ))?; contract_to_check.check_trait_compliance( @@ -598,7 +599,7 @@ impl FunctionType { (expected_type, value) => { if !expected_type.admits(&StacksEpochId::Epoch21, value)? { let actual_type = TypeSignature::type_of(value)?; - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -637,7 +638,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(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -654,7 +655,7 @@ fn check_function_arg_signature( } } if !admitted { - return Err(CheckErrorKind::UnionTypeError( + return Err(StaticCheckErrorKind::UnionTypeError( expected_types.clone(), Box::new(actual_type.clone()), ) @@ -735,14 +736,14 @@ pub fn clarity2_trait_check_trait_compliance( func, tracker, ) { - return Err(CheckErrorKind::IncompatibleTrait( + return Err(StaticCheckErrorKind::IncompatibleTrait( Box::new(expected_trait_identifier.clone()), Box::new(actual_trait_identifier.clone()), ) .into()); } } else { - return Err(CheckErrorKind::IncompatibleTrait( + return Err(StaticCheckErrorKind::IncompatibleTrait( Box::new(expected_trait_identifier.clone()), Box::new(actual_trait_identifier.clone()), ) @@ -763,7 +764,7 @@ fn clarity2_inner_type_check_type( tracker: &mut T, ) -> Result { if depth > MAX_TYPE_DEPTH { - return Err(CheckErrorKind::TypeSignatureTooDeep.into()); + return Err(StaticCheckErrorKind::TypeSignatureTooDeep.into()); } // Recurse into values to check embedded traits properly @@ -816,7 +817,7 @@ fn clarity2_inner_type_check_type( tracker, )?; } else { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -828,7 +829,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(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -848,7 +849,7 @@ fn clarity2_inner_type_check_type( )?; } None => { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -881,24 +882,24 @@ fn clarity2_inner_type_check_type( TypeSignature::CallableType(CallableSubtype::Principal(contract_identifier)), TypeSignature::CallableType(CallableSubtype::Trait(expected_trait_id)), ) => { - let contract_to_check = match db - .load_contract(contract_identifier, &StacksEpochId::Epoch21)? - { - Some(contract) => { - runtime_cost( - ClarityCostFunction::AnalysisFetchContractEntry, - tracker, - contract_analysis_size(&contract)?, - )?; - contract - } - None => { - runtime_cost(ClarityCostFunction::AnalysisFetchContractEntry, tracker, 1)?; - return Err( - CheckErrorKind::NoSuchContract(contract_identifier.to_string()).into(), - ); - } - }; + let contract_to_check = + match db.load_contract(contract_identifier, &StacksEpochId::Epoch21)? { + Some(contract) => { + runtime_cost( + ClarityCostFunction::AnalysisFetchContractEntry, + tracker, + contract_analysis_size(&contract)?, + )?; + contract + } + None => { + runtime_cost(ClarityCostFunction::AnalysisFetchContractEntry, tracker, 1)?; + return Err(StaticCheckErrorKind::NoSuchContract( + contract_identifier.to_string(), + ) + .into()); + } + }; let expected_trait = clarity2_lookup_trait(db, contract_context, expected_trait_id, tracker)?; contract_to_check.check_trait_compliance( @@ -926,7 +927,7 @@ fn clarity2_inner_type_check_type( (TypeSignature::NoType, _) => (), (_, _) => { if !expected_type.admits_type(&StacksEpochId::Epoch21, actual_type)? { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -948,7 +949,7 @@ fn clarity2_lookup_trait( if contract_context.is_contract(&trait_id.contract_identifier) { return Ok(contract_context .get_trait(trait_id) - .ok_or(CheckErrorKind::NoSuchTrait( + .ok_or(StaticCheckErrorKind::NoSuchTrait( trait_id.contract_identifier.to_string(), trait_id.name.to_string(), ))? @@ -975,7 +976,7 @@ fn clarity2_lookup_trait( } Ok(None) => { runtime_cost(ClarityCostFunction::AnalysisUseTraitEntry, tracker, 1)?; - Err(CheckErrorKind::NoSuchTrait( + Err(StaticCheckErrorKind::NoSuchTrait( trait_id.contract_identifier.to_string(), trait_id.name.to_string(), ) @@ -1013,14 +1014,14 @@ fn type_reserved_variable( let var_type = match variable { TxSender => TypeSignature::PrincipalType, TxSponsor => TypeSignature::new_option(TypeSignature::PrincipalType) - .map_err(|_| CheckErrorKind::Expects("Bad construction".into()))?, + .map_err(|_| StaticCheckErrorKind::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(|_| CheckErrorKind::Expects("Bad construction".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad construction".into()))?, NativeTrue => TypeSignature::BoolType, NativeFalse => TypeSignature::BoolType, TotalLiquidMicroSTX => TypeSignature::UIntType, @@ -1089,7 +1090,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &return_type, ) .map_err(|_| { - CheckErrorKind::ReturnTypesMustMatch( + StaticCheckErrorKind::ReturnTypesMustMatch( Box::new(expected_type), Box::new(return_type), ) @@ -1120,7 +1121,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { } Err(e) => Err(e), })? - .ok_or_else(|| CheckErrorKind::Expects("Expected a depth result".into()))?; + .ok_or_else(|| StaticCheckErrorKind::Expects("Expected a depth result".into()))?; } runtime_cost(ClarityCostFunction::AnalysisStorage, self, size)?; @@ -1197,15 +1198,16 @@ 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(CheckErrorKind::UncheckedIntermediaryResponses); + return_failure = Err(StaticCheckErrorKind::UncheckedIntermediaryResponses); } } else { last_return = Some(type_return); } } - let last_return = last_return - .ok_or_else(|| StaticCheckError::new(CheckErrorKind::CheckerImplementationFailure))?; + let last_return = last_return.ok_or_else(|| { + StaticCheckError::new(StaticCheckErrorKind::CheckerImplementationFailure) + })?; return_failure?; Ok(last_return) @@ -1268,9 +1270,13 @@ impl<'a, 'b> TypeChecker<'a, 'b> { } } if let Err(mut check_error) = check_result { - if let CheckErrorKind::IncorrectArgumentCount(expected, _actual) = *check_error.err { - check_error.err = - Box::new(CheckErrorKind::IncorrectArgumentCount(expected, args.len())); + if let StaticCheckErrorKind::IncorrectArgumentCount(expected, _actual) = + *check_error.err + { + check_error.err = Box::new(StaticCheckErrorKind::IncorrectArgumentCount( + expected, + args.len(), + )); check_error.diagnostic = Diagnostic::err(check_error.err.as_ref()); } // accumulate the checking costs @@ -1300,10 +1306,10 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result<(ClarityName, FixedFunction), StaticCheckError> { let (function_name, args) = signature .split_first() - .ok_or(CheckErrorKind::RequiresAtLeastArguments(1, 0))?; + .ok_or(StaticCheckErrorKind::RequiresAtLeastArguments(1, 0))?; let function_name = function_name .match_atom() - .ok_or(CheckErrorKind::BadFunctionName)?; + .ok_or(StaticCheckErrorKind::BadFunctionName)?; let args = parse_name_type_pairs::<(), StaticCheckError>( StacksEpochId::Epoch21, args, @@ -1312,7 +1318,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { )?; if self.function_return_tracker.is_some() { - return Err(CheckErrorKind::Expects( + return Err(StaticCheckErrorKind::Expects( "Interpreter error: Previous function define left dirty typecheck state.".into(), ) .into()); @@ -1368,7 +1374,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &return_type, ) .map_err(|_| { - CheckErrorKind::ReturnTypesMustMatch( + StaticCheckErrorKind::ReturnTypesMustMatch( Box::new(expected.clone()), Box::new(return_type), ) @@ -1408,10 +1414,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(|_| CheckErrorKind::BadMapTypeDefinition)?; + .map_err(|_| StaticCheckErrorKind::BadMapTypeDefinition)?; let value_type = TypeSignature::parse_type_repr(StacksEpochId::Epoch21, value_type, &mut ()) - .map_err(|_| CheckErrorKind::BadMapTypeDefinition)?; + .map_err(|_| StaticCheckErrorKind::BadMapTypeDefinition)?; Ok((map_name.clone(), (key_type, value_type))) } @@ -1443,19 +1449,21 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result { let (function_name, args) = expression .split_first() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::NonFunctionApplication)?; self.type_map.set_type(function_name, no_type())?; let function_name = function_name .match_atom() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::UnknownFunction(function_name.to_string())), + _ => Err(StaticCheckErrorKind::UnknownFunction( + function_name.to_string(), + )), }?; for (expected_type, found_type) in function.args.iter().map(|x| &x.signature).zip(args) @@ -1487,7 +1495,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(CheckErrorKind::UndefinedVariable(name.to_string()).into()); + return Err(StaticCheckErrorKind::UndefinedVariable(name.to_string()).into()); } runtime_cost( @@ -1499,7 +1507,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { if let Some(type_result) = context.lookup_variable_type(name) { Ok(type_result.clone()) } else { - Err(CheckErrorKind::UndefinedVariable(name.to_string()).into()) + Err(StaticCheckErrorKind::UndefinedVariable(name.to_string()).into()) } } } @@ -1518,7 +1526,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { let contract_to_check = self .db .load_contract(contract_identifier, &StacksEpochId::Epoch21)? - .ok_or(CheckErrorKind::NoSuchContract( + .ok_or(StaticCheckErrorKind::NoSuchContract( contract_identifier.to_string(), ))?; @@ -1528,13 +1536,13 @@ impl<'a, 'b> TypeChecker<'a, 'b> { &trait_identifier.contract_identifier, &StacksEpochId::Epoch21, )? - .ok_or(CheckErrorKind::NoSuchContract( + .ok_or(StaticCheckErrorKind::NoSuchContract( trait_identifier.contract_identifier.to_string(), ))?; let trait_definition = contract_defining_trait .get_defined_trait(&trait_identifier.name) - .ok_or(CheckErrorKind::NoSuchTrait( + .ok_or(StaticCheckErrorKind::NoSuchTrait( trait_identifier.contract_identifier.to_string(), trait_identifier.name.to_string(), ))?; @@ -1551,7 +1559,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: StaticCheckError = CheckErrorKind::TypeError( + let mut err: StaticCheckError = StaticCheckErrorKind::TypeError( Box::new(expected_type.clone()), Box::new(actual_type.clone()), ) @@ -1575,7 +1583,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(CheckErrorKind::UnexpectedTraitOrFieldReference.into()); + return Err(StaticCheckErrorKind::UnexpectedTraitOrFieldReference.into()); } }; @@ -1613,7 +1621,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(CheckErrorKind::UnexpectedTraitOrFieldReference.into()); + return Err(StaticCheckErrorKind::UnexpectedTraitOrFieldReference.into()); } }; @@ -1645,7 +1653,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result<(ClarityName, TypeSignature), StaticCheckError> { let expected_type = TypeSignature::parse_type_repr::<()>(StacksEpochId::Epoch21, var_type, &mut ()) - .map_err(|_e| CheckErrorKind::DefineVariableBadSignature)?; + .map_err(|_e| StaticCheckErrorKind::DefineVariableBadSignature)?; self.type_check_expects(initial, context, &expected_type)?; @@ -1673,7 +1681,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { ) -> Result<(ClarityName, TypeSignature), StaticCheckError> { let asset_type = TypeSignature::parse_type_repr::<()>(StacksEpochId::Epoch21, nft_type, &mut ()) - .map_err(|_| CheckErrorKind::DefineNFTBadSignature)?; + .map_err(|_| StaticCheckErrorKind::DefineNFTBadSignature)?; Ok((asset_name.clone(), asset_type)) } @@ -1748,9 +1756,9 @@ impl<'a, 'b> TypeChecker<'a, 'b> { .add_public_function_type(f_name, FunctionType::Fixed(f_type))?; return Ok(Some(())); } else { - return Err(CheckErrorKind::PublicFunctionMustReturnResponse(Box::new( - f_type.returns, - )) + return Err(StaticCheckErrorKind::PublicFunctionMustReturnResponse( + Box::new(f_type.returns), + ) .into()); } } @@ -1891,9 +1899,10 @@ 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( - CheckErrorKind::TraitReferenceUnknown(name.to_string()).into() - ); + return Err(StaticCheckErrorKind::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 098300af775..c00c7aaeeaf 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, CheckErrorKind, StaticCheckError}; +use crate::vm::analysis::errors::{check_argument_count, StaticCheckError, StaticCheckErrorKind}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::runtime_cost; use crate::vm::representations::SymbolicExpression; @@ -30,13 +30,15 @@ pub fn check_special_get_owner( ) -> Result { check_argument_count(2, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_asset_type = checker .contract_context .get_nft_type(asset_name) .cloned() - .ok_or_else(|| CheckErrorKind::NoSuchNFT(asset_name.to_string()))?; + .ok_or_else(|| StaticCheckErrorKind::NoSuchNFT(asset_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -58,10 +60,12 @@ pub fn check_special_get_balance( ) -> Result { check_argument_count(2, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; if !checker.contract_context.ft_exists(asset_name) { - return Err(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); + return Err(StaticCheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } runtime_cost(ClarityCostFunction::AnalysisTypeLookup, checker, 1)?; @@ -79,13 +83,15 @@ pub fn check_special_mint_asset( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; let expected_asset_type = checker .contract_context .get_nft_type(asset_name) - .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))? + .ok_or(StaticCheckErrorKind::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 +116,9 @@ pub fn check_special_mint_token( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_amount: TypeSignature = TypeSignature::UIntType; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; @@ -121,7 +129,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(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); + return Err(StaticCheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } Ok(TypeSignature::ResponseType(Box::new(( @@ -137,13 +145,15 @@ pub fn check_special_transfer_asset( ) -> Result { check_argument_count(4, args)?; - let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let token_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; let expected_asset_type = checker .contract_context .get_nft_type(token_name) - .ok_or(CheckErrorKind::NoSuchNFT(token_name.to_string()))? + .ok_or(StaticCheckErrorKind::NoSuchNFT(token_name.to_string()))? .clone(); runtime_cost( @@ -169,7 +179,9 @@ pub fn check_special_transfer_token( ) -> Result { check_argument_count(4, args)?; - let token_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let token_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_amount: TypeSignature = TypeSignature::UIntType; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; @@ -181,7 +193,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(CheckErrorKind::NoSuchFT(token_name.to_string()).into()); + return Err(StaticCheckErrorKind::NoSuchFT(token_name.to_string()).into()); } Ok(TypeSignature::ResponseType(Box::new(( @@ -225,7 +237,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(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, )); runtime_cost(ClarityCostFunction::AnalysisTypeLookup, checker, 0)?; @@ -248,10 +260,12 @@ pub fn check_special_get_token_supply( ) -> Result { check_argument_count(1, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; if !checker.contract_context.ft_exists(asset_name) { - return Err(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); + return Err(StaticCheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } runtime_cost(ClarityCostFunction::AnalysisTypeLookup, checker, 1)?; @@ -266,13 +280,15 @@ pub fn check_special_burn_asset( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; let expected_asset_type = checker .contract_context .get_nft_type(asset_name) - .ok_or(CheckErrorKind::NoSuchNFT(asset_name.to_string()))? + .ok_or(StaticCheckErrorKind::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 +313,9 @@ pub fn check_special_burn_token( ) -> Result { check_argument_count(3, args)?; - let asset_name = args[0].match_atom().ok_or(CheckErrorKind::BadTokenName)?; + let asset_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadTokenName)?; let expected_amount: TypeSignature = TypeSignature::UIntType; let expected_owner_type: TypeSignature = TypeSignature::PrincipalType; @@ -308,7 +326,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(CheckErrorKind::NoSuchFT(asset_name.to_string()).into()); + return Err(StaticCheckErrorKind::NoSuchFT(asset_name.to_string()).into()); } Ok(TypeSignature::ResponseType(Box::new(( 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 874084f16f6..3ad5fc72b59 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 @@ -1,4 +1,4 @@ -use clarity_types::errors::CheckErrorKind; +use clarity_types::errors::analysis::StaticCheckErrorKind; use clarity_types::types::{StringSubtype, MAX_TO_ASCII_BUFFER_LEN}; use stacks_common::types::StacksEpochId; @@ -62,7 +62,7 @@ pub fn check_special_to_ascii( check_argument_count(1, args)?; let input_type = checker.type_check( args.first() - .ok_or(CheckErrorKind::CheckerImplementationFailure)?, + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)?, context, )?; @@ -92,12 +92,14 @@ pub fn check_special_to_ascii( TypeSignature::TO_ASCII_BUFFER_MAX, TypeSignature::STRING_UTF8_MAX, ]; - return Err(CheckErrorKind::UnionTypeError(types, input_type.into()).into()); + return Err(StaticCheckErrorKind::UnionTypeError(types, input_type.into()).into()); } }; Ok( TypeSignature::new_response(result_type, TypeSignature::UIntType).map_err(|_| { - CheckErrorKind::Expects("FATAL: Legal Clarity response type marked invalid".into()) + StaticCheckErrorKind::Expects( + "FATAL: Legal Clarity response type marked invalid".into(), + ) })?, ) } 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 0b95c44f86c..26e44b9aea5 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, CheckErrorKind, StaticCheckError, TypeChecker, TypingContext, + check_arguments_at_least, StaticCheckError, StaticCheckErrorKind, TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost}; @@ -31,14 +31,16 @@ pub fn check_special_fetch_entry( ) -> Result { check_arguments_at_least(2, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; + let map_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::NoSuchMap(map_name.to_string()))?; + .ok_or(StaticCheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -55,7 +57,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(StaticCheckError::new(CheckErrorKind::TypeError( + Err(StaticCheckError::new(StaticCheckErrorKind::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) @@ -71,14 +73,16 @@ pub fn check_special_delete_entry( ) -> Result { check_arguments_at_least(2, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; + let map_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadMapName)?; let key_type = checker.type_check(&args[1], context)?; let (expected_key_type, _) = checker .contract_context .get_map_type(map_name) - .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; + .ok_or(StaticCheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -88,7 +92,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(StaticCheckError::new(CheckErrorKind::TypeError( + Err(StaticCheckError::new(StaticCheckErrorKind::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) @@ -104,7 +108,9 @@ fn check_set_or_insert_entry( ) -> Result { check_arguments_at_least(3, args)?; - let map_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; + let map_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::BadMapName)?; let key_type = checker.type_check(&args[1], context)?; let value_type = checker.type_check(&args[2], context)?; @@ -112,7 +118,7 @@ fn check_set_or_insert_entry( let (expected_key_type, expected_value_type) = checker .contract_context .get_map_type(map_name) - .ok_or(CheckErrorKind::NoSuchMap(map_name.to_string()))?; + .ok_or(StaticCheckErrorKind::NoSuchMap(map_name.to_string()))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -129,12 +135,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(StaticCheckError::new(CheckErrorKind::TypeError( + Err(StaticCheckError::new(StaticCheckErrorKind::TypeError( Box::new(expected_key_type.clone()), Box::new(key_type), ))) } else if !expected_value_type.admits_type(&StacksEpochId::Epoch21, &value_type)? { - Err(StaticCheckError::new(CheckErrorKind::TypeError( + Err(StaticCheckError::new(StaticCheckErrorKind::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 267be5c9cb3..2496897dac3 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::{CheckErrorKind, StaticCheckError, SyntaxBindingErrorType}; +use crate::vm::analysis::errors::{StaticCheckError, StaticCheckErrorKind, SyntaxBindingErrorType}; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost, CostErrors, CostTracker}; use crate::vm::diagnostic::DiagnosableError; @@ -70,14 +70,17 @@ fn check_special_list_cons( for arg in args.iter() { // don't use map here, since type_check has side-effects. let checked = checker.type_check(arg, context)?; - let cost = checked.type_size().and_then(|ty_size| { - checker - .compute_cost( - ClarityCostFunction::AnalysisListItemsCheck, - &[ty_size.into()], - ) - .map_err(CheckErrorKind::from) - }); + let cost = checked + .type_size() + .map_err(StaticCheckErrorKind::from) + .and_then(|ty_size| { + checker + .compute_cost( + ClarityCostFunction::AnalysisListItemsCheck, + &[ty_size.into()], + ) + .map_err(StaticCheckErrorKind::from) + }); costs.push(cost); if let Some(cur_size) = entries_size { @@ -97,7 +100,7 @@ fn check_special_list_cons( checker.add_cost(cost?)?; } if entries_size.is_none() { - return Err(CheckErrorKind::ValueTooLarge.into()); + return Err(StaticCheckErrorKind::ValueTooLarge.into()); } let typed_args = result; TypeSignature::parent_list_type(&typed_args) @@ -156,10 +159,12 @@ fn inner_handle_tuple_get( let return_type = tuple_type_sig .field_type(field_to_get) - .ok_or(StaticCheckError::new(CheckErrorKind::NoSuchTupleField( - field_to_get.to_string(), - tuple_type_sig.clone(), - )))? + .ok_or(StaticCheckError::new( + StaticCheckErrorKind::NoSuchTupleField( + field_to_get.to_string(), + tuple_type_sig.clone(), + ), + ))? .clone(); Ok(return_type) } @@ -173,7 +178,7 @@ fn check_special_get( let field_to_get = args[0] .match_atom() - .ok_or(CheckErrorKind::BadTupleFieldName)?; + .ok_or(StaticCheckErrorKind::BadTupleFieldName)?; let argument_type = checker.type_check(&args[1], context)?; @@ -185,10 +190,10 @@ fn check_special_get( let option_type = TypeSignature::new_option(inner_type)?; Ok(option_type) } else { - Err(CheckErrorKind::ExpectedTuple(value_type_sig).into()) + Err(StaticCheckErrorKind::ExpectedTuple(value_type_sig).into()) } } else { - Err(CheckErrorKind::ExpectedTuple(Box::new(argument_type)).into()) + Err(StaticCheckErrorKind::ExpectedTuple(Box::new(argument_type)).into()) } } @@ -202,13 +207,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(CheckErrorKind::ExpectedTuple(Box::new(res.clone()))), + _ => Err(StaticCheckErrorKind::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(CheckErrorKind::ExpectedTuple(Box::new(res.clone()))), + _ => Err(StaticCheckErrorKind::ExpectedTuple(Box::new(res.clone()))), }?; runtime_cost( ClarityCostFunction::AnalysisCheckTupleMerge, @@ -256,7 +261,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(CheckErrorKind::BadTupleConstruction(format!( + cons_error = Err(StaticCheckErrorKind::BadTupleConstruction(format!( "type size of {type_size} bytes exceeds maximum of {MAX_VALUE_SIZE} bytes" ))); } @@ -266,8 +271,9 @@ pub fn check_special_tuple_cons( )?; cons_error?; - let tuple_signature = TupleTypeSignature::try_from(tuple_type_data) - .map_err(|e| CheckErrorKind::BadTupleConstruction(e.message()))?; + let tuple_signature = TupleTypeSignature::try_from(tuple_type_data).map_err(|e| { + StaticCheckErrorKind::BadTupleConstruction(StaticCheckErrorKind::from(e).message()) + })?; Ok(TypeSignature::TupleType(tuple_signature)) } @@ -282,7 +288,7 @@ fn check_special_let( let binding_list = args[0] .match_list() - .ok_or(StaticCheckError::new(CheckErrorKind::BadLetSyntax))?; + .ok_or(StaticCheckError::new(StaticCheckErrorKind::BadLetSyntax))?; let mut out_context = context.extend()?; @@ -295,9 +301,9 @@ 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(StaticCheckError::new(CheckErrorKind::NameAlreadyUsed( - var_name.to_string(), - ))); + return Err(StaticCheckError::new( + StaticCheckErrorKind::NameAlreadyUsed(var_name.to_string()), + )); } let typed_result = checker.type_check(var_sexp, &out_context)?; @@ -337,14 +343,14 @@ fn check_special_fetch_var( let var_name = args[0] .match_atom() - .ok_or(StaticCheckError::new(CheckErrorKind::BadMapName))?; + .ok_or(StaticCheckError::new(StaticCheckErrorKind::BadMapName))?; let value_type = checker .contract_context .get_persisted_variable_type(var_name) - .ok_or(StaticCheckError::new(CheckErrorKind::NoSuchDataVariable( - var_name.to_string(), - )))?; + .ok_or(StaticCheckError::new( + StaticCheckErrorKind::NoSuchDataVariable(var_name.to_string()), + ))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -362,14 +368,18 @@ fn check_special_set_var( ) -> Result { check_arguments_at_least(2, args)?; - let var_name = args[0].match_atom().ok_or(CheckErrorKind::BadMapName)?; + let var_name = args[0] + .match_atom() + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::NoSuchDataVariable(var_name.to_string()))?; + .ok_or(StaticCheckErrorKind::NoSuchDataVariable( + var_name.to_string(), + ))?; runtime_cost( ClarityCostFunction::AnalysisTypeLookup, @@ -379,7 +389,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(StaticCheckError::new(CheckErrorKind::TypeError( + Err(StaticCheckError::new(StaticCheckErrorKind::TypeError( Box::new(expected_value_type.clone()), Box::new(value_type), ))) @@ -408,7 +418,9 @@ fn check_special_equals( costs.push(cost); arg_type = Some( TypeSignature::least_supertype(&StacksEpochId::Epoch21, &x_type, &cur_type) - .map_err(|_| CheckErrorKind::TypeError(Box::new(x_type), Box::new(cur_type))), + .map_err(|_| { + StaticCheckErrorKind::TypeError(Box::new(x_type), Box::new(cur_type)) + }), ); } } @@ -419,7 +431,9 @@ fn check_special_equals( // check if there was a least supertype failure. arg_type.ok_or_else(|| { - CheckErrorKind::Expects("Arg type should be set because arguments checked for >= 1".into()) + StaticCheckErrorKind::Expects( + "Arg type should be set because arguments checked for >= 1".into(), + ) })??; Ok(TypeSignature::BoolType) @@ -442,9 +456,11 @@ fn check_special_if( analysis_typecheck_cost(checker, expr1, expr2)?; TypeSignature::least_supertype(&StacksEpochId::Epoch21, expr1, expr2) + .map_err(StaticCheckErrorKind::from) .and_then(|t| t.concretize()) .map_err(|_| { - CheckErrorKind::IfArmsMustMatch(Box::new(expr1.clone()), Box::new(expr2.clone())).into() + StaticCheckErrorKind::IfArmsMustMatch(Box::new(expr1.clone()), Box::new(expr2.clone())) + .into() }) } @@ -456,7 +472,7 @@ fn check_contract_call( check_arguments_at_least(2, args)?; let func_name = args[1].match_atom().ok_or(StaticCheckError::new( - CheckErrorKind::ContractCallExpectName, + StaticCheckErrorKind::ContractCallExpectName, ))?; checker.type_map.set_type(&args[1], no_type())?; @@ -481,10 +497,12 @@ fn check_contract_call( { Ok(function) } else { - Err(StaticCheckError::new(CheckErrorKind::NoSuchPublicFunction( - contract_identifier.to_string(), - func_name.to_string(), - ))) + Err(StaticCheckError::new( + StaticCheckErrorKind::NoSuchPublicFunction( + contract_identifier.to_string(), + func_name.to_string(), + ), + )) } }?; @@ -504,7 +522,7 @@ fn check_contract_call( let trait_id = match context.lookup_trait_reference_type(trait_instance) { Some(trait_id) => trait_id, _ => { - return Err(CheckErrorKind::TraitReferenceUnknown( + return Err(StaticCheckErrorKind::TraitReferenceUnknown( trait_instance.to_string(), ) .into()); @@ -514,15 +532,14 @@ fn check_contract_call( runtime_cost(ClarityCostFunction::AnalysisLookupFunction, checker, 0)?; let trait_signature = checker.contract_context.get_trait(trait_id).ok_or( - CheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()), + StaticCheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()), + )?; + let func_signature = trait_signature.get(func_name).ok_or( + StaticCheckErrorKind::TraitMethodUnknown( + trait_id.name.to_string(), + func_name.to_string(), + ), )?; - let func_signature = - trait_signature - .get(func_name) - .ok_or(CheckErrorKind::TraitMethodUnknown( - trait_id.name.to_string(), - func_name.to_string(), - ))?; runtime_cost( ClarityCostFunction::AnalysisLookupFunctionTypes, @@ -556,10 +573,12 @@ fn check_contract_call( { Ok(function) } else { - Err(StaticCheckError::new(CheckErrorKind::NoSuchPublicFunction( - contract_identifier.to_string(), - func_name.to_string(), - ))) + Err(StaticCheckError::new( + StaticCheckErrorKind::NoSuchPublicFunction( + contract_identifier.to_string(), + func_name.to_string(), + ), + )) } }?; @@ -575,7 +594,7 @@ fn check_contract_call( } Some(var_type) => { // Any other typed constant is an error - return Err(CheckErrorKind::ExpectedCallableType(Box::new( + return Err(StaticCheckErrorKind::ExpectedCallableType(Box::new( var_type.clone(), )) .into()); @@ -585,7 +604,7 @@ fn check_contract_call( let trait_id = match context.lookup_trait_reference_type(trait_instance) { Some(trait_id) => trait_id, _ => { - return Err(CheckErrorKind::TraitReferenceUnknown( + return Err(StaticCheckErrorKind::TraitReferenceUnknown( trait_instance.to_string(), ) .into()); @@ -595,10 +614,10 @@ fn check_contract_call( runtime_cost(ClarityCostFunction::AnalysisLookupFunction, checker, 0)?; let trait_signature = checker.contract_context.get_trait(trait_id).ok_or( - CheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()), + StaticCheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()), )?; let func_signature = trait_signature.get(func_name).ok_or( - CheckErrorKind::TraitMethodUnknown( + StaticCheckErrorKind::TraitMethodUnknown( trait_id.name.to_string(), func_name.to_string(), ), @@ -617,7 +636,7 @@ fn check_contract_call( } _ => { return Err(StaticCheckError::new( - CheckErrorKind::ContractCallExpectName, + StaticCheckErrorKind::ContractCallExpectName, )) } }; @@ -641,14 +660,18 @@ fn check_contract_of( SymbolicExpressionType::Atom(trait_instance) => trait_instance, _ => { return Err(StaticCheckError::new( - CheckErrorKind::ContractOfExpectsTrait, + StaticCheckErrorKind::ContractOfExpectsTrait, )) } }; let trait_id = match context.lookup_trait_reference_type(trait_instance) { Some(trait_id) => trait_id, - _ => return Err(CheckErrorKind::TraitReferenceUnknown(trait_instance.to_string()).into()), + _ => { + return Err( + StaticCheckErrorKind::TraitReferenceUnknown(trait_instance.to_string()).into(), + ) + } }; runtime_cost(ClarityCostFunction::ContractOf, checker, 1)?; @@ -656,7 +679,7 @@ fn check_contract_of( checker .contract_context .get_trait(trait_id) - .ok_or_else(|| CheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()))?; + .ok_or_else(|| StaticCheckErrorKind::TraitReferenceUnknown(trait_id.name.to_string()))?; Ok(TypeSignature::PrincipalType) } @@ -670,7 +693,7 @@ fn check_principal_of( checker.type_check_expects(&args[0], context, &TypeSignature::BUFFER_33)?; Ok( TypeSignature::new_response(TypeSignature::PrincipalType, TypeSignature::UIntType) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, ) } @@ -702,13 +725,13 @@ fn check_principal_construct( ("error_code".into(), TypeSignature::UIntType), ( "value".into(), - TypeSignature::new_option(TypeSignature::PrincipalType).map_err(|_| CheckErrorKind::Expects("FATAL: failed to create (optional principal) type signature".into()))?, + TypeSignature::new_option(TypeSignature::PrincipalType).map_err(|_| StaticCheckErrorKind::Expects("FATAL: failed to create (optional principal) type signature".into()))?, ), ]) - .map_err(|_| CheckErrorKind::Expects("FAIL: PrincipalConstruct failed to initialize type signature".into()))? + .map_err(|_| StaticCheckErrorKind::Expects("FAIL: PrincipalConstruct failed to initialize type signature".into()))? .into() ) - .map_err(|_| CheckErrorKind::Expects("FATAL: failed to create `(response principal { error_code: uint, principal: (optional principal) })` type signature".into()))? + .map_err(|_| StaticCheckErrorKind::Expects("FATAL: failed to create `(response principal { error_code: uint, principal: (optional principal) })` type signature".into()))? ) } @@ -722,7 +745,7 @@ fn check_secp256k1_recover( checker.type_check_expects(&args[1], context, &TypeSignature::BUFFER_65)?; Ok( TypeSignature::new_response(TypeSignature::BUFFER_33, TypeSignature::UIntType) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, ) } @@ -758,13 +781,13 @@ fn check_get_block_info( check_arguments_at_least(2, args)?; let block_info_prop_str = args[0].match_atom().ok_or(StaticCheckError::new( - CheckErrorKind::GetBlockInfoExpectPropertyName, + StaticCheckErrorKind::GetBlockInfoExpectPropertyName, ))?; let block_info_prop = BlockInfoProperty::lookup_by_name_at_version(block_info_prop_str, &checker.clarity_version) .ok_or(StaticCheckError::new( - CheckErrorKind::NoSuchBlockInfoProperty(block_info_prop_str.to_string()), + StaticCheckErrorKind::NoSuchBlockInfoProperty(block_info_prop_str.to_string()), ))?; checker.type_check_expects(&args[1], context, &TypeSignature::UIntType)?; @@ -773,8 +796,8 @@ fn check_get_block_info( } // # Errors -// - `CheckErrorKind::GetBurnBlockInfoExpectPropertyName` when `args[0]` is not a valid `ClarityName`. -// - `CheckErrorKind::NoSuchBlockInfoProperty` when `args[0]` does not name a `BurnBlockInfoProperty`. +// - `StaticCheckErrorKind::GetBurnBlockInfoExpectPropertyName` when `args[0]` is not a valid `ClarityName`. +// - `StaticCheckErrorKind::NoSuchBlockInfoProperty` when `args[0]` does not name a `BurnBlockInfoProperty`. fn check_get_burn_block_info( checker: &mut TypeChecker, args: &[SymbolicExpression], @@ -783,19 +806,19 @@ fn check_get_burn_block_info( check_argument_count(2, args)?; let block_info_prop_str = args[0].match_atom().ok_or(StaticCheckError::new( - CheckErrorKind::GetBurnBlockInfoExpectPropertyName, + StaticCheckErrorKind::GetBurnBlockInfoExpectPropertyName, ))?; let block_info_prop = BurnBlockInfoProperty::lookup_by_name(block_info_prop_str).ok_or(StaticCheckError::new( - CheckErrorKind::NoSuchBlockInfoProperty(block_info_prop_str.to_string()), + StaticCheckErrorKind::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(|_| { - CheckErrorKind::Expects("FAILED to type valid burn info property".into()) + StaticCheckErrorKind::Expects("FAILED to type valid burn info property".into()) })?, )?) } @@ -808,11 +831,11 @@ fn check_get_stacks_block_info( check_argument_count(2, args)?; let block_info_prop_str = args[0].match_atom().ok_or(StaticCheckError::new( - CheckErrorKind::GetStacksBlockInfoExpectPropertyName, + StaticCheckErrorKind::GetStacksBlockInfoExpectPropertyName, ))?; let block_info_prop = StacksBlockInfoProperty::lookup_by_name(block_info_prop_str).ok_or( - StaticCheckError::new(CheckErrorKind::NoSuchStacksBlockInfoProperty( + StaticCheckError::new(StaticCheckErrorKind::NoSuchStacksBlockInfoProperty( block_info_prop_str.to_string(), )), )?; @@ -830,12 +853,12 @@ fn check_get_tenure_info( check_argument_count(2, args)?; let block_info_prop_str = args[0].match_atom().ok_or(StaticCheckError::new( - CheckErrorKind::GetTenureInfoExpectPropertyName, + StaticCheckErrorKind::GetTenureInfoExpectPropertyName, ))?; let block_info_prop = TenureInfoProperty::lookup_by_name(block_info_prop_str).ok_or(StaticCheckError::new( - CheckErrorKind::NoSuchTenureInfoProperty(block_info_prop_str.to_string()), + StaticCheckErrorKind::NoSuchTenureInfoProperty(block_info_prop_str.to_string()), ))?; checker.type_check_expects(&args[1], context, &TypeSignature::UIntType)?; @@ -865,7 +888,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 { @@ -894,7 +917,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::IntType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -905,7 +928,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::UIntType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -916,7 +939,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -927,11 +950,12 @@ impl TypedNativeFunction { Simple(SimpleNativeFunction(FunctionType::Fixed(FixedFunction { args: vec![FunctionArg::new( TypeSignature::SequenceType(SequenceSubtype::BufferType( - BufferLength::try_from(16_u32) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + BufferLength::try_from(16_u32).map_err(|_| { + StaticCheckErrorKind::Expects("Bad constructor".into()) + })?, )), ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -943,11 +967,12 @@ impl TypedNativeFunction { Simple(SimpleNativeFunction(FunctionType::Fixed(FixedFunction { args: vec![FunctionArg::new( TypeSignature::SequenceType(SequenceSubtype::BufferType( - BufferLength::try_from(16_u32) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + BufferLength::try_from(16_u32).map_err(|_| { + StaticCheckErrorKind::Expects("Bad constructor".into()) + })?, )), ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -983,7 +1008,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::BoolType, ClarityName::try_from("value".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1036,7 +1061,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("owner".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1048,7 +1073,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("principal".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1056,7 +1081,8 @@ 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(), TypeSignature::BUFFER_1), ("hash-bytes".into(), TypeSignature::BUFFER_20), @@ -1065,11 +1091,13 @@ impl TypedNativeFunction { TypeSignature::new_option( TypeSignature::CONTRACT_NAME_STRING_ASCII_MAX, ) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| { + StaticCheckErrorKind::Expects("Bad constructor".into()) + })?, ), ]) .map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: PrincipalDestruct failed to initialize type signature" .into(), ) @@ -1085,7 +1113,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("owner".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1096,7 +1124,7 @@ impl TypedNativeFunction { ("unlock-height".into(), TypeSignature::UIntType), ]) .map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: StxGetAccount failed to initialize type signature".into(), ) })? @@ -1107,7 +1135,7 @@ impl TypedNativeFunction { FunctionArg::new( TypeSignature::UIntType, ClarityName::try_from("amount".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1115,7 +1143,7 @@ impl TypedNativeFunction { FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("sender".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1125,7 +1153,7 @@ impl TypedNativeFunction { TypeSignature::BoolType, TypeSignature::UIntType, ) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, }))), StxTransfer => Special(SpecialNativeFunction(&assets::check_special_stx_transfer)), StxTransferMemo => Special(SpecialNativeFunction( @@ -1208,7 +1236,7 @@ impl TypedNativeFunction { args: vec![FunctionArg::new( TypeSignature::PrincipalType, ClarityName::try_from("contract".to_owned()).map_err(|_| { - CheckErrorKind::Expects( + StaticCheckErrorKind::Expects( "FAIL: ClarityName failed to accept default arg name".into(), ) })?, @@ -1217,7 +1245,7 @@ impl TypedNativeFunction { TypeSignature::BUFFER_32, TypeSignature::UIntType, ) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, }))), ToAscii => Special(SpecialNativeFunction(&conversions::check_special_to_ascii)), RestrictAssets => Special(SpecialNativeFunction( 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 b4f01b196c7..57406396d71 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,8 +19,8 @@ use clarity_types::types::TypeSignature; use stacks_common::types::StacksEpochId; use super::{ - check_argument_count, check_arguments_at_least, no_type, CheckErrorKind, StaticCheckError, - TypeChecker, + check_argument_count, check_arguments_at_least, no_type, StaticCheckError, + StaticCheckErrorKind, TypeChecker, }; use crate::vm::analysis::type_checker::contexts::TypingContext; use crate::vm::costs::cost_functions::ClarityCostFunction; @@ -83,7 +83,7 @@ pub fn check_special_is_response( if let TypeSignature::ResponseType(_types) = input { Ok(TypeSignature::BoolType) } else { - Err(CheckErrorKind::ExpectedResponseType(Box::new(input.clone())).into()) + Err(StaticCheckErrorKind::ExpectedResponseType(Box::new(input.clone())).into()) } } @@ -101,7 +101,7 @@ pub fn check_special_is_optional( if let TypeSignature::OptionalType(_type) = input { Ok(TypeSignature::BoolType) } else { - Err(CheckErrorKind::ExpectedOptionalType(Box::new(input.clone())).into()) + Err(StaticCheckErrorKind::ExpectedOptionalType(Box::new(input.clone())).into()) } } @@ -121,12 +121,15 @@ pub fn check_special_default_to( let contained_type = *input_type; TypeSignature::least_supertype(&StacksEpochId::Epoch21, &default, &contained_type).map_err( |_| { - CheckErrorKind::DefaultTypesMustMatch(Box::new(default), Box::new(contained_type)) - .into() + StaticCheckErrorKind::DefaultTypesMustMatch( + Box::new(default), + Box::new(contained_type), + ) + .into() }, ) } else { - Err(CheckErrorKind::ExpectedOptionalType(Box::new(input)).into()) + Err(StaticCheckErrorKind::ExpectedOptionalType(Box::new(input)).into()) } } @@ -154,7 +157,7 @@ fn inner_unwrap( match input { TypeSignature::OptionalType(input_type) => { if input_type.is_no_type() { - Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) + Err(StaticCheckErrorKind::CouldNotDetermineResponseOkType.into()) } else { Ok(*input_type) } @@ -162,12 +165,12 @@ fn inner_unwrap( TypeSignature::ResponseType(response_type) => { let ok_type = response_type.0; if ok_type.is_no_type() { - Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) + Err(StaticCheckErrorKind::CouldNotDetermineResponseOkType.into()) } else { Ok(ok_type) } } - _ => Err(CheckErrorKind::ExpectedOptionalOrResponseType(Box::new(input)).into()), + _ => Err(StaticCheckErrorKind::ExpectedOptionalOrResponseType(Box::new(input)).into()), } } @@ -180,12 +183,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(CheckErrorKind::CouldNotDetermineResponseErrType.into()) + Err(StaticCheckErrorKind::CouldNotDetermineResponseErrType.into()) } else { Ok(err_type) } } else { - Err(CheckErrorKind::ExpectedResponseType(Box::new(input)).into()) + Err(StaticCheckErrorKind::ExpectedResponseType(Box::new(input)).into()) } } @@ -233,7 +236,7 @@ pub fn check_special_try_ret( match input { TypeSignature::OptionalType(input_type) => { if input_type.is_no_type() { - Err(CheckErrorKind::CouldNotDetermineResponseOkType.into()) + Err(StaticCheckErrorKind::CouldNotDetermineResponseOkType.into()) } else { checker.track_return_type(TypeSignature::new_option(TypeSignature::NoType)?)?; Ok(*input_type) @@ -242,9 +245,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(CheckErrorKind::CouldNotDetermineResponseOkType.into()) + Err(StaticCheckErrorKind::CouldNotDetermineResponseOkType.into()) } else if err_type.is_no_type() { - Err(CheckErrorKind::CouldNotDetermineResponseErrType.into()) + Err(StaticCheckErrorKind::CouldNotDetermineResponseErrType.into()) } else { checker.track_return_type(TypeSignature::new_response( TypeSignature::NoType, @@ -253,7 +256,7 @@ pub fn check_special_try_ret( Ok(ok_type) } } - _ => Err(CheckErrorKind::ExpectedOptionalOrResponseType(Box::new(input)).into()), + _ => Err(StaticCheckErrorKind::ExpectedOptionalOrResponseType(Box::new(input)).into()), } } @@ -306,7 +309,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(CheckErrorKind::NameAlreadyUsed(bind_name.into()).into()); + return Err(StaticCheckErrorKind::NameAlreadyUsed(bind_name.into()).into()); } inner_context.add_variable_type(bind_name, bind_type, checker.clarity_version); @@ -325,22 +328,22 @@ fn check_special_match_opt( context: &TypingContext, ) -> Result { if args.len() != 3 { - Err(CheckErrorKind::BadMatchOptionSyntax(Box::new( - CheckErrorKind::IncorrectArgumentCount(4, args.len() + 1), + Err(StaticCheckErrorKind::BadMatchOptionSyntax(Box::new( + StaticCheckErrorKind::IncorrectArgumentCount(4, args.len() + 1), )))?; } let bind_name = args[0] .match_atom() .ok_or_else(|| { - CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::ExpectedName)) + StaticCheckErrorKind::BadMatchOptionSyntax(Box::new(StaticCheckErrorKind::ExpectedName)) })? .clone(); let some_branch = &args[1]; let none_branch = &args[2]; if option_type.is_no_type() { - return Err(CheckErrorKind::CouldNotDetermineMatchTypes.into()); + return Err(StaticCheckErrorKind::CouldNotDetermineMatchTypes.into()); } let some_branch_type = @@ -355,8 +358,11 @@ fn check_special_match_opt( &none_branch_type, ) .map_err(|_| { - CheckErrorKind::MatchArmsMustMatch(Box::new(some_branch_type), Box::new(none_branch_type)) - .into() + StaticCheckErrorKind::MatchArmsMustMatch( + Box::new(some_branch_type), + Box::new(none_branch_type), + ) + .into() }) } @@ -367,22 +373,26 @@ fn check_special_match_resp( context: &TypingContext, ) -> Result { if args.len() != 4 { - Err(CheckErrorKind::BadMatchResponseSyntax(Box::new( - CheckErrorKind::IncorrectArgumentCount(5, args.len() + 1), + Err(StaticCheckErrorKind::BadMatchResponseSyntax(Box::new( + StaticCheckErrorKind::IncorrectArgumentCount(5, args.len() + 1), )))?; } let ok_bind_name = args[0] .match_atom() .ok_or_else(|| { - CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)) + StaticCheckErrorKind::BadMatchResponseSyntax(Box::new( + StaticCheckErrorKind::ExpectedName, + )) })? .clone(); let ok_branch = &args[1]; let err_bind_name = args[2] .match_atom() .ok_or_else(|| { - CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)) + StaticCheckErrorKind::BadMatchResponseSyntax(Box::new( + StaticCheckErrorKind::ExpectedName, + )) })? .clone(); let err_branch = &args[3]; @@ -390,7 +400,7 @@ fn check_special_match_resp( let (ok_type, err_type) = resp_type; if ok_type.is_no_type() || err_type.is_no_type() { - return Err(CheckErrorKind::CouldNotDetermineMatchTypes.into()); + return Err(StaticCheckErrorKind::CouldNotDetermineMatchTypes.into()); } let ok_branch_type = eval_with_new_binding(ok_branch, ok_bind_name, ok_type, checker, context)?; @@ -401,8 +411,11 @@ fn check_special_match_resp( TypeSignature::least_supertype(&StacksEpochId::Epoch21, &ok_branch_type, &err_branch_type) .map_err(|_| { - CheckErrorKind::MatchArmsMustMatch(Box::new(ok_branch_type), Box::new(err_branch_type)) - .into() + StaticCheckErrorKind::MatchArmsMustMatch( + Box::new(ok_branch_type), + Box::new(err_branch_type), + ) + .into() }) } @@ -422,6 +435,6 @@ pub fn check_special_match( TypeSignature::ResponseType(resp_type) => { check_special_match_resp(*resp_type, checker, &args[1..], context) } - _ => Err(CheckErrorKind::BadMatchInput(Box::new(input)).into()), + _ => Err(StaticCheckErrorKind::BadMatchInput(Box::new(input)).into()), } } diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/post_conditions.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/post_conditions.rs index dc862545adb..4288820fd62 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/post_conditions.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/post_conditions.rs @@ -13,8 +13,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use clarity_types::errors::analysis::{check_argument_count, check_arguments_at_least}; -use clarity_types::errors::{CheckErrorKind, StaticCheckError}; +use clarity_types::errors::analysis::{ + check_argument_count, check_arguments_at_least, StaticCheckErrorKind, +}; +use clarity_types::errors::StaticCheckError; use clarity_types::representations::SymbolicExpression; use clarity_types::types::{SequenceSubtype, TypeSignature}; @@ -40,21 +42,23 @@ pub fn check_restrict_assets( let asset_owner = args .first() - .ok_or(CheckErrorKind::CheckerImplementationFailure)?; + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)?; let allowance_list = args .get(1) - .ok_or(CheckErrorKind::CheckerImplementationFailure)? + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)? .match_list() - .ok_or(CheckErrorKind::ExpectedListOfAllowances( + .ok_or(StaticCheckErrorKind::ExpectedListOfAllowances( "restrict-assets?".into(), 2, ))?; let body_exprs = args .get(2..) - .ok_or(CheckErrorKind::CheckerImplementationFailure)?; + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)?; if allowance_list.len() > MAX_ALLOWANCES { - return Err(CheckErrorKind::TooManyAllowances(MAX_ALLOWANCES, allowance_list.len()).into()); + return Err( + StaticCheckErrorKind::TooManyAllowances(MAX_ALLOWANCES, allowance_list.len()).into(), + ); } runtime_cost( @@ -67,7 +71,7 @@ pub fn check_restrict_assets( for allowance in allowance_list { if check_allowance(checker, allowance, context)? { - return Err(CheckErrorKind::WithAllAllowanceNotAllowed.into()); + return Err(StaticCheckErrorKind::WithAllAllowanceNotAllowed.into()); } } @@ -76,12 +80,12 @@ pub fn check_restrict_assets( for expr in body_exprs { let type_return = checker.type_check(expr, context)?; if type_return.is_response_type() { - return Err(CheckErrorKind::UncheckedIntermediaryResponses.into()); + return Err(StaticCheckErrorKind::UncheckedIntermediaryResponses.into()); } last_return = Some(type_return); } - let ok_type = last_return.ok_or_else(|| CheckErrorKind::CheckerImplementationFailure)?; + let ok_type = last_return.ok_or_else(|| StaticCheckErrorKind::CheckerImplementationFailure)?; Ok(TypeSignature::new_response( ok_type, TypeSignature::UIntType, @@ -97,18 +101,20 @@ pub fn check_as_contract( let allowance_list = args .first() - .ok_or(CheckErrorKind::CheckerImplementationFailure)? + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)? .match_list() - .ok_or(CheckErrorKind::ExpectedListOfAllowances( + .ok_or(StaticCheckErrorKind::ExpectedListOfAllowances( "as-contract?".into(), 1, ))?; let body_exprs = args .get(1..) - .ok_or(CheckErrorKind::CheckerImplementationFailure)?; + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)?; if allowance_list.len() > MAX_ALLOWANCES { - return Err(CheckErrorKind::TooManyAllowances(MAX_ALLOWANCES, allowance_list.len()).into()); + return Err( + StaticCheckErrorKind::TooManyAllowances(MAX_ALLOWANCES, allowance_list.len()).into(), + ); } runtime_cost( @@ -119,7 +125,7 @@ pub fn check_as_contract( for allowance in allowance_list { if check_allowance(checker, allowance, context)? && allowance_list.len() > 1 { - return Err(CheckErrorKind::WithAllAllowanceNotAlone.into()); + return Err(StaticCheckErrorKind::WithAllAllowanceNotAlone.into()); } } @@ -128,12 +134,12 @@ pub fn check_as_contract( for expr in body_exprs { let type_return = checker.type_check(expr, context)?; if type_return.is_response_type() { - return Err(CheckErrorKind::UncheckedIntermediaryResponses.into()); + return Err(StaticCheckErrorKind::UncheckedIntermediaryResponses.into()); } last_return = Some(type_return); } - let ok_type = last_return.ok_or_else(|| CheckErrorKind::CheckerImplementationFailure)?; + let ok_type = last_return.ok_or_else(|| StaticCheckErrorKind::CheckerImplementationFailure)?; Ok(TypeSignature::new_response( ok_type, TypeSignature::UIntType, @@ -148,7 +154,7 @@ pub fn check_allowance_err( _args: &[SymbolicExpression], _context: &TypingContext, ) -> Result { - Err(CheckErrorKind::AllowanceExprNotAllowed.into()) + Err(StaticCheckErrorKind::AllowanceExprNotAllowed.into()) } /// Type check an allowance expression, returning whether it is a @@ -160,17 +166,17 @@ pub fn check_allowance( ) -> Result { let list = allowance .match_list() - .ok_or(CheckErrorKind::ExpectedListApplication)?; + .ok_or(StaticCheckErrorKind::ExpectedListApplication)?; let (allowance_fn, args) = list .split_first() - .ok_or(CheckErrorKind::ExpectedListApplication)?; + .ok_or(StaticCheckErrorKind::ExpectedListApplication)?; let function_name = allowance_fn .match_atom() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::NonFunctionApplication)?; let Some(ref native_function) = NativeFunctions::lookup_by_name_at_version(function_name, &checker.clarity_version) else { - return Err(CheckErrorKind::ExpectedAllowanceExpr(function_name.to_string()).into()); + return Err(StaticCheckErrorKind::ExpectedAllowanceExpr(function_name.to_string()).into()); }; match native_function { @@ -181,7 +187,7 @@ pub fn check_allowance( check_allowance_with_stacking(checker, args, context) } NativeFunctions::AllowanceAll => check_allowance_all(checker, args, context), - _ => Err(CheckErrorKind::ExpectedAllowanceExpr(function_name.to_string()).into()), + _ => Err(StaticCheckErrorKind::ExpectedAllowanceExpr(function_name.to_string()).into()), } } @@ -196,7 +202,7 @@ fn check_allowance_with_stx( checker.type_check_expects( args.first() - .ok_or(CheckErrorKind::CheckerImplementationFailure)?, + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)?, context, &TypeSignature::UIntType, )?; @@ -215,19 +221,19 @@ fn check_allowance_with_ft( checker.type_check_expects( args.first() - .ok_or(CheckErrorKind::CheckerImplementationFailure)?, + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)?, context, &TypeSignature::PrincipalType, )?; checker.type_check_expects( args.get(1) - .ok_or(CheckErrorKind::CheckerImplementationFailure)?, + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)?, context, &TypeSignature::STRING_ASCII_128, )?; checker.type_check_expects( args.get(2) - .ok_or(CheckErrorKind::CheckerImplementationFailure)?, + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)?, context, &TypeSignature::UIntType, )?; @@ -246,13 +252,13 @@ fn check_allowance_with_nft( checker.type_check_expects( args.first() - .ok_or(CheckErrorKind::CheckerImplementationFailure)?, + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)?, context, &TypeSignature::PrincipalType, )?; checker.type_check_expects( args.get(1) - .ok_or(CheckErrorKind::CheckerImplementationFailure)?, + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)?, context, &TypeSignature::STRING_ASCII_128, )?; @@ -260,14 +266,14 @@ fn check_allowance_with_nft( // Asset identifiers must be a Clarity list with any type of elements let id_list_ty = checker.type_check( args.get(2) - .ok_or(CheckErrorKind::CheckerImplementationFailure)?, + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)?, context, )?; let TypeSignature::SequenceType(SequenceSubtype::ListType(list_data)) = id_list_ty else { - return Err(CheckErrorKind::WithNftExpectedListOfIdentifiers.into()); + return Err(StaticCheckErrorKind::WithNftExpectedListOfIdentifiers.into()); }; if list_data.get_max_len() > MAX_NFT_IDENTIFIERS { - return Err(CheckErrorKind::MaxIdentifierLengthExceeded( + return Err(StaticCheckErrorKind::MaxIdentifierLengthExceeded( MAX_NFT_IDENTIFIERS, list_data.get_max_len(), ) @@ -288,7 +294,7 @@ fn check_allowance_with_stacking( checker.type_check_expects( args.first() - .ok_or(CheckErrorKind::CheckerImplementationFailure)?, + .ok_or(StaticCheckErrorKind::CheckerImplementationFailure)?, context, &TypeSignature::UIntType, )?; 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 c2e162dae25..ab81b4a5d22 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,8 +18,8 @@ use stacks_common::types::StacksEpochId; use super::{SimpleNativeFunction, TypedNativeFunction}; use crate::vm::analysis::type_checker::v2_1::{ - check_argument_count, check_arguments_at_least, CheckErrorKind, StaticCheckError, TypeChecker, - TypingContext, + check_argument_count, check_arguments_at_least, StaticCheckError, StaticCheckErrorKind, + TypeChecker, TypingContext, }; use crate::vm::costs::cost_functions::ClarityCostFunction; use crate::vm::costs::{analysis_typecheck_cost, runtime_cost, CostTracker}; @@ -44,14 +44,15 @@ fn get_simple_native_or_user_define( { Ok(function_type) } else { - Err( - CheckErrorKind::IllegalOrUnknownFunctionApplication(function_name.to_string()) - .into(), + Err(StaticCheckErrorKind::IllegalOrUnknownFunctionApplication( + function_name.to_string(), ) + .into()) } } else { checker.get_function_type(function_name).ok_or( - CheckErrorKind::IllegalOrUnknownFunctionApplication(function_name.to_string()).into(), + StaticCheckErrorKind::IllegalOrUnknownFunctionApplication(function_name.to_string()) + .into(), ) } } @@ -65,7 +66,7 @@ pub fn check_special_map( let function_name = args[0] .match_atom() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::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)?; @@ -107,7 +108,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(CheckErrorKind::ExpectedSequence(Box::new(argument_type)).into()); + return Err(StaticCheckErrorKind::ExpectedSequence(Box::new(argument_type)).into()); } }; @@ -137,8 +138,8 @@ pub fn check_special_map( } if let Err(mut check_error) = check_result { - if let CheckErrorKind::IncorrectArgumentCount(expected, _actual) = *check_error.err { - check_error.err = Box::new(CheckErrorKind::IncorrectArgumentCount( + if let StaticCheckErrorKind::IncorrectArgumentCount(expected, _actual) = *check_error.err { + check_error.err = Box::new(StaticCheckErrorKind::IncorrectArgumentCount( expected, args.len().saturating_sub(1), )); @@ -159,7 +160,7 @@ pub fn check_special_map( context.clarity_version, )?; TypeSignature::list_of(mapped_type, min_args) - .map_err(|_| CheckErrorKind::ConstructedListTooLarge.into()) + .map_err(|_| StaticCheckErrorKind::ConstructedListTooLarge.into()) } pub fn check_special_filter( @@ -171,7 +172,7 @@ pub fn check_special_filter( let function_name = args[0] .match_atom() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::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)?; @@ -182,7 +183,7 @@ pub fn check_special_filter( { let input_type = match argument_type { TypeSignature::SequenceType(ref sequence_type) => Ok(sequence_type.unit_type()), - _ => Err(CheckErrorKind::ExpectedSequence(Box::new( + _ => Err(StaticCheckErrorKind::ExpectedSequence(Box::new( argument_type.clone(), ))), }?; @@ -195,7 +196,7 @@ pub fn check_special_filter( )?; if TypeSignature::BoolType != filter_type { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BoolType), Box::new(filter_type), ) @@ -215,7 +216,7 @@ pub fn check_special_fold( let function_name = args[0] .match_atom() - .ok_or(CheckErrorKind::NonFunctionApplication)?; + .ok_or(StaticCheckErrorKind::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)?; @@ -225,7 +226,9 @@ pub fn check_special_fold( let input_type = match argument_type { TypeSignature::SequenceType(sequence_type) => Ok(sequence_type.unit_type()), - _ => Err(CheckErrorKind::ExpectedSequence(Box::new(argument_type))), + _ => Err(StaticCheckErrorKind::ExpectedSequence(Box::new( + argument_type, + ))), }?; let initial_value_type = checker.type_check(&args[2], context)?; @@ -283,29 +286,29 @@ pub fn check_special_concat( )?; let new_len = lhs_max_len .checked_add(rhs_max_len) - .ok_or(CheckErrorKind::MaxLengthOverflow)?; + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::MaxLengthOverflow)?; + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::MaxLengthOverflow)?; + .ok_or(StaticCheckErrorKind::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(CheckErrorKind::MaxLengthOverflow)?; + .ok_or(StaticCheckErrorKind::MaxLengthOverflow)?; TypeSignature::SequenceType(StringType(UTF8(size.try_into()?))) } (_, _) => { - return Err(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(lhs_type.clone()), Box::new(rhs_type.clone()), ) @@ -313,7 +316,7 @@ pub fn check_special_concat( } } } - _ => return Err(CheckErrorKind::ExpectedSequence(Box::new(lhs_type.clone())).into()), + _ => return Err(StaticCheckErrorKind::ExpectedSequence(Box::new(lhs_type.clone())).into()), }; Ok(res) } @@ -342,11 +345,11 @@ pub fn check_special_append( )?; let new_len = lhs_max_len .checked_add(1) - .ok_or(CheckErrorKind::MaxLengthOverflow)?; + .ok_or(StaticCheckErrorKind::MaxLengthOverflow)?; let return_type = TypeSignature::list_of(list_entry_type, new_len)?; Ok(return_type) } - _ => Err(CheckErrorKind::ExpectedListApplication.into()), + _ => Err(StaticCheckErrorKind::ExpectedListApplication.into()), } } @@ -361,7 +364,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(CheckErrorKind::TypeError( + return Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(expected_len_type), ) @@ -378,7 +381,7 @@ pub fn check_special_as_max_len( .set_type(&args[1], TypeSignature::UIntType)?; let expected_len = - u32::try_from(expected_len).map_err(|_e| CheckErrorKind::MaxLengthOverflow)?; + u32::try_from(expected_len).map_err(|_e| StaticCheckErrorKind::MaxLengthOverflow)?; let sequence = checker.type_check(&args[0], context)?; runtime_cost(ClarityCostFunction::AnalysisIterableFunc, checker, 0)?; @@ -404,7 +407,7 @@ pub fn check_special_as_max_len( StringUTF8Length::try_from(expected_len)?, )))), )), - _ => Err(CheckErrorKind::ExpectedSequence(Box::new(sequence)).into()), + _ => Err(StaticCheckErrorKind::ExpectedSequence(Box::new(sequence)).into()), } } @@ -420,7 +423,9 @@ pub fn check_special_len( match collection_type { TypeSignature::SequenceType(_) => Ok(()), - _ => Err(CheckErrorKind::ExpectedSequence(Box::new(collection_type))), + _ => Err(StaticCheckErrorKind::ExpectedSequence(Box::new( + collection_type, + ))), }?; Ok(TypeSignature::UIntType) @@ -449,16 +454,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(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, )))), )), TypeSignature::SequenceType(StringType(UTF8(_))) => Ok(TypeSignature::OptionalType( Box::new(TypeSignature::SequenceType(StringType(UTF8( StringUTF8Length::try_from(1u32) - .map_err(|_| CheckErrorKind::Expects("Bad constructor".into()))?, + .map_err(|_| StaticCheckErrorKind::Expects("Bad constructor".into()))?, )))), )), - _ => Err(CheckErrorKind::ExpectedSequence(Box::new(collection_type)).into()), + _ => Err(StaticCheckErrorKind::ExpectedSequence(Box::new(collection_type)).into()), } } @@ -474,7 +479,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(CheckErrorKind::ExpectedSequence(Box::new(list_type))), + _ => Err(StaticCheckErrorKind::ExpectedSequence(Box::new(list_type))), }?; checker.type_check_expects(&args[1], context, &expected_input_type)?; @@ -497,7 +502,7 @@ pub fn check_special_slice( TypeSignature::SequenceType(seq) => { TypeSignature::new_option(TypeSignature::SequenceType(seq))? } - _ => return Err(CheckErrorKind::ExpectedSequence(Box::new(seq_type)).into()), + _ => return Err(StaticCheckErrorKind::ExpectedSequence(Box::new(seq_type)).into()), }; // Check left position argument @@ -521,7 +526,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(CheckErrorKind::ExpectedSequence(Box::new(input_type)).into()), + _ => return Err(StaticCheckErrorKind::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 cd2c5620c04..e8a4eeadaac 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::CheckErrorKind; +use crate::vm::analysis::errors::StaticCheckErrorKind; 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 = [ - CheckErrorKind::NoSuchFT("stackoos".to_string()), - CheckErrorKind::BadTokenName, - CheckErrorKind::BadTokenName, - CheckErrorKind::TypeError( + StaticCheckErrorKind::NoSuchFT("stackoos".to_string()), + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::IntType), ), - CheckErrorKind::BadTokenName, - CheckErrorKind::NoSuchNFT("stackoos".to_string()), - CheckErrorKind::TypeError( + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::NoSuchNFT("stackoos".to_string()), + StaticCheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(string_ascii_type(15)), ), - CheckErrorKind::BadTokenName, - CheckErrorKind::NoSuchNFT("stackoos".to_string()), - CheckErrorKind::TypeError( + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::NoSuchNFT("stackoos".to_string()), + StaticCheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(string_ascii_type(15)), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::NoSuchFT("stackoos".to_string()), - CheckErrorKind::BadTokenName, - CheckErrorKind::TypeError( + StaticCheckErrorKind::NoSuchFT("stackoos".to_string()), + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::BoolType), ), - CheckErrorKind::BadTokenName, - CheckErrorKind::NoSuchNFT("stackoos".to_string()), - CheckErrorKind::TypeError( + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::NoSuchNFT("stackoos".to_string()), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::BadTokenName, - CheckErrorKind::TypeError( + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::TypeError( Box::new(string_ascii_type(10)), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::NoSuchFT("stackoos".to_string()), - CheckErrorKind::BadTokenName, - CheckErrorKind::TypeError( + StaticCheckErrorKind::NoSuchFT("stackoos".to_string()), + StaticCheckErrorKind::BadTokenName, + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::BoolType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::BoolType), ), - CheckErrorKind::DefineNFTBadSignature, - CheckErrorKind::TypeError( + StaticCheckErrorKind::DefineNFTBadSignature, + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrorKind::NoSuchFT("stackoos".to_string()), - CheckErrorKind::NoSuchFT("stackoos".to_string()), - CheckErrorKind::TypeError( + StaticCheckErrorKind::NoSuchFT("stackoos".to_string()), + StaticCheckErrorKind::NoSuchFT("stackoos".to_string()), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::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 2b09b450d3f..8ce09650793 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,11 +21,10 @@ use serde_json; use stacks_common::types::StacksEpochId; use crate::vm::analysis::contract_interface_builder::build_contract_interface; -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, ContractAnalysis, - StaticCheckError, + StaticCheckError, StaticCheckErrorKind, }; use crate::vm::ast::parse; use crate::vm::costs::LimitedCostTracker; @@ -494,7 +493,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, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*err.err, StaticCheckErrorKind::TypeError(_, _))); } #[test] @@ -535,12 +534,12 @@ fn test_bad_map_usage() { for contract in tests.iter() { let err = mem_type_check(contract).unwrap_err(); - assert!(matches!(*err.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*err.err, StaticCheckErrorKind::TypeError(_, _))); } assert!(matches!( *mem_type_check(unhandled_option).unwrap_err().err, - CheckErrorKind::UnionTypeError(_, _) + StaticCheckErrorKind::UnionTypeError(_, _) )); } @@ -629,7 +628,7 @@ fn test_expects() { eprintln!("unmatched_return_types returned check error: {err}"); assert!(matches!( *err.err, - CheckErrorKind::ReturnTypesMustMatch(_, _) + StaticCheckErrorKind::ReturnTypesMustMatch(_, _) )); } @@ -637,21 +636,21 @@ fn test_expects() { eprintln!("bad_default_types returned check error: {err}"); assert!(matches!( *err.err, - CheckErrorKind::DefaultTypesMustMatch(_, _) + StaticCheckErrorKind::DefaultTypesMustMatch(_, _) )); let err = mem_type_check(notype_response_type).unwrap_err(); eprintln!("notype_response_type returned check error: {err}"); assert!(matches!( *err.err, - CheckErrorKind::CouldNotDetermineResponseErrType + StaticCheckErrorKind::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, - CheckErrorKind::CouldNotDetermineResponseOkType + StaticCheckErrorKind::CouldNotDetermineResponseOkType )); } @@ -687,7 +686,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 { - CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { + StaticCheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -714,7 +713,7 @@ fn test_bad_principal_to_trait() { let err = mem_type_check(bad_principal_to_trait).unwrap_err(); match *err.err { - CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { + StaticCheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::PrincipalType, @@ -727,7 +726,7 @@ fn test_bad_principal_to_trait() { }; let err = mem_type_check_v1(bad_principal_to_trait).unwrap_err(); match *err.err { - CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { + StaticCheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::PrincipalType, @@ -756,7 +755,7 @@ fn test_bad_other_trait() { let err = mem_type_check(bad_other_trait).unwrap_err(); match *err.err { - CheckErrorKind::IncompatibleTrait(expected, actual) => { + StaticCheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-2"); assert_eq!(actual.name.as_str(), "trait-1"); } @@ -764,7 +763,7 @@ fn test_bad_other_trait() { }; let err = mem_type_check_v1(bad_other_trait).unwrap_err(); match *err.err { - CheckErrorKind::TypeError(expected, actual) => match (&*expected, &*actual) { + StaticCheckErrorKind::TypeError(expected, actual) => match (&*expected, &*actual) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -797,7 +796,7 @@ fn test_embedded_trait() { mem_type_check(embedded_trait).unwrap(); let err = mem_type_check_v1(embedded_trait).unwrap_err(); match *err.err { - CheckErrorKind::TraitReferenceUnknown(name) => { + StaticCheckErrorKind::TraitReferenceUnknown(name) => { assert_eq!(name.as_str(), "contract"); } _ => panic!("Unexpected error: {err:?}"), @@ -827,7 +826,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 { - CheckErrorKind::TraitReferenceUnknown(name) => { + StaticCheckErrorKind::TraitReferenceUnknown(name) => { assert_eq!(name.as_str(), "contract"); } _ => panic!("Unexpected error: {err:?}"), @@ -860,7 +859,7 @@ fn test_bad_embedded_trait() { let err = mem_type_check(bad_embedded_trait).unwrap_err(); match *err.err { - CheckErrorKind::IncompatibleTrait(expected, actual) => { + StaticCheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-12"); assert_eq!(actual.name.as_str(), "trait-1"); } @@ -868,7 +867,7 @@ fn test_bad_embedded_trait() { }; let err = mem_type_check_v1(bad_embedded_trait).unwrap_err(); match *err.err { - CheckErrorKind::TraitReferenceUnknown(name) => { + StaticCheckErrorKind::TraitReferenceUnknown(name) => { assert_eq!(name.as_str(), "contract"); } _ => panic!("Unexpected error: {err:?}"), @@ -890,7 +889,7 @@ fn test_let_trait() { mem_type_check(let_trait).unwrap(); let err = mem_type_check_v1(let_trait).unwrap_err(); match *err.err { - CheckErrorKind::TraitReferenceUnknown(name) => { + StaticCheckErrorKind::TraitReferenceUnknown(name) => { assert_eq!(name.as_str(), "t1"); } _ => panic!("Unexpected error: {err:?}"), @@ -916,7 +915,7 @@ fn test_let3_trait() { mem_type_check(let3_trait).unwrap(); let err = mem_type_check_v1(let3_trait).unwrap_err(); match *err.err { - CheckErrorKind::TraitReferenceUnknown(name) => { + StaticCheckErrorKind::TraitReferenceUnknown(name) => { assert_eq!(name.as_str(), "t3"); } _ => panic!("Unexpected error: {err:?}"), @@ -971,7 +970,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 { - CheckErrorKind::TraitReferenceUnknown(name) => { + StaticCheckErrorKind::TraitReferenceUnknown(name) => { assert_eq!(name.as_str(), "t4"); } _ => panic!("Unexpected error: {err:?}"), @@ -995,7 +994,7 @@ fn test_trait_args_differ() { let err = mem_type_check(trait_args_differ).unwrap_err(); match *err.err { - CheckErrorKind::IncompatibleTrait(expected, actual) => { + StaticCheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-2"); assert_eq!(actual.name.as_str(), "trait-1"); } @@ -1003,7 +1002,7 @@ fn test_trait_args_differ() { }; let err = mem_type_check_v1(trait_args_differ).unwrap_err(); match *err.err { - CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { + StaticCheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1033,7 +1032,7 @@ fn test_trait_arg_counts_differ1() { let err = mem_type_check(trait_to_compatible_trait).unwrap_err(); match *err.err { - CheckErrorKind::IncompatibleTrait(expected, found) => { + StaticCheckErrorKind::IncompatibleTrait(expected, found) => { assert_eq!(expected.name.as_str(), "trait-2"); assert_eq!(found.name.as_str(), "trait-1"); } @@ -1041,7 +1040,7 @@ fn test_trait_arg_counts_differ1() { }; let err = mem_type_check_v1(trait_to_compatible_trait).unwrap_err(); match *err.err { - CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { + StaticCheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1071,7 +1070,7 @@ fn test_trait_arg_counts_differ2() { let err = mem_type_check(trait_to_compatible_trait).unwrap_err(); match *err.err { - CheckErrorKind::IncompatibleTrait(expected, found) => { + StaticCheckErrorKind::IncompatibleTrait(expected, found) => { assert_eq!(expected.name.as_str(), "trait-2"); assert_eq!(found.name.as_str(), "trait-1"); } @@ -1079,7 +1078,7 @@ fn test_trait_arg_counts_differ2() { }; let err = mem_type_check_v1(trait_to_compatible_trait).unwrap_err(); match *err.err { - CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { + StaticCheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1109,7 +1108,7 @@ fn test_trait_ret_ty_differ() { let err = mem_type_check(trait_ret_ty_differ).unwrap_err(); match *err.err { - CheckErrorKind::IncompatibleTrait(expected, actual) => { + StaticCheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-2"); assert_eq!(actual.name.as_str(), "trait-1"); } @@ -1117,7 +1116,7 @@ fn test_trait_ret_ty_differ() { }; let err = mem_type_check_v1(trait_ret_ty_differ).unwrap_err(); match *err.err { - CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { + StaticCheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1155,7 +1154,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 { - CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { + StaticCheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1192,7 +1191,7 @@ fn test_trait_with_bad_trait_arg() { let err = mem_type_check(trait_with_bad_trait_arg).unwrap_err(); match *err.err { - CheckErrorKind::IncompatibleTrait(expected, actual) => { + StaticCheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-b"); assert_eq!(actual.name.as_str(), "trait-a"); } @@ -1200,7 +1199,7 @@ fn test_trait_with_bad_trait_arg() { }; let err = mem_type_check_v1(trait_with_bad_trait_arg).unwrap_err(); match *err.err { - CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { + StaticCheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1238,7 +1237,7 @@ fn test_trait_with_superset_trait_arg() { let err = mem_type_check(trait_with_superset_trait_arg).unwrap_err(); match *err.err { - CheckErrorKind::IncompatibleTrait(expected, actual) => { + StaticCheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-b"); assert_eq!(actual.name.as_str(), "trait-a"); } @@ -1248,7 +1247,7 @@ fn test_trait_with_superset_trait_arg() { let err = mem_type_check_v1(trait_with_superset_trait_arg).unwrap_err(); match *err.err { - CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { + StaticCheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1287,7 +1286,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 { - CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { + StaticCheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1311,7 +1310,7 @@ fn test_trait_with_duplicate_method() { let err = mem_type_check(trait_with_duplicate_method).unwrap_err(); match *err.err { - CheckErrorKind::DefineTraitDuplicateMethod(method_name) => { + StaticCheckErrorKind::DefineTraitDuplicateMethod(method_name) => { assert_eq!(method_name.as_str(), "foo"); } _ => panic!("Unexpected error: {err:?}"), @@ -1340,7 +1339,7 @@ fn test_trait_to_subtrait_and_back() { let err = mem_type_check(trait_to_subtrait_and_back).unwrap_err(); match *err.err { - CheckErrorKind::IncompatibleTrait(expected, actual) => { + StaticCheckErrorKind::IncompatibleTrait(expected, actual) => { assert_eq!(expected.name.as_str(), "trait-2"); assert_eq!(actual.name.as_str(), "trait-1"); } @@ -1348,7 +1347,7 @@ fn test_trait_to_subtrait_and_back() { }; let err = mem_type_check_v1(trait_to_subtrait_and_back).unwrap_err(); match *err.err { - CheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { + StaticCheckErrorKind::TypeError(expected, found) => match (&*expected, &*found) { ( TypeSignature::CallableType(CallableSubtype::Trait(expected_trait)), TypeSignature::CallableType(CallableSubtype::Trait(found_trait)), @@ -1395,7 +1394,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 { - CheckErrorKind::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { + StaticCheckErrorKind::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { ( TypeSignature::CallableType(CallableSubtype::Trait(trait1)), TypeSignature::CallableType(CallableSubtype::Trait(trait2)), @@ -1409,7 +1408,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 { - CheckErrorKind::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { + StaticCheckErrorKind::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { ( TypeSignature::CallableType(CallableSubtype::Trait(trait1)), TypeSignature::CallableType(CallableSubtype::Trait(trait2)), @@ -1441,7 +1440,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 { - CheckErrorKind::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { + StaticCheckErrorKind::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { ( TypeSignature::CallableType(CallableSubtype::Trait(trait1)), TypeSignature::CallableType(CallableSubtype::Trait(trait2)), @@ -1455,7 +1454,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 { - CheckErrorKind::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { + StaticCheckErrorKind::IfArmsMustMatch(type1, type2) => match (&*type1, &*type2) { ( TypeSignature::CallableType(CallableSubtype::Trait(trait1)), TypeSignature::CallableType(CallableSubtype::Trait(trait2)), @@ -1514,7 +1513,7 @@ fn test_traits_multi_contract(#[case] version: ClarityVersion) { match result { Ok(_) if version >= ClarityVersion::Clarity2 => (), Err(StaticCheckError { err, .. }) if version < ClarityVersion::Clarity2 => match *err { - CheckErrorKind::TraitMethodUnknown(trait_name, function) => { + StaticCheckErrorKind::TraitMethodUnknown(trait_name, function) => { assert_eq!(trait_name.as_str(), "a"); assert_eq!(function.as_str(), "do-it"); } @@ -3399,7 +3398,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? 123)", "int type", - Err(CheckErrorKind::TypeError( + Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::IntType), )), @@ -3407,7 +3406,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? u123)", "uint type", - Err(CheckErrorKind::TypeError( + Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::UIntType), )), @@ -3415,7 +3414,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? true)", "bool type", - Err(CheckErrorKind::TypeError( + Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::BoolType), )), @@ -3423,7 +3422,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? 0x1234)", "buffer type", - Err(CheckErrorKind::TypeError( + Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::SequenceType(SequenceSubtype::BufferType( BufferLength::try_from(2u32).unwrap(), @@ -3433,7 +3432,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(CheckErrorKind::TypeError( + Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::SequenceType(SequenceSubtype::StringType( StringSubtype::ASCII(BufferLength::try_from(43u32).unwrap()), @@ -3443,7 +3442,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(CheckErrorKind::TypeError( + Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::SequenceType(SequenceSubtype::StringType( StringSubtype::UTF8(StringUTF8Length::try_from(40u32).unwrap()), @@ -3453,7 +3452,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? (list 1 2 3))", "list type", - Err(CheckErrorKind::TypeError( + Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::SequenceType(SequenceSubtype::ListType( ListTypeData::new_list(TypeSignature::IntType, 3).unwrap(), @@ -3463,7 +3462,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? { a: 1, b: u2 })", "tuple type", - Err(CheckErrorKind::TypeError( + Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::TupleType( vec![ @@ -3478,7 +3477,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? (some u789))", "optional type", - Err(CheckErrorKind::TypeError( + Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::new_option(TypeSignature::UIntType).unwrap()), )), @@ -3486,7 +3485,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc ( "(contract-hash? (ok true))", "response type", - Err(CheckErrorKind::TypeError( + Err(StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new( TypeSignature::new_response(TypeSignature::BoolType, TypeSignature::NoType) @@ -3503,7 +3502,7 @@ fn test_contract_hash(#[case] version: ClarityVersion, #[case] epoch: StacksEpoc let expected = if version >= ClarityVersion::Clarity4 { clarity4_expected } else { - &Err(CheckErrorKind::UnknownFunction( + &Err(StaticCheckErrorKind::UnknownFunction( "contract-hash?".to_string(), )) }; diff --git a/clarity/src/vm/analysis/type_checker/v2_1/tests/conversions.rs b/clarity/src/vm/analysis/type_checker/v2_1/tests/conversions.rs index b889bcc53ff..5cc016fafe4 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/tests/conversions.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/tests/conversions.rs @@ -12,8 +12,7 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . - -use clarity_types::errors::CheckErrorKind; +use clarity_types::errors::analysis::StaticCheckErrorKind; use clarity_types::types::{ BufferLength, ListTypeData, SequenceSubtype, StringSubtype, TypeSignature, MAX_TO_ASCII_BUFFER_LEN, @@ -99,7 +98,7 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ( &format!("(to-ascii? 0x{})", "ff".repeat(524285)), "oversized buffer type", - Err(CheckErrorKind::UnionTypeError( + Err(StaticCheckErrorKind::UnionTypeError( to_ascii_expected_types.clone(), Box::new(TypeSignature::SequenceType(SequenceSubtype::BufferType( BufferLength::try_from(524285u32).unwrap(), @@ -125,7 +124,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(CheckErrorKind::UnionTypeError( + Err(StaticCheckErrorKind::UnionTypeError( to_ascii_expected_types.clone(), Box::new(TypeSignature::SequenceType(SequenceSubtype::StringType( StringSubtype::ASCII(BufferLength::try_from(43u32).unwrap()), @@ -135,7 +134,7 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ( "(to-ascii? (list 1 2 3))", "list type", - Err(CheckErrorKind::UnionTypeError( + Err(StaticCheckErrorKind::UnionTypeError( to_ascii_expected_types.clone(), Box::new(TypeSignature::SequenceType(SequenceSubtype::ListType( ListTypeData::new_list(TypeSignature::IntType, 3).unwrap(), @@ -145,7 +144,7 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ( "(to-ascii? { a: 1, b: u2 })", "tuple type", - Err(CheckErrorKind::UnionTypeError( + Err(StaticCheckErrorKind::UnionTypeError( to_ascii_expected_types.clone(), Box::new(TypeSignature::TupleType( vec![ @@ -160,7 +159,7 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ( "(to-ascii? (some u789))", "optional type", - Err(CheckErrorKind::UnionTypeError( + Err(StaticCheckErrorKind::UnionTypeError( to_ascii_expected_types.clone(), Box::new(TypeSignature::new_option(TypeSignature::UIntType).unwrap()), )), @@ -168,7 +167,7 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ( "(to-ascii? (ok true))", "response type", - Err(CheckErrorKind::UnionTypeError( + Err(StaticCheckErrorKind::UnionTypeError( to_ascii_expected_types.clone(), Box::new( TypeSignature::new_response(TypeSignature::BoolType, TypeSignature::NoType) @@ -185,7 +184,9 @@ fn test_to_ascii(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) let expected = if version >= ClarityVersion::Clarity4 { clarity4_expected } else { - &Err(CheckErrorKind::UnknownFunction("to-ascii?".to_string())) + &Err(StaticCheckErrorKind::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 3fe94fa3df2..81788d7b81d 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 @@ -21,7 +21,7 @@ use rstest::rstest; use rstest_reuse::{self, *}; use stacks_common::types::StacksEpochId; -use crate::vm::analysis::errors::{CheckErrorKind, StaticCheckError, SyntaxBindingError}; +use crate::vm::analysis::errors::{StaticCheckError, StaticCheckErrorKind, SyntaxBindingError}; use crate::vm::analysis::mem_type_check as mem_run_analysis; use crate::vm::analysis::types::ContractAnalysis; use crate::vm::ast::build_ast; @@ -103,26 +103,26 @@ fn test_from_consensus_buff() { let bad = [ ( "(from-consensus-buff?)", - CheckErrorKind::IncorrectArgumentCount(2, 0), + StaticCheckErrorKind::IncorrectArgumentCount(2, 0), ), ( "(from-consensus-buff? 0x00 0x00 0x00)", - CheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), ), ( "(from-consensus-buff? 0x00 0x00)", - CheckErrorKind::InvalidTypeDescription, + StaticCheckErrorKind::InvalidTypeDescription, ), ( "(from-consensus-buff? int u6)", - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_MAX), Box::new(TypeSignature::UIntType), ), ), ( "(from-consensus-buff? (buff 1048576) 0x00)", - CheckErrorKind::ValueTooLarge, + StaticCheckErrorKind::ValueTooLarge, ), ]; @@ -199,26 +199,26 @@ fn test_to_consensus_buff() { let bad = [ ( "(to-consensus-buff?)", - CheckErrorKind::IncorrectArgumentCount(1, 0), + StaticCheckErrorKind::IncorrectArgumentCount(1, 0), ), ( "(to-consensus-buff? 0x00 0x00)", - CheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), ), ( "(define-private (my-func (x (buff 1048576))) (to-consensus-buff? x))", - CheckErrorKind::ValueTooLarge, + StaticCheckErrorKind::ValueTooLarge, ), ( "(define-private (my-func (x (buff 1048570))) (to-consensus-buff? x))", - CheckErrorKind::ValueTooLarge, + StaticCheckErrorKind::ValueTooLarge, ), ( "(define-private (my-func (x (buff 1048567))) (to-consensus-buff? x))", - CheckErrorKind::ValueTooLarge, + StaticCheckErrorKind::ValueTooLarge, ), ]; @@ -277,10 +277,10 @@ fn test_get_block_info() { "(get-block-info? time)", ]; let bad_expected = [ - 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), + StaticCheckErrorKind::NoSuchBlockInfoProperty("none".to_string()), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::RequiresAtLeastArguments(2, 1), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -312,7 +312,7 @@ fn test_get_block_info() { } for good_test in good_v210.iter() { - if let CheckErrorKind::NoSuchBlockInfoProperty(_) = + if let StaticCheckErrorKind::NoSuchBlockInfoProperty(_) = *type_check_helper_v1(good_test).unwrap_err().err { } else { @@ -333,10 +333,10 @@ fn test_get_burn_block_info() { r#"(get-burn-block-info? header-hash "a")"#, ]; let bad_expected = [ - CheckErrorKind::NoSuchBlockInfoProperty("none".to_string()), - CheckErrorKind::IncorrectArgumentCount(2, 0), - CheckErrorKind::IncorrectArgumentCount(2, 1), - CheckErrorKind::TypeError( + StaticCheckErrorKind::NoSuchBlockInfoProperty("none".to_string()), + StaticCheckErrorKind::IncorrectArgumentCount(2, 0), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::TypeError( Box::new(UIntType), Box::new(SequenceType(StringType(ASCII( BufferLength::try_from(1u32).expect("BufferLength::try_from failed"), @@ -377,10 +377,10 @@ fn test_define_trait(#[case] version: ClarityVersion, #[case] epoch: StacksEpoch "(define-trait)", ]; let bad_expected = [ - CheckErrorKind::InvalidTypeDescription, - CheckErrorKind::DefineTraitBadSignature, - CheckErrorKind::DefineTraitBadSignature, - CheckErrorKind::InvalidTypeDescription, + StaticCheckErrorKind::InvalidTypeDescription, + StaticCheckErrorKind::DefineTraitBadSignature, + StaticCheckErrorKind::DefineTraitBadSignature, + StaticCheckErrorKind::InvalidTypeDescription, ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -475,42 +475,42 @@ fn test_stx_ops() { "(stx-get-balance 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR)" ]; let bad_expected = [ - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(PrincipalType), Box::new(SequenceType(BufferType( BufferLength::try_from(2_u32).unwrap(), ))), ), - 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( + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(3, 5), + StaticCheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(UIntType)), + StaticCheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError( Box::new(PrincipalType), Box::new(OptionalType(Box::from(PrincipalType))), ), - CheckErrorKind::IncorrectArgumentCount(3, 4), - CheckErrorKind::TypeError( + StaticCheckErrorKind::IncorrectArgumentCount(3, 4), + StaticCheckErrorKind::TypeError( Box::new(PrincipalType), Box::new(SequenceType(BufferType( BufferLength::try_from(2_u32).unwrap(), ))), ), - 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( + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(4, 5), + StaticCheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(UIntType)), + StaticCheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError( Box::new(PrincipalType), Box::new(OptionalType(Box::from(PrincipalType))), ), - 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), + StaticCheckErrorKind::IncorrectArgumentCount(4, 3), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::TypeError(Box::new(PrincipalType), Box::new(BoolType)), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -539,7 +539,7 @@ fn test_tx_sponsor() { ]; let bad = ["(stx-transfer? u10 tx-sponsor? 'SM2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0G)"]; - let bad_expected = [CheckErrorKind::TypeError( + let bad_expected = [StaticCheckErrorKind::TypeError( Box::new(PrincipalType), Box::new(OptionalType(Box::from(PrincipalType))), )]; @@ -607,7 +607,7 @@ fn test_destructuring_opts(#[case] version: ClarityVersion, #[case] epoch: Stack let bad = [ ( "(unwrap-err! (some 2) 2)", - CheckErrorKind::ExpectedResponseType(Box::new(TypeSignature::from_string( + StaticCheckErrorKind::ExpectedResponseType(Box::new(TypeSignature::from_string( "(optional int)", version, epoch, @@ -615,92 +615,101 @@ fn test_destructuring_opts(#[case] version: ClarityVersion, #[case] epoch: Stack ), ( "(unwrap! (err 3) 2)", - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(unwrap-err-panic (ok 3))", - CheckErrorKind::CouldNotDetermineResponseErrType, + StaticCheckErrorKind::CouldNotDetermineResponseErrType, ), ( "(unwrap-panic none)", - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(define-private (foo) (if (> 1 0) none none)) (unwrap-panic (foo))", - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(unwrap-panic (err 3))", - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(match none inner-value (/ 1 0) (+ 1 8))", - CheckErrorKind::CouldNotDetermineMatchTypes, + StaticCheckErrorKind::CouldNotDetermineMatchTypes, ), ( "(match (ok 1) ok-val (/ ok-val 0) err-val (+ err-val 7))", - CheckErrorKind::CouldNotDetermineMatchTypes, + StaticCheckErrorKind::CouldNotDetermineMatchTypes, ), ( "(match (err 1) ok-val (/ ok-val 0) err-val (+ err-val 7))", - CheckErrorKind::CouldNotDetermineMatchTypes, + StaticCheckErrorKind::CouldNotDetermineMatchTypes, ), ( "(define-private (foo) (if (> 1 0) (ok 1) (err u8))) (match (foo) ok-val (+ 1 ok-val) err-val (/ err-val u0))", - CheckErrorKind::MatchArmsMustMatch( + StaticCheckErrorKind::MatchArmsMustMatch( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), ), ( "(match (some 1) inner-value (+ 1 inner-value) (> 1 28))", - CheckErrorKind::MatchArmsMustMatch( + StaticCheckErrorKind::MatchArmsMustMatch( Box::new(TypeSignature::IntType), Box::new(TypeSignature::BoolType), ), ), ( "(match (some 1) inner-value (+ 1 inner-value))", - CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::IncorrectArgumentCount( - 4, 3, - ))), + StaticCheckErrorKind::BadMatchOptionSyntax(Box::new( + StaticCheckErrorKind::IncorrectArgumentCount(4, 3), + )), ), ( "(match (ok 1) inner-value (+ 1 inner-value))", - CheckErrorKind::BadMatchResponseSyntax(Box::new( - CheckErrorKind::IncorrectArgumentCount(5, 3), + StaticCheckErrorKind::BadMatchResponseSyntax(Box::new( + StaticCheckErrorKind::IncorrectArgumentCount(5, 3), )), ), ( "(match (ok 1) 1 (+ 1 1) err-val (+ 2 err-val))", - CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)), + StaticCheckErrorKind::BadMatchResponseSyntax(Box::new( + StaticCheckErrorKind::ExpectedName, + )), ), ( "(match (ok 1) ok-val (+ 1 1) (+ 3 4) (+ 2 err-val))", - CheckErrorKind::BadMatchResponseSyntax(Box::new(CheckErrorKind::ExpectedName)), + StaticCheckErrorKind::BadMatchResponseSyntax(Box::new( + StaticCheckErrorKind::ExpectedName, + )), ), ( "(match (some 1) 2 (+ 1 1) (+ 3 4))", - CheckErrorKind::BadMatchOptionSyntax(Box::new(CheckErrorKind::ExpectedName)), + StaticCheckErrorKind::BadMatchOptionSyntax(Box::new( + StaticCheckErrorKind::ExpectedName, + )), + ), + ( + "(match)", + StaticCheckErrorKind::RequiresAtLeastArguments(1, 0), ), - ("(match)", CheckErrorKind::RequiresAtLeastArguments(1, 0)), ( "(match 1 ok-val (/ ok-val 0) err-val (+ err-val 7))", - CheckErrorKind::BadMatchInput(Box::new(TypeSignature::from_string( + StaticCheckErrorKind::BadMatchInput(Box::new(TypeSignature::from_string( "int", version, epoch, ))), ), ( "(default-to 3 5)", - CheckErrorKind::ExpectedOptionalType(Box::new(TypeSignature::IntType)), + StaticCheckErrorKind::ExpectedOptionalType(Box::new(TypeSignature::IntType)), ), ( "(define-private (foo (x int)) (match (some 3) x (+ x 2) 5))", - CheckErrorKind::NameAlreadyUsed("x".to_string()), + StaticCheckErrorKind::NameAlreadyUsed("x".to_string()), ), ( "(define-private (t1 (x uint)) (if (> x u1) (ok x) (err false))) @@ -708,7 +717,7 @@ fn test_destructuring_opts(#[case] version: ClarityVersion, #[case] epoch: Stack (if (> x u4) (err u3) (ok (+ u2 (try! (t1 x))))))", - CheckErrorKind::ReturnTypesMustMatch( + StaticCheckErrorKind::ReturnTypesMustMatch( Box::new( TypeSignature::new_response(TypeSignature::NoType, TypeSignature::BoolType) .unwrap(), @@ -723,7 +732,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))))", - CheckErrorKind::ReturnTypesMustMatch( + StaticCheckErrorKind::ReturnTypesMustMatch( Box::new( TypeSignature::new_response(TypeSignature::NoType, TypeSignature::BoolType) .unwrap(), @@ -733,23 +742,23 @@ fn test_destructuring_opts(#[case] version: ClarityVersion, #[case] epoch: Stack ), ( "(try! (ok 3))", - CheckErrorKind::CouldNotDetermineResponseErrType, + StaticCheckErrorKind::CouldNotDetermineResponseErrType, ), ( "(try! none)", - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(try! (err 3))", - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ), ( "(try! 3)", - CheckErrorKind::ExpectedOptionalOrResponseType(Box::new(TypeSignature::IntType)), + StaticCheckErrorKind::ExpectedOptionalOrResponseType(Box::new(TypeSignature::IntType)), ), ( "(try! (ok 3) 4)", - CheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), ), ]; @@ -772,14 +781,14 @@ fn test_at_block() { let bad = [ ( "(at-block (sha512 u0) u1)", - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_32), Box::new(TypeSignature::BUFFER_64), ), ), ( "(at-block (sha256 u0) u1 u2)", - CheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), ), ]; @@ -813,7 +822,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)", - CheckErrorKind::UnexpectedTraitOrFieldReference, + StaticCheckErrorKind::UnexpectedTraitOrFieldReference, )]; for (bad_test, expected) in bad.iter() { @@ -860,23 +869,23 @@ fn test_bitwise_bad_checks() { "(bit-or 1 2 u4)", ]; let bad_expected = [ - CheckErrorKind::IncorrectArgumentCount(2, 1), - CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::UnionTypeError( + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::UnionTypeError( vec![IntType, UIntType], Box::new(SequenceType(StringType(ASCII( BufferLength::try_from(5u32).unwrap(), )))), ), - 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)), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -901,12 +910,12 @@ fn test_simple_arithmetic_checks() { "(and (or true false) (+ 1 2 3))", ]; let bad_expected = [ - 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)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::RequiresAtLeastArguments(1, 0), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::UndefinedVariable("x".to_string()), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -967,14 +976,14 @@ fn test_simple_hash_checks() { for bad_test in bad_types.iter() { assert!(matches!( *type_check_helper(bad_test).unwrap_err().err, - CheckErrorKind::UnionTypeError(_, _) + StaticCheckErrorKind::UnionTypeError(_, _) )); } for bad_test in invalid_args.iter() { assert!(matches!( *type_check_helper(bad_test).unwrap_err().err, - CheckErrorKind::IncorrectArgumentCount(_, _) + StaticCheckErrorKind::IncorrectArgumentCount(_, _) )); } } @@ -997,10 +1006,10 @@ fn test_simple_ifs() { ]; let bad_expected = [ - 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)), + StaticCheckErrorKind::IfArmsMustMatch(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::IfArmsMustMatch(Box::new(ascii_type(1)), Box::new(BoolType)), + StaticCheckErrorKind::IncorrectArgumentCount(3, 0), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1033,9 +1042,9 @@ fn test_simple_lets() { ]; let bad_expected = [ - CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_invalid_length(0)), - CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_not_atom(0)), - CheckErrorKind::TypeError( + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_invalid_length(0)), + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_not_atom(0)), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), @@ -1108,47 +1117,47 @@ fn test_index_of() { ]; let bad_expected = [ - CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), - CheckErrorKind::TypeError( + StaticCheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_MIN), Box::new(TypeSignature::STRING_ASCII_MIN), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::STRING_UTF8_MIN), Box::new(TypeSignature::STRING_ASCII_MIN), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::STRING_ASCII_MIN), Box::new(TypeSignature::STRING_UTF8_MIN), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::list_of(TypeSignature::IntType, 1).unwrap()), Box::new(TypeSignature::list_of(TypeSignature::IntType, 2).unwrap()), ), - CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), - CheckErrorKind::TypeError( + StaticCheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_MIN), Box::new(TypeSignature::STRING_ASCII_MIN), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::STRING_UTF8_MIN), Box::new(TypeSignature::STRING_ASCII_MIN), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::STRING_ASCII_MIN), Box::new(TypeSignature::STRING_UTF8_MIN), ), - CheckErrorKind::CouldNotDetermineType, - CheckErrorKind::CouldNotDetermineType, - CheckErrorKind::CouldNotDetermineType, + StaticCheckErrorKind::CouldNotDetermineType, + StaticCheckErrorKind::CouldNotDetermineType, + StaticCheckErrorKind::CouldNotDetermineType, ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -1192,16 +1201,16 @@ fn test_element_at() { ]; let bad_expected = [ - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), - CheckErrorKind::TypeError( + StaticCheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::UIntType), Box::new(TypeSignature::IntType), ), - CheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), + StaticCheckErrorKind::ExpectedSequence(Box::new(TypeSignature::IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1233,12 +1242,12 @@ fn test_eqs(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) { ]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::list_of(IntType, 1).unwrap()), Box::new(IntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::from_string( "(optional bool)", version, @@ -1276,9 +1285,9 @@ fn test_asserts() { ]; let bad_expected = [ - CheckErrorKind::IncorrectArgumentCount(2, 1), - CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1342,23 +1351,23 @@ fn test_lists() { "(map + (list 1 2 3 4 5) (list true true true true true))", ]; let bad_expected = [ - 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)), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(buff_type(20))), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(buff_type(20))), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::UnknownFunction("ynot".to_string()), + StaticCheckErrorKind::IllegalOrUnknownFunctionApplication("if".to_string()), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), + StaticCheckErrorKind::ExpectedSequence(Box::new(UIntType)), + StaticCheckErrorKind::ExpectedSequence(Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1399,20 +1408,20 @@ fn test_buff() { "(len 1)", ]; let bad_expected = [ - 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)), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(buff_type(20))), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::UnknownFunction("ynot".to_string()), + StaticCheckErrorKind::IllegalOrUnknownFunctionApplication("if".to_string()), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::UnionTypeError(vec![IntType, UIntType], Box::new(BoolType)), + StaticCheckErrorKind::ExpectedSequence(Box::new(UIntType)), + StaticCheckErrorKind::ExpectedSequence(Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -1480,9 +1489,9 @@ fn test_native_as_max_len() { "(as-max-len? 0x01 u1048577)", ]; let bad_expected = [ - CheckErrorKind::ValueTooLarge, - CheckErrorKind::ValueTooLarge, - CheckErrorKind::ValueTooLarge, + StaticCheckErrorKind::ValueTooLarge, + StaticCheckErrorKind::ValueTooLarge, + StaticCheckErrorKind::ValueTooLarge, ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { assert_eq!(*expected, *type_check_helper(bad_test).unwrap_err().err); @@ -1526,9 +1535,9 @@ fn test_native_append() { ]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::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); @@ -1566,9 +1575,9 @@ fn test_slice_list() { ]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::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); @@ -1597,9 +1606,9 @@ fn test_slice_buff() { ]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::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); @@ -1631,9 +1640,9 @@ fn test_slice_ascii() { ]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::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); @@ -1662,9 +1671,9 @@ fn test_slice_utf8() { ]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::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); @@ -1710,17 +1719,17 @@ fn test_replace_at_list() { ]; let bad_expected = [ - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(IntType), Box::new(SequenceType(ListType( ListTypeData::new_list(IntType, 1).unwrap(), ))), ), - 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( + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(3, 4), + StaticCheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::TypeError( Box::new(SequenceType(ListType( ListTypeData::new_list(IntType, 1).unwrap(), ))), @@ -1768,20 +1777,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 = [ - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(SequenceType(BufferType(buff_len.clone()))), Box::new(SequenceType(ListType( ListTypeData::new_list(IntType, 1).unwrap(), ))), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(SequenceType(BufferType(buff_len.clone()))), Box::new(SequenceType(StringType(ASCII(buff_len.clone())))), ), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(3, 4), - CheckErrorKind::IncorrectArgumentCount(3, 2), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(3, 4), + StaticCheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::TypeError( Box::new(SequenceType(BufferType(buff_len))), Box::new(SequenceType(BufferType(buff_len_two))), ), @@ -1826,20 +1835,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 = [ - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(SequenceType(StringType(ASCII(buff_len.clone())))), Box::new(SequenceType(ListType( ListTypeData::new_list(IntType, 1).unwrap(), ))), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(SequenceType(StringType(ASCII(buff_len.clone())))), Box::new(SequenceType(BufferType(buff_len.clone()))), ), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(3, 4), - CheckErrorKind::IncorrectArgumentCount(3, 2), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(3, 4), + StaticCheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::TypeError( Box::new(SequenceType(StringType(ASCII(buff_len)))), Box::new(SequenceType(StringType(ASCII(buff_len_two)))), ), @@ -1884,20 +1893,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 = [ - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(SequenceType(StringType(UTF8(str_len.clone())))), Box::new(SequenceType(ListType( ListTypeData::new_list(IntType, 1).unwrap(), ))), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(SequenceType(StringType(UTF8(str_len.clone())))), Box::new(SequenceType(BufferType(buff_len))), ), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(3, 4), - CheckErrorKind::IncorrectArgumentCount(3, 2), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::IncorrectArgumentCount(3, 4), + StaticCheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::TypeError( Box::new(SequenceType(StringType(UTF8(str_len)))), Box::new(SequenceType(StringType(UTF8(str_len_two)))), ), @@ -1926,9 +1935,9 @@ fn test_native_concat() { ]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(UIntType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::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); @@ -2011,8 +2020,8 @@ fn test_tuples() { ]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(BoolType), Box::new(IntType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -2036,7 +2045,7 @@ fn test_empty_tuple_should_fail() { assert_eq!( *mem_type_check(contract_src).unwrap_err().err, - CheckErrorKind::EmptyTuplesNotAllowed, + StaticCheckErrorKind::EmptyTuplesNotAllowed, ); } @@ -2116,9 +2125,9 @@ fn test_simple_uints() { let bad = ["(> u1 1)", "(to-uint true)", "(to-int false)"]; let bad_expected = [ - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), - CheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), - CheckErrorKind::TypeError(Box::new(UIntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(IntType)), + StaticCheckErrorKind::TypeError(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::TypeError(Box::new(UIntType), Box::new(BoolType)), ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -2150,9 +2159,9 @@ fn test_buffer_to_ints() { ]; let bad_expected = [ - CheckErrorKind::IncorrectArgumentCount(1, 2), - CheckErrorKind::IncorrectArgumentCount(1, 0), - CheckErrorKind::TypeError( + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 0), + StaticCheckErrorKind::TypeError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32).unwrap(), ))), @@ -2160,7 +2169,7 @@ fn test_buffer_to_ints() { BufferLength::try_from(17_u32).unwrap(), ))), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(SequenceType(BufferType( BufferLength::try_from(16_u32).unwrap(), ))), @@ -2224,37 +2233,37 @@ fn test_string_to_ints() { ]; let bad_expected = [ - CheckErrorKind::IncorrectArgumentCount(1, 2), - CheckErrorKind::IncorrectArgumentCount(1, 0), - CheckErrorKind::UnionTypeError( + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 0), + StaticCheckErrorKind::UnionTypeError( vec![IntType, UIntType], Box::new(SequenceType(BufferType( BufferLength::try_from(17_u32).unwrap(), ))), ), - CheckErrorKind::UnionTypeError( + StaticCheckErrorKind::UnionTypeError( vec![IntType, UIntType], Box::new(SequenceType(StringType(ASCII( BufferLength::try_from(1_u32).unwrap(), )))), ), - CheckErrorKind::IncorrectArgumentCount(1, 2), - CheckErrorKind::IncorrectArgumentCount(1, 0), - CheckErrorKind::UnionTypeError( + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 0), + StaticCheckErrorKind::UnionTypeError( vec![IntType, UIntType], Box::new(SequenceType(BufferType( BufferLength::try_from(17_u32).unwrap(), ))), ), - CheckErrorKind::UnionTypeError( + StaticCheckErrorKind::UnionTypeError( vec![IntType, UIntType], Box::new(SequenceType(StringType(ASCII( BufferLength::try_from(1_u32).unwrap(), )))), ), - CheckErrorKind::IncorrectArgumentCount(1, 2), - CheckErrorKind::IncorrectArgumentCount(1, 0), - CheckErrorKind::UnionTypeError( + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 0), + StaticCheckErrorKind::UnionTypeError( vec![ TypeSignature::STRING_ASCII_MAX, TypeSignature::STRING_UTF8_MAX, @@ -2263,16 +2272,16 @@ fn test_string_to_ints() { BufferLength::try_from(17_u32).unwrap(), ))), ), - CheckErrorKind::UnionTypeError( + StaticCheckErrorKind::UnionTypeError( vec![ TypeSignature::STRING_ASCII_MAX, TypeSignature::STRING_UTF8_MAX, ], Box::new(IntType), ), - CheckErrorKind::IncorrectArgumentCount(1, 2), - CheckErrorKind::IncorrectArgumentCount(1, 0), - CheckErrorKind::UnionTypeError( + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 0), + StaticCheckErrorKind::UnionTypeError( vec![ TypeSignature::STRING_ASCII_MAX, TypeSignature::STRING_UTF8_MAX, @@ -2281,7 +2290,7 @@ fn test_string_to_ints() { BufferLength::try_from(17_u32).unwrap(), ))), ), - CheckErrorKind::UnionTypeError( + StaticCheckErrorKind::UnionTypeError( vec![ TypeSignature::STRING_ASCII_MAX, TypeSignature::STRING_UTF8_MAX, @@ -2336,7 +2345,7 @@ fn test_response_inference(#[case] version: ClarityVersion, #[case] epoch: Stack ]; let bad_expected = [ - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::from_string( "(response bool int)", version, @@ -2344,8 +2353,8 @@ fn test_response_inference(#[case] version: ClarityVersion, #[case] epoch: Stack )), Box::new(BoolType), ), - CheckErrorKind::ReturnTypesMustMatch(Box::new(IntType), Box::new(BoolType)), - CheckErrorKind::CouldNotDetermineResponseOkType, + StaticCheckErrorKind::ReturnTypesMustMatch(Box::new(IntType), Box::new(BoolType)), + StaticCheckErrorKind::CouldNotDetermineResponseOkType, ]; for (good_test, expected) in good.iter().zip(expected.iter()) { @@ -2463,7 +2472,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 { - CheckErrorKind::TypeError(t1, t2) => { + StaticCheckErrorKind::TypeError(t1, t2) => { *t1 == TypeSignature::from_string("(optional bool)", version, epoch) && *t2 == TypeSignature::from_string("(optional int)", version, epoch) } @@ -2473,7 +2482,7 @@ fn test_options(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) { } else { assert!( match *mem_run_analysis(contract, version, epoch).unwrap_err().err { - CheckErrorKind::TypeError(t1, t2) => { + StaticCheckErrorKind::TypeError(t1, t2) => { *t1 == TypeSignature::from_string("bool", version, epoch) && *t2 == TypeSignature::from_string("int", version, epoch) } @@ -2582,7 +2591,7 @@ fn test_missing_value_on_declaration_should_fail() { let res = mem_type_check(contract_src).unwrap_err(); assert!(matches!( *res.err, - CheckErrorKind::IncorrectArgumentCount(_, _) + StaticCheckErrorKind::IncorrectArgumentCount(_, _) )); } @@ -2593,7 +2602,7 @@ fn test_mismatching_type_on_declaration_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*res.err, StaticCheckErrorKind::TypeError(_, _))); } #[test] @@ -2609,7 +2618,7 @@ fn test_mismatching_type_on_update_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*res.err, StaticCheckErrorKind::TypeError(_, _))); } #[test] @@ -2621,7 +2630,10 @@ fn test_direct_access_to_persisted_var_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::UndefinedVariable(_) + )); } #[test] @@ -2636,7 +2648,7 @@ fn test_data_var_shadowed_by_let_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); + assert!(matches!(*res.err, StaticCheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -2649,7 +2661,10 @@ fn test_mutating_unknown_data_var_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NoSuchDataVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::NoSuchDataVariable(_) + )); } #[test] @@ -2660,7 +2675,10 @@ fn test_accessing_unknown_data_var_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NoSuchDataVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::NoSuchDataVariable(_) + )); } #[test] @@ -2671,7 +2689,7 @@ fn test_let_shadowed_by_let_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); + assert!(matches!(*res.err, StaticCheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -2683,7 +2701,7 @@ fn test_let_shadowed_by_nested_let_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); + assert!(matches!(*res.err, StaticCheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -2696,7 +2714,7 @@ fn test_define_constant_shadowed_by_let_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); + assert!(matches!(*res.err, StaticCheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -2708,7 +2726,7 @@ fn test_define_constant_shadowed_by_argument_should_fail() { "#; let res = mem_type_check(contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::NameAlreadyUsed(_))); + assert!(matches!(*res.err, StaticCheckErrorKind::NameAlreadyUsed(_))); } #[test] @@ -2908,7 +2926,7 @@ fn test_fetch_entry_mismatching_type_signatures() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*res.err, StaticCheckErrorKind::TypeError(_, _))); } } @@ -2923,7 +2941,10 @@ fn test_fetch_entry_unbound_variables() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::UndefinedVariable(_) + )); } } @@ -2965,7 +2986,7 @@ fn test_insert_entry_mismatching_type_signatures() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*res.err, StaticCheckErrorKind::TypeError(_, _))); } } @@ -2983,7 +3004,10 @@ fn test_insert_entry_unbound_variables() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::UndefinedVariable(_) + )); } } @@ -3023,7 +3047,7 @@ fn test_delete_entry_mismatching_type_signatures() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*res.err, StaticCheckErrorKind::TypeError(_, _))); } } @@ -3038,7 +3062,10 @@ fn test_delete_entry_unbound_variables() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::UndefinedVariable(_) + )); } } @@ -3082,7 +3109,7 @@ fn test_set_entry_mismatching_type_signatures() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::TypeError(_, _))); + assert!(matches!(*res.err, StaticCheckErrorKind::TypeError(_, _))); } } @@ -3100,7 +3127,10 @@ fn test_set_entry_unbound_variables() { ({case}))" ); let res = mem_type_check(&contract_src).unwrap_err(); - assert!(matches!(*res.err, CheckErrorKind::UndefinedVariable(_))); + assert!(matches!( + *res.err, + StaticCheckErrorKind::UndefinedVariable(_) + )); } } @@ -3216,7 +3246,7 @@ fn test_buff_negative_len() { (func 0x00)"; let res = mem_type_check(contract_src).unwrap_err(); - assert_eq!(*res.err, CheckErrorKind::ValueOutOfBounds); + assert_eq!(*res.err, StaticCheckErrorKind::ValueOutOfBounds); } #[test] @@ -3225,7 +3255,7 @@ fn test_string_ascii_negative_len() { (func \"\")"; let res = mem_type_check(contract_src).unwrap_err(); - assert_eq!(*res.err, CheckErrorKind::ValueOutOfBounds); + assert_eq!(*res.err, StaticCheckErrorKind::ValueOutOfBounds); } #[test] @@ -3234,7 +3264,7 @@ fn test_string_utf8_negative_len() { (func u\"\")"; let res = mem_type_check(contract_src).unwrap_err(); - assert_eq!(*res.err, CheckErrorKind::ValueOutOfBounds); + assert_eq!(*res.err, StaticCheckErrorKind::ValueOutOfBounds); } #[test] @@ -3278,7 +3308,7 @@ fn test_comparison_types() { r#"(>= "aaa" "aaa" "aaa")"#, ]; let bad_expected = [ - CheckErrorKind::UnionTypeError( + StaticCheckErrorKind::UnionTypeError( vec![ IntType, UIntType, @@ -3292,7 +3322,7 @@ fn test_comparison_types() { ], Box::new(PrincipalType), ), - CheckErrorKind::UnionTypeError( + StaticCheckErrorKind::UnionTypeError( vec![ IntType, UIntType, @@ -3308,7 +3338,7 @@ fn test_comparison_types() { ListTypeData::new_list(IntType, 3).unwrap(), ))), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(SequenceType(StringType(UTF8( StringUTF8Length::try_from(3u32).unwrap(), )))), @@ -3316,7 +3346,7 @@ fn test_comparison_types() { BufferLength::try_from(2_u32).unwrap(), )))), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(SequenceType(StringType(ASCII( BufferLength::try_from(3_u32).unwrap(), )))), @@ -3324,7 +3354,7 @@ fn test_comparison_types() { BufferLength::try_from(2_u32).unwrap(), ))), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(SequenceType(BufferType( BufferLength::try_from(2_u32).unwrap(), ))), @@ -3332,7 +3362,7 @@ fn test_comparison_types() { StringUTF8Length::try_from(3u32).unwrap(), )))), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(SequenceType(BufferType( BufferLength::try_from(2_u32).unwrap(), ))), @@ -3340,9 +3370,9 @@ fn test_comparison_types() { BufferLength::try_from(3_u32).unwrap(), )))), ), - CheckErrorKind::IncorrectArgumentCount(2, 0), - CheckErrorKind::IncorrectArgumentCount(2, 1), - CheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::IncorrectArgumentCount(2, 0), + StaticCheckErrorKind::IncorrectArgumentCount(2, 1), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), ]; for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) { @@ -3371,9 +3401,9 @@ fn test_principal_destruct() { r#"(principal-destruct? 0x22)"#, ]; let bad_expected = [ - CheckErrorKind::IncorrectArgumentCount(1, 2), - CheckErrorKind::IncorrectArgumentCount(1, 0), - CheckErrorKind::TypeError( + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 0), + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::PrincipalType), Box::new(TypeSignature::BUFFER_1), ), @@ -3427,17 +3457,17 @@ fn test_principal_construct() { // Too few arguments, just has the `(buff 1)`. ( r#"(principal-construct? 0x22)"#, - CheckErrorKind::RequiresAtLeastArguments(2, 1), + StaticCheckErrorKind::RequiresAtLeastArguments(2, 1), ), // Too few arguments, just hs the `(buff 20)`. ( r#"(principal-construct? 0xfa6bf38ed557fe417333710d6033e9419391a320)"#, - CheckErrorKind::RequiresAtLeastArguments(2, 1), + StaticCheckErrorKind::RequiresAtLeastArguments(2, 1), ), // The first buffer is too long, should be `(buff 1)`. ( r#"(principal-construct? 0xfa6bf38ed557fe417333710d6033e9419391a320 0xfa6bf38ed557fe417333710d6033e9419391a320)"#, - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_1), Box::new(TypeSignature::BUFFER_20), ), @@ -3445,7 +3475,7 @@ fn test_principal_construct() { // The second buffer is too long, should be `(buff 20)`. ( r#"(principal-construct? 0x22 0xfa6bf38ed557fe417333710d6033e9419391a32009)"#, - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_20), Box::new(TypeSignature::SequenceType(SequenceSubtype::BufferType( 21_u32.try_into().unwrap(), @@ -3455,12 +3485,15 @@ fn test_principal_construct() { // `int` argument instead of `(buff 1)` for version. ( r#"(principal-construct? 22 0xfa6bf38ed557fe417333710d6033e9419391a320)"#, - CheckErrorKind::TypeError(Box::new(TypeSignature::BUFFER_1), Box::new(IntType.clone())), + StaticCheckErrorKind::TypeError( + Box::new(TypeSignature::BUFFER_1), + Box::new(IntType.clone()), + ), ), // `name` argument is too long ( r#"(principal-construct? 0x22 0xfa6bf38ed557fe417333710d6033e9419391a320 "foooooooooooooooooooooooooooooooooooooooo")"#, - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::CONTRACT_NAME_STRING_ASCII_MAX), Box::new(SequenceType(StringType(ASCII(41_u32.try_into().unwrap())))), ), @@ -3468,7 +3501,7 @@ fn test_principal_construct() { // bad argument type for `name` ( r#"(principal-construct? 0x22 0xfa6bf38ed557fe417333710d6033e9419391a320 u123)"#, - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::CONTRACT_NAME_STRING_ASCII_MAX), Box::new(UIntType), ), @@ -3476,7 +3509,7 @@ fn test_principal_construct() { // too many arguments ( r#"(principal-construct? 0x22 0xfa6bf38ed557fe417333710d6033e9419391a320 "foo" "bar")"#, - CheckErrorKind::RequiresAtMostArguments(3, 4), + StaticCheckErrorKind::RequiresAtMostArguments(3, 4), ), ]; @@ -3530,7 +3563,7 @@ fn test_trait_args() { )"]; let contract_identifier = QualifiedContractIdentifier::transient(); - let bad_expected = [CheckErrorKind::IncompatibleTrait( + let bad_expected = [StaticCheckErrorKind::IncompatibleTrait( Box::new(TraitIdentifier { name: ClarityName::from("trait-foo"), contract_identifier: contract_identifier.clone(), @@ -3696,15 +3729,15 @@ fn test_list_arg(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ", ]; let bad_expected = [ - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::list_of(TypeSignature::IntType, 3).unwrap()), Box::new(TypeSignature::list_of(TypeSignature::IntType, 4).unwrap()), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::list_of(TypeSignature::IntType, 3).unwrap()), Box::new(TypeSignature::list_of(TypeSignature::UIntType, 1).unwrap()), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::list_of(TypeSignature::IntType, 3).unwrap()), Box::new( TypeSignature::list_of( @@ -3716,15 +3749,15 @@ fn test_list_arg(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) ), ]; let bad_expected2 = [ - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::list_of(TypeSignature::IntType, 3).unwrap()), Box::new(TypeSignature::list_of(TypeSignature::IntType, 4).unwrap()), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::UIntType), ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::IntType), Box::new(TypeSignature::list_of(TypeSignature::NoType, 0).unwrap()), ), @@ -3836,17 +3869,17 @@ fn test_simple_bad_syntax_bindings() { "(from-consensus-buff? (tuple (a (string-ascii -12))) 0x00)", ]; let expected = [ - 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, + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_not_list(0)), + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_invalid_length(0)), + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::let_binding_not_atom(0)), + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::eval_binding_not_list(0)), + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::eval_binding_invalid_length(0)), + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::eval_binding_not_atom(0)), + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::tuple_cons_not_list(0)), + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::tuple_cons_invalid_length(0)), + StaticCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::tuple_cons_not_atom(0)), + StaticCheckErrorKind::ValueOutOfBounds, + StaticCheckErrorKind::ValueOutOfBounds, ]; for (bad_code, expected_err) in bad.iter().zip(expected.iter()) { @@ -3870,9 +3903,9 @@ fn test_nested_bad_type_signature_syntax_bindings() { ]; let expected = [ - CheckErrorKind::ValueOutOfBounds, - CheckErrorKind::InvalidTypeDescription, - CheckErrorKind::ValueOutOfBounds, + StaticCheckErrorKind::ValueOutOfBounds, + StaticCheckErrorKind::InvalidTypeDescription, + StaticCheckErrorKind::ValueOutOfBounds, ]; for (bad_code, expected_err) in bad.iter().zip(expected.iter()) { @@ -3897,21 +3930,21 @@ fn test_secp256k1_recover_type_check() { let bad_cases = [ ( "(secp256k1-recover?)".to_string(), - CheckErrorKind::IncorrectArgumentCount(2, 0), + StaticCheckErrorKind::IncorrectArgumentCount(2, 0), ), ( format!( "(secp256k1-recover? {} {} {})", SECP256_MESSAGE_HASH, SECP256K1_SIGNATURE, SECP256K1_PUBLIC_KEY ), - CheckErrorKind::IncorrectArgumentCount(2, 3), + StaticCheckErrorKind::IncorrectArgumentCount(2, 3), ), ( format!( "(secp256k1-recover? {} {})", SECP256K1_SIGNATURE, SECP256K1_SIGNATURE ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_32), Box::new(TypeSignature::BUFFER_65), ), @@ -3921,7 +3954,7 @@ fn test_secp256k1_recover_type_check() { "(secp256k1-recover? {} {})", SECP256_MESSAGE_HASH, SECP256K1_SIGNATURE_TOO_LONG ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_65), Box::new(buffer_66_type.clone()), ), @@ -3955,21 +3988,21 @@ fn test_secp256k1_verify_type_check() { let bad_cases = [ ( "(secp256k1-verify)".to_string(), - CheckErrorKind::IncorrectArgumentCount(3, 0), + StaticCheckErrorKind::IncorrectArgumentCount(3, 0), ), ( format!( "(secp256k1-verify {} {})", SECP256_MESSAGE_HASH, SECP256K1_SIGNATURE ), - CheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::IncorrectArgumentCount(3, 2), ), ( format!( "(secp256k1-verify {} {} {})", SECP256K1_SIGNATURE, SECP256K1_SIGNATURE, SECP256K1_PUBLIC_KEY ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_32), Box::new(TypeSignature::BUFFER_65), ), @@ -3979,7 +4012,7 @@ fn test_secp256k1_verify_type_check() { "(secp256k1-verify {} {} {})", SECP256_MESSAGE_HASH, SECP256K1_SIGNATURE_TOO_LONG, SECP256K1_PUBLIC_KEY ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_65), Box::new(buffer_66_type.clone()), ), @@ -3989,7 +4022,7 @@ fn test_secp256k1_verify_type_check() { "(secp256k1-verify {} {} {})", SECP256_MESSAGE_HASH, SECP256K1_SIGNATURE, SECP256K1_SIGNATURE ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_33), Box::new(TypeSignature::BUFFER_65), ), @@ -4018,21 +4051,21 @@ fn test_secp256r1_verify_type_check() { let bad_cases = [ ( "(secp256r1-verify)".to_string(), - CheckErrorKind::IncorrectArgumentCount(3, 0), + StaticCheckErrorKind::IncorrectArgumentCount(3, 0), ), ( format!( "(secp256r1-verify {} {})", SECP256_MESSAGE_HASH, SECP256R1_SIGNATURE ), - CheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::IncorrectArgumentCount(3, 2), ), ( format!( "(secp256r1-verify {} {} {})", SECP256K1_SIGNATURE, SECP256R1_SIGNATURE, SECP256K1_PUBLIC_KEY ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_32), Box::new(TypeSignature::BUFFER_65), ), @@ -4042,7 +4075,7 @@ fn test_secp256r1_verify_type_check() { "(secp256r1-verify {} {} {})", SECP256_MESSAGE_HASH, SECP256K1_SIGNATURE, SECP256K1_PUBLIC_KEY ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_64), Box::new(TypeSignature::BUFFER_65), ), @@ -4052,7 +4085,7 @@ fn test_secp256r1_verify_type_check() { "(secp256r1-verify {} {} {})", SECP256_MESSAGE_HASH, SECP256R1_SIGNATURE, SECP256K1_SIGNATURE ), - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( Box::new(TypeSignature::BUFFER_33), Box::new(TypeSignature::BUFFER_65), ), diff --git a/clarity/src/vm/analysis/type_checker/v2_1/tests/post_conditions.rs b/clarity/src/vm/analysis/type_checker/v2_1/tests/post_conditions.rs index 6ad86098ed9..1b9e8e5ed2d 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/tests/post_conditions.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/tests/post_conditions.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use clarity_types::errors::CheckErrorKind; +use clarity_types::errors::analysis::StaticCheckErrorKind; use clarity_types::representations::MAX_STRING_LEN; use clarity_types::types::TypeSignature; use stacks_common::types::StacksEpochId; @@ -70,22 +70,22 @@ fn test_restrict_assets(#[case] version: ClarityVersion, #[case] _epoch: StacksE // with-all-assets-unsafe ( "(restrict-assets? tx-sender ((with-all-assets-unsafe)) true)", - CheckErrorKind::WithAllAllowanceNotAllowed, + StaticCheckErrorKind::WithAllAllowanceNotAllowed, ), // no asset-owner ( "(restrict-assets? ((with-stx u5000)) true)", - CheckErrorKind::RequiresAtLeastArguments(3, 2), + StaticCheckErrorKind::RequiresAtLeastArguments(3, 2), ), // no asset-owner, 3 args ( "(restrict-assets? ((with-stx u5000)) true true)", - CheckErrorKind::NonFunctionApplication, + StaticCheckErrorKind::NonFunctionApplication, ), // bad asset-owner type ( "(restrict-assets? u100 ((with-stx u5000)) true)", - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::PrincipalType.into(), TypeSignature::UIntType.into(), ), @@ -93,57 +93,57 @@ fn test_restrict_assets(#[case] version: ClarityVersion, #[case] _epoch: StacksE // no allowances ( "(restrict-assets? tx-sender true)", - CheckErrorKind::RequiresAtLeastArguments(3, 2), + StaticCheckErrorKind::RequiresAtLeastArguments(3, 2), ), // allowance not in list ( "(restrict-assets? tx-sender (with-stx u1) true)", - CheckErrorKind::ExpectedListApplication, + StaticCheckErrorKind::ExpectedListApplication, ), // other value in place of allowance list ( "(restrict-assets? tx-sender u1 true)", - CheckErrorKind::ExpectedListOfAllowances("restrict-assets?".into(), 2), + StaticCheckErrorKind::ExpectedListOfAllowances("restrict-assets?".into(), 2), ), // non-allowance in allowance list ( "(restrict-assets? tx-sender (u1) true)", - CheckErrorKind::ExpectedListApplication, + StaticCheckErrorKind::ExpectedListApplication, ), // empty list in allowance list ( "(restrict-assets? tx-sender (()) true)", - CheckErrorKind::NonFunctionApplication, + StaticCheckErrorKind::NonFunctionApplication, ), // list with literal in allowance list ( "(restrict-assets? tx-sender ((123)) true)", - CheckErrorKind::NonFunctionApplication, + StaticCheckErrorKind::NonFunctionApplication, ), // non-allowance function in allowance list ( "(restrict-assets? tx-sender ((foo)) true)", - CheckErrorKind::UnknownFunction("foo".into()), + StaticCheckErrorKind::UnknownFunction("foo".into()), ), // no body expressions ( "(restrict-assets? tx-sender ((with-stx u5000)))", - CheckErrorKind::RequiresAtLeastArguments(3, 2), + StaticCheckErrorKind::RequiresAtLeastArguments(3, 2), ), // unhandled response in only body expression ( "(restrict-assets? tx-sender ((with-stx u1000)) (err u1))", - CheckErrorKind::UncheckedIntermediaryResponses, + StaticCheckErrorKind::UncheckedIntermediaryResponses, ), // unhandled response in last body expression ( "(restrict-assets? tx-sender ((with-stx u1000)) true (err u1))", - CheckErrorKind::UncheckedIntermediaryResponses, + StaticCheckErrorKind::UncheckedIntermediaryResponses, ), // unhandled response in other body expression ( "(restrict-assets? tx-sender ((with-stx u1000)) (err u1) true)", - CheckErrorKind::UncheckedIntermediaryResponses, + StaticCheckErrorKind::UncheckedIntermediaryResponses, ), // too many allowances ( @@ -153,7 +153,7 @@ fn test_restrict_assets(#[case] version: ClarityVersion, #[case] _epoch: StacksE .collect::>() .join(" ") ), - CheckErrorKind::TooManyAllowances(MAX_ALLOWANCES, 130), + StaticCheckErrorKind::TooManyAllowances(MAX_ALLOWANCES, 130), ), // different error types thrown from body expressions ( @@ -164,7 +164,7 @@ fn test_restrict_assets(#[case] version: ClarityVersion, #[case] _epoch: StacksE u0 ) )", - CheckErrorKind::ReturnTypesMustMatch( + StaticCheckErrorKind::ReturnTypesMustMatch( TypeSignature::new_response(TypeSignature::NoType, TypeSignature::UIntType) .unwrap() .into(), @@ -179,7 +179,7 @@ fn test_restrict_assets(#[case] version: ClarityVersion, #[case] _epoch: StacksE if version < ClarityVersion::Clarity4 { // restrict-assets? is only available in Clarity 4+ assert_eq!( - CheckErrorKind::UnknownFunction("restrict-assets?".to_string()), + StaticCheckErrorKind::UnknownFunction("restrict-assets?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}", ); @@ -196,7 +196,7 @@ fn test_restrict_assets(#[case] version: ClarityVersion, #[case] _epoch: StacksE if version < ClarityVersion::Clarity4 { // restrict-assets? is only available in Clarity 4+ assert_eq!( - CheckErrorKind::UnknownFunction("restrict-assets?".to_string()), + StaticCheckErrorKind::UnknownFunction("restrict-assets?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}", ); @@ -248,67 +248,67 @@ fn test_as_contract(#[case] version: ClarityVersion, #[case] _epoch: StacksEpoch // no allowances ( "(as-contract? true)", - CheckErrorKind::RequiresAtLeastArguments(2, 1), + StaticCheckErrorKind::RequiresAtLeastArguments(2, 1), ), // allowance not in list ( "(as-contract? (with-stx u1) true)", - CheckErrorKind::ExpectedListApplication, + StaticCheckErrorKind::ExpectedListApplication, ), // other value in place of allowance list ( "(as-contract? u1 true)", - CheckErrorKind::ExpectedListOfAllowances("as-contract?".into(), 1), + StaticCheckErrorKind::ExpectedListOfAllowances("as-contract?".into(), 1), ), // non-allowance in allowance list ( "(as-contract? (u1) true)", - CheckErrorKind::ExpectedListApplication, + StaticCheckErrorKind::ExpectedListApplication, ), // empty list in allowance list ( "(as-contract? (()) true)", - CheckErrorKind::NonFunctionApplication, + StaticCheckErrorKind::NonFunctionApplication, ), // list with literal in allowance list ( "(as-contract? ((123)) true)", - CheckErrorKind::NonFunctionApplication, + StaticCheckErrorKind::NonFunctionApplication, ), // non-allowance function in allowance list ( "(as-contract? ((foo)) true)", - CheckErrorKind::UnknownFunction("foo".into()), + StaticCheckErrorKind::UnknownFunction("foo".into()), ), // no body expressions ( "(as-contract? ((with-stx u5000)))", - CheckErrorKind::RequiresAtLeastArguments(2, 1), + StaticCheckErrorKind::RequiresAtLeastArguments(2, 1), ), // unhandled response in only body expression ( "(as-contract? ((with-stx u1000)) (err u1))", - CheckErrorKind::UncheckedIntermediaryResponses, + StaticCheckErrorKind::UncheckedIntermediaryResponses, ), // unhandled response in last body expression ( "(as-contract? ((with-stx u1000)) true (err u1))", - CheckErrorKind::UncheckedIntermediaryResponses, + StaticCheckErrorKind::UncheckedIntermediaryResponses, ), // unhandled response in other body expression ( "(as-contract? ((with-stx u1000)) (err u1) true)", - CheckErrorKind::UncheckedIntermediaryResponses, + StaticCheckErrorKind::UncheckedIntermediaryResponses, ), // other allowances together with with-all-assets-unsafe (first) ( "(as-contract? ((with-all-assets-unsafe) (with-stx u1000)) true)", - CheckErrorKind::WithAllAllowanceNotAlone, + StaticCheckErrorKind::WithAllAllowanceNotAlone, ), // other allowances together with with-all-assets-unsafe (second) ( "(as-contract? ((with-stx u1000) (with-all-assets-unsafe)) true)", - CheckErrorKind::WithAllAllowanceNotAlone, + StaticCheckErrorKind::WithAllAllowanceNotAlone, ), // too many allowances ( @@ -318,7 +318,7 @@ fn test_as_contract(#[case] version: ClarityVersion, #[case] _epoch: StacksEpoch .collect::>() .join(" ") ), - CheckErrorKind::TooManyAllowances(MAX_ALLOWANCES, 130), + StaticCheckErrorKind::TooManyAllowances(MAX_ALLOWANCES, 130), ), // different error types thrown from body expressions ( @@ -329,7 +329,7 @@ fn test_as_contract(#[case] version: ClarityVersion, #[case] _epoch: StacksEpoch u0 ) )", - CheckErrorKind::ReturnTypesMustMatch( + StaticCheckErrorKind::ReturnTypesMustMatch( TypeSignature::new_response(TypeSignature::NoType, TypeSignature::UIntType) .unwrap() .into(), @@ -344,7 +344,7 @@ fn test_as_contract(#[case] version: ClarityVersion, #[case] _epoch: StacksEpoch if version < ClarityVersion::Clarity4 { // as-contract? is only available in Clarity 4+ assert_eq!( - CheckErrorKind::UnknownFunction("as-contract?".to_string()), + StaticCheckErrorKind::UnknownFunction("as-contract?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}" ); @@ -361,7 +361,7 @@ fn test_as_contract(#[case] version: ClarityVersion, #[case] _epoch: StacksEpoch if version < ClarityVersion::Clarity4 { // as-contract? is only available in Clarity 4+ assert_eq!( - CheckErrorKind::UnknownFunction("as-contract?".to_string()), + StaticCheckErrorKind::UnknownFunction("as-contract?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}" ); @@ -408,17 +408,17 @@ fn test_with_stx_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stac // no arguments ( "(restrict-assets? tx-sender ((with-stx)) true)", - CheckErrorKind::IncorrectArgumentCount(1, 0), + StaticCheckErrorKind::IncorrectArgumentCount(1, 0), ), // too many arguments ( "(restrict-assets? tx-sender ((with-stx u1000 u2000)) true)", - CheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), ), // wrong type - string instead of uint ( r#"(restrict-assets? tx-sender ((with-stx "1000")) true)"#, - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::UIntType.into(), TypeSignature::new_ascii_type_checked(4).into(), ), @@ -426,7 +426,7 @@ fn test_with_stx_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stac // wrong type - int instead of uint ( "(restrict-assets? tx-sender ((with-stx 1000)) true)", - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::UIntType.into(), TypeSignature::IntType.into(), ), @@ -436,7 +436,7 @@ fn test_with_stx_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stac for (code, expected_type) in &good { if version < ClarityVersion::Clarity4 { assert_eq!( - CheckErrorKind::UnknownFunction("restrict-assets?".to_string()), + StaticCheckErrorKind::UnknownFunction("restrict-assets?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}" ); @@ -452,7 +452,7 @@ fn test_with_stx_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stac for (code, expected_err) in &bad { if version < ClarityVersion::Clarity4 { assert_eq!( - CheckErrorKind::UnknownFunction("restrict-assets?".to_string()), + StaticCheckErrorKind::UnknownFunction("restrict-assets?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}" ); @@ -514,27 +514,27 @@ fn test_with_ft_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stack // no arguments ( "(restrict-assets? tx-sender ((with-ft)) true)", - CheckErrorKind::IncorrectArgumentCount(3, 0), + StaticCheckErrorKind::IncorrectArgumentCount(3, 0), ), // one argument ( "(restrict-assets? tx-sender ((with-ft .token)) true)", - CheckErrorKind::IncorrectArgumentCount(3, 1), + StaticCheckErrorKind::IncorrectArgumentCount(3, 1), ), // two arguments ( r#"(restrict-assets? tx-sender ((with-ft .token "token-name")) true)"#, - CheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::IncorrectArgumentCount(3, 2), ), // too many arguments ( r#"(restrict-assets? tx-sender ((with-ft .token "token-name" u1000 u2000)) true)"#, - CheckErrorKind::IncorrectArgumentCount(3, 4), + StaticCheckErrorKind::IncorrectArgumentCount(3, 4), ), // wrong type for contract-id - uint instead of principal ( r#"(restrict-assets? tx-sender ((with-ft u123 "token-name" u1000)) true)"#, - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::PrincipalType.into(), TypeSignature::UIntType.into(), ), @@ -542,7 +542,7 @@ fn test_with_ft_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stack // wrong type for token-name - uint instead of string ( "(restrict-assets? tx-sender ((with-ft .token u123 u1000)) true)", - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::new_ascii_type_checked(MAX_STRING_LEN as u32).into(), TypeSignature::UIntType.into(), ), @@ -550,7 +550,7 @@ fn test_with_ft_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stack // wrong type for amount - string instead of uint ( r#"(restrict-assets? tx-sender ((with-ft .token "token-name" "1000")) true)"#, - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::UIntType.into(), TypeSignature::new_ascii_type_checked(4).into(), ), @@ -558,7 +558,7 @@ fn test_with_ft_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stack // wrong type for amount - int instead of uint ( r#"(restrict-assets? tx-sender ((with-ft .token "token-name" 1000)) true)"#, - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::UIntType.into(), TypeSignature::IntType.into(), ), @@ -566,7 +566,7 @@ fn test_with_ft_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stack // too long token name (longer than 128 chars) ( "(restrict-assets? tx-sender ((with-ft .token \"this-token-name-is-way-too-long-to-be-valid-because-it-has-more-than-one-hundred-and-twenty-eight-characters-in-it-so-it-is-not-a-valid-token-name\" u1000)) true)", - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::new_ascii_type_checked(MAX_STRING_LEN as u32).into(), TypeSignature::new_ascii_type_checked(146u32).into(), ), @@ -576,7 +576,7 @@ fn test_with_ft_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stack for (code, expected_type) in &good { if version < ClarityVersion::Clarity4 { assert_eq!( - CheckErrorKind::UnknownFunction("restrict-assets?".to_string()), + StaticCheckErrorKind::UnknownFunction("restrict-assets?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}", ); @@ -592,7 +592,7 @@ fn test_with_ft_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stack for (code, expected_err) in &bad { if version < ClarityVersion::Clarity4 { assert_eq!( - CheckErrorKind::UnknownFunction("restrict-assets?".to_string()), + StaticCheckErrorKind::UnknownFunction("restrict-assets?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}", ); @@ -664,27 +664,27 @@ fn test_with_nft_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stac // no arguments ( "(restrict-assets? tx-sender ((with-nft)) true)", - CheckErrorKind::IncorrectArgumentCount(3, 0), + StaticCheckErrorKind::IncorrectArgumentCount(3, 0), ), // one argument ( "(restrict-assets? tx-sender ((with-nft .token)) true)", - CheckErrorKind::IncorrectArgumentCount(3, 1), + StaticCheckErrorKind::IncorrectArgumentCount(3, 1), ), // two arguments ( r#"(restrict-assets? tx-sender ((with-nft .token "token-name")) true)"#, - CheckErrorKind::IncorrectArgumentCount(3, 2), + StaticCheckErrorKind::IncorrectArgumentCount(3, 2), ), // too many arguments ( r#"(restrict-assets? tx-sender ((with-nft .token "token-name" (list u123) (list u456))) true)"#, - CheckErrorKind::IncorrectArgumentCount(3, 4), + StaticCheckErrorKind::IncorrectArgumentCount(3, 4), ), // wrong type for contract-id - uint instead of principal ( r#"(restrict-assets? tx-sender ((with-nft u123 "token-name" (list u456))) true)"#, - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::PrincipalType.into(), TypeSignature::UIntType.into(), ), @@ -692,7 +692,7 @@ fn test_with_nft_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stac // wrong type for token-name - uint instead of string ( "(restrict-assets? tx-sender ((with-nft .token u123 (list u456))) true)", - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::new_ascii_type_checked(MAX_STRING_LEN as u32).into(), TypeSignature::UIntType.into(), ), @@ -700,7 +700,7 @@ fn test_with_nft_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stac // too long token name (longer than 128 chars) ( "(restrict-assets? tx-sender ((with-ft .token \"this-token-name-is-way-too-long-to-be-valid-because-it-has-more-than-one-hundred-and-twenty-eight-characters-in-it-so-it-is-not-a-valid-token-name\" u1000)) true)", - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::new_ascii_type_checked(MAX_STRING_LEN as u32).into(), TypeSignature::new_ascii_type_checked(146u32).into(), ), @@ -713,14 +713,14 @@ fn test_with_nft_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stac .collect::>() .join(" ") ), - CheckErrorKind::MaxIdentifierLengthExceeded(MAX_NFT_IDENTIFIERS, 130), + StaticCheckErrorKind::MaxIdentifierLengthExceeded(MAX_NFT_IDENTIFIERS, 130), ), ]; for (code, expected_type) in &good { if version < ClarityVersion::Clarity4 { assert_eq!( - CheckErrorKind::UnknownFunction("restrict-assets?".to_string()), + StaticCheckErrorKind::UnknownFunction("restrict-assets?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}", ); @@ -736,7 +736,7 @@ fn test_with_nft_allowance(#[case] version: ClarityVersion, #[case] _epoch: Stac for (code, expected_err) in &bad { if version < ClarityVersion::Clarity4 { assert_eq!( - CheckErrorKind::UnknownFunction("restrict-assets?".to_string()), + StaticCheckErrorKind::UnknownFunction("restrict-assets?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}", ); @@ -778,17 +778,17 @@ fn test_with_stacking_allowance(#[case] version: ClarityVersion, #[case] _epoch: // no arguments ( "(restrict-assets? tx-sender ((with-stacking)) true)", - CheckErrorKind::IncorrectArgumentCount(1, 0), + StaticCheckErrorKind::IncorrectArgumentCount(1, 0), ), // too many arguments ( "(restrict-assets? tx-sender ((with-stacking u1000 u2000)) true)", - CheckErrorKind::IncorrectArgumentCount(1, 2), + StaticCheckErrorKind::IncorrectArgumentCount(1, 2), ), // wrong type - string instead of uint ( r#"(restrict-assets? tx-sender ((with-stacking "1000")) true)"#, - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::UIntType.into(), TypeSignature::new_ascii_type_checked(4).into(), ), @@ -796,7 +796,7 @@ fn test_with_stacking_allowance(#[case] version: ClarityVersion, #[case] _epoch: // wrong type - int instead of uint ( "(restrict-assets? tx-sender ((with-stacking 1000)) true)", - CheckErrorKind::TypeError( + StaticCheckErrorKind::TypeError( TypeSignature::UIntType.into(), TypeSignature::IntType.into(), ), @@ -806,7 +806,7 @@ fn test_with_stacking_allowance(#[case] version: ClarityVersion, #[case] _epoch: for (code, expected_type) in &good { if version < ClarityVersion::Clarity4 { assert_eq!( - CheckErrorKind::UnknownFunction("restrict-assets?".to_string()), + StaticCheckErrorKind::UnknownFunction("restrict-assets?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}", ); @@ -822,7 +822,7 @@ fn test_with_stacking_allowance(#[case] version: ClarityVersion, #[case] _epoch: for (code, expected_err) in &bad { if version < ClarityVersion::Clarity4 { assert_eq!( - CheckErrorKind::UnknownFunction("restrict-assets?".to_string()), + StaticCheckErrorKind::UnknownFunction("restrict-assets?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}", ); @@ -857,19 +857,19 @@ fn test_with_all_assets_unsafe_allowance( // with-all-assets-unsafe in restrict-assets? (not allowed) ( "(restrict-assets? tx-sender ((with-all-assets-unsafe)) true)", - CheckErrorKind::WithAllAllowanceNotAllowed, + StaticCheckErrorKind::WithAllAllowanceNotAllowed, ), // with-all-assets-unsafe with arguments (should take 0) ( "(restrict-assets? tx-sender ((with-all-assets-unsafe u123)) true)", - CheckErrorKind::IncorrectArgumentCount(0, 1), + StaticCheckErrorKind::IncorrectArgumentCount(0, 1), ), ]; for (code, expected_type) in &good { if version < ClarityVersion::Clarity4 { assert_eq!( - CheckErrorKind::UnknownFunction("as-contract?".to_string()), + StaticCheckErrorKind::UnknownFunction("as-contract?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}", ); @@ -885,7 +885,7 @@ fn test_with_all_assets_unsafe_allowance( for (code, expected_err) in &bad { if version < ClarityVersion::Clarity4 { assert_eq!( - CheckErrorKind::UnknownFunction("restrict-assets?".to_string()), + StaticCheckErrorKind::UnknownFunction("restrict-assets?".to_string()), *type_check_helper_version(code, version).unwrap_err().err, "{code}", ); diff --git a/clarity/src/vm/analysis/types.rs b/clarity/src/vm/analysis/types.rs index 1be8f15918e..58f08e8de95 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::{CheckErrorKind, StaticCheckError}; +use crate::vm::analysis::errors::{StaticCheckError, StaticCheckErrorKind}; 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(CheckErrorKind::BadTraitImplementation( + return Err(StaticCheckErrorKind::BadTraitImplementation( trait_name, func_name.to_string(), ) @@ -250,7 +250,7 @@ impl ContractAnalysis { } if !expected_sig.returns.admits_type(epoch, &func.returns)? { - return Err(CheckErrorKind::BadTraitImplementation( + return Err(StaticCheckErrorKind::BadTraitImplementation( trait_name, func_name.to_string(), ) @@ -258,7 +258,7 @@ impl ContractAnalysis { } } (_, _) => { - return Err(CheckErrorKind::BadTraitImplementation( + return Err(StaticCheckErrorKind::BadTraitImplementation( trait_name, func_name.to_string(), ) diff --git a/clarity/src/vm/clarity.rs b/clarity/src/vm/clarity.rs index ef51074c72a..bd06b628c46 100644 --- a/clarity/src/vm/clarity.rs +++ b/clarity/src/vm/clarity.rs @@ -2,7 +2,9 @@ use std::fmt; use stacks_common::types::StacksEpochId; -use crate::vm::analysis::{AnalysisDatabase, CheckErrorKind, ContractAnalysis, StaticCheckError}; +use crate::vm::analysis::{ + AnalysisDatabase, CheckErrorKind, ContractAnalysis, StaticCheckError, StaticCheckErrorKind, +}; use crate::vm::ast::errors::{ParseError, ParseErrorKind}; use crate::vm::ast::ContractAST; use crate::vm::contexts::{AssetMap, Environment, OwnedEnvironment}; @@ -76,17 +78,18 @@ impl std::error::Error for ClarityError { } } +#[cfg(any(test, feature = "testing"))] impl From for ClarityError { fn from(e: StaticCheckError) -> Self { match *e.err { - CheckErrorKind::CostOverflow => { + StaticCheckErrorKind::CostOverflow => { ClarityError::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - CheckErrorKind::CostBalanceExceeded(a, b) => ClarityError::CostError(a, b), - CheckErrorKind::MemoryBalanceExceeded(_a, _b) => { + StaticCheckErrorKind::CostBalanceExceeded(a, b) => ClarityError::CostError(a, b), + StaticCheckErrorKind::MemoryBalanceExceeded(_a, _b) => { ClarityError::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } - CheckErrorKind::ExecutionTimeExpired => { + StaticCheckErrorKind::ExecutionTimeExpired => { ClarityError::CostError(ExecutionCost::max_value(), ExecutionCost::max_value()) } _ => ClarityError::StaticCheck(e), @@ -255,7 +258,7 @@ pub trait TransactionConnection: ClarityConnection { let cost_track = contract_analysis.take_contract_cost_tracker(); (cost_track, Ok((contract_ast, contract_analysis))) } - Err(e) => (e.1, Err(e.0.into())), + Err(e) => (e.1, Err(ClarityError::StaticCheck(e.0))), } }) } @@ -275,13 +278,13 @@ pub trait TransactionConnection: ClarityConnection { Ok(_) => { let result = db .commit() - .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")).into()); + .map_err(|e| StaticCheckErrorKind::Expects(format!("{e:?}")).into()); (cost_tracker, result) } Err(e) => { let result = db .roll_back() - .map_err(|e| CheckErrorKind::Expects(format!("{e:?}")).into()); + .map_err(|e| StaticCheckErrorKind::Expects(format!("{e:?}")).into()); if result.is_err() { (cost_tracker, result) } else { diff --git a/clarity/src/vm/errors.rs b/clarity/src/vm/errors.rs index bc3d9c1e469..11341ea05b5 100644 --- a/clarity/src/vm/errors.rs +++ b/clarity/src/vm/errors.rs @@ -21,7 +21,7 @@ pub use clarity_types::errors::{ pub use crate::vm::analysis::errors::{ check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckErrorKind, - SyntaxBindingError, SyntaxBindingErrorType, + StaticCheckError, StaticCheckErrorKind, SyntaxBindingError, SyntaxBindingErrorType, }; #[cfg(test)] diff --git a/clarity/src/vm/functions/define.rs b/clarity/src/vm/functions/define.rs index 30094737998..80ac4f6988e 100644 --- a/clarity/src/vm/functions/define.rs +++ b/clarity/src/vm/functions/define.rs @@ -16,6 +16,9 @@ use std::collections::BTreeMap; +use clarity_types::errors::analysis::CommonCheckErrorKind; +use clarity_types::VmExecutionError; + use crate::vm::callables::{DefineType, DefinedFunction}; use crate::vm::contexts::{ContractContext, Environment, LocalContext}; use crate::vm::errors::{ @@ -288,7 +291,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>, CheckErrorKind> { + ) -> std::result::Result>, CommonCheckErrorKind> { let (define_type, args) = match DefineFunctions::try_parse(expression) { Some(x) => x, None => return Ok(None), @@ -296,7 +299,9 @@ impl<'a> DefineFunctionsParsed<'a> { let result = match define_type { DefineFunctions::Constant => { check_argument_count(2, args)?; - let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; + let name = args[0] + .match_atom() + .ok_or(CommonCheckErrorKind::ExpectedName)?; DefineFunctionsParsed::Constant { name, value: &args[1], @@ -306,7 +311,7 @@ impl<'a> DefineFunctionsParsed<'a> { check_argument_count(2, args)?; let signature = args[0] .match_list() - .ok_or(CheckErrorKind::DefineFunctionBadSignature)?; + .ok_or(CommonCheckErrorKind::DefineFunctionBadSignature)?; DefineFunctionsParsed::PrivateFunction { signature, body: &args[1], @@ -316,7 +321,7 @@ impl<'a> DefineFunctionsParsed<'a> { check_argument_count(2, args)?; let signature = args[0] .match_list() - .ok_or(CheckErrorKind::DefineFunctionBadSignature)?; + .ok_or(CommonCheckErrorKind::DefineFunctionBadSignature)?; DefineFunctionsParsed::ReadOnlyFunction { signature, body: &args[1], @@ -326,7 +331,7 @@ impl<'a> DefineFunctionsParsed<'a> { check_argument_count(2, args)?; let signature = args[0] .match_list() - .ok_or(CheckErrorKind::DefineFunctionBadSignature)?; + .ok_or(CommonCheckErrorKind::DefineFunctionBadSignature)?; DefineFunctionsParsed::PublicFunction { signature, body: &args[1], @@ -334,7 +339,9 @@ impl<'a> DefineFunctionsParsed<'a> { } DefineFunctions::NonFungibleToken => { check_argument_count(2, args)?; - let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; + let name = args[0] + .match_atom() + .ok_or(CommonCheckErrorKind::ExpectedName)?; DefineFunctionsParsed::NonFungibleToken { name, nft_type: &args[1], @@ -342,7 +349,9 @@ impl<'a> DefineFunctionsParsed<'a> { } DefineFunctions::FungibleToken => { check_arguments_at_least(1, args)?; - let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; + let name = args[0] + .match_atom() + .ok_or(CommonCheckErrorKind::ExpectedName)?; if args.len() == 1 { DefineFunctionsParsed::UnboundedFungibleToken { name } } else if args.len() == 2 { @@ -351,12 +360,14 @@ impl<'a> DefineFunctionsParsed<'a> { max_supply: &args[1], } } else { - return Err(CheckErrorKind::IncorrectArgumentCount(1, args.len())); + return Err(CommonCheckErrorKind::IncorrectArgumentCount(1, args.len())); } } DefineFunctions::Map => { check_argument_count(3, args)?; - let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; + let name = args[0] + .match_atom() + .ok_or(CommonCheckErrorKind::ExpectedName)?; DefineFunctionsParsed::Map { name, key_type: &args[1], @@ -365,7 +376,9 @@ impl<'a> DefineFunctionsParsed<'a> { } DefineFunctions::PersistedVariable => { check_argument_count(3, args)?; - let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; + let name = args[0] + .match_atom() + .ok_or(CommonCheckErrorKind::ExpectedName)?; DefineFunctionsParsed::PersistedVariable { name, data_type: &args[1], @@ -374,7 +387,9 @@ impl<'a> DefineFunctionsParsed<'a> { } DefineFunctions::Trait => { check_argument_count(2, args)?; - let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; + let name = args[0] + .match_atom() + .ok_or(CommonCheckErrorKind::ExpectedName)?; DefineFunctionsParsed::Trait { name, functions: &args[1..], @@ -382,13 +397,15 @@ impl<'a> DefineFunctionsParsed<'a> { } DefineFunctions::UseTrait => { check_argument_count(2, args)?; - let name = args[0].match_atom().ok_or(CheckErrorKind::ExpectedName)?; + let name = args[0] + .match_atom() + .ok_or(CommonCheckErrorKind::ExpectedName)?; match &args[1].expr { Field(ref field) => DefineFunctionsParsed::UseTrait { name, trait_identifier: field, }, - _ => return Err(CheckErrorKind::ExpectedTraitIdentifier), + _ => return Err(CommonCheckErrorKind::ExpectedTraitIdentifier), } } DefineFunctions::ImplTrait => { @@ -397,7 +414,7 @@ impl<'a> DefineFunctionsParsed<'a> { Field(ref field) => DefineFunctionsParsed::ImplTrait { trait_identifier: field, }, - _ => return Err(CheckErrorKind::ExpectedTraitIdentifier), + _ => return Err(CommonCheckErrorKind::ExpectedTraitIdentifier), } } }; @@ -409,7 +426,9 @@ pub fn evaluate_define( expression: &SymbolicExpression, env: &mut Environment, ) -> Result { - if let Some(define_type) = DefineFunctionsParsed::try_parse(expression)? { + if let Some(define_type) = DefineFunctionsParsed::try_parse(expression) + .map_err(|e| VmExecutionError::Unchecked(e.into()))? + { match define_type { DefineFunctionsParsed::Constant { name, value } => { handle_define_variable(name, value, env) diff --git a/clarity/src/vm/functions/mod.rs b/clarity/src/vm/functions/mod.rs index 2b2e94f06e7..a6603c01795 100644 --- a/clarity/src/vm/functions/mod.rs +++ b/clarity/src/vm/functions/mod.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +use clarity_types::errors::analysis::CommonCheckErrorKind; use stacks_common::types::StacksEpochId; use crate::vm::callables::{cost_input_sized_vararg, CallableType, NativeHandle}; @@ -711,7 +712,7 @@ pub fn handle_binding_list( ) -> std::result::Result<(), E> where F: FnMut(&ClarityName, &SymbolicExpression) -> std::result::Result<(), E>, - E: for<'a> From<(CheckErrorKind, &'a SymbolicExpression)>, + E: for<'a> From<(CommonCheckErrorKind, &'a SymbolicExpression)>, { for (i, binding) in bindings.iter().enumerate() { let binding_expression = binding.match_list().ok_or_else(|| { diff --git a/clarity/src/vm/tests/variables.rs b/clarity/src/vm/tests/variables.rs index af65c3e24c9..cbace07f7c0 100644 --- a/clarity/src/vm/tests/variables.rs +++ b/clarity/src/vm/tests/variables.rs @@ -13,7 +13,6 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . - #[cfg(any(test, feature = "testing"))] use rstest::rstest; #[cfg(test)] @@ -25,7 +24,7 @@ use crate::vm::{ analysis::type_checker::v2_1::tests::contracts::type_check_version, ast::parse, database::MemoryBackingStore, - errors::{CheckErrorKind, VmExecutionError}, + errors::{CheckErrorKind, StaticCheckErrorKind, VmExecutionError}, tests::{tl_env_factory, TopLevelMemoryEnvironmentGenerator}, types::{PrincipalData, QualifiedContractIdentifier, Value}, ClarityVersion, ContractContext, @@ -54,7 +53,7 @@ fn test_block_height( if version >= ClarityVersion::Clarity3 { let err = analysis.unwrap_err(); assert_eq!( - CheckErrorKind::UndefinedVariable("block-height".to_string()), + StaticCheckErrorKind::UndefinedVariable("block-height".to_string()), *err.err ); } else { @@ -113,7 +112,7 @@ fn test_stacks_block_height( if version < ClarityVersion::Clarity3 { let err = analysis.unwrap_err(); assert_eq!( - CheckErrorKind::UndefinedVariable("stacks-block-height".to_string()), + StaticCheckErrorKind::UndefinedVariable("stacks-block-height".to_string()), *err.err ); } else { @@ -172,7 +171,7 @@ fn test_tenure_height( if version < ClarityVersion::Clarity3 { let err = analysis.unwrap_err(); assert_eq!( - CheckErrorKind::UndefinedVariable("tenure-height".to_string()), + StaticCheckErrorKind::UndefinedVariable("tenure-height".to_string()), *err.err ); } else { @@ -208,12 +207,12 @@ fn test_tenure_height( } } +#[cfg(test)] #[derive(Debug, PartialEq)] -enum WhenError { - Analysis, - Initialization, - Runtime, - Never, +enum ExpectedContractError { + Analysis(StaticCheckErrorKind), + Initialization(CheckErrorKind), + Runtime(CheckErrorKind), } #[cfg(test)] @@ -225,9 +224,8 @@ fn expect_contract_error( name: &str, contract: &str, expected_errors: &[( - WhenError, fn(ClarityVersion, StacksEpochId) -> bool, - CheckErrorKind, + ExpectedContractError, )], expected_success: Value, ) { @@ -244,13 +242,15 @@ fn expect_contract_error( type_check_version(&contract_identifier, &mut exprs, db, true, epoch, version) }); - for (when, err_condition, expected_error) in expected_errors { - if *when == WhenError::Analysis && err_condition(version, epoch) { - let err = analysis.unwrap_err(); - assert_eq!(*expected_error, *err.err); + for (err_condition, expected_error) in expected_errors { + if let ExpectedContractError::Analysis(expected_error) = expected_error { + if err_condition(version, epoch) { + let err = analysis.unwrap_err(); + assert_eq!(expected_error, &*err.err); - // Do not continue with the test if the analysis failed. - return; + // Do not continue with the test if the analysis failed. + return; + } } } @@ -270,17 +270,18 @@ fn expect_contract_error( None, ); - 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 VmExecutionError::Unchecked(inner_err) = &err { - assert_eq!(expected_error, inner_err); - } else { - panic!("Expected an Unchecked error, but got a different error"); + for (err_condition, expected_error) in expected_errors { + if let ExpectedContractError::Initialization(expected_error) = expected_error { + if err_condition(version, epoch) { + let err = init_result.unwrap_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"); + } + // Do not continue with the test if the initialization failed. + return; } - - // Do not continue with the test if the initialization failed. - return; } } @@ -289,17 +290,19 @@ fn expect_contract_error( // Call the function let eval_result = env.eval_read_only(&contract_identifier, "(test-func)"); - 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 VmExecutionError::Unchecked(inner_err) = &err { - assert_eq!(expected_error, inner_err); - } else { - panic!("Expected an Unchecked error, but got a different error"); + for (err_condition, expected_error) in expected_errors { + if let ExpectedContractError::Runtime(expected_error) = expected_error { + if err_condition(version, epoch) { + let err = eval_result.unwrap_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"); + } + + // Do not continue with the test if the evaluation failed. + return; } - - // Do not continue with the test if the evaluation failed. - return; } } @@ -326,14 +329,16 @@ fn reuse_block_height( "#, &[ ( - WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "block-height".to_string(), + )), ), ( - WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::ReservedWord("block-height".to_string()), + ExpectedContractError::Analysis(StaticCheckErrorKind::ReservedWord( + "block-height".to_string(), + )), ), ], Value::UInt(1234), @@ -353,14 +358,16 @@ fn reuse_block_height( "#, &[ ( - WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "block-height".to_string(), + )), ), ( - WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::ReservedWord("block-height".to_string()), + ExpectedContractError::Analysis(StaticCheckErrorKind::ReservedWord( + "block-height".to_string(), + )), ), ], Value::Bool(true), @@ -381,14 +388,16 @@ fn reuse_block_height( "#, &[ ( - WhenError::Runtime, |version, _| version < ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("block-height".to_string()), + ExpectedContractError::Runtime(CheckErrorKind::NameAlreadyUsed( + "block-height".to_string(), + )), ), ( - WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::ReservedWord("block-height".to_string()), + ExpectedContractError::Analysis(StaticCheckErrorKind::ReservedWord( + "block-height".to_string(), + )), ), ], Value::Int(32), @@ -412,14 +421,16 @@ fn reuse_block_height( "#, &[ ( - WhenError::Runtime, |version, _| version < ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("block-height".to_string()), + ExpectedContractError::Runtime(CheckErrorKind::NameAlreadyUsed( + "block-height".to_string(), + )), ), ( - WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::ReservedWord("block-height".to_string()), + ExpectedContractError::Analysis(StaticCheckErrorKind::ReservedWord( + "block-height".to_string(), + )), ), ], Value::Int(3), @@ -437,14 +448,16 @@ fn reuse_block_height( "#, &[ ( - WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "block-height".to_string(), + )), ), ( - WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::ReservedWord("block-height".to_string()), + ExpectedContractError::Analysis(StaticCheckErrorKind::ReservedWord( + "block-height".to_string(), + )), ), ], Value::Bool(true), @@ -462,14 +475,16 @@ fn reuse_block_height( "#, &[ ( - WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "block-height".to_string(), + )), ), ( - WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::ReservedWord("block-height".to_string()), + ExpectedContractError::Analysis(StaticCheckErrorKind::ReservedWord( + "block-height".to_string(), + )), ), ], Value::UInt(1234), @@ -487,14 +502,16 @@ fn reuse_block_height( "#, &[ ( - WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "block-height".to_string(), + )), ), ( - WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::ReservedWord("block-height".to_string()), + ExpectedContractError::Analysis(StaticCheckErrorKind::ReservedWord( + "block-height".to_string(), + )), ), ], Value::Bool(false), @@ -527,14 +544,16 @@ fn reuse_block_height( "#, &[ ( - WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "block-height".to_string(), + )), ), ( - WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::ReservedWord("block-height".to_string()), + ExpectedContractError::Analysis(StaticCheckErrorKind::ReservedWord( + "block-height".to_string(), + )), ), ], Value::Bool(false), @@ -552,14 +571,16 @@ fn reuse_block_height( "#, &[ ( - WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "block-height".to_string(), + )), ), ( - WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::ReservedWord("block-height".to_string()), + ExpectedContractError::Analysis(StaticCheckErrorKind::ReservedWord( + "block-height".to_string(), + )), ), ], Value::Bool(false), @@ -577,14 +598,16 @@ fn reuse_block_height( "#, &[ ( - WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "block-height".to_string(), + )), ), ( - WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::ReservedWord("block-height".to_string()), + ExpectedContractError::Analysis(StaticCheckErrorKind::ReservedWord( + "block-height".to_string(), + )), ), ], Value::Bool(true), @@ -602,14 +625,16 @@ fn reuse_block_height( "#, &[ ( - WhenError::Initialization, |version, _| version < ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "block-height".to_string(), + )), ), ( - WhenError::Analysis, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::ReservedWord("block-height".to_string()), + ExpectedContractError::Analysis(StaticCheckErrorKind::ReservedWord( + "block-height".to_string(), + )), ), ], Value::Bool(true), @@ -635,9 +660,10 @@ fn reuse_stacks_block_height( ) "#, &[( - WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "stacks-block-height".to_string(), + )), )], Value::UInt(1234), ); @@ -655,9 +681,10 @@ fn reuse_stacks_block_height( ) "#, &[( - WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "stacks-block-height".to_string(), + )), )], Value::Bool(true), ); @@ -676,9 +703,10 @@ fn reuse_stacks_block_height( ) "#, &[( - WhenError::Runtime, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), + ExpectedContractError::Runtime(CheckErrorKind::NameAlreadyUsed( + "stacks-block-height".to_string(), + )), )], Value::Int(32), ); @@ -700,9 +728,10 @@ fn reuse_stacks_block_height( ) "#, &[( - WhenError::Runtime, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), + ExpectedContractError::Runtime(CheckErrorKind::NameAlreadyUsed( + "stacks-block-height".to_string(), + )), )], Value::Int(3), ); @@ -718,9 +747,10 @@ fn reuse_stacks_block_height( (define-private (test-func) (stacks-block-height)) "#, &[( - WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "stacks-block-height".to_string(), + )), )], Value::Bool(true), ); @@ -736,9 +766,10 @@ fn reuse_stacks_block_height( (define-read-only (test-func) stacks-block-height) "#, &[( - WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "stacks-block-height".to_string(), + )), )], Value::UInt(1234), ); @@ -754,9 +785,10 @@ fn reuse_stacks_block_height( (define-read-only (test-func) false) "#, &[( - WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "stacks-block-height".to_string(), + )), )], Value::Bool(false), ); @@ -787,9 +819,10 @@ fn reuse_stacks_block_height( (define-read-only (test-func) false) "#, &[( - WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "stacks-block-height".to_string(), + )), )], Value::Bool(false), ); @@ -805,9 +838,10 @@ fn reuse_stacks_block_height( (define-read-only (test-func) false) "#, &[( - WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "stacks-block-height".to_string(), + )), )], Value::Bool(false), ); @@ -823,9 +857,10 @@ fn reuse_stacks_block_height( (define-private (test-func) (unwrap-panic (stacks-block-height))) "#, &[( - WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "stacks-block-height".to_string(), + )), )], Value::Bool(true), ); @@ -841,9 +876,10 @@ fn reuse_stacks_block_height( (define-private (test-func) (stacks-block-height)) "#, &[( - WhenError::Initialization, |version, _| version >= ClarityVersion::Clarity3, - CheckErrorKind::NameAlreadyUsed("stacks-block-height".to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + "stacks-block-height".to_string(), + )), )], Value::Bool(true), ); @@ -872,9 +908,10 @@ fn reuse_builtin_name( "# ), &[( - WhenError::Initialization, version_check, - CheckErrorKind::NameAlreadyUsed(name.to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + name.to_string(), + )), )], Value::UInt(1234), ); @@ -894,9 +931,10 @@ fn reuse_builtin_name( "# ), &[( - WhenError::Initialization, version_check, - CheckErrorKind::NameAlreadyUsed(name.to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + name.to_string(), + )), )], Value::Bool(true), ); @@ -917,9 +955,8 @@ fn reuse_builtin_name( "# ), &[( - WhenError::Runtime, version_check, - CheckErrorKind::NameAlreadyUsed(name.to_string()), + ExpectedContractError::Runtime(CheckErrorKind::NameAlreadyUsed(name.to_string())), )], Value::Int(32), ); @@ -943,9 +980,8 @@ fn reuse_builtin_name( "# ), &[( - WhenError::Runtime, version_check, - CheckErrorKind::NameAlreadyUsed(name.to_string()), + ExpectedContractError::Runtime(CheckErrorKind::NameAlreadyUsed(name.to_string())), )], Value::Int(3), ); @@ -963,9 +999,10 @@ fn reuse_builtin_name( "# ), &[( - WhenError::Initialization, version_check, - CheckErrorKind::NameAlreadyUsed(name.to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + name.to_string(), + )), )], Value::Bool(true), ); @@ -983,9 +1020,10 @@ fn reuse_builtin_name( "# ), &[( - WhenError::Initialization, version_check, - CheckErrorKind::NameAlreadyUsed(name.to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + name.to_string(), + )), )], Value::UInt(1234), ); @@ -1003,9 +1041,10 @@ fn reuse_builtin_name( "# ), &[( - WhenError::Initialization, version_check, - CheckErrorKind::NameAlreadyUsed(name.to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + name.to_string(), + )), )], Value::Bool(false), ); @@ -1040,9 +1079,10 @@ fn reuse_builtin_name( "# ), &[( - WhenError::Initialization, version_check, - CheckErrorKind::NameAlreadyUsed(name.to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + name.to_string(), + )), )], Value::Bool(false), ); @@ -1060,9 +1100,10 @@ fn reuse_builtin_name( "# ), &[( - WhenError::Initialization, version_check, - CheckErrorKind::NameAlreadyUsed(name.to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + name.to_string(), + )), )], Value::Bool(false), ); @@ -1080,9 +1121,10 @@ fn reuse_builtin_name( "# ), &[( - WhenError::Initialization, version_check, - CheckErrorKind::NameAlreadyUsed(name.to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + name.to_string(), + )), )], Value::Bool(true), ); @@ -1100,9 +1142,10 @@ fn reuse_builtin_name( "# ), &[( - WhenError::Initialization, version_check, - CheckErrorKind::NameAlreadyUsed(name.to_string()), + ExpectedContractError::Initialization(CheckErrorKind::NameAlreadyUsed( + name.to_string(), + )), )], Value::Bool(true), ); @@ -1133,7 +1176,7 @@ fn test_block_time( if version < ClarityVersion::Clarity4 { let err = analysis.unwrap_err(); assert_eq!( - CheckErrorKind::UndefinedVariable("stacks-block-time".to_string()), + StaticCheckErrorKind::UndefinedVariable("stacks-block-time".to_string()), *err.err ); } else { @@ -1260,7 +1303,7 @@ fn test_current_contract( if version < ClarityVersion::Clarity4 { let err = analysis.unwrap_err(); assert_eq!( - CheckErrorKind::UndefinedVariable("current-contract".to_string()), + StaticCheckErrorKind::UndefinedVariable("current-contract".to_string()), *err.err ); } else { diff --git a/clarity/src/vm/types/signatures.rs b/clarity/src/vm/types/signatures.rs index aadf25f846d..f68f9586a00 100644 --- a/clarity/src/vm/types/signatures.rs +++ b/clarity/src/vm/types/signatures.rs @@ -17,6 +17,7 @@ use std::collections::BTreeMap; use std::fmt; +use clarity_types::errors::analysis::{CommonCheckErrorKind, StaticCheckErrorKind}; pub use clarity_types::types::signatures::{ AssetIdentifier, BufferLength, CallableSubtype, ListTypeData, SequenceSubtype, StringSubtype, StringUTF8Length, TupleTypeSignature, TypeSignature, @@ -26,7 +27,7 @@ use stacks_common::types::StacksEpochId; use self::TypeSignature::SequenceType; use crate::vm::costs::{runtime_cost, CostOverflowingMath}; -use crate::vm::errors::{CheckErrorKind, SyntaxBindingError, SyntaxBindingErrorType}; +use crate::vm::errors::{SyntaxBindingError, SyntaxBindingErrorType}; use crate::vm::representations::{ ClarityName, SymbolicExpression, SymbolicExpressionType, TraitDefinition, }; @@ -162,59 +163,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; + ) -> Result; fn parse_buff_type_repr( type_args: &[SymbolicExpression], - ) -> Result; + ) -> 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, CheckErrorKind>; + ) -> Result, CommonCheckErrorKind>; #[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(CheckErrorKind::UnknownTypeName(typename.into())), + _ => Err(CommonCheckErrorKind::UnknownTypeName(typename.into())), } } @@ -224,18 +225,19 @@ impl TypeSignatureExt for TypeSignature { epoch: StacksEpochId, type_args: &[SymbolicExpression], accounting: &mut A, - ) -> Result { + ) -> Result { if type_args.len() != 2 { - return Err(CheckErrorKind::InvalidTypeDescription); + return Err(CommonCheckErrorKind::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(|_| CheckErrorKind::ValueTooLarge)?; + let max_len = + u32::try_from(*max_len).map_err(|_| CommonCheckErrorKind::ValueTooLarge)?; ListTypeData::new_list(entry_type, max_len).map(|x| x.into()) } else { - Err(CheckErrorKind::InvalidTypeDescription) + Err(CommonCheckErrorKind::InvalidTypeDescription) } } @@ -245,8 +247,8 @@ impl TypeSignatureExt for TypeSignature { epoch: StacksEpochId, type_args: &[SymbolicExpression], accounting: &mut A, - ) -> Result { - let mapped_key_types = parse_name_type_pairs::<_, CheckErrorKind>( + ) -> Result { + let mapped_key_types = parse_name_type_pairs::<_, CommonCheckErrorKind>( epoch, type_args, SyntaxBindingErrorType::TupleCons, @@ -260,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(CheckErrorKind::InvalidTypeDescription); + return Err(CommonCheckErrorKind::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(CheckErrorKind::InvalidTypeDescription) + Err(CommonCheckErrorKind::InvalidTypeDescription) } } @@ -276,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(CheckErrorKind::InvalidTypeDescription); + return Err(CommonCheckErrorKind::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(CheckErrorKind::InvalidTypeDescription) + Err(CommonCheckErrorKind::InvalidTypeDescription) } } @@ -293,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(CheckErrorKind::InvalidTypeDescription); + return Err(CommonCheckErrorKind::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(CheckErrorKind::InvalidTypeDescription) + Err(CommonCheckErrorKind::InvalidTypeDescription) } } @@ -310,9 +312,9 @@ impl TypeSignatureExt for TypeSignature { epoch: StacksEpochId, type_args: &[SymbolicExpression], accounting: &mut A, - ) -> Result { + ) -> Result { if type_args.len() != 1 { - return Err(CheckErrorKind::InvalidTypeDescription); + return Err(CommonCheckErrorKind::InvalidTypeDescription); } let inner_type = TypeSignature::parse_type_repr(epoch, &type_args[0], accounting)?; @@ -323,20 +325,21 @@ impl TypeSignatureExt for TypeSignature { epoch: StacksEpochId, type_args: &[SymbolicExpression], accounting: &mut A, - ) -> Result { + ) -> Result { if type_args.len() != 2 { - return Err(CheckErrorKind::InvalidTypeDescription); + return Err(CommonCheckErrorKind::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)?; - TypeSignature::new_response(ok_type, err_type) + let response_type = TypeSignature::new_response(ok_type, err_type)?; + Ok(response_type) } fn parse_type_repr( epoch: StacksEpochId, x: &SymbolicExpression, accounting: &mut A, - ) -> Result { + ) -> Result { runtime_cost(ClarityCostFunction::TypeParseStep, accounting, 0)?; match x.expr { @@ -347,7 +350,7 @@ impl TypeSignatureExt for TypeSignature { SymbolicExpressionType::List(ref list_contents) => { let (compound_type, rest) = list_contents .split_first() - .ok_or(CheckErrorKind::InvalidTypeDescription)?; + .ok_or(CommonCheckErrorKind::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), @@ -361,10 +364,10 @@ impl TypeSignatureExt for TypeSignature { "response" => { TypeSignature::parse_response_type_repr(epoch, rest, accounting) } - _ => Err(CheckErrorKind::InvalidTypeDescription), + _ => Err(CommonCheckErrorKind::InvalidTypeDescription), } } else { - Err(CheckErrorKind::InvalidTypeDescription) + Err(CommonCheckErrorKind::InvalidTypeDescription) } } SymbolicExpressionType::TraitReference(_, ref trait_definition) @@ -389,7 +392,7 @@ impl TypeSignatureExt for TypeSignature { )), } } - _ => Err(CheckErrorKind::InvalidTypeDescription), + _ => Err(CommonCheckErrorKind::InvalidTypeDescription), } } @@ -398,43 +401,43 @@ impl TypeSignatureExt for TypeSignature { accounting: &mut A, epoch: StacksEpochId, clarity_version: ClarityVersion, - ) -> Result, CheckErrorKind> { + ) -> Result, CommonCheckErrorKind> { let mut trait_signature: BTreeMap = BTreeMap::new(); let functions_types = type_args .first() - .ok_or_else(|| CheckErrorKind::InvalidTypeDescription)? + .ok_or_else(|| CommonCheckErrorKind::InvalidTypeDescription)? .match_list() - .ok_or(CheckErrorKind::DefineTraitBadSignature)?; + .ok_or(CommonCheckErrorKind::DefineTraitBadSignature)?; for function_type in functions_types.iter() { let args = function_type .match_list() - .ok_or(CheckErrorKind::DefineTraitBadSignature)?; + .ok_or(CommonCheckErrorKind::DefineTraitBadSignature)?; if args.len() != 3 { - return Err(CheckErrorKind::InvalidTypeDescription); + return Err(CommonCheckErrorKind::InvalidTypeDescription); } // Extract function's name let fn_name = args[0] .match_atom() - .ok_or(CheckErrorKind::DefineTraitBadSignature)?; + .ok_or(CommonCheckErrorKind::DefineTraitBadSignature)?; // Extract function's arguments let fn_args_exprs = args[1] .match_list() - .ok_or(CheckErrorKind::DefineTraitBadSignature)?; + .ok_or(CommonCheckErrorKind::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(CheckErrorKind::DefineTraitBadSignature), + _ => Err(CommonCheckErrorKind::DefineTraitBadSignature), }, - _ => Err(CheckErrorKind::DefineTraitBadSignature), + _ => Err(CommonCheckErrorKind::DefineTraitBadSignature), }?; if trait_signature @@ -448,7 +451,7 @@ impl TypeSignatureExt for TypeSignature { .is_some() && clarity_version >= ClarityVersion::Clarity2 { - return Err(CheckErrorKind::DefineTraitDuplicateMethod( + return Err(CommonCheckErrorKind::DefineTraitDuplicateMethod( fn_name.to_string(), )); } @@ -473,7 +476,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 = @@ -484,11 +487,12 @@ 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 = - function_type_size.cost_overflow_add(u64::from(arg.type_size()?))?; + function_type_size = function_type_size + .cost_overflow_add(u64::from(arg.type_size()?)) + .map_err(|_| StaticCheckErrorKind::CostOverflow)?; } Ok(function_type_size) } @@ -497,7 +501,7 @@ impl FunctionSignature { &self, epoch: &StacksEpochId, args: Vec, - ) -> Result { + ) -> Result { if args.len() != self.args.len() { return Ok(false); } @@ -546,7 +550,7 @@ pub fn parse_name_type_pairs( accounting: &mut A, ) -> Result, E> where - E: for<'a> From<(CheckErrorKind, &'a SymbolicExpression)>, + E: for<'a> From<(CommonCheckErrorKind, &'a SymbolicExpression)>, { // this is a pretty deep nesting here, but what we're trying to do is pick out the values of // the form: @@ -555,14 +559,14 @@ where use crate::vm::representations::SymbolicExpressionType::List; // step 1: parse it into a vec of symbolicexpression pairs. - let as_pairs: Result, (CheckErrorKind, &SymbolicExpression)> = name_type_pairs + let as_pairs: Result, (CommonCheckErrorKind, &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(( - CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::InvalidLength( + CommonCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::InvalidLength( binding_error_type, i, )), @@ -581,7 +585,7 @@ where .collect(); // step 2: turn into a vec of (name, typesignature) pairs. - let key_types: Result, (CheckErrorKind, &SymbolicExpression)> = (as_pairs?) + let key_types: Result, (CommonCheckErrorKind, &SymbolicExpression)> = (as_pairs?) .iter() .enumerate() .map(|(i, (name_symbol, type_symbol))| { @@ -589,7 +593,7 @@ where .match_atom() .ok_or_else(|| { ( - CheckErrorKind::BadSyntaxBinding(SyntaxBindingError::NotAtom( + CommonCheckErrorKind::BadSyntaxBinding(SyntaxBindingError::NotAtom( binding_error_type, i, )), @@ -614,13 +618,14 @@ impl fmt::Display for FunctionArg { #[cfg(test)] mod test { + use clarity_types::errors::CheckErrorKind; + use clarity_types::errors::CheckErrorKind::*; #[cfg(test)] use rstest::rstest; #[cfg(test)] use rstest_reuse::{self, *}; use stacks_common::types::StacksEpochId; - use super::CheckErrorKind::*; use super::*; use crate::vm::tests::test_clarity_versions; use crate::vm::types::QualifiedContractIdentifier; @@ -635,7 +640,9 @@ mod test { epoch, ) .unwrap()[0]; - TypeSignature::parse_type_repr(epoch, expr, &mut ()).unwrap_err() + TypeSignature::parse_type_repr(epoch, expr, &mut ()) + .unwrap_err() + .into() } #[apply(test_clarity_versions)] @@ -663,7 +670,7 @@ mod test { assert_eq!( TupleTypeSignature::try_from(keys).unwrap_err(), - ValueTooLarge + CommonCheckErrorKind::ValueTooLarge ); } diff --git a/stackslib/src/chainstate/stacks/boot/contract_tests.rs b/stackslib/src/chainstate/stacks/boot/contract_tests.rs index d7b9302de7b..61b8bcc4b11 100644 --- a/stackslib/src/chainstate/stacks/boot/contract_tests.rs +++ b/stackslib/src/chainstate/stacks/boot/contract_tests.rs @@ -6,7 +6,7 @@ use clarity::vm::analysis::mem_type_check; use clarity::vm::clarity::TransactionConnection; use clarity::vm::contexts::OwnedEnvironment; use clarity::vm::database::*; -use clarity::vm::errors::{CheckErrorKind, VmExecutionError}; +use clarity::vm::errors::{CheckErrorKind, StaticCheckErrorKind, 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, @@ -1713,7 +1713,7 @@ fn simple_epoch21_test() { ClarityError::StaticCheck(e) => { assert_eq!( *e.err, - CheckErrorKind::UnknownFunction("stx-account".into()) + StaticCheckErrorKind::UnknownFunction("stx-account".into()) ); } e => panic!("Should have caused an analysis error: {:#?}", e), diff --git a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_block_with_contract_call_success.snap.new b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_block_with_contract_call_success.snap.new deleted file mode 100644 index e63bca6f961..00000000000 --- a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_block_with_contract_call_success.snap.new +++ /dev/null @@ -1,160 +0,0 @@ ---- -source: stackslib/src/chainstate/tests/consensus.rs -assertion_line: 893 -expression: result -snapshot_kind: text ---- -[ - Success(ExpectedBlockOutput( - marf_hash: "186c8e49bcfc59bb67ed22f031f009a44681f296392e0f92bed520918ba463ae", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 11968, - ), - ), - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: UInt(1), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 103, - read_count: 3, - runtime: 499, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 104, - read_count: 4, - runtime: 12467, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "ad23713f072473cad6a32125ed5fa822bb62bbfae8ed2302209c12d2f1958128", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 11968, - ), - ), - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: UInt(1), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 103, - read_count: 3, - runtime: 499, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 104, - read_count: 4, - runtime: 12467, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "021bd30b09b5ac6ff34abd11f05244a966af937b584b1752f272cd717bb25f1d", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 11968, - ), - ), - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: UInt(1), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 103, - read_count: 3, - runtime: 499, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 104, - read_count: 4, - runtime: 12467, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "0e2829cdc4ea57ab95e61b1c17c604c51b501ab684b75c90286623253aceac31", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 11968, - ), - ), - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: UInt(1), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 103, - read_count: 3, - runtime: 499, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 104, - read_count: 4, - runtime: 12467, - ), - )), -] diff --git a/stackslib/src/clarity_cli.rs b/stackslib/src/clarity_cli.rs index b893e9ed4de..5140ae76497 100644 --- a/stackslib/src/clarity_cli.rs +++ b/stackslib/src/clarity_cli.rs @@ -43,7 +43,6 @@ 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::StaticCheckError; use crate::clarity::vm::analysis::{AnalysisDatabase, ContractAnalysis}; use crate::clarity::vm::ast::build_ast; use crate::clarity::vm::contexts::{AssetMap, GlobalContext, OwnedEnvironment}; @@ -51,7 +50,9 @@ 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::{InterpreterResult, RuntimeError, VmExecutionError}; +use crate::clarity::vm::errors::{ + InterpreterResult, RuntimeError, StaticCheckError, VmExecutionError, +}; use crate::clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use crate::clarity::vm::{ analysis, ast, eval_all, ClarityVersion, ContractContext, ContractName, SymbolicExpression, diff --git a/stackslib/src/clarity_vm/tests/analysis_costs.rs b/stackslib/src/clarity_vm/tests/analysis_costs.rs index 45b03e4f5b6..183b3abb21a 100644 --- a/stackslib/src/clarity_vm/tests/analysis_costs.rs +++ b/stackslib/src/clarity_vm/tests/analysis_costs.rs @@ -16,7 +16,7 @@ use clarity::vm::clarity::{ClarityError, TransactionConnection}; use clarity::vm::costs::ExecutionCost; -use clarity::vm::errors::CheckErrorKind; +use clarity::vm::errors::StaticCheckErrorKind; use clarity::vm::functions::NativeFunctions; use clarity::vm::test_util::TEST_HEADER_DB; use clarity::vm::tests::{test_only_mainnet_to_chain_id, UnitTestBurnStateDB}; @@ -320,7 +320,7 @@ fn undefined_top_variable_error(#[case] use_mainnet: bool, #[case] epoch: Stacks let Err(ClarityError::StaticCheck(check_error)) = analysis_result else { panic!("Bad analysis result: {analysis_result:?}"); }; - let CheckErrorKind::UndefinedVariable(var_name) = *check_error.err else { + let StaticCheckErrorKind::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 bc8a2c96dd5..ce90e4a8ecb 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::clarity::ClarityError; -use clarity::vm::errors::{CheckErrorKind, VmExecutionError}; +use clarity::vm::errors::{CheckErrorKind, StaticCheckErrorKind, VmExecutionError}; use clarity::vm::types::SequenceData::Buffer; use clarity::vm::types::{ BuffData, OptionalData, PrincipalData, QualifiedContractIdentifier, TupleData, TypeSignature, @@ -49,7 +49,7 @@ fn test_get_burn_block_info_eval() { let res = clarity_db.analyze_smart_contract(&contract_identifier, clarity_version, contract); if let Err(ClarityError::StaticCheck(check_error)) = res { - if let CheckErrorKind::UnknownFunction(func_name) = *check_error.err { + if let StaticCheckErrorKind::UnknownFunction(func_name) = *check_error.err { assert_eq!(func_name, "get-burn-block-info?"); } else { panic!("Bad analysis error: {:?}", &check_error); @@ -70,7 +70,7 @@ fn test_get_burn_block_info_eval() { let res = clarity_db.analyze_smart_contract(&contract_identifier, clarity_version, contract); if let Err(ClarityError::StaticCheck(check_error)) = res { - if let CheckErrorKind::UnknownFunction(func_name) = *check_error.err { + if let StaticCheckErrorKind::UnknownFunction(func_name) = *check_error.err { assert_eq!(func_name, "get-burn-block-info?"); } else { panic!("Bad analysis error: {:?}", &check_error); @@ -162,7 +162,7 @@ fn test_get_block_info_eval_v210() { let res = clarity_db.analyze_smart_contract(&contract_identifier, clarity_version, contract); if let Err(ClarityError::StaticCheck(check_error)) = res { - if let CheckErrorKind::NoSuchBlockInfoProperty(name) = *check_error.err { + if let StaticCheckErrorKind::NoSuchBlockInfoProperty(name) = *check_error.err { assert_eq!(name, "block-reward"); } else { panic!("Bad analysis error: {:?}", &check_error); @@ -183,7 +183,7 @@ fn test_get_block_info_eval_v210() { let res = clarity_db.analyze_smart_contract(&contract_identifier, clarity_version, contract); if let Err(ClarityError::StaticCheck(check_error)) = res { - if let CheckErrorKind::NoSuchBlockInfoProperty(name) = *check_error.err { + if let StaticCheckErrorKind::NoSuchBlockInfoProperty(name) = *check_error.err { assert_eq!(name, "block-reward"); } else { panic!("Bad analysis error: {:?}", &check_error); @@ -345,7 +345,7 @@ fn trait_invocation_205_with_stored_principal() { .unwrap_err(); match error { ClarityError::StaticCheck(ref e) => match *e.err { - CheckErrorKind::TypeError(..) => (), + StaticCheckErrorKind::TypeError(..) => (), _ => panic!("Unexpected error: {:?}", error), }, _ => panic!("Unexpected error: {:?}", error), @@ -876,7 +876,7 @@ fn test_block_heights() { contract_clarity3, ); if let Err(ClarityError::StaticCheck(check_error)) = res { - if let CheckErrorKind::UndefinedVariable(var_name) = *check_error.err { + if let StaticCheckErrorKind::UndefinedVariable(var_name) = *check_error.err { assert_eq!(var_name, "stacks-block-height"); } else { panic!("Bad analysis error: {:?}", &check_error); @@ -910,7 +910,7 @@ fn test_block_heights() { contract_clarity3, ); if let Err(ClarityError::StaticCheck(check_error)) = res { - if let CheckErrorKind::UndefinedVariable(var_name) = *check_error.err { + if let StaticCheckErrorKind::UndefinedVariable(var_name) = *check_error.err { assert_eq!(var_name, "stacks-block-height"); } else { panic!("Bad analysis error: {:?}", &check_error); @@ -926,7 +926,7 @@ fn test_block_heights() { contract_clarity1, ); if let Err(ClarityError::StaticCheck(check_error)) = res { - if let CheckErrorKind::UndefinedVariable(var_name) = *check_error.err { + if let StaticCheckErrorKind::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/large_contract.rs b/stackslib/src/clarity_vm/tests/large_contract.rs index 06a154ffd1d..dc35a56507d 100644 --- a/stackslib/src/clarity_vm/tests/large_contract.rs +++ b/stackslib/src/clarity_vm/tests/large_contract.rs @@ -71,7 +71,7 @@ const SIMPLE_TOKENS: &str = "(define-map tokens { account: principal } { balance (token-credit! to amount))))) (define-public (faucet) (let ((original-sender tx-sender)) - (as-contract (print (token-transfer (print original-sender) u1))))) + (as-contract (print (token-transfer (print original-sender) u1))))) (define-public (mint-after (block-to-release uint)) (if (>= block-height block-to-release) (faucet) @@ -512,7 +512,7 @@ fn inner_test_simple_naming_system(owned_env: &mut OwnedEnvironment, version: Cl \"not enough balance\") (err 1) (err 3))))) - (define-public (register + (define-public (register (recipient-principal principal) (name int) (salt int))