Skip to content

Conversation

jcnelson
Copy link
Member

Description

This PR improves the expressiveness of CheckErrors::BadSyntaxBinding and some related binding errors to indicate both the kind of binding considered, as well as the specific structural deficiency. Specifically, it differentiates between faulty let-bindings, function definitions, and tuple constructors, and it treats all instance of invalid type signatures found in top-level definitions as CheckErrors::BadSyntaxBinding while reporting the inner CheckErrors error message and innermost faulty binding in the signature.

For example, in develop today, these errors are reported.

$ echo '(let ((u1 u2)) true)' | clarity-cli eval_raw - | jq -r '.error.analysis' | head -n 1
BadSyntaxBinding
$ echo '(define-public (foo (string -19)) (ok true))' | clarity-cli eval_raw - | jq -r '.error.analysis' | head -n 1
BadSyntaxBinding
$ echo '(tuple oops (foo u1))' | clarity-cli eval_raw - | jq -r '.error.analysis' | head -n 1
TupleExpectsPairs

In this PR, these same errors are as follows:

$ echo '(let ((u1 u2)) true)' | /tmp/clarity-cli eval_raw - | jq -r '.error.analysis' | head -n 1
BadSyntaxBinding(NotAtom(Let, 0, SymbolicExpression { expr: LiteralValue(UInt(1)), id: 5 }))
$ echo '(define-public (foo (string -19)) (ok true))' | /tmp/clarity-cli eval_raw - | jq -r '.error.analysis' | head -n 1
BadSyntaxBinding(BadTypeSignature(0, SymbolicExpression { expr: LiteralValue(Int(-19)), id: 7 }, "supplied type description is invalid"))
$ echo '(tuple oops (foo u1))' | /tmp/clarity-cli eval_raw - | jq -r '.error.analysis' | head -n 1
BadSyntaxBinding(NotList(TupleCons, 0, SymbolicExpression { expr: Atom(ClarityName("oops")), id: 3 }))

Right now, this PR does not touch CheckErrors::BadMayTypeDefinition, but I'm happy to add that as well.

Applicable issues

Additional info (benefits, drawbacks, caveats)

Looking at where the errors were used, it does not appear that any changes are consensus critical. I could not find any place in the codebase where the caller matches on a CheckErrors value affected by this PR.

Checklist

  • Test coverage for new or modified code paths
  • Changelog is updated
  • Required documentation changes (e.g., docs/rpc/openapi.yaml and rpc-endpoints.md for v2 endpoints, event-dispatcher.md for new events)
  • New clarity functions have corresponding PR in clarity-benchmarking repo
  • New integration test(s) added to bitcoin-tests.yml

jcnelson added 20 commits July 31, 2025 16:46
… formatting code) to specialize CheckErrors::BadSyntaxBinding. Also, remove tuple-specific bad syntax binding errors since they are now captured by BadSyntaxBinding
…e-bindings, report the specific kind of error instead of the generic BadSyntaxBinding
…kind of binding being checked so an error will result in a meaningful message
…ype-check being performed so error messages can reflect it
… to now check for the specific variant of BadSyntaxBinding. Also, add comprehensive checks for each variant of BadSyntaxBinding, as well as test to verify that error messages do not grow unbound with the type's nesting depth
…nding error and the specific context in which it occurs
…reporting, and consolidate Display implementation for SymbolicExpression and SymbolicExpressionType
…and update tests to expect when BadSyntaxBinding wraps another CheckErrors variant
…g expecting it to wrap an inner CheckErrors variant which lead to a bad binding
…xBindingError::BadTypeSignature(..) ..), instead of BadSyntaxExpectedListOfPairs, so the caller has a better idea about what is structurally deficient about the binding or type signature
@jcnelson jcnelson requested review from a team as code owners July 31, 2025 21:38
@jcnelson jcnelson changed the base branch from master to develop July 31, 2025 21:38
@jcnelson jcnelson requested review from kantai and obycode August 1, 2025 15:32
Copy link

codecov bot commented Aug 1, 2025

Codecov Report

❌ Patch coverage is 92.34973% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.11%. Comparing base (073d2f4) to head (e047935).
⚠️ Report is 61 commits behind head on develop.

Files with missing lines Patch % Lines
clarity/src/vm/analysis/errors.rs 84.61% 12 Missing ⚠️
...y/src/vm/analysis/type_checker/v2_1/natives/mod.rs 87.50% 7 Missing ⚠️
clarity/src/vm/tests/mod.rs 0.00% 4 Missing ⚠️
clarity/src/vm/representations.rs 57.14% 3 Missing ⚠️
.../src/vm/analysis/type_checker/v2_05/natives/mod.rs 94.73% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #6343      +/-   ##
===========================================
+ Coverage    75.26%   80.11%   +4.85%     
===========================================
  Files          555      555              
  Lines       351247   351471     +224     
===========================================
+ Hits        264353   281598   +17245     
+ Misses       86894    69873   -17021     
Files with missing lines Coverage Δ
clarity/src/vm/analysis/read_only_checker/mod.rs 87.39% <100.00%> (+0.75%) ⬆️
clarity/src/vm/analysis/tests/mod.rs 100.00% <100.00%> (+11.90%) ⬆️
clarity/src/vm/analysis/type_checker/v2_05/mod.rs 90.41% <100.00%> (+0.48%) ⬆️
...ty/src/vm/analysis/type_checker/v2_05/tests/mod.rs 99.89% <100.00%> (+9.54%) ⬆️
clarity/src/vm/analysis/type_checker/v2_1/mod.rs 90.42% <100.00%> (+0.18%) ⬆️
...ity/src/vm/analysis/type_checker/v2_1/tests/mod.rs 99.84% <100.00%> (+6.71%) ⬆️
clarity/src/vm/errors.rs 74.68% <100.00%> (+0.99%) ⬆️
clarity/src/vm/functions/define.rs 98.86% <100.00%> (+0.02%) ⬆️
clarity/src/vm/functions/mod.rs 98.01% <100.00%> (+0.97%) ⬆️
clarity/src/vm/functions/tuples.rs 83.33% <100.00%> (ø)
... and 8 more

... and 233 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 073d2f4...e047935. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@obycode obycode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. I just noted a couple of import clippy warnings that need to be fixed.

Copy link
Contributor

@kantai kantai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have two high-level pieces of feedback on the new error type:

  1. The new error struct shouldn't keep a copy of the expression. Either the struct and the binding handlers should be refactored so that this can be avoided (making sure to pass the correct expression to the CheckError struct). Another option is that rather than wrap the SyntaxBindingError into a CheckErrors variant, we do something like make each of the SyntaxBindingError variants into a new CheckErrors variant, and then define From<SyntaxBindingError> for CheckError which pulls the expression out of the SyntaxBindingError (so rather than wrapping a SyntaxBindingError, we're converting from a SyntaxBindingError). I'm a little agnostic between those, but I definitely think that using the CheckError's diagnostic/expression field is the right thing to do.

  2. BadTypeSignature should be dropped, and the underlying error should just be returned. I think the pain of returning the underlying error is that previously the CheckError expression that is constructed used the whole binding as the expression (e.g., the tuple type definition) rather than the just the offending expression. So instead, we should just make sure that we're setting the offending expression on the returned CheckError. This will probably involve some careful type handling in the parse_name_type_pairs function, but it certainly seems doable.

@github-project-automation github-project-automation bot moved this from Status: In Review to Status: 💻 In Progress in Stacks Core Eng Aug 15, 2025
@jcnelson jcnelson requested review from kantai and obycode August 15, 2025 23:22
obycode
obycode previously approved these changes Aug 19, 2025
Copy link
Contributor

@obycode obycode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

…_type_pairs() return Result<_, E> where E: for<'a> From<(CheckErrors, &'a SymbolicExpression)> so these functions can be used in both analysis and runtime contexts with the appropriate error types (this patch also adds conversions for them)
@jcnelson jcnelson added this pull request to the merge queue Aug 26, 2025
Merged via the queue into stacks-network:develop with commit ed22100 Aug 26, 2025
834 of 850 checks passed
@jcnelson jcnelson deleted the fix/bad-syntax-binding-error-variants branch August 26, 2025 14:34
@github-project-automation github-project-automation bot moved this from Status: 💻 In Progress to Status: ✅ Done in Stacks Core Eng Aug 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

[VM] Anemic VM errors in type-checking bindings
3 participants