Skip to content

Commit 34c387c

Browse files
committed
chore: address PR feedback; have handle_binding_list() and parse_name_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)
1 parent 61daffe commit 34c387c

File tree

8 files changed

+73
-30
lines changed

8 files changed

+73
-30
lines changed

clarity/src/vm/analysis/errors.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,20 @@ impl From<(SyntaxBindingError, &SymbolicExpression)> for CheckError {
373373
}
374374
}
375375

376+
impl From<(CheckErrors, &SymbolicExpression)> for CheckError {
377+
fn from(e: (CheckErrors, &SymbolicExpression)) -> Self {
378+
let mut ce = Self::new(e.0);
379+
ce.set_expression(e.1);
380+
ce
381+
}
382+
}
383+
384+
impl From<(CheckErrors, &SymbolicExpression)> for CheckErrors {
385+
fn from(e: (CheckErrors, &SymbolicExpression)) -> Self {
386+
e.0
387+
}
388+
}
389+
376390
impl fmt::Display for CheckErrors {
377391
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
378392
write!(f, "{self:?}")

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> {
335335
if pair_expression.len() != 2 {
336336
return Err(CheckError::with_expression(
337337
SyntaxBindingError::let_binding_invalid_length(i).into(),
338-
&SymbolicExpression::list(pair_expression.to_vec()),
338+
pair,
339339
));
340340
}
341341

@@ -383,7 +383,7 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> {
383383
if pair_expression.len() != 2 {
384384
return Err(CheckError::with_expression(
385385
SyntaxBindingError::tuple_cons_invalid_length(i).into(),
386-
&SymbolicExpression::list(pair_expression.to_vec()),
386+
pair,
387387
));
388388
}
389389

clarity/src/vm/analysis/type_checker/v2_05/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> {
556556
let function_name = function_name
557557
.match_atom()
558558
.ok_or(CheckErrors::BadFunctionName)?;
559-
let args = parse_name_type_pairs::<()>(
559+
let args = parse_name_type_pairs::<(), CheckError>(
560560
StacksEpochId::Epoch2_05,
561561
args,
562562
SyntaxBindingErrorType::Eval,

clarity/src/vm/analysis/type_checker/v2_1/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1251,7 +1251,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> {
12511251
let function_name = function_name
12521252
.match_atom()
12531253
.ok_or(CheckErrors::BadFunctionName)?;
1254-
let args = parse_name_type_pairs::<()>(
1254+
let args = parse_name_type_pairs::<(), CheckError>(
12551255
StacksEpochId::Epoch21,
12561256
args,
12571257
SyntaxBindingErrorType::Eval,

clarity/src/vm/errors.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use crate::vm::ast::errors::ParseError;
3030
use crate::vm::contexts::StackTrace;
3131
use crate::vm::costs::CostErrors;
3232
use crate::vm::types::Value;
33+
use crate::vm::SymbolicExpression;
3334

3435
#[derive(Debug)]
3536
pub struct IncomparableError<T> {
@@ -207,6 +208,12 @@ impl From<CheckErrors> for Error {
207208
}
208209
}
209210

211+
impl From<(CheckErrors, &SymbolicExpression)> for Error {
212+
fn from(err: (CheckErrors, &SymbolicExpression)) -> Self {
213+
Error::Unchecked(err.0)
214+
}
215+
}
216+
210217
impl From<ShortReturnType> for Error {
211218
fn from(err: ShortReturnType) -> Self {
212219
Error::ShortReturn(err)

clarity/src/vm/functions/define.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,12 @@ fn handle_define_function(
142142

143143
check_legal_define(function_name, env.contract_context)?;
144144

145-
let arguments =
146-
parse_name_type_pairs(*env.epoch(), arg_symbols, SyntaxBindingErrorType::Eval, env)?;
145+
let arguments = parse_name_type_pairs::<_, CheckErrors>(
146+
*env.epoch(),
147+
arg_symbols,
148+
SyntaxBindingErrorType::Eval,
149+
env,
150+
)?;
147151

148152
for (argument, _) in arguments.iter() {
149153
check_legal_define(argument, env.contract_context)?;

clarity/src/vm/functions/mod.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -669,23 +669,27 @@ pub fn handle_binding_list<F, E>(
669669
) -> std::result::Result<(), E>
670670
where
671671
F: FnMut(&ClarityName, &SymbolicExpression) -> std::result::Result<(), E>,
672-
E: From<CheckErrors>,
672+
E: for<'a> From<(CheckErrors, &'a SymbolicExpression)>,
673673
{
674674
for (i, binding) in bindings.iter().enumerate() {
675675
let binding_expression = binding.match_list().ok_or_else(|| {
676-
CheckErrors::BadSyntaxBinding(SyntaxBindingError::NotList(binding_error_type, i))
676+
(
677+
SyntaxBindingError::NotList(binding_error_type, i).into(),
678+
binding,
679+
)
677680
})?;
678681
if binding_expression.len() != 2 {
679-
return Err(
680-
CheckErrors::BadSyntaxBinding(SyntaxBindingError::InvalidLength(
681-
binding_error_type,
682-
i,
683-
))
684-
.into(),
685-
);
682+
return Err((
683+
SyntaxBindingError::InvalidLength(binding_error_type, i).into(),
684+
binding,
685+
)
686+
.into());
686687
}
687688
let var_name = binding_expression[0].match_atom().ok_or_else(|| {
688-
CheckErrors::BadSyntaxBinding(SyntaxBindingError::NotAtom(binding_error_type, i))
689+
(
690+
SyntaxBindingError::NotAtom(binding_error_type, i).into(),
691+
&binding_expression[0],
692+
)
689693
})?;
690694
let var_sexp = &binding_expression[1];
691695

clarity/src/vm/types/signatures.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,7 @@ impl TypeSignature {
14941494
type_args: &[SymbolicExpression],
14951495
accounting: &mut A,
14961496
) -> Result<TypeSignature> {
1497-
let mapped_key_types = parse_name_type_pairs(
1497+
let mapped_key_types = parse_name_type_pairs::<_, CheckErrors>(
14981498
epoch,
14991499
type_args,
15001500
SyntaxBindingErrorType::TupleCons,
@@ -1919,57 +1919,71 @@ use crate::vm::ClarityVersion;
19191919
/// Try to parse a list of (name_i, type_i) pairs into Vec<(ClarityName, TypeSignature)>.
19201920
/// On failure, return both the type-check error as well as the index of the symbolic expression which caused
19211921
/// the problem (for purposes of reporting the error).
1922-
pub fn parse_name_type_pairs<A: CostTracker>(
1922+
pub fn parse_name_type_pairs<A: CostTracker, E>(
19231923
epoch: StacksEpochId,
19241924
name_type_pairs: &[SymbolicExpression],
19251925
binding_error_type: SyntaxBindingErrorType,
19261926
accounting: &mut A,
1927-
) -> std::result::Result<Vec<(ClarityName, TypeSignature)>, CheckErrors> {
1927+
) -> std::result::Result<Vec<(ClarityName, TypeSignature)>, E>
1928+
where
1929+
E: for<'a> From<(CheckErrors, &'a SymbolicExpression)>,
1930+
{
19281931
// this is a pretty deep nesting here, but what we're trying to do is pick out the values of
19291932
// the form:
19301933
// ((name1 type1) (name2 type2) (name3 type3) ...)
19311934
// which is a list of 2-length lists of atoms.
19321935
use crate::vm::representations::SymbolicExpressionType::List;
19331936

19341937
// step 1: parse it into a vec of symbolicexpression pairs.
1935-
let as_pairs: std::result::Result<Vec<_>, CheckErrors> = name_type_pairs
1938+
let as_pairs: std::result::Result<Vec<_>, (CheckErrors, &SymbolicExpression)> = name_type_pairs
19361939
.iter()
19371940
.enumerate()
19381941
.map(|(i, key_type_pair)| {
19391942
if let List(ref as_vec) = key_type_pair.expr {
19401943
if as_vec.len() != 2 {
1941-
Err(CheckErrors::BadSyntaxBinding(
1942-
SyntaxBindingError::InvalidLength(binding_error_type, i),
1944+
Err((
1945+
CheckErrors::BadSyntaxBinding(SyntaxBindingError::InvalidLength(
1946+
binding_error_type,
1947+
i,
1948+
)),
1949+
key_type_pair,
19431950
))
19441951
} else {
19451952
Ok((&as_vec[0], &as_vec[1]))
19461953
}
19471954
} else {
1948-
Err(SyntaxBindingError::NotList(binding_error_type, i).into())
1955+
Err((
1956+
SyntaxBindingError::NotList(binding_error_type, i).into(),
1957+
key_type_pair,
1958+
))
19491959
}
19501960
})
19511961
.collect();
19521962

19531963
// step 2: turn into a vec of (name, typesignature) pairs.
1954-
let key_types: std::result::Result<Vec<_>, CheckErrors> = (as_pairs?)
1964+
let key_types: std::result::Result<Vec<_>, (CheckErrors, &SymbolicExpression)> = (as_pairs?)
19551965
.iter()
19561966
.enumerate()
19571967
.map(|(i, (name_symbol, type_symbol))| {
19581968
let name = name_symbol
19591969
.match_atom()
19601970
.ok_or_else(|| {
1961-
CheckErrors::BadSyntaxBinding(SyntaxBindingError::NotAtom(
1962-
binding_error_type,
1963-
i,
1964-
))
1971+
(
1972+
CheckErrors::BadSyntaxBinding(SyntaxBindingError::NotAtom(
1973+
binding_error_type,
1974+
i,
1975+
)),
1976+
*name_symbol,
1977+
)
19651978
})?
19661979
.clone();
1967-
let type_info = TypeSignature::parse_type_repr(epoch, type_symbol, accounting)?;
1980+
let type_info = TypeSignature::parse_type_repr(epoch, type_symbol, accounting)
1981+
.map_err(|e| (e, *type_symbol))?;
19681982
Ok((name, type_info))
19691983
})
19701984
.collect();
19711985

1972-
key_types
1986+
Ok(key_types?)
19731987
}
19741988

19751989
impl fmt::Display for TupleTypeSignature {

0 commit comments

Comments
 (0)