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
28
init(underlying: Value, narrowed: Type) is
29
super.init();
30
31
self.underlying = underlying;
32
self._type = narrowed;
33
si
34
35
gen(context: IR.CONTEXT) is
36
gen(underlying, context);
37
si
38
39
gen_address(context: IR.CONTEXT) is
40
underlying.gen_address(context);
41
si
42
43
to_string() -> string =>
44
"narrow-view:[{type}]({underlying})";
45
si
46
si