Skip to content
← Back

src/semantic/pack_tuple_source.ghul

1
namespace Semantic is
2
use Types.Type
3
4
// Which argument decides the tuple a spread formal's pack binds to.
5
//
6
// A literal written at `f: T.. -> U` is adapted into a one-parameter
7
// wrapper that destructures the pack's tuple, and the wrapper is not
8
// rebuilt once it is in place. While the tuple is still a placeholder
9
// the adaptation is premature exactly when some other formal holds the
10
// same placeholder - `each[T](source: Iterable[T], f: T.. -> void)` -
11
// because that formal's argument settles the tuple on a later walk.
12
// Where no other formal holds it, the literal is the only thing that
13
// can decide it, and adapting it is how that happens.
14
class PACK_TUPLE_SOURCE is
15
init() is
16
super.init()
17
si
18
19
is_decided_by_another_formal(formals: Collections.List[Type], index: int, pack: Type) -> bool is
20
for i in 0..formals.count do
21
if i != index /\ _shares_placeholder(formals[i], pack) then
22
return true
23
fi
24
od
25
26
return false
27
si
28
29
_shares_placeholder(type: Type, pack: Type) -> bool is
30
if type.is_inferred then
31
return _holds(pack, type)
32
fi
33
34
for argument in type.arguments do
35
if _shares_placeholder(argument, pack) then
36
return true
37
fi
38
od
39
40
return false
41
si
42
43
_holds(type: Type, placeholder: Type) -> bool is
44
if type == placeholder then
45
return true
46
fi
47
48
for argument in type.arguments do
49
if _holds(argument, placeholder) then
50
return true
51
fi
52
od
53
54
return false
55
si
56
si
57
si