Appearance
| 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 |