Skip to content
← Back

src/semantic/constructor_constraint_retry.ghul

1
namespace Semantic is
2
use Source.LOCATION;
3
4
use Types.Type;
5
6
// Pre-specialisation pass run on a null first overload-resolution
7
// of a constructor call. When the call carries a return-type /
8
// assignment-type / let-init constraint, each candidate is asked
9
// OWNER_CONSTRAINT_SPECIALIZER.specialize_from_constraint: its
10
// direct / variant-of-constraint / ancestor-unification paths pin
11
// whatever owner-generic args the constraint covers, turning
12
// wild formals into concrete ones so the re-resolve's per-arg
13
// binding becomes verification rather than inference.
14
//
15
// The caller passes the candidate list, retries overload resolution
16
// against the returned list only when this method returns non-null,
17
// and falls through (preserving the original null result and its
18
// diagnostic) when no candidate was specialised. Returning null on
19
// "no progress" — rather than the original list — keeps the
20
// existing diagnostic intact and avoids a wasted second resolver
21
// pass when the constraint contributes nothing.
22
//
23
// Stateless: callers can share a single instance.
24
class CONSTRUCTOR_CONSTRAINT_RETRY is
25
_owner_constraint_specializer: OWNER_CONSTRAINT_SPECIALIZER;
26
27
init(owner_constraint_specializer: OWNER_CONSTRAINT_SPECIALIZER) is
28
super.init();
29
_owner_constraint_specializer = owner_constraint_specializer;
30
si
31
32
// For each candidate in `candidates`, run specialize_from_
33
// constraint against `constraint`. Returns the resulting list
34
// iff at least one candidate was specialised (i.e. the call
35
// would change the resolver's input); otherwise null. The
36
// returned list contains all candidates in input order, with
37
// each replaced by its specialised form where applicable —
38
// candidates the constraint doesn't touch come through
39
// unchanged so the resolver keeps seeing the full set.
40
try_specialise_candidates(
41
location: LOCATION,
42
candidates: Collections.Iterable[Symbols.Function]?,
43
constraint: Type?
44
) -> Collections.List[Symbols.Function]? is
45
if !candidates? \/ !constraint? \/ constraint.is_sentinel \/ constraint.is_inferred then
46
return null;
47
fi
48
49
let result = Collections.LIST[Symbols.Function]();
50
let any_specialised mut = false;
51
52
for f in candidates do
53
let specialised = _owner_constraint_specializer.specialize_from_constraint(location, f, constraint);
54
55
if specialised != f then
56
any_specialised = true;
57
fi
58
59
result.add(specialised);
60
od
61
62
if !any_specialised then
63
return null;
64
fi
65
66
return result;
67
si
68
si
69
si