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.
|
||||
* `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
|
||||
------------
|
||||
|
@ -1720,7 +1720,27 @@ impl Module {
|
||||
result?;
|
||||
|
||||
// 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() {
|
||||
0 => (),
|
||||
1 => {
|
||||
|
@ -145,9 +145,9 @@ impl fmt::Display for EvalAltResult {
|
||||
}
|
||||
|
||||
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::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::ErrorAssignmentToConstant(s, ..) => write!(f, "Cannot modify constant: {}", s)?,
|
||||
Self::ErrorMismatchOutputType(s, r, ..) => match (r.as_str(), s.as_str()) {
|
||||
("", s) => write!(f, "Output type is incorrect, expecting {}", s),
|
||||
(r, "") => write!(f, "Output type is incorrect: {}", r),
|
||||
(r, s) => write!(f, "Output type is incorrect: {} (expecting {})", r, s),
|
||||
Self::ErrorMismatchOutputType(e, a, ..) => match (a.as_str(), e.as_str()) {
|
||||
("", e) => write!(f, "Output type is incorrect, expecting {}", e),
|
||||
(a, "") => write!(f, "Output type is incorrect: {}", a),
|
||||
(a, e) => write!(f, "Output type is incorrect: {} (expecting {})", a, e),
|
||||
}?,
|
||||
Self::ErrorMismatchDataType(s, r, ..) => match (r.as_str(), s.as_str()) {
|
||||
("", s) => write!(f, "Data type is incorrect, expecting {}", s),
|
||||
(r, "") => write!(f, "Data type is incorrect: {}", r),
|
||||
(r, s) => write!(f, "Data type is incorrect: {} (expecting {})", r, s),
|
||||
Self::ErrorMismatchDataType(e, a, ..) => match (a.as_str(), e.as_str()) {
|
||||
("", e) => write!(f, "Data type is incorrect, expecting {}", e),
|
||||
(a, "") => write!(f, "Data type is incorrect: {}", a),
|
||||
(a, e) => write!(f, "Data type is incorrect: {} (expecting {})", a, e),
|
||||
}?,
|
||||
Self::ErrorArithmetic(s, ..) => match s.as_str() {
|
||||
"" => f.write_str("Arithmetic error"),
|
||||
|
Loading…
Reference in New Issue
Block a user