Skip to content
← Back

src/semantic/operand_wait.ghul

1
namespace Semantic is
2
use Types.Type
3
4
// Which operand a rule has to wait for, and whether a type holds
5
// such a wait.
6
//
7
// A rule cannot fire while an operand's type is still an inference
8
// placeholder, and what it does about that depends on where the
9
// placeholder's type is coming from. A function literal's parameter
10
// is typed by the call site the literal is passed to, which is
11
// resolved on a later walk: the rule waits, because reporting a
12
// failure would name `***` and committing one would freeze it into
13
// whatever consumes the result. A local awaiting its own later uses
14
// is the opposite case - what settles it is elsewhere in the same
15
// body, and the rule's failure is part of what drives the walk that
16
// reaches it - so that one is left to fail as before.
17
class OPERAND_WAIT is
18
// The operand a rule must wait for, or absent when neither is
19
// one. The left operand is answered first, so a rule reports the
20
// side it reads first.
21
for_operands(left: Type?, right: Type?) -> Type? static is
22
if is_typed_by_the_call_site(left) then
23
return left
24
fi
25
26
if is_typed_by_the_call_site(right) then
27
return right
28
fi
29
30
null
31
si
32
33
// Whether a type is the placeholder of an argument, whose type
34
// the call site supplies rather than the body.
35
is_typed_by_the_call_site(type: Type?) -> bool static is
36
if let placeholder: Types.INFERRED_VARIABLE_TYPE = type then
37
return placeholder.origin.is_argument
38
fi
39
40
false
41
si
42
43
// Whether a type holds a rule's waiting result, however deeply -
44
// a tuple element, say. A variable's own placeholder is not one:
45
// it settles in place, so a type holding one is the right answer
46
// once it has.
47
is_held_by(type: Type) -> bool static is
48
// Nothing to look for, and not every type answers a walk.
49
if !type.contains_inferred then
50
return false
51
fi
52
53
let waiting mut = false
54
55
type.walk(
56
inner =>
57
if isa Types.INFERRED_JOIN_TYPE(inner) then
58
waiting = true
59
fi)
60
61
waiting
62
si
63
si
64
si