module volt.semantic.overload

Code Map

module volt.semantic.overload;


//! Okay, so here's a rough description of how function overload
//! resolution is supposed to work. No doubt there will be discrepancies
//! between this description and the implementation proper. We in the
//! business call those 'bugs'.
enum ThrowOnError;
enum DoNotThrow;

fn selectFunction(target: TargetInfo, functions: ir.Function[], arguments: ir.Exp[], loc: const(Location), throwOnError: bool) ir.Function { }
fn selectFunction(target: TargetInfo, fset: ir.FunctionSet, arguments: ir.Exp[], loc: const(Location), throwOnError: bool) ir.Function { }
fn selectFunction(target: TargetInfo, fset: ir.FunctionSet, arguments: ir.Variable[], loc: const(Location), throwOnError: bool) ir.Function { }
fn selectFunction(target: TargetInfo, functions: ir.Function[], arguments: ir.Variable[], loc: const(Location), throwOnError: bool) ir.Function { }
fn matchLevel(target: TargetInfo, homogenous: bool, argument: ir.Type, parameter: ir.Type, exp: ir.Exp) i32 { }
fn specialisationComparison(ao: Object, bo: Object) bool { }
fn selectFunction(target: TargetInfo, fset: ir.FunctionSet, arguments: ir.Type[], loc: const(Location), throwOnError: bool) ir.Function { }
fn selectFunction(target: TargetInfo, fset: ir.FunctionSet, arguments: ir.Type[], exps: ir.Exp[], loc: const(Location), throwOnError: bool) ir.Function { }
fn selectFunction(target: TargetInfo, functions: ir.Function[], arguments: ir.Type[], loc: const(Location), throwOnError: bool) ir.Function { }
fn selectFunction(target: TargetInfo, functions: FunctionSink, arguments: ir.Type[], loc: const(Location), throwOnError: bool) ir.Function { }
fn selectFunction(target: TargetInfo, functions: scope (scope (ir.Function)[]), arguments: ir.Type[], exps: ir.Exp[], loc: const(Location), throwOnError: bool) ir.Function { }
enum ThrowOnError

Okay, so here's a rough description of how function overload resolution is supposed to work. No doubt there will be discrepancies between this description and the implementation proper. We in the business call those 'bugs'.

For all functions of a given name, first those without the correct number of parameters are culled.

Then of that list, a match level is generated for each function, the match level is the lowest of

4 - Exact match 3 - Exact match with conversion to const 2 - Match with implicit conversion 1 - No match

Then the list is culled down to only functions of the highest match level. If the list has only one element, it is chosen, otherwise the functions are sorted by their specialisation: a function is more specialised than another function if its parameters can be given to the other but the other's cannot be given to it.

For example, foo(ChildClass) is more specialised than foo(Object), as ChildClass can be passed as an Object, but not the other way around.

If after this, there is a function that is more specialised than the next in the list, it is chosen, otherwise an error is generated.