Skip to content
← Back

src/ir/values/load/symbol.ghul

1
namespace IR.Values.Load is
2
use TypeTyped = Semantic.Types.Typed
3
use Semantic.Types.Type
4
use SymbolBase = Semantic.Symbols.Symbol
5
6
class SYMBOL: Value, TypeTyped is
7
symbol: SymbolBase
8
has_symbol: bool => true
9
has_address: bool => true
10
is_consumable: bool => false
11
12
// A load of a symbol with no value form. A namespace never has
13
// one; a function group reaches here when several overloads
14
// were in scope and nothing said which was wanted, or when a
15
// single generic one had nothing to take its type arguments
16
// from. Naming which of those it is saves the reader working
17
// out what about the expression was rejected.
18
non_consumable_message: string is
19
if isa Semantic.Symbols.NAMESPACE(symbol) then
20
return "cannot use a namespace as a value"
21
fi
22
23
let group = cast Semantic.Symbols.FUNCTION_GROUP?(symbol)
24
25
if group? /\ group.count > 1 then
26
return "cannot tell which overload of {symbol.name} is meant here: give the expected function type"
27
fi
28
29
if group? /\ group.count == 1 /\ group.functions[0].is_generic then
30
return "cannot infer the type arguments of {symbol.name} here: give the expected function type"
31
fi
32
33
return "cannot use this here"
34
si
35
36
// Concrete type at construction time. Snapshotted so later
37
// mutation of `symbol.type` (e.g. type-narrowing release
38
// restoring a Variable's declared type) doesn't change the
39
// type observed by IR consumers — the load *was* of a value
40
// of `_snapshot_type`, regardless of where the symbol's
41
// type ends up later. Null when the symbol's type was an
42
// inference placeholder at load time; that case stays lazy
43
// so iterative-inference resolution still flows through, and
44
// may still be null when this is read: the caller-facing
45
// contract is `Value.type: Type?`, and a caller reading this
46
// before the placeholder resolves is expected to see absence
47
// rather than a settled type.
48
_snapshot_type: Type?
49
50
type: Type? pure =>
51
if _snapshot_type? then
52
_snapshot_type
53
else
54
cast TypeTyped?(symbol)?.type
55
fi
56
57
// Pin the snapshotted type to a flow-narrowed form. Used
58
// when optional-narrowing establishes the loaded variable is
59
// non-null at this use site: the load *is* of the
60
// non-optional type, even though the symbol's declared type
61
// still carries `?`. Mirrors how `isa`-narrowing reaches the
62
// snapshot via a mutated `symbol.type` at construction time.
63
narrow_snapshot_type(narrowed: Type) is
64
_snapshot_type = narrowed
65
si
66
67
// The guard a complement-narrowed load needs; see NARROW_GUARD.
68
guard_complement_narrow(context: IR.CONTEXT) is
69
NARROW_GUARD.emit(_snapshot_type, context)
70
si
71
72
from: Value?
73
74
init(from: Value?, symbol: SymbolBase) is
75
super.init()
76
77
self.from = from
78
self.symbol = symbol
79
80
let typed = cast TypeTyped?(symbol)
81
82
if typed? then
83
let typed_type = typed.type
84
85
if typed_type? /\ !typed_type.is_sentinel then
86
_snapshot_type = typed_type
87
fi
88
fi
89
si
90
91
gen(context: IR.CONTEXT) is
92
gen(from, context)
93
context.fixme("load member {symbol.qualified_name}")
94
si
95
96
gen_address(context: IR.CONTEXT) is
97
gen(from, context)
98
context.fixme("load member address {symbol.qualified_name}")
99
si
100
101
to_string() -> string =>
102
"load:[{type}]({from},\"{symbol.name}\")"
103
si
104
si