|
|
@@ -164,8 +164,10 @@ pub(super) fn call_function_type(
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/// Create a list of functions that can be called in this context. If global is true, then
|
|
|
-/// include functions outside of contracts
|
|
|
+/// Create a list of functions matching the given `name` that can be called in this context.
|
|
|
+/// A function is available if it has a body block or if its virtual and its contract is not concrete.
|
|
|
+///
|
|
|
+/// If global is true, then include functions outside of contracts.
|
|
|
pub fn available_functions(
|
|
|
name: &str,
|
|
|
global: bool,
|
|
|
@@ -188,12 +190,14 @@ pub fn available_functions(
|
|
|
ns.contracts[contract_no]
|
|
|
.all_functions
|
|
|
.keys()
|
|
|
+ .filter(|func_no| ns.functions[**func_no].name == name)
|
|
|
.filter_map(|func_no| {
|
|
|
- if ns.functions[*func_no].name == name && ns.functions[*func_no].has_body {
|
|
|
- Some(*func_no)
|
|
|
- } else {
|
|
|
- None
|
|
|
+ let is_abstract = ns.functions[*func_no].is_virtual
|
|
|
+ && !ns.contracts[contract_no].is_concrete();
|
|
|
+ if ns.functions[*func_no].has_body || is_abstract {
|
|
|
+ return Some(*func_no);
|
|
|
}
|
|
|
+ None
|
|
|
}),
|
|
|
);
|
|
|
}
|