Skip to content

Commit 88f4280

Browse files
committed
Merge branch 'aac-client-breaking' of https://github.com/stacks-network/stacks-core into chore/aac-rename-check-errors
2 parents 68b959d + 5d37187 commit 88f4280

File tree

50 files changed

+499
-447
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+499
-447
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> {
501501
/// - Returns CheckErrorKind::WriteAttemptedInReadOnly if there is a read-only
502502
/// violation, i.e. if some function marked read-only attempts to modify
503503
/// the chainstate.
504-
pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), CheckError>
504+
pub fn run(&mut self, contract_analysis: &ContractAnalysis) -> Result<(), StaticCheckError>
505505
```
506506

507507
This comment is considered positive because it explains the contract of the function in pseudo-code. Someone who understands the constructs mentioned could, e.g., write a test for this method from this description.

clarity-types/src/errors/analysis.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -485,9 +485,15 @@ pub enum CheckErrorKind {
485485
}
486486

487487
#[derive(Debug, PartialEq)]
488-
pub struct CheckError {
488+
/// Represents an error encountered during Clarity's type-checking and semantic analysis phase.
489+
/// Wraps a `CheckErrorKind` variant, optionally includes the expressions causing the error,
490+
/// and provides diagnostic information for debugging.
491+
pub struct StaticCheckError {
492+
/// The specific type-checking or semantic error that occurred.
489493
pub err: Box<CheckErrorKind>,
494+
/// Optional vector of expressions related to the error, if available.
490495
pub expressions: Option<Vec<SymbolicExpression>>,
496+
/// Diagnostic details (e.g., line/column numbers, error message, suggestions) around the error.
491497
pub diagnostic: Diagnostic,
492498
}
493499

@@ -502,10 +508,10 @@ impl CheckErrorKind {
502508
}
503509
}
504510

505-
impl CheckError {
506-
pub fn new(err: CheckErrorKind) -> CheckError {
511+
impl StaticCheckError {
512+
pub fn new(err: CheckErrorKind) -> StaticCheckError {
507513
let diagnostic = Diagnostic::err(&err);
508-
CheckError {
514+
StaticCheckError {
509515
err: Box::new(err),
510516
expressions: None,
511517
diagnostic,
@@ -533,13 +539,13 @@ impl CheckError {
533539
}
534540
}
535541

536-
impl From<(SyntaxBindingError, &SymbolicExpression)> for CheckError {
542+
impl From<(SyntaxBindingError, &SymbolicExpression)> for StaticCheckError {
537543
fn from(e: (SyntaxBindingError, &SymbolicExpression)) -> Self {
538544
Self::with_expression(CheckErrorKind::BadSyntaxBinding(e.0), e.1)
539545
}
540546
}
541547

542-
impl From<(CheckErrorKind, &SymbolicExpression)> for CheckError {
548+
impl From<(CheckErrorKind, &SymbolicExpression)> for StaticCheckError {
543549
fn from(e: (CheckErrorKind, &SymbolicExpression)) -> Self {
544550
let mut ce = Self::new(e.0);
545551
ce.set_expression(e.1);
@@ -559,7 +565,7 @@ impl fmt::Display for CheckErrorKind {
559565
}
560566
}
561567

562-
impl fmt::Display for CheckError {
568+
impl fmt::Display for StaticCheckError {
563569
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
564570
write!(f, "{}", self.err)?;
565571

@@ -571,9 +577,9 @@ impl fmt::Display for CheckError {
571577
}
572578
}
573579

574-
impl From<CostErrors> for CheckError {
580+
impl From<CostErrors> for StaticCheckError {
575581
fn from(err: CostErrors) -> Self {
576-
CheckError::from(CheckErrorKind::from(err))
582+
StaticCheckError::from(CheckErrorKind::from(err))
577583
}
578584
}
579585

@@ -596,7 +602,7 @@ impl From<CostErrors> for CheckErrorKind {
596602
}
597603
}
598604

599-
impl error::Error for CheckError {
605+
impl error::Error for StaticCheckError {
600606
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
601607
None
602608
}
@@ -608,9 +614,9 @@ impl error::Error for CheckErrorKind {
608614
}
609615
}
610616

611-
impl From<CheckErrorKind> for CheckError {
617+
impl From<CheckErrorKind> for StaticCheckError {
612618
fn from(err: CheckErrorKind) -> Self {
613-
CheckError::new(err)
619+
StaticCheckError::new(err)
614620
}
615621
}
616622

clarity-types/src/errors/mod.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub mod lexer;
2020

2121
use std::{error, fmt};
2222

23-
pub use analysis::{CheckError, CheckErrorKind};
23+
pub use analysis::{CheckErrorKind, StaticCheckError};
2424
pub use ast::{ParseError, ParseErrors, ParseResult};
2525
pub use cost::CostErrors;
2626
pub use lexer::LexerError;
@@ -46,7 +46,7 @@ pub enum Error {
4646
Unchecked(CheckErrorKind),
4747
Interpreter(InterpreterError),
4848
Runtime(RuntimeErrorType, Option<StackTrace>),
49-
ShortReturn(ShortReturnType),
49+
EarlyReturn(EarlyReturnError),
5050
}
5151

5252
/// InterpreterErrors are errors that *should never* occur.
@@ -104,8 +104,15 @@ pub enum RuntimeErrorType {
104104
}
105105

106106
#[derive(Debug, PartialEq)]
107-
pub enum ShortReturnType {
108-
ExpectedValue(Box<Value>),
107+
/// Errors triggered during Clarity contract evaluation that cause early termination.
108+
/// These errors halt evaluation and fail the transaction.
109+
pub enum EarlyReturnError {
110+
/// Failed to unwrap an `Optional` (`none`) or `Response` (`err` or `ok`) Clarity value.
111+
/// The `Box<Value>` holds the original or thrown value. Triggered by `try!`, `unwrap-or`, or
112+
/// `unwrap-err-or`.
113+
UnwrapFailed(Box<Value>),
114+
/// An 'asserts!' expression evaluated to false.
115+
/// The `Box<Value>` holds the value provided as the second argument to `asserts!`.
109116
AssertionFailed(Box<Value>),
110117
}
111118

@@ -122,7 +129,7 @@ impl PartialEq<Error> for Error {
122129
match (self, other) {
123130
(Error::Runtime(x, _), Error::Runtime(y, _)) => x == y,
124131
(Error::Unchecked(x), Error::Unchecked(y)) => x == y,
125-
(Error::ShortReturn(x), Error::ShortReturn(y)) => x == y,
132+
(Error::EarlyReturn(x), Error::EarlyReturn(y)) => x == y,
126133
(Error::Interpreter(x), Error::Interpreter(y)) => x == y,
127134
_ => false,
128135
}
@@ -208,9 +215,9 @@ impl From<(CheckErrorKind, &SymbolicExpression)> for Error {
208215
}
209216
}
210217

211-
impl From<ShortReturnType> for Error {
212-
fn from(err: ShortReturnType) -> Self {
213-
Error::ShortReturn(err)
218+
impl From<EarlyReturnError> for Error {
219+
fn from(err: EarlyReturnError) -> Self {
220+
Error::EarlyReturn(err)
214221
}
215222
}
216223

@@ -225,11 +232,11 @@ impl From<Error> for () {
225232
fn from(_err: Error) -> Self {}
226233
}
227234

228-
impl From<ShortReturnType> for Value {
229-
fn from(val: ShortReturnType) -> Self {
235+
impl From<EarlyReturnError> for Value {
236+
fn from(val: EarlyReturnError) -> Self {
230237
match val {
231-
ShortReturnType::ExpectedValue(v) => *v,
232-
ShortReturnType::AssertionFailed(v) => *v,
238+
EarlyReturnError::UnwrapFailed(v) => *v,
239+
EarlyReturnError::AssertionFailed(v) => *v,
233240
}
234241
}
235242
}
@@ -241,15 +248,15 @@ mod test {
241248
#[test]
242249
fn equality() {
243250
assert_eq!(
244-
Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true)))),
245-
Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true))))
251+
Error::EarlyReturn(EarlyReturnError::UnwrapFailed(Box::new(Value::Bool(true)))),
252+
Error::EarlyReturn(EarlyReturnError::UnwrapFailed(Box::new(Value::Bool(true))))
246253
);
247254
assert_eq!(
248255
Error::Interpreter(InterpreterError::InterpreterError("".to_string())),
249256
Error::Interpreter(InterpreterError::InterpreterError("".to_string()))
250257
);
251258
assert!(
252-
Error::ShortReturn(ShortReturnType::ExpectedValue(Box::new(Value::Bool(true))))
259+
Error::EarlyReturn(EarlyReturnError::UnwrapFailed(Box::new(Value::Bool(true))))
253260
!= Error::Interpreter(InterpreterError::InterpreterError("".to_string()))
254261
);
255262
}

clarity-types/src/types/serialization.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use crate::types::{
3333

3434
/// Errors that may occur in serialization or deserialization
3535
/// If deserialization failed because the described type is a bad type and
36-
/// a CheckError is thrown, it gets wrapped in BadTypeError.
36+
/// a CheckErrorKind is thrown, it gets wrapped in BadTypeError.
3737
/// Any IOErrrors from the supplied buffer will manifest as IOError variants,
3838
/// except for EOF -- if the deserialization code experiences an EOF, it is caught
3939
/// and rethrown as DeserializationError
@@ -493,7 +493,7 @@ impl TypeSignature {
493493
Err(CheckErrorKind::CouldNotDetermineSerializationType) => {
494494
if no_ok_type {
495495
// if both the ok type and the error type are NoType,
496-
// throw a CheckError. This should not be possible, but the check
496+
// throw a CheckErrorKind. This should not be possible, but the check
497497
// is done out of caution.
498498
return Err(CheckErrorKind::CouldNotDetermineSerializationType);
499499
} else {

clarity/src/vm/analysis/analysis_db.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use clarity_types::representations::ClarityName;
2020
use clarity_types::types::{QualifiedContractIdentifier, TraitIdentifier};
2121
use stacks_common::types::StacksEpochId;
2222

23-
use crate::vm::analysis::errors::{CheckError, CheckErrorKind};
23+
use crate::vm::analysis::errors::{CheckErrorKind, StaticCheckError};
2424
use crate::vm::analysis::type_checker::ContractAnalysis;
2525
use crate::vm::database::{
2626
ClarityBackingStore, ClarityDeserializable, ClaritySerializable, RollbackWrapper,
@@ -63,13 +63,13 @@ impl<'a> AnalysisDatabase<'a> {
6363
self.store.nest();
6464
}
6565

66-
pub fn commit(&mut self) -> Result<(), CheckError> {
66+
pub fn commit(&mut self) -> Result<(), StaticCheckError> {
6767
self.store
6868
.commit()
6969
.map_err(|e| CheckErrorKind::Expects(format!("{e:?}")).into())
7070
}
7171

72-
pub fn roll_back(&mut self) -> Result<(), CheckError> {
72+
pub fn roll_back(&mut self) -> Result<(), StaticCheckError> {
7373
self.store
7474
.rollback()
7575
.map_err(|e| CheckErrorKind::Expects(format!("{e:?}")).into())
@@ -99,11 +99,11 @@ impl<'a> AnalysisDatabase<'a> {
9999
pub fn load_contract_non_canonical(
100100
&mut self,
101101
contract_identifier: &QualifiedContractIdentifier,
102-
) -> Result<Option<ContractAnalysis>, CheckError> {
102+
) -> Result<Option<ContractAnalysis>, StaticCheckError> {
103103
self.store
104104
.get_metadata(contract_identifier, AnalysisDatabase::storage_key())
105105
// treat NoSuchContract error thrown by get_metadata as an Option::None --
106-
// the analysis will propagate that as a CheckError anyways.
106+
// the analysis will propagate that as a StaticCheckError anyways.
107107
.ok()
108108
.flatten()
109109
.map(|x| {
@@ -118,12 +118,12 @@ impl<'a> AnalysisDatabase<'a> {
118118
&mut self,
119119
contract_identifier: &QualifiedContractIdentifier,
120120
epoch: &StacksEpochId,
121-
) -> Result<Option<ContractAnalysis>, CheckError> {
121+
) -> Result<Option<ContractAnalysis>, StaticCheckError> {
122122
Ok(self
123123
.store
124124
.get_metadata(contract_identifier, AnalysisDatabase::storage_key())
125125
// treat NoSuchContract error thrown by get_metadata as an Option::None --
126-
// the analysis will propagate that as a CheckError anyways.
126+
// the analysis will propagate that as a StaticCheckError anyways.
127127
.ok()
128128
.flatten()
129129
.map(|x| {
@@ -141,7 +141,7 @@ impl<'a> AnalysisDatabase<'a> {
141141
&mut self,
142142
contract_identifier: &QualifiedContractIdentifier,
143143
contract: &ContractAnalysis,
144-
) -> Result<(), CheckError> {
144+
) -> Result<(), StaticCheckError> {
145145
let key = AnalysisDatabase::storage_key();
146146
if self.store.has_metadata_entry(contract_identifier, key) {
147147
return Err(
@@ -158,7 +158,7 @@ impl<'a> AnalysisDatabase<'a> {
158158
pub fn get_clarity_version(
159159
&mut self,
160160
contract_identifier: &QualifiedContractIdentifier,
161-
) -> Result<ClarityVersion, CheckError> {
161+
) -> Result<ClarityVersion, StaticCheckError> {
162162
// TODO: this function loads the whole contract to obtain the function type.
163163
// but it doesn't need to -- rather this information can just be
164164
// stored as its own entry. the analysis cost tracking currently only
@@ -176,7 +176,7 @@ impl<'a> AnalysisDatabase<'a> {
176176
contract_identifier: &QualifiedContractIdentifier,
177177
function_name: &str,
178178
epoch: &StacksEpochId,
179-
) -> Result<Option<FunctionType>, CheckError> {
179+
) -> Result<Option<FunctionType>, StaticCheckError> {
180180
// TODO: this function loads the whole contract to obtain the function type.
181181
// but it doesn't need to -- rather this information can just be
182182
// stored as its own entry. the analysis cost tracking currently only
@@ -196,7 +196,7 @@ impl<'a> AnalysisDatabase<'a> {
196196
contract_identifier: &QualifiedContractIdentifier,
197197
function_name: &str,
198198
epoch: &StacksEpochId,
199-
) -> Result<Option<FunctionType>, CheckError> {
199+
) -> Result<Option<FunctionType>, StaticCheckError> {
200200
// TODO: this function loads the whole contract to obtain the function type.
201201
// but it doesn't need to -- rather this information can just be
202202
// stored as its own entry. the analysis cost tracking currently only
@@ -216,7 +216,7 @@ impl<'a> AnalysisDatabase<'a> {
216216
contract_identifier: &QualifiedContractIdentifier,
217217
trait_name: &str,
218218
epoch: &StacksEpochId,
219-
) -> Result<Option<BTreeMap<ClarityName, FunctionSignature>>, CheckError> {
219+
) -> Result<Option<BTreeMap<ClarityName, FunctionSignature>>, StaticCheckError> {
220220
// TODO: this function loads the whole contract to obtain the function type.
221221
// but it doesn't need to -- rather this information can just be
222222
// stored as its own entry. the analysis cost tracking currently only
@@ -237,7 +237,7 @@ impl<'a> AnalysisDatabase<'a> {
237237
pub fn get_implemented_traits(
238238
&mut self,
239239
contract_identifier: &QualifiedContractIdentifier,
240-
) -> Result<BTreeSet<TraitIdentifier>, CheckError> {
240+
) -> Result<BTreeSet<TraitIdentifier>, StaticCheckError> {
241241
let contract = self
242242
.load_contract_non_canonical(contract_identifier)?
243243
.ok_or(CheckErrorKind::NoSuchContract(

clarity/src/vm/analysis/arithmetic_checker/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use clarity_types::representations::ClarityName;
1818

1919
pub use super::errors::{
20-
check_argument_count, check_arguments_at_least, CheckError, CheckErrorKind,
20+
check_argument_count, check_arguments_at_least, CheckErrorKind, StaticCheckError,
2121
};
2222
use crate::vm::analysis::types::ContractAnalysis;
2323
use crate::vm::functions::define::{DefineFunctions, DefineFunctionsParsed};

clarity/src/vm/analysis/contract_interface_builder/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::collections::{BTreeMap, BTreeSet};
1919
use stacks_common::types::StacksEpochId;
2020

2121
use crate::vm::analysis::types::ContractAnalysis;
22-
use crate::vm::analysis::CheckError;
22+
use crate::vm::analysis::StaticCheckError;
2323
use crate::vm::types::signatures::CallableSubtype;
2424
use crate::vm::types::{
2525
FixedFunction, FunctionArg, FunctionType, TupleTypeSignature, TypeSignature,
@@ -28,7 +28,7 @@ use crate::vm::{CheckErrorKind, ClarityName, ClarityVersion};
2828

2929
pub fn build_contract_interface(
3030
contract_analysis: &ContractAnalysis,
31-
) -> Result<ContractInterface, CheckError> {
31+
) -> Result<ContractInterface, StaticCheckError> {
3232
let mut contract_interface =
3333
ContractInterface::new(contract_analysis.epoch, contract_analysis.clarity_version);
3434

@@ -267,7 +267,7 @@ impl ContractInterfaceFunction {
267267
fn from_map(
268268
map: &BTreeMap<ClarityName, FunctionType>,
269269
access: ContractInterfaceFunctionAccess,
270-
) -> Result<Vec<ContractInterfaceFunction>, CheckError> {
270+
) -> Result<Vec<ContractInterfaceFunction>, StaticCheckError> {
271271
map.iter()
272272
.map(|(name, function_type)| {
273273
Ok(ContractInterfaceFunction {
@@ -400,7 +400,7 @@ impl ContractInterface {
400400
}
401401
}
402402

403-
pub fn serialize(&self) -> Result<String, CheckError> {
403+
pub fn serialize(&self) -> Result<String, StaticCheckError> {
404404
serde_json::to_string(self).map_err(|_| {
405405
CheckErrorKind::Expects("Failed to serialize contract interface".into()).into()
406406
})

clarity/src/vm/analysis/errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

1717
pub use clarity_types::errors::analysis::{
18-
check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckError,
19-
CheckErrorKind, SyntaxBindingError, SyntaxBindingErrorType,
18+
check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckErrorKind,
19+
StaticCheckError, SyntaxBindingError, SyntaxBindingErrorType,
2020
};

0 commit comments

Comments
 (0)