Raise error when exporting local anonymous function.
This commit is contained in:
parent
73f10b8adc
commit
39ef766bf1
@ -14,6 +14,7 @@ Bug fixes
|
|||||||
|
|
||||||
* Invalid property or method access such as `a.b::c.d` or `a.b::func()` no longer panics but properly returns a syntax error.
|
* Invalid property or method access such as `a.b::c.d` or `a.b::func()` no longer panics but properly returns a syntax error.
|
||||||
* `Scope::is_constant` now returns the correct value.
|
* `Scope::is_constant` now returns the correct value.
|
||||||
|
* Exporting a variable that contains a local function pointer (including anonymous function or closure) now raises a runtime error.
|
||||||
|
|
||||||
Enhancements
|
Enhancements
|
||||||
------------
|
------------
|
||||||
|
@ -1720,7 +1720,27 @@ impl Module {
|
|||||||
result?;
|
result?;
|
||||||
|
|
||||||
// Variables with an alias left in the scope become module variables
|
// Variables with an alias left in the scope become module variables
|
||||||
for (.., value, mut aliases) in scope {
|
for (name, value, mut aliases) in scope {
|
||||||
|
// It is an error to export function pointers that refer to encapsulated functions
|
||||||
|
if let Some(fn_ptr) = value.downcast_ref::<crate::FnPtr>() {
|
||||||
|
if ast.iter_fn_def().any(|f| f.name == fn_ptr.fn_name()) {
|
||||||
|
return Err(crate::ERR::ErrorMismatchDataType(
|
||||||
|
"".to_string(),
|
||||||
|
if fn_ptr.is_anonymous() {
|
||||||
|
format!("cannot export closure in variable {}", name)
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"cannot export function pointer to local function '{}' in variable {}",
|
||||||
|
fn_ptr.fn_name(),
|
||||||
|
name
|
||||||
|
)
|
||||||
|
},
|
||||||
|
crate::Position::NONE,
|
||||||
|
)
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match aliases.len() {
|
match aliases.len() {
|
||||||
0 => (),
|
0 => (),
|
||||||
1 => {
|
1 => {
|
||||||
|
@ -145,9 +145,9 @@ impl fmt::Display for EvalAltResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Self::ErrorInModule(s, err, ..) if s.is_empty() => {
|
Self::ErrorInModule(s, err, ..) if s.is_empty() => {
|
||||||
write!(f, "Error in module: {}", err)?
|
write!(f, "Error in module > {}", err)?
|
||||||
}
|
}
|
||||||
Self::ErrorInModule(s, err, ..) => write!(f, "Error in module {}: {}", s, err)?,
|
Self::ErrorInModule(s, err, ..) => write!(f, "Error in module '{}' > {}", s, err)?,
|
||||||
|
|
||||||
Self::ErrorVariableExists(s, ..) => write!(f, "Variable is already defined: {}", s)?,
|
Self::ErrorVariableExists(s, ..) => write!(f, "Variable is already defined: {}", s)?,
|
||||||
Self::ErrorForbiddenVariable(s, ..) => write!(f, "Forbidden variable name: {}", s)?,
|
Self::ErrorForbiddenVariable(s, ..) => write!(f, "Forbidden variable name: {}", s)?,
|
||||||
@ -180,15 +180,15 @@ impl fmt::Display for EvalAltResult {
|
|||||||
Self::ErrorRuntime(d, ..) => write!(f, "Runtime error: {}", d)?,
|
Self::ErrorRuntime(d, ..) => write!(f, "Runtime error: {}", d)?,
|
||||||
|
|
||||||
Self::ErrorAssignmentToConstant(s, ..) => write!(f, "Cannot modify constant: {}", s)?,
|
Self::ErrorAssignmentToConstant(s, ..) => write!(f, "Cannot modify constant: {}", s)?,
|
||||||
Self::ErrorMismatchOutputType(s, r, ..) => match (r.as_str(), s.as_str()) {
|
Self::ErrorMismatchOutputType(e, a, ..) => match (a.as_str(), e.as_str()) {
|
||||||
("", s) => write!(f, "Output type is incorrect, expecting {}", s),
|
("", e) => write!(f, "Output type is incorrect, expecting {}", e),
|
||||||
(r, "") => write!(f, "Output type is incorrect: {}", r),
|
(a, "") => write!(f, "Output type is incorrect: {}", a),
|
||||||
(r, s) => write!(f, "Output type is incorrect: {} (expecting {})", r, s),
|
(a, e) => write!(f, "Output type is incorrect: {} (expecting {})", a, e),
|
||||||
}?,
|
}?,
|
||||||
Self::ErrorMismatchDataType(s, r, ..) => match (r.as_str(), s.as_str()) {
|
Self::ErrorMismatchDataType(e, a, ..) => match (a.as_str(), e.as_str()) {
|
||||||
("", s) => write!(f, "Data type is incorrect, expecting {}", s),
|
("", e) => write!(f, "Data type is incorrect, expecting {}", e),
|
||||||
(r, "") => write!(f, "Data type is incorrect: {}", r),
|
(a, "") => write!(f, "Data type is incorrect: {}", a),
|
||||||
(r, s) => write!(f, "Data type is incorrect: {} (expecting {})", r, s),
|
(a, e) => write!(f, "Data type is incorrect: {} (expecting {})", a, e),
|
||||||
}?,
|
}?,
|
||||||
Self::ErrorArithmetic(s, ..) => match s.as_str() {
|
Self::ErrorArithmetic(s, ..) => match s.as_str() {
|
||||||
"" => f.write_str("Arithmetic error"),
|
"" => f.write_str("Arithmetic error"),
|
||||||
|
Loading…
Reference in New Issue
Block a user