Skip to content
← Back

src/semantic/unit_variant_constructor.ghul

1
namespace Semantic is
2
use Source.LOCATION;
3
use Types.Type;
4
use IR.Values.Value;
5
6
// Lowers a bare reference to a unit variant — `RED`, `COLOR.RED`,
7
// `Option.NONE`, `Many.EMPTY`, `Option.NONE[int]` — to a NEW value
8
// that points at the variant's interned singleton.
9
// `gen_unit_variant_singleton` and `IR.Values.NEW.gen` cooperate to
10
// emit `ldsfld` for that path.
11
//
12
// For a generic union the variant only constructs once every type
13
// parameter is fixed. When the caller has an expected type pushed
14
// in by the parent context — assignment LHS, function-argument
15
// slot, return slot, explicit type arguments via `Option.NONE[int]`
16
// — `try_load` borrows the OWNER_CONSTRAINT_SPECIALIZER to derive
17
// the type arguments from it, the same way `Option.NONE()` does
18
// today via resolve_constructor. When the variant is generic and
19
// the constraint can't fill every owner slot, `try_load` returns
20
// null and the caller falls back to a TYPE_EXPRESSION; any
21
// enclosing `()` then drives the regular constructor-resolution
22
// path.
23
class UNIT_VARIANT_CONSTRUCTOR is
24
_owner_constraint_specializer: OWNER_CONSTRAINT_SPECIALIZER;
25
_type_arg_placeholder_registry: TYPE_ARG_PLACEHOLDER_REGISTRY;
26
_function_caller: FUNCTION_CALLER;
27
28
init(
29
owner_constraint_specializer: OWNER_CONSTRAINT_SPECIALIZER,
30
type_arg_placeholder_registry: TYPE_ARG_PLACEHOLDER_REGISTRY,
31
function_caller: FUNCTION_CALLER
32
) is
33
super.init();
34
35
_owner_constraint_specializer = owner_constraint_specializer;
36
_type_arg_placeholder_registry = type_arg_placeholder_registry;
37
_function_caller = function_caller;
38
si
39
40
try_load(
41
location: LOCATION,
42
variant: Symbols.VARIANT?,
43
constraint: Type?,
44
cache_key: Syntax.Trees.Node
45
) -> UNIT_VARIANT_LOAD? is
46
if !variant? \/ !variant.is_unit_variant then
47
return null;
48
fi
49
50
let init_group = cast Symbols.FUNCTION_GROUP?(variant.find_direct("init"));
51
52
if !init_group? \/ init_group.functions.count == 0 then
53
return null;
54
fi
55
56
let init mut = init_group.functions[0];
57
58
if variant.is_generic then
59
if constraint? then
60
init = _owner_constraint_specializer.specialize_from_constraint(location, init, constraint);
61
fi
62
63
// Any owner-generic slot the constraint didn't fix
64
// (or every slot when no constraint reached us) is
65
// covered by a phantom origin keyed off `cache_key`.
66
// The enclosing call's overload resolver back-feeds
67
// each phantom from the argument slot it lands in,
68
// matching the path taken by resolve_constructor for
69
// the parenthesised form.
70
init = _type_arg_placeholder_registry.specialize_with_placeholders(location, init, cache_key);
71
fi
72
73
let owner_type = init.owner!.type;
74
assert owner_type? else "variant constructor owner has no type";
75
let value = _function_caller.call_constructor(init, Collections.LIST[Value](), owner_type);
76
77
return UNIT_VARIANT_LOAD(value, init);
78
si
79
si
80
81
class UNIT_VARIANT_LOAD is
82
value: Value;
83
constructor: Symbols.Function;
84
85
init(value: Value, constructor: Symbols.Function) is
86
super.init();
87
self.value = value;
88
self.constructor = constructor;
89
si
90
si
91
si