Skip to content
← Back

src/semantic/symbols/generic_parameter_alignment.ghul

1
namespace Semantic.Symbols is
2
use Collections.List
3
use Collections.LIST
4
use Collections.MAP
5
6
use Types.Type
7
8
use Ghul.Pipes
9
10
// Two declarations of the same generic method have type parameters
11
// that are distinct symbols, so nothing relates one declaration's
12
// `T` to the other's except the position each was declared in.
13
// Reading one side's types in the other's terms is what lets the
14
// two be compared at all - by the arguments they take, by the type
15
// they return, and by anything else built from those parameters.
16
class GENERIC_PARAMETER_ALIGNMENT is
17
// `type`, as it reads where `ours` are the type parameters in
18
// scope: each of `theirs` is replaced by whichever of `ours`
19
// stands at the same position. Unchanged where either side
20
// declares none, or where the two declare different numbers,
21
// which is not an override in the first place.
22
rewrite(type: Type, ours: List[Type], theirs: List[Type]) -> Type static is
23
let substitution = _substitution(ours, theirs)
24
25
if substitution.count == 0 then
26
return type
27
fi
28
29
return type.specialize(substitution)
30
si
31
32
rewrite_all(types: List[Type], ours: List[Type], theirs: List[Type])
33
-> List[Type] static
34
is
35
let substitution = _substitution(ours, theirs)
36
37
if substitution.count == 0 then
38
return types
39
fi
40
41
return types |> map(t => t.specialize(substitution)) |> collect()
42
si
43
44
_substitution(ours: List[Type], theirs: List[Type])
45
-> Collections.Map[Symbol, Type] static
46
is
47
let result = MAP[Symbol, Type]()
48
49
if ours.count == 0 \/ ours.count != theirs.count then
50
return result
51
fi
52
53
for i in 0..ours.count do
54
if let their_symbol = theirs[i].symbol then
55
result[their_symbol] = ours[i]
56
fi
57
od
58
59
return result
60
si
61
si
62
si