Fix bug in constant interpolated string.
This commit is contained in:
parent
fc976172e7
commit
1073a7bd54
@ -12,6 +12,7 @@ Bug fixes
|
|||||||
* `switch` cases with conditions that evaluate to constant `()` no longer optimize to `false` (should raise a type error during runtime).
|
* `switch` cases with conditions that evaluate to constant `()` no longer optimize to `false` (should raise a type error during runtime).
|
||||||
* Fixes concatenation of BLOB's and strings, where the BLOB's should be interpreted as UTF-8 encoded strings.
|
* Fixes concatenation of BLOB's and strings, where the BLOB's should be interpreted as UTF-8 encoded strings.
|
||||||
* Capturing an unknown variable in a closure no longer panics.
|
* Capturing an unknown variable in a closure no longer panics.
|
||||||
|
* Fixes panic in interpolated strings with constant expressions.
|
||||||
|
|
||||||
New features
|
New features
|
||||||
------------
|
------------
|
||||||
|
@ -5,12 +5,16 @@ use crate::engine::{KEYWORD_FN_PTR, OP_EXCLUSIVE_RANGE, OP_INCLUSIVE_RANGE};
|
|||||||
use crate::func::hashing::ALT_ZERO_HASH;
|
use crate::func::hashing::ALT_ZERO_HASH;
|
||||||
use crate::tokenizer::Token;
|
use crate::tokenizer::Token;
|
||||||
use crate::types::dynamic::Union;
|
use crate::types::dynamic::Union;
|
||||||
use crate::{calc_fn_hash, Dynamic, FnPtr, Identifier, ImmutableString, Position, StaticVec, INT};
|
use crate::{
|
||||||
|
calc_fn_hash, Dynamic, FnPtr, Identifier, ImmutableString, Position, SmartString, StaticVec,
|
||||||
|
INT,
|
||||||
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
use std::{
|
use std::{
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
fmt,
|
fmt,
|
||||||
|
fmt::Write,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
iter::once,
|
iter::once,
|
||||||
num::{NonZeroU8, NonZeroUsize},
|
num::{NonZeroU8, NonZeroUsize},
|
||||||
@ -576,6 +580,16 @@ impl Expr {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interpolated string
|
||||||
|
Self::InterpolatedString(x, ..) if self.is_constant() => {
|
||||||
|
let mut s = SmartString::new_const();
|
||||||
|
for segment in x.iter() {
|
||||||
|
let v = segment.get_literal_value().unwrap();
|
||||||
|
write!(&mut s, "{}", v).unwrap();
|
||||||
|
}
|
||||||
|
s.into()
|
||||||
|
}
|
||||||
|
|
||||||
// Fn
|
// Fn
|
||||||
Self::FnCall(ref x, ..)
|
Self::FnCall(ref x, ..)
|
||||||
if !x.is_qualified() && x.args.len() == 1 && x.name == KEYWORD_FN_PTR =>
|
if !x.is_qualified() && x.args.len() == 1 && x.name == KEYWORD_FN_PTR =>
|
||||||
|
@ -12,7 +12,7 @@ use crate::tokenizer::{Span, Token};
|
|||||||
use crate::types::dynamic::AccessMode;
|
use crate::types::dynamic::AccessMode;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, FnPtr, Identifier,
|
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, FnPtr, Identifier,
|
||||||
Position, Scope, StaticVec, AST, INT,
|
Position, Scope, StaticVec, AST, INT, ImmutableString,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
@ -1052,10 +1052,10 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) {
|
|||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = Expr::StringConstant(state.engine.const_empty_string(), *pos);
|
*expr = Expr::StringConstant(state.engine.const_empty_string(), *pos);
|
||||||
}
|
}
|
||||||
// `...`
|
// `... ${const} ...`
|
||||||
Expr::InterpolatedString(x, ..) if x.len() == 1 && matches!(x[0], Expr::StringConstant(..)) => {
|
Expr::InterpolatedString(..) if expr.is_constant() => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = mem::take(&mut x[0]);
|
*expr = Expr::StringConstant(expr.get_literal_value().unwrap().cast::<ImmutableString>(), expr.position());
|
||||||
}
|
}
|
||||||
// `... ${ ... } ...`
|
// `... ${ ... } ...`
|
||||||
Expr::InterpolatedString(x, ..) => {
|
Expr::InterpolatedString(x, ..) => {
|
||||||
|
@ -334,6 +334,8 @@ fn test_string_split() -> Result<(), Box<EvalAltResult>> {
|
|||||||
fn test_string_interpolated() -> Result<(), Box<EvalAltResult>> {
|
fn test_string_interpolated() -> Result<(), Box<EvalAltResult>> {
|
||||||
let engine = Engine::new();
|
let engine = Engine::new();
|
||||||
|
|
||||||
|
assert_eq!(engine.eval::<String>("`${}`")?, "");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
engine.eval::<String>(
|
engine.eval::<String>(
|
||||||
"
|
"
|
||||||
|
Loading…
Reference in New Issue
Block a user