Skip to content
← Back

src/ir/values/narrow_view.ghul

1
namespace IR.Values is
2
use Semantic.Types.Type
3
4
// Present a flow-narrowed optional reference at its non-optional
5
// type without changing its representation. An optional reference
6
// (`T?`) and its non-optional form (`T`) share IL, so the view is
7
// a pure type-system reinterpretation that gens identically to
8
// the underlying load. Used where presence narrowing establishes
9
// a member-access path holds a value (`receiver.prop` inside
10
// `if receiver.prop? then …`): the use is of `T`, even though the
11
// member is declared `T?`. The value-type optionals (`NULLABLE[T]`
12
// / `MAYBE[T]`) use NARROW_PROJECT instead, since they must emit a
13
// `.value` unwrap. The local-variable path reaches the same effect
14
// through Load.SYMBOL.narrow_snapshot_type; a member load is not
15
// always a Load.SYMBOL, so the view wraps any value.
16
class NARROW_VIEW: Value is
17
underlying: Value
18
_type: Type
19
20
type: Type => _type
21
has_symbol: bool => underlying.has_symbol
22
symbol: Semantic.Symbols.Symbol => underlying.symbol
23
is_consumable: bool => underlying.is_consumable
24
has_address: bool => underlying.has_address
25
is_lightweight_pure: bool => underlying.is_lightweight_pure
26
is_state_changing_call: bool => underlying.is_state_changing_call
27
is_receiver_interior_call: bool => underlying.is_receiver_interior_call
28
29
init(underlying: Value, narrowed: Type) is
30
super.init()
31
32
self.underlying = underlying
33
self._type = narrowed
34
si
35
36
gen(context: IR.CONTEXT) is
37
gen(underlying, context)
38
39
NARROW_GUARD.emit(_type, context)
40
si
41
42
gen_address(context: IR.CONTEXT) is
43
underlying.gen_address(context)
44
si
45
46
to_string() -> string =>
47
"narrow-view:[{type}]({underlying})"
48
si
49
si