Fix panic of continue/break/return in try-catch block.
This commit is contained in:
parent
e88e65f36e
commit
2dd5aceb1d
@ -569,6 +569,14 @@ impl State {
|
|||||||
pub fn pop_fn_resolution_cache(&mut self) {
|
pub fn pop_fn_resolution_cache(&mut self) {
|
||||||
self.fn_resolution_caches.pop();
|
self.fn_resolution_caches.pop();
|
||||||
}
|
}
|
||||||
|
/// Clear the current functions resolution cache.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if there is no current functions resolution cache.
|
||||||
|
pub fn clear_fn_resolution_cache(&mut self) {
|
||||||
|
self.fn_resolution_caches.last_mut().unwrap().clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// _(INTERNALS)_ A type containing all the limits imposed by the [`Engine`].
|
/// _(INTERNALS)_ A type containing all the limits imposed by the [`Engine`].
|
||||||
@ -1908,11 +1916,9 @@ impl Engine {
|
|||||||
Stmt::Import(_, _, _) => {
|
Stmt::Import(_, _, _) => {
|
||||||
// When imports list is modified, clear the functions lookup cache
|
// When imports list is modified, clear the functions lookup cache
|
||||||
if _has_imports {
|
if _has_imports {
|
||||||
state.fn_resolution_caches.last_mut().map(|c| c.clear());
|
state.clear_fn_resolution_cache();
|
||||||
} else if restore {
|
} else if restore {
|
||||||
state
|
state.push_fn_resolution_cache();
|
||||||
.fn_resolution_caches
|
|
||||||
.push(HashMap::with_capacity_and_hasher(16, StraightHasherBuilder));
|
|
||||||
_has_imports = true;
|
_has_imports = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1926,7 +1932,7 @@ impl Engine {
|
|||||||
scope.rewind(prev_scope_len);
|
scope.rewind(prev_scope_len);
|
||||||
if _has_imports {
|
if _has_imports {
|
||||||
// If imports list is modified, pop the functions lookup cache
|
// If imports list is modified, pop the functions lookup cache
|
||||||
state.fn_resolution_caches.pop();
|
state.pop_fn_resolution_cache();
|
||||||
}
|
}
|
||||||
mods.truncate(prev_mods_len);
|
mods.truncate(prev_mods_len);
|
||||||
state.scope_level -= 1;
|
state.scope_level -= 1;
|
||||||
@ -2286,6 +2292,7 @@ impl Engine {
|
|||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => result,
|
Ok(_) => result,
|
||||||
|
Err(err) if err.is_pseudo_error() => Err(err),
|
||||||
Err(err) if !err.is_catchable() => Err(err),
|
Err(err) if !err.is_catchable() => Err(err),
|
||||||
Err(mut err) => {
|
Err(mut err) => {
|
||||||
let value = match *err {
|
let value = match *err {
|
||||||
|
@ -272,6 +272,15 @@ impl<T: AsRef<str>> From<T> for Box<EvalAltResult> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EvalAltResult {
|
impl EvalAltResult {
|
||||||
|
/// Is this a pseudo error? A pseudo error is one that does not occur naturally.
|
||||||
|
///
|
||||||
|
/// [`LoopBreak`][EvalAltResult::LoopBreak] or [`Return`][EvalAltResult::Return] are pseudo errors.
|
||||||
|
pub fn is_pseudo_error(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::LoopBreak(_, _) | Self::Return(_, _) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
/// Can this error be caught?
|
/// Can this error be caught?
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
|
Loading…
Reference in New Issue
Block a user