mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-14 09:44:26 +00:00
scoring experiment
This commit is contained in:
@@ -728,35 +728,38 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand
|
||||
if (operand->mode == Addressing_Constant) {
|
||||
if (check_representable_as_constant(c, operand->value, dst, nullptr)) {
|
||||
if (is_type_typed(dst) && src->kind == Type_Basic) {
|
||||
// NOTE: prefer the untyped constant's default type (int, f64, string, bool,
|
||||
// rune) over other members of the same family, so a call like g(1) picks
|
||||
// `int` over `i64` instead of scoring them identically and going ambiguous.
|
||||
switch (src->Basic.kind) {
|
||||
case Basic_UntypedBool:
|
||||
if (is_type_boolean(dst)) {
|
||||
return 1;
|
||||
return are_types_identical(dst, default_type(src)) ? 1 : 2;
|
||||
}
|
||||
break;
|
||||
case Basic_UntypedRune:
|
||||
if (is_type_integer(dst) || is_type_rune(dst)) {
|
||||
return 1;
|
||||
return are_types_identical(dst, default_type(src)) ? 1 : 2;
|
||||
}
|
||||
break;
|
||||
case Basic_UntypedInteger:
|
||||
if (is_type_integer(dst) || is_type_rune(dst)) {
|
||||
return 1;
|
||||
return are_types_identical(dst, default_type(src)) ? 1 : 2;
|
||||
}
|
||||
break;
|
||||
case Basic_UntypedString:
|
||||
if (is_type_string(dst)) {
|
||||
return 1;
|
||||
return are_types_identical(dst, default_type(src)) ? 1 : 2;
|
||||
}
|
||||
break;
|
||||
case Basic_UntypedFloat:
|
||||
if (is_type_float(dst)) {
|
||||
return 1;
|
||||
return are_types_identical(dst, default_type(src)) ? 1 : 2;
|
||||
}
|
||||
break;
|
||||
case Basic_UntypedComplex:
|
||||
if (is_type_complex(dst)) {
|
||||
return 1;
|
||||
return are_types_identical(dst, default_type(src)) ? 1 : 2;
|
||||
}
|
||||
if (is_type_quaternion(dst)) {
|
||||
return 2;
|
||||
@@ -764,12 +767,13 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand
|
||||
break;
|
||||
case Basic_UntypedQuaternion:
|
||||
if (is_type_quaternion(dst)) {
|
||||
return 1;
|
||||
return are_types_identical(dst, default_type(src)) ? 1 : 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 2;
|
||||
// A cross-family constant conversion ranks below a same-family one.
|
||||
return 3;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -7012,6 +7016,11 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A
|
||||
error(o->expr, "'..' in a variadic procedure can only have one variadic argument at the end");
|
||||
}
|
||||
if (data) {
|
||||
// A synthesised default argument is not evidence of a better match: it
|
||||
// contributes assign_score_function(1) as a dummy bonus and is then scored
|
||||
// again as a perfect-match argument. Discount both, plus 1 to break the
|
||||
// resulting tie, so an exact-arity overload wins.
|
||||
score -= dummy_argument_count * (assign_score_function(0) + assign_score_function(1) + 1);
|
||||
data->score = score;
|
||||
data->result_type = final_proc_type->Proc.results;
|
||||
data->gen_entity = gen_entity;
|
||||
@@ -7041,6 +7050,11 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A
|
||||
}
|
||||
|
||||
if (data) {
|
||||
// A synthesised default argument is not evidence of a better match: it
|
||||
// contributes assign_score_function(1) as a dummy bonus and is then scored
|
||||
// again as a perfect-match argument. Discount both, plus 1 to break the
|
||||
// resulting tie, so an exact-arity overload wins.
|
||||
score -= dummy_argument_count * (assign_score_function(0) + assign_score_function(1) + 1);
|
||||
data->score = score;
|
||||
data->result_type = final_proc_type->Proc.results;
|
||||
data->gen_entity = gen_entity;
|
||||
@@ -7593,8 +7607,10 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c,
|
||||
array_add(&proc_entities, data.gen_entity);
|
||||
index = proc_entities.count-1;
|
||||
|
||||
// prefer non-polymorphic procedures over polymorphic
|
||||
item.score += assign_score_function(1);
|
||||
// Prefer non-polymorphic procedures over polymorphic. This must be a
|
||||
// small tie-break: assign_score_function(1) is ~a full perfect-match
|
||||
// unit, so adding it made a generic beat an exact concrete overload.
|
||||
item.score -= 1;
|
||||
}
|
||||
|
||||
max_matched_features = gb_max(max_matched_features, matched_target_features(&pt->Proc));
|
||||
|
||||
Reference in New Issue
Block a user