Skip to content
← Back

src/syntax/process/compile_calls.ghul

1
namespace Syntax.Process is
2
use Logging;
3
use Source;
4
5
use Semantic.Types.Type;
6
7
use IR.Values;
8
9
use Ghul.Pipes;
10
11
// Compiles calls and constructor invocations: the `new` expression,
12
// function / method / closure / indexer calls, and the shared
13
// constructor-resolution path. Split out of COMPILE_EXPRESSIONS,
14
// which delegates visit(new) and the enclosed logic of
15
// visit(call) here. The try/catch wrapper of visit(call) — with
16
// its speculation bracket around the argument walk — stays on the
17
// visitor; visit_call is the enclosed logic.
18
class COMPILE_CALLS is
19
_logger: Logger;
20
_symbol_table: Semantic.SYMBOL_TABLE;
21
_symbol_use_locations: Semantic.SYMBOL_USE_LOCATIONS;
22
_innate_symbol_lookup: Semantic.Lookups.InnateSymbolLookup;
23
_overload_resolver: Semantic.OVERLOAD_RESOLVER;
24
_function_caller: Semantic.FUNCTION_CALLER;
25
_owner_constraint_specializer: Semantic.OWNER_CONSTRAINT_SPECIALIZER;
26
_owner_type_arg_specializer: Semantic.OWNER_TYPE_ARG_SPECIALIZER;
27
_constructor_constraint_retry: Semantic.CONSTRUCTOR_CONSTRAINT_RETRY;
28
_under_determination_detector: Semantic.UNDER_DETERMINATION_DETECTOR;
29
_type_arg_placeholder_registry: Semantic.TYPE_ARG_PLACEHOLDER_REGISTRY;
30
_access: COMPILE_ACCESS;
31
_visitor: COMPILE_EXPRESSIONS;
32
_named_argument_binder: NAMED_ARGUMENT_BINDER;
33
_flow: NARROWING_FLOW;
34
_delegate_shape: Semantic.DELEGATE_SHAPE;
35
_delegate_push_candidates: Semantic.DELEGATE_PUSH_CANDIDATES;
36
_symbol_loader: Semantic.SYMBOL_LOADER;
37
38
init(
39
logger: Logger,
40
symbol_table: Semantic.SYMBOL_TABLE,
41
symbol_use_locations: Semantic.SYMBOL_USE_LOCATIONS,
42
innate_symbol_lookup: Semantic.Lookups.InnateSymbolLookup,
43
overload_resolver: Semantic.OVERLOAD_RESOLVER,
44
function_caller: Semantic.FUNCTION_CALLER,
45
owner_constraint_specializer: Semantic.OWNER_CONSTRAINT_SPECIALIZER,
46
owner_type_arg_specializer: Semantic.OWNER_TYPE_ARG_SPECIALIZER,
47
under_determination_detector: Semantic.UNDER_DETERMINATION_DETECTOR,
48
type_arg_placeholder_registry: Semantic.TYPE_ARG_PLACEHOLDER_REGISTRY,
49
access: COMPILE_ACCESS,
50
visitor: COMPILE_EXPRESSIONS,
51
flow: NARROWING_FLOW,
52
symbol_loader: Semantic.SYMBOL_LOADER
53
) is
54
super.init();
55
56
_logger = logger;
57
_symbol_table = symbol_table;
58
_symbol_use_locations = symbol_use_locations;
59
_innate_symbol_lookup = innate_symbol_lookup;
60
_overload_resolver = overload_resolver;
61
_function_caller = function_caller;
62
_owner_constraint_specializer = owner_constraint_specializer;
63
_owner_type_arg_specializer = owner_type_arg_specializer;
64
_constructor_constraint_retry = Semantic.CONSTRUCTOR_CONSTRAINT_RETRY(owner_constraint_specializer);
65
_under_determination_detector = under_determination_detector;
66
_type_arg_placeholder_registry = type_arg_placeholder_registry;
67
_access = access;
68
_visitor = visitor;
69
_named_argument_binder = NAMED_ARGUMENT_BINDER(logger);
70
_flow = flow;
71
_delegate_shape = Semantic.DELEGATE_SHAPE();
72
_delegate_push_candidates = Semantic.DELEGATE_PUSH_CANDIDATES(_delegate_shape, innate_symbol_lookup);
73
_symbol_loader = symbol_loader;
74
si
75
76
// Rebuild a named call's already-collected argument lists - the
77
// AST expressions and the parallel value / type lists - into
78
// the resolved overload's parameter order. `permutation` is
79
// indexed by formal parameter; a negative entry marks a
80
// parameter the call omitted, which is filled with a `default`
81
// value of that parameter's type (taken from `target`).
82
_apply_named_permutation(
83
argument_expressions: Trees.Expressions.LIST,
84
arguments: Collections.LIST[Value],
85
argument_types: Collections.LIST[Type],
86
permutation: Collections.List[int],
87
target: Semantic.Symbols.Function
88
) is
89
let source_expressions = Collections.LIST[Trees.Expressions.Expression](argument_expressions);
90
let source_arguments = Collections.LIST[Value](arguments);
91
let source_argument_types = Collections.LIST[Type](argument_types);
92
93
argument_expressions.expressions.clear();
94
arguments.clear();
95
argument_types.clear();
96
97
for formal_index in 0..permutation.count do
98
let source_index = permutation[formal_index];
99
100
if source_index >= 0 then
101
argument_expressions.expressions.add(source_expressions[source_index]);
102
arguments.add(source_arguments[source_index]);
103
argument_types.add(source_argument_types[source_index]);
104
else
105
let formal_type = target.arguments[formal_index];
106
let stored = target.argument_defaults[formal_index];
107
let default_value = DEFAULT_ARGUMENT_VALUES.build(stored, formal_type, _innate_symbol_lookup);
108
109
let default_expression = Trees.Expressions.DEFAULT(argument_expressions.location, null);
110
default_expression.set_expected_type(formal_type, "");
111
default_expression.compile_expressions_state.value = default_value;
112
113
argument_expressions.expressions.add(default_expression);
114
arguments.add(default_value);
115
argument_types.add(formal_type);
116
fi
117
od
118
si
119
120
visit_new(`new: Trees.Expressions.NEW) is
121
// TODO call resolve_constructor() instead
122
123
`new.compile_expressions_state.value = null;
124
125
let type: Type? mut;
126
127
if `new.type_expression? then
128
type = `new.type_expression.type;
129
130
if type == null then
131
_logger.poison(`new.type_expression!.location, "has no type");
132
`new.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), `new.location);
133
return;
134
fi
135
elif let `new.expected_type? then
136
// `new(args)` form: no explicit type, take the type
137
// from the parent context's constraint (LHS of an
138
// assignment / typed initializer / call arg whose
139
// formal type is known). A `BOX?` constraint is
140
// peeled — a constructor produces the underlying
141
// instance and is widened to the optional at the
142
// assignment site, so the NEW value carries the
143
// non-optional class type rather than masquerading
144
// as `BOX?`.
145
type = expected_type.as_non_optional();
146
else
147
_logger.error(`new.location, "cannot infer type for new");
148
`new.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), `new.location);
149
return;
150
fi
151
152
if !isa Semantic.Types.NAMED(type) then
153
if `new.type_expression? then
154
_logger.error(`new.type_expression.location, "cannot instantiate {type}");
155
else
156
_logger.error(`new.location, "cannot instantiate {type}");
157
fi
158
`new.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), `new.location);
159
return;
160
fi
161
162
if `new.type_expression? then
163
`new.type_expression.check_is_not_void(_logger, "cannot use void type here");
164
fi
165
166
let named_type = type;
167
let type_symbol mut = named_type.symbol;
168
169
if let abstract_class: Semantic.Symbols.CLASS = type_symbol then
170
if abstract_class.is_abstract then
171
_logger.error(`new.location, "cannot instantiate abstract class {abstract_class.name}");
172
fi
173
fi
174
175
let symbol = named_type.scope.find_direct("init");
176
177
let function_group = cast Semantic.Symbols.FUNCTION_GROUP?(symbol);
178
179
let arguments = Collections.LIST[Value]();
180
let argument_types = Collections.LIST[Type]();
181
182
for a in `new.arguments do
183
let value = a.value;
184
185
if value? /\ value.type? /\ value.check_is_consumable(_logger, a.location) then
186
arguments.add(value);
187
argument_types.add(value.type!);
188
else
189
let t = Semantic.Types.ERROR();
190
191
arguments.add(DUMMY(t, a.location));
192
193
argument_types.add(t);
194
fi
195
od
196
197
if !function_group? then
198
`new.compile_expressions_state.value =
199
DUMMY(
200
type,
201
`new.location
202
);
203
204
_logger.error(`new.location, "no constructor found init({argument_types|})");
205
206
return;
207
fi
208
209
let overload_result = _overload_resolver.resolve(`new.location, function_group, argument_types, false, true, true);
210
211
if overload_result == null then
212
`new.compile_expressions_state.value =
213
DUMMY(
214
type,
215
`new.location
216
);
217
218
return;
219
fi
220
221
let function mut = overload_result.function;
222
223
function = _owner_constraint_specializer.specialize_from_constraint(`new.location, function, `new.expected_type);
224
225
if isa Semantic.Symbols.GENERIC(function.owner) then
226
type_symbol = cast Semantic.Symbols.Symbol(function.owner);
227
// The GENERIC owner of a resolved constructor always carries
228
// a concrete type (the specialized class) by this point.
229
type = function.owner.type;
230
fi;
231
232
let is_directly_owned mut = false;
233
234
if isa Semantic.Symbols.GENERIC(type_symbol) /\ isa Semantic.Symbols.Symbol(function.owner) then
235
is_directly_owned = type_symbol =~ cast Semantic.Symbols.Symbol(function.owner);
236
else
237
is_directly_owned = type_symbol == function.owner;
238
fi
239
240
if !is_directly_owned then
241
_logger.error(`new.location, "cannot call superclass constructor {function}");
242
fi
243
244
if `new.type_expression? then
245
let right_location = `new.type_expression.right_location;
246
_symbol_use_locations.add_symbol_use(right_location, function);
247
_symbol_use_locations.add_symbol_use(right_location, type_symbol.root_unspecialized_symbol);
248
fi
249
250
`new.compile_expressions_state.value =
251
NEW(
252
// every branch above either sets type or early-returns
253
type,
254
function,
255
arguments
256
);
257
si
258
259
// Sibling-arg specialisation entry: produce the phantom-
260
// origin list for unbound slots from the per-AST cache, then
261
// delegate to `OWNER_TYPE_ARG_SPECIALIZER` for the binding
262
// and specialisation logic. Phantom origins live on the
263
// placeholder registry so match propagation across body-retry
264
// iterations lands on the same Variables; the specialiser
265
// itself is stateless, which lets the binding contract be
266
// unit-tested in isolation.
267
_specialise_candidate_from_concrete_siblings(
268
candidate: Semantic.Symbols.Function,
269
argument_types: Collections.List[Semantic.Types.Type],
270
cache_key: Trees.Node,
271
location: LOCATION
272
) -> Semantic.Symbols.Function? is
273
if isa Semantic.Symbols.GENERIC(candidate.owner) then
274
return candidate;
275
fi
276
277
let owner_classy = cast Semantic.Symbols.Classy?(candidate.owner);
278
279
if !owner_classy? \/ !owner_classy.is_generic then
280
return candidate;
281
fi
282
283
let origins = _type_arg_placeholder_registry.get_or_create(cache_key, location, owner_classy);
284
285
return _owner_type_arg_specializer.specialize_from_concrete_siblings(candidate, argument_types, origins, location);
286
si
287
288
// Find the single arity- and instance-matching candidate in a
289
// function group, or null if there are zero or multiple. Used
290
// by `visit_call`'s constraint-push retry: when the first
291
// overload resolution fails, having exactly one candidate to
292
// push formal arg types from disambiguates the constraint
293
// direction. Multi-candidate disambiguation under constraint
294
// push is bigger work tracked under #1174.
295
_try_find_single_arity_candidate(
296
group: Semantic.Symbols.FUNCTION_GROUP,
297
arg_count: int,
298
want_instance: bool
299
) -> Semantic.Symbols.Function? is
300
let result: Semantic.Symbols.Function? mut = null;
301
let count mut = 0;
302
303
for f in group.functions do
304
if !want_instance /\ f.is_instance then
305
continue;
306
fi
307
308
if !f.are_arguments_declared then
309
continue;
310
fi
311
312
if f.arguments.count != arg_count then
313
continue;
314
fi
315
316
result = f;
317
count = count + 1;
318
od
319
320
if count == 1 then
321
return result;
322
fi
323
324
return null;
325
si
326
327
// should be called with logger speculating
328
_compile_call_arguments(
329
argument_expressions: Trees.Expressions.LIST,
330
arguments: Collections.LIST[Value],
331
argument_types: Collections.LIST[Type]
332
) is
333
for a in argument_expressions do
334
_compile_one_argument(a, arguments, argument_types);
335
od
336
si
337
338
// True for a bare `_` argument (no explicit `_[T]` type
339
// argument) that failed to infer a type on the first walk -
340
// before the callee was resolved, nothing had pushed it an
341
// expected type yet.
342
is_unresolved_default_argument(a: Trees.Expressions.Expression) -> bool static is
343
if !isa Trees.Expressions.DEFAULT(a) \/ a.type_expression? then
344
return false;
345
fi
346
347
if let value: Value = a.value then
348
if let type: Type = value.type then
349
return type.is_error;
350
fi
351
352
return true;
353
fi
354
355
return true;
356
si
357
358
// True when the call carries at least one unresolved `default`
359
// argument.
360
has_unresolved_default_argument(argument_expressions: Collections.List[Trees.Expressions.Expression]) -> bool static =>
361
argument_expressions |> any(a => COMPILE_CALLS.is_unresolved_default_argument(a));
362
363
// Once overload resolution has settled on a single, unambiguous
364
// `function`, retry any bare `_` argument that had no type to
365
// infer against on the first walk - the resolved callee's
366
// formal types are available now. Re-walks every argument
367
// under a fresh speculation level, since the roll-back below
368
// discards whatever the first walk logged for the whole call,
369
// not just the `_` arguments.
370
//
371
// A `_` argument is only ever pushed a type when the resolved
372
// formal at that position is itself concrete: a generic
373
// candidate whose type variable is pinned by a sibling
374
// argument or an enclosing constraint is already specialized
375
// by this point, so the formal there is concrete too, but a
376
// type variable free only in the `_` slot leaves the formal
377
// wild and the argument is left to re-report its original
378
// "cannot infer type of default here" error - a `_` argument
379
// never itself contributes to binding a type variable.
380
//
381
// A resolved formal with a declared .NET default value (an
382
// optional CLR parameter) takes that value rather than the
383
// type's zero value, so a positionally-written `_` behaves
384
// exactly like omitting the same parameter by name.
385
_resolve_deferred_defaults(
386
function: Semantic.Symbols.Function,
387
argument_expressions: Collections.List[Trees.Expressions.Expression],
388
arguments: Collections.LIST[Value],
389
argument_types: Collections.LIST[Type]
390
) is
391
if !has_unresolved_default_argument(argument_expressions) then
392
return;
393
fi
394
395
_logger.roll_back();
396
_logger.speculate();
397
_flow.restore();
398
399
for (index, a) in argument_expressions |> index() do
400
if
401
COMPILE_CALLS.is_unresolved_default_argument(a) /\
402
index < function.arguments.count /\
403
!function.arguments[index].is_wild
404
then
405
let formal_type = function.arguments[index];
406
407
let stored =
408
if index < function.argument_defaults.count then
409
function.argument_defaults[index]
410
else
411
null
412
fi;
413
414
if stored? then
415
a.compile_expressions_state.value = DEFAULT_ARGUMENT_VALUES.build(stored, formal_type, _innate_symbol_lookup);
416
else
417
a.set_expected_type(formal_type, "");
418
a.walk(_visitor);
419
fi
420
elif isa Trees.Expressions.DEFAULT(a) then
421
// A `_[T]` argument, or a `DEFAULT` node
422
// `_apply_named_permutation` synthesised to fill an
423
// omitted named argument with the callee's own
424
// declared default value, already carries its
425
// final value. Re-walking either through
426
// `visit_default` would overwrite that value with
427
// the type's zero value - visit_default has no way
428
// to tell "already resolved to the right thing"
429
// from "resolved once, resolve again" - so leave
430
// it untouched. A still-unresolved `_` whose
431
// formal is wild has no value to protect and is
432
// walked below to re-report its own error under
433
// this fresh speculation level.
434
if COMPILE_CALLS.is_unresolved_default_argument(a) then
435
a.walk(_visitor);
436
fi
437
else
438
// ensure any error messages are committed
439
a.walk(_visitor);
440
fi
441
442
if let value: Value = a.value /\ value.type? then
443
arguments[index] = value;
444
argument_types[index] = value.type!;
445
fi
446
od
447
si
448
449
_compile_one_argument(
450
a: Trees.Expressions.Expression,
451
arguments: Collections.LIST[Value],
452
argument_types: Collections.LIST[Type]
453
) is
454
let value = a.value;
455
456
if value? /\ value.type? /\ value.check_is_consumable(_logger, a.location) then
457
arguments.add(value);
458
argument_types.add(value.type!);
459
else
460
let t = Semantic.Types.ERROR();
461
462
arguments.add(DUMMY(t, a.location));
463
464
argument_types.add(t);
465
fi
466
si
467
468
// Find the delegate type's own compiler-synthesized
469
// constructor - `.ctor(object, native int)`, the only one a
470
// real .NET delegate type ever declares.
471
_find_delegate_constructor(type: Semantic.Types.Type) -> Semantic.Symbols.Function? is
472
let named = cast Semantic.Types.NAMED?(type);
473
474
if !named? then
475
return null;
476
fi
477
478
let symbol = named.scope.find_direct("init");
479
480
if let group: Semantic.Symbols.FUNCTION_GROUP = symbol then
481
if group.count == 1 then
482
return group.functions[0];
483
fi
484
485
return null;
486
fi
487
488
return cast Semantic.Symbols.Function?(symbol);
489
si
490
491
// Resolve a member that is either a bare Function or a
492
// single-member FUNCTION_GROUP - the shape `find_member`
493
// returns for a non-overloaded method (mirrors
494
// DELEGATE_SHAPE._find_invoke).
495
_find_single_function_member(type: Semantic.Types.Type, name: string) -> Semantic.Symbols.Function? is
496
let symbol = type.find_member(name);
497
498
if let group: Semantic.Symbols.FUNCTION_GROUP = symbol then
499
if group.count == 1 then
500
return group.functions[0];
501
fi
502
503
return null;
504
fi
505
506
return cast Semantic.Symbols.Function?(symbol);
507
si
508
509
// A real .NET delegate type's sole constructor is the
510
// compiler-synthesized `.ctor(object, native int)`, which no
511
// ghūl call site can satisfy (nothing produces a usable
512
// `native int`), so a single-argument constructor call
513
// against a named delegate type is free to mean explicit
514
// conversion: `TargetDelegate(functionValue)`.
515
//
516
// A literal written directly as the argument is pushed the
517
// delegate type as its expected type, the same way an
518
// assignment or argument-formal context does (see
519
// COMPILE_LAMBDAS.visit_function), and constructs the
520
// delegate directly via ldftn/newobj. An existing
521
// function/delegate-typed value has no compile-time method
522
// token to `ldftn` - its method is only known at runtime, via
523
// its own `Method` property - so it is reconstructed over
524
// (Target, MethodHandle function pointer) via the target
525
// delegate's own constructor instead.
526
_resolve_delegate_value_construction(
527
location: LOCATION,
528
type: Semantic.Types.Type,
529
argument_expression: Trees.Expressions.Expression
530
) -> (Value, Value) is
531
if isa Trees.Expressions.FUNCTION(argument_expression) then
532
_logger.roll_back();
533
_logger.speculate();
534
_flow.restore();
535
536
argument_expression.set_expected_type(type, "{{0}} is not assignable to {{1}}");
537
argument_expression.walk(_visitor);
538
539
let value = argument_expression.value;
540
541
if !value? \/ !value.type? \/ !value.check_is_consumable(_logger, argument_expression.location) then
542
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)));
543
fi
544
545
return (cast Value(DUMMY(type, location)), value);
546
fi
547
548
let value = argument_expression.value;
549
550
if !value? \/ !value.type? \/ !value.check_is_consumable(_logger, argument_expression.location) then
551
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)));
552
fi
553
554
let source_type = value.type!;
555
556
if !source_type.is_function /\ !_delegate_shape.is_named_delegate(source_type) then
557
_logger.error(argument_expression.location, "no constructor found init({source_type})");
558
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)));
559
fi
560
561
// Compile-time shape check: the two call shapes must
562
// actually agree. `Delegate.CreateDelegate` would have
563
// caught a mismatch for us at construction time, but
564
// going straight to a raw function pointer below bypasses
565
// that check entirely, so it has to happen here instead.
566
let source_shape =
567
if source_type.is_function then
568
source_type
569
else
570
_delegate_shape.try_get_function_type(source_type, _innate_symbol_lookup)
571
fi;
572
573
let target_shape = _delegate_shape.try_get_function_type(type, _innate_symbol_lookup);
574
575
if !source_shape? \/ !target_shape? \/ !target_shape.is_assignable_from(source_shape) then
576
_logger.error(argument_expression.location, "{source_type} is not assignable to {type}");
577
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)));
578
fi
579
580
// `Target`/`Method` report only the last entry of a
581
// combined (multicast) delegate's invocation list, so a
582
// source built via `Delegate.Combine` would silently lose
583
// every earlier target. Not guarded against: ghūl has no
584
// syntax to combine delegates, so no ghūl-produced value
585
// reaching here is ever multicast.
586
let target_property = cast Semantic.Symbols.Property?(source_type.find_member("target"));
587
let method_property = cast Semantic.Symbols.Property?(source_type.find_member("method"));
588
589
if !target_property? \/ !method_property? then
590
_logger.error(argument_expression.location, "cannot convert {source_type} to {type}");
591
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)));
592
fi
593
594
let target_value = target_property.load(location, value, _symbol_loader);
595
let method_value = method_property.load(location, value, _symbol_loader);
596
let method_type = method_value.type!;
597
598
let handle_property = cast Semantic.Symbols.Property?(method_type.find_member("method_handle"));
599
600
if !handle_property? then
601
_logger.error(argument_expression.location, "cannot convert {source_type} to {type}");
602
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)));
603
fi
604
605
let handle_value = handle_property.load(location, method_value, _symbol_loader);
606
let handle_type = handle_value.type!;
607
608
let get_function_pointer_function = _find_single_function_member(handle_type, "get_function_pointer");
609
610
if !get_function_pointer_function? then
611
_logger.error(argument_expression.location, "cannot convert {source_type} to {type}");
612
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)));
613
fi
614
615
let pointer_value = get_function_pointer_function.call(location, handle_value, Collections.LIST[Value](), null, _function_caller);
616
617
let ctor = _find_delegate_constructor(type);
618
619
if !ctor? then
620
_logger.error(argument_expression.location, "cannot convert {source_type} to {type}");
621
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)));
622
fi
623
624
let ctor_arguments = Collections.LIST[Value]();
625
ctor_arguments.add(target_value);
626
ctor_arguments.add(pointer_value);
627
628
let constructed = _function_caller.call_constructor(ctor, ctor_arguments, type);
629
630
return (cast Value(DUMMY(type, location)), constructed);
631
si
632
633
resolve_constructor(
634
location: LOCATION,
635
right_location: LOCATION,
636
type: Semantic.Types.Type mut,
637
argument_expressions: Trees.Expressions.LIST,
638
argument_names: Collections.List[Trees.Identifiers.Identifier]?,
639
constraint: Semantic.Types.Type?,
640
cache_key: Trees.Node
641
) -> (Value, Value) is
642
let result: Value mut;
643
644
// An explicit `Foo[...]` callee enters already specialized
645
// and was constraint-checked by `specialize_type`; an
646
// inferred `Foo(...)` callee is specialized below by
647
// overload resolution and is checked post-resolution.
648
let was_generic_on_entry = isa Semantic.Types.GENERIC(type);
649
650
let named_type = cast Semantic.Types.NAMED?(type)!;
651
let type_symbol mut = named_type.symbol;
652
653
if
654
!argument_names? /\
655
argument_expressions.expressions.count == 1 /\
656
_delegate_shape.is_named_delegate(type)
657
then
658
return _resolve_delegate_value_construction(location, type, argument_expressions.expressions[0]);
659
fi
660
661
if let abstract_class: Semantic.Symbols.CLASS = type_symbol then
662
if abstract_class.is_abstract then
663
_logger.error(location, "cannot instantiate abstract class {abstract_class.name}");
664
fi
665
fi
666
667
let symbol = named_type.scope.find_direct("init");
668
669
let function_group = cast Semantic.Symbols.FUNCTION_GROUP?(symbol);
670
671
let arguments = Collections.LIST[Value]();
672
let argument_types = Collections.LIST[Type]();
673
674
_compile_call_arguments(argument_expressions, arguments, argument_types);
675
676
if !function_group? then
677
_logger.error(location, "no constructor found init({argument_types|})");
678
679
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)));
680
fi
681
682
let named_restrict: Collections.List[Semantic.Symbols.Function]? mut = null;
683
684
if argument_names? then
685
let binding = _named_argument_binder.bind(location, function_group, argument_names, true);
686
687
if !binding? then
688
return (cast Value(Load.SYMBOL(null, function_group)), cast Value(DUMMY(type, location)));
689
fi
690
691
_apply_named_permutation(argument_expressions, arguments, argument_types, binding.permutation, binding.targets[0]);
692
693
named_restrict = binding.targets;
694
fi
695
696
let overload_result mut = _overload_resolver.resolve(location, function_group, argument_types, false, true, true, named_restrict);
697
698
// Sibling-arg fall-back: first resolve returned null AND
699
// there's at least one FUNCTION-literal arg in the call.
700
// The lambda's body walked under no parameter-type
701
// constraint and likely errored, leaving an actual type
702
// that doesn't reflect the real signature; binding fails;
703
// resolver returns null. Try tentatively binding the
704
// candidate's owner-generic args from the *resolvable*
705
// sibling actuals (skipping the failing lambda), fill the
706
// remaining slots with cached phantoms, then push the
707
// substituted formals as constraints to each arg and
708
// re-walk. The second resolve sees the lambda's now-
709
// resolved actual type and binds T from it.
710
//
711
// The lambda guard matters: if no arg is a lambda, the
712
// original null result reflects a genuine type mismatch
713
// (e.g. `Pair([1,2,3], LIST[int]([4,5,6]))` — int[] and
714
// LIST[int] don't unify for T) and the user-facing
715
// diagnostic is correct as-is.
716
if overload_result == null /\ argument_types |> any(a => a.is_function_with_any_implicit_argument_types) then
717
let candidate = _try_find_single_arity_candidate(function_group, argument_types.count, true);
718
719
if candidate? then
720
let specialized_candidate = _specialise_candidate_from_concrete_siblings(candidate, argument_types, cache_key, location);
721
722
if specialized_candidate? /\ specialized_candidate != candidate then
723
_logger.roll_back();
724
_logger.speculate();
725
_flow.restore();
726
727
for (index, a) in argument_expressions |> index() do
728
let f = specialized_candidate.arguments[index];
729
730
a.set_expected_type(f, "{{0}} is not assignable to {{1}}");
731
732
a.walk(_visitor);
733
734
if let a.value? /\ value.type? /\ value.check_is_consumable(_logger, a.location) then
735
arguments[index] = value;
736
argument_types[index] = value.type!;
737
else
738
let t = Semantic.Types.ERROR();
739
arguments[index] = DUMMY(t, a.location);
740
argument_types[index] = t;
741
fi
742
od
743
744
overload_result = _overload_resolver.resolve(location, function_group, argument_types, false, true, true, named_restrict);
745
fi
746
fi
747
fi
748
749
// Return-type-constraint fall-back: first resolve returned
750
// null AND we have a constraint pushed in by an enclosing
751
// return / let-init / assignment. The candidate's owner-
752
// generic args may include slots no actual arg can bind
753
// (e.g. `RESULT.OK(42)` against `RESULT[int, string]` —
754
// OK's arg binds T, the constraint contributes S; without
755
// a contribution from the constraint, binding fails and
756
// the resolver returns null). Pre-specialise each candidate
757
// from the constraint via CONSTRUCTOR_CONSTRAINT_RETRY,
758
// then re-resolve with the specialised list. Now formals
759
// are no-longer-wild concrete types and arg binding
760
// becomes verification.
761
if overload_result == null /\ constraint? then
762
let search = if named_restrict? then named_restrict else function_group.functions fi;
763
let pre_specialised = _constructor_constraint_retry.try_specialise_candidates(location, search, constraint);
764
765
if pre_specialised? then
766
_logger.roll_back();
767
_logger.speculate();
768
769
overload_result = _overload_resolver.resolve(location, function_group, argument_types, false, true, true, pre_specialised);
770
fi
771
fi
772
773
if overload_result == null then
774
return (cast Value(Load.SYMBOL(null, function_group)), cast Value(DUMMY(type, location)));
775
fi
776
777
if overload_result.needs_retry then
778
_logger.roll_back();
779
_logger.speculate();
780
_flow.restore();
781
782
for (index, a) in argument_expressions |> index() do
783
// let use debug_despose = debug_enter();
784
if a.value? /\ isa Trees.Expressions.FUNCTION(a) then
785
let f = overload_result.function.arguments[index];
786
787
a.set_expected_type(f, "{{0}} is not assignable to {{1}}");
788
a.walk(_visitor);
789
790
argument_types[index] = a.value!.type!;
791
else
792
// ensure any error messages are committed
793
a.walk(_visitor);
794
fi
795
796
if a.value? then
797
arguments[index] = a.value;
798
fi
799
od
800
801
overload_result = _overload_resolver.resolve(location, function_group, argument_types, false, true, true, named_restrict);
802
803
if !overload_result? then
804
return (cast Value(Load.SYMBOL(null, function_group)), cast Value(DUMMY(type, location)));
805
fi
806
fi
807
808
let function mut = overload_result.function;
809
810
function = _owner_constraint_specializer.specialize_from_constraint(location, function, constraint);
811
function = _type_arg_placeholder_registry.specialize_with_placeholders(location, function, cache_key);
812
813
_resolve_deferred_defaults(function, argument_expressions.expressions, arguments, argument_types);
814
815
if isa Semantic.Symbols.GENERIC(function.owner) then
816
type_symbol = cast Semantic.Symbols.Symbol(function.owner);
817
// The GENERIC owner of a resolved constructor always carries
818
// a concrete type (the specialized class) by this point.
819
type = function.owner.type;
820
fi;
821
822
let is_directly_owned mut = false;
823
824
if isa Semantic.Symbols.GENERIC(type_symbol) /\ isa Semantic.Symbols.Symbol(function.owner) then
825
is_directly_owned = type_symbol =~ cast Semantic.Symbols.Symbol(function.owner);
826
else
827
is_directly_owned = type_symbol == function.owner;
828
fi
829
830
if !is_directly_owned then
831
_logger.error(location, "cannot call superclass constructor {function}");
832
fi
833
834
_symbol_use_locations.add_symbol_use(right_location, function);
835
_symbol_use_locations.add_symbol_use(right_location, type_symbol.root_unspecialized_symbol);
836
837
if !was_generic_on_entry then
838
if let constructed: Semantic.Types.GENERIC = type then
839
if let generic_symbol: Semantic.Symbols.GENERIC = constructed.symbol then
840
generic_symbol.symbol.check_argument_constraints(location, _logger, constructed.arguments);
841
fi
842
fi
843
fi
844
845
return (cast Value(Load.SYMBOL(null, function_group)), _function_caller.call_constructor(function, arguments, type));
846
si
847
848
// True iff any formal arg in the resolver's PARTIAL function
849
// is itself ERROR or contains an ERROR. Signal that the
850
// partial binding was driven from a tainted lambda actual
851
// (a typical free-function-with-lambda inference scenario)
852
// and the PARTIAL formals shouldn't be pushed as constraints
853
// unchanged.
854
_partial_arguments_contain_error(function: Semantic.Symbols.Function) -> bool is
855
if !function.are_arguments_declared then
856
return false;
857
fi
858
859
let found = Ghul.BOX(false);
860
861
for arg in function.arguments do
862
arg.walk((t: Type) is
863
if t.is_error then
864
found.value = true;
865
fi
866
si);
867
868
if found.value then
869
return true;
870
fi
871
od
872
873
return false;
874
si
875
876
// True iff any formal arg in the resolver's PARTIAL function
877
// still references one of the function's own generic
878
// type-variables (i.e. the resolver couldn't bind that slot
879
// from any sibling actual). Same shape problem as
880
// `_partial_arguments_contain_error`: pushing the formal as-is
881
// burdens the lambda's re-walk with a constraint
882
// (`int -> STEP[T]`) that can't be satisfied by anything
883
// concrete the body produces. Re-specialise with phantoms in
884
// those slots so the constraint pushed becomes
885
// (`int -> STEP[<phantom>]`) — actually informative, and
886
// open to match propagation from inside the body.
887
_partial_arguments_contain_unbound_function_type_variable(function: Semantic.Symbols.Function) -> bool is
888
let found = Ghul.BOX(false);
889
890
for arg in function.arguments do
891
arg.walk((t: Type) is
892
if t.is_function_generic_argument then
893
found.value = true;
894
fi
895
si);
896
897
if found.value then
898
return true;
899
fi
900
od
901
902
return false;
903
si
904
905
// True if any of the actual argument expressions is a
906
// Trees.Expressions.FUNCTION literal. Used to gate the
907
// constraint-push retry on the recoverable case where a
908
// not-yet-constrained lambda body walked with placeholder
909
// args and produced an ERROR-tainted type that the under-
910
// determination detector wouldn't otherwise recognise as
911
// recoverable.
912
//
913
// Static so it can be exercised by unit tests with hand-built
914
// expression lists, without spinning up COMPILE_CALLS's full
915
// dependency graph.
916
has_function_literal_argument(argument_expressions: Collections.List[Trees.Expressions.Expression]?) -> bool static is
917
if !argument_expressions? then
918
return false;
919
fi
920
921
for a in argument_expressions do
922
if isa Trees.Expressions.FUNCTION(a) then
923
return true;
924
fi
925
od
926
927
return false;
928
si
929
930
// An empty array literal argument has no elements to infer its
931
// element type from, so it walks to object[] and fails to match a
932
// more specific array parameter. Like a function literal, it can be
933
// re-walked under a pushed formal type, so it is a signal that a
934
// null overload result might be recoverable.
935
has_empty_array_literal_argument(argument_expressions: Collections.List[Trees.Expressions.Expression]?) -> bool static is
936
if !argument_expressions? then
937
return false;
938
fi
939
940
for a in argument_expressions do
941
if let sequence: Trees.Expressions.SEQUENCE = a then
942
if sequence.elements.expressions.count == 0 then
943
return true;
944
fi
945
fi
946
od
947
948
return false;
949
si
950
951
// Walk the scope stack from current_function outward to find
952
// the recursive closure a `rec` reference here would bind to.
953
// Mirrors the lookup in `visit(RECURSE)`.
954
_find_recursive_target() -> Semantic.Symbols.Closure? is
955
let function = _symbol_table.current_function;
956
957
if !function? \/ !function.is_closure then
958
return null;
959
fi
960
961
let closure = cast Semantic.Symbols.Closure?(function)!;
962
963
if closure.is_recursive then
964
return closure;
965
fi
966
967
let stack = _symbol_table.stack;
968
let index mut = stack.count - 1;
969
let seen_self mut = false;
970
971
while index >= 0 do
972
let scope = stack[index];
973
974
if scope.is_closure then
975
let c = cast Semantic.Symbols.Closure?(scope)!;
976
977
if seen_self then
978
if c.is_recursive then
979
return c;
980
fi
981
elif c == closure then
982
seen_self = true;
983
fi
984
fi
985
986
index = index - 1;
987
od
988
989
return null;
990
si
991
992
// Push each actual argument of a `rec(actual...)` call onto
993
// the recursive closure's parameter Variables as a LUB
994
// candidate. When the actual isn't assignable to the
995
// parameter's current type, reset that type back to an
996
// INFERRED_VARIABLE_TYPE placeholder so the next outer-body
997
// retry iteration's closure_arg_resolver re-derives the
998
// parameter type from the widened LUB. Handles both self-rec
999
// and nested-rec (rec referring to an outer recursive
1000
// ancestor) — the target is determined by walking the
1001
// closure stack mirroring `visit(RECURSE)`.
1002
try_propagate_recursive_call_args(call: Trees.Expressions.CALL) is
1003
if !isa Trees.Expressions.RECURSE(call.function) then
1004
return;
1005
fi
1006
1007
let closure = _find_recursive_target();
1008
1009
if !closure? then
1010
return;
1011
fi
1012
1013
let param_count = closure.argument_names.count;
1014
let args = call.arguments.expressions;
1015
let arg_count = args.count;
1016
1017
let n = if param_count < arg_count then param_count else arg_count fi;
1018
1019
let i mut = 0;
1020
while i < n do
1021
let name = closure.argument_names[i];
1022
let param = cast Semantic.Symbols.Variable?(closure.find_direct(name));
1023
let arg_expr = args[i];
1024
1025
// Prefer arg_expr.value.type, but fall back to the
1026
// resolved symbol's type when the value's snapshot
1027
// is null — happens for outer-scope locals captured
1028
// into a nested closure before being typed.
1029
let actual: Semantic.Types.Type? mut = null;
1030
if let arg_expr?.value? /\ value.type? then
1031
actual = value.type;
1032
elif isa Trees.Expressions.IDENTIFIER(arg_expr) then
1033
let id_expr = arg_expr;
1034
let sym = _visitor.find(id_expr.identifier);
1035
if sym? then
1036
actual = sym.type;
1037
fi
1038
fi
1039
1040
if param? /\ actual? then
1041
if actual.is_settled then
1042
_logger.mark_consumed_any_if(param.add_lower_bound(actual));
1043
1044
// Reset the param's type if currently
1045
// resolved to something narrower than the
1046
// actual — leaves it concrete when the
1047
// actual fits.
1048
if
1049
param.type? /\
1050
!param.type.is_sentinel /\
1051
!param.type.is_assignable_from(actual)
1052
then
1053
param.set_type(Semantic.Types.INFERRED_VARIABLE_TYPE(param));
1054
_logger.mark_consumed_any();
1055
fi
1056
fi
1057
fi
1058
1059
i = i + 1;
1060
od
1061
si
1062
1063
// Constraint-push retry: when the first resolve fails AND
1064
// there's exactly one arity-matching candidate AND at least
1065
// one argument's first-walk type is under-determined for
1066
// its corresponding formal type, push that candidate's
1067
// formal arg types as constraints to each call argument
1068
// and re-walk. This catches `apply(Box())` cases where a
1069
// constructor argument's owner generic args were
1070
// under-determined the first time round but become
1071
// resolvable from the formal argument's type. The
1072
// candidate's signature is the only signal we have for
1073
// what the under-determined arg should resolve to —
1074
// multi-candidate disambiguation under constraint push
1075
// is left to a more general overload-as-constraint
1076
// pass under #1174.
1077
// Constraint-push retry for when the initial overload resolution
1078
// returned null. Generalised over the source of the argument
1079
// expressions: calls pass `call.arguments.expressions` /
1080
// `call.arguments.location` / `call` as the cache key; binary
1081
// operators pass `[left, right]`, `binary.location`, the BINARY
1082
// node; unary operators pass `[right]`, `unary.location`, the
1083
// UNARY node. Assumes the caller is inside a `_logger.speculate()`
1084
// level: this method does `_logger.roll_back(); _logger.speculate();`
1085
// to re-enter before re-walking, mirroring the visit_call wrapper.
1086
try_overload_after_null(
1087
function_group: Semantic.Symbols.FUNCTION_GROUP,
1088
arguments: Collections.LIST[Value],
1089
argument_types: Collections.LIST[Type],
1090
want_instance: bool,
1091
named_restrict: Collections.List[Semantic.Symbols.Function]?,
1092
argument_expressions: Collections.List[Trees.Expressions.Expression],
1093
argument_location: LOCATION,
1094
cache_key: Trees.Node
1095
) -> Semantic.OVERLOAD_RESOLVE_RESULT? is
1096
let candidate = _try_find_single_arity_candidate(function_group, argument_types.count, want_instance);
1097
let effective_candidate = candidate ?? _delegate_push_candidates.find_single_pushable_candidate(function_group, argument_types, want_instance);
1098
1099
// Trigger the retry when at least one actual
1100
// is a FUNCTION literal even if its first-walk
1101
// type has been ERROR-tainted by a body that
1102
// walked without a constraint. The lambda can
1103
// be re-walked under a pushed formal, so a
1104
// FUNCTION arg is the natural signal that the
1105
// null overload result might be recoverable.
1106
// The pre-existing `any_arg_under_determined`
1107
// path still covers the constructor-arg shape
1108
// (e.g. `apply(Box())`). A named-delegate formal
1109
// mismatched against a bare function-shaped actual
1110
// (a named function reference, or a lambda that
1111
// resolved to its own native shape) is the same kind
1112
// of recoverable gap.
1113
1114
if effective_candidate? /\ (
1115
_under_determination_detector.any_arg_under_determined(effective_candidate, argument_types) \/
1116
COMPILE_CALLS.has_function_literal_argument(argument_expressions) \/
1117
COMPILE_CALLS.has_empty_array_literal_argument(argument_expressions) \/
1118
_delegate_push_candidates.has_push_mismatch(effective_candidate, argument_types)
1119
) then
1120
// Sibling-arg specialisation, symmetric to
1121
// the path in `resolve_constructor`: when
1122
// one actual is a not-yet-resolved FUNCTION
1123
// literal AND the candidate has a generic
1124
// owner, push specialised formals (bound
1125
// from concrete sibling actuals) rather
1126
// than unsubstituted formals containing
1127
// free type variables that the lambda's
1128
// argument-setup would reject as "type
1129
// variable" anyway. Owners that aren't
1130
// generic short-circuit inside
1131
// OWNER_TYPE_ARG_SPECIALIZER and the
1132
// pre-existing behaviour is preserved.
1133
let push_candidate: Semantic.Symbols.Function? mut = effective_candidate;
1134
1135
// Two-step specialisation: try
1136
// owner-class generic args first (for
1137
// method calls whose receiver class is
1138
// generic), then if push_candidate is
1139
// still the unsubstituted candidate and
1140
// the candidate has its own generic
1141
// args, try binding those from concrete
1142
// siblings. The function-own path is
1143
// what catches free-function HOFs like
1144
// `generate[T,S]((0,1), state => ...)` —
1145
// S binds from the (0,1) actual, T fills
1146
// from a phantom, and the substituted
1147
// formal-arg-type can then constrain the
1148
// lambda's body re-walk.
1149
push_candidate = _specialise_candidate_from_concrete_siblings(effective_candidate, argument_types, cache_key, argument_location);
1150
1151
if push_candidate == effective_candidate /\ effective_candidate.is_generic then
1152
let phantom_origins = _type_arg_placeholder_registry.get_or_create_for_function(cache_key, argument_location, effective_candidate);
1153
push_candidate = _owner_type_arg_specializer.specialize_function_own_args_from_concrete_siblings(effective_candidate, argument_types, phantom_origins, argument_location);
1154
fi
1155
1156
_logger.roll_back();
1157
_logger.speculate();
1158
_flow.restore();
1159
1160
for (index, a) in argument_expressions |> index() do
1161
let f = push_candidate!.arguments[index];
1162
1163
a.set_expected_type(f, "{{0}} is not assignable to {{1}}");
1164
1165
a.walk(_visitor);
1166
1167
if let a.value? /\ value.type? /\ value.check_is_consumable(_logger, a.location) then
1168
arguments[index] = value;
1169
argument_types[index] = value.type!;
1170
else
1171
let t = Semantic.Types.ERROR();
1172
1173
arguments[index] = DUMMY(t, a.location);
1174
argument_types[index] = t;
1175
fi
1176
od
1177
1178
return _overload_resolver.resolve(argument_location, function_group, argument_types, true, want_instance, false, named_restrict);
1179
fi
1180
1181
return null;
1182
si
1183
1184
// PARTIAL re-specialisation: the resolver may
1185
// have driven its type-arg binding from a
1186
// tainted lambda actual whose body errored on
1187
// the first walk (the free-function lambda-
1188
// inference gap). Pushing those ERROR-bearing
1189
// formals as constraints to the lambda would
1190
// taint its re-walk too. Detect the case and
1191
// re-specialise from CLEAN siblings via the
1192
// function-own-args specialiser (which skips
1193
// ERROR / placeholder-bearing actuals); push
1194
// that cleaner form.
1195
//
1196
// Same shape for unbound function-own type
1197
// variables: when the resolver couldn't bind a
1198
// slot, the formal still contains the
1199
// candidate's literal `T` / `S` /…, which is
1200
// useless as a constraint downstream
1201
// (literal `T` matches nothing concrete the
1202
// body could produce). Re-specialise so those
1203
// slots become phantoms — open to match propagation
1204
// from inside the lambda body.
1205
// PARTIAL-result retry. Generalised over the source of the
1206
// argument expressions in the same way as `try_overload_after_null`.
1207
// Assumes the caller is inside a `_logger.speculate()` level.
1208
try_overload_on_partial(
1209
overload_result: Semantic.OVERLOAD_RESOLVE_RESULT,
1210
function_group: Semantic.Symbols.FUNCTION_GROUP,
1211
arguments: Collections.LIST[Value],
1212
argument_types: Collections.LIST[Type],
1213
want_instance: bool,
1214
named_restrict: Collections.List[Semantic.Symbols.Function]?,
1215
argument_expressions: Collections.List[Trees.Expressions.Expression],
1216
argument_location: LOCATION,
1217
cache_key: Trees.Node
1218
) -> Semantic.OVERLOAD_RESOLVE_RESULT? is
1219
let push_function mut = overload_result.function;
1220
1221
if
1222
_partial_arguments_contain_error(push_function) \/
1223
_partial_arguments_contain_unbound_function_type_variable(push_function)
1224
then
1225
let candidate = _try_find_single_arity_candidate(function_group, argument_types.count, want_instance);
1226
1227
if candidate? /\ candidate.is_generic then
1228
let phantom_origins = _type_arg_placeholder_registry.get_or_create_for_function(cache_key, argument_location, candidate);
1229
let respecialized = _owner_type_arg_specializer.specialize_function_own_args_from_concrete_siblings(candidate, argument_types, phantom_origins, argument_location);
1230
1231
if respecialized != candidate then
1232
push_function = respecialized;
1233
fi
1234
fi
1235
fi
1236
1237
_logger.roll_back();
1238
_logger.speculate();
1239
_flow.restore();
1240
1241
for (index, a) in argument_expressions |> index() do
1242
// A delegate formal is pushed onto any argument, not only
1243
// a literal: an expression that merely contains literals
1244
// (an `if` over two of them, say) forwards the constraint
1245
// to them and joins at the delegate type. One that cannot
1246
// act on it re-walks unchanged and is caught by the
1247
// delegate check below.
1248
if
1249
a.value? /\
1250
(
1251
isa Trees.Expressions.FUNCTION(a) \/
1252
_delegate_shape.is_named_delegate(push_function.arguments[index])
1253
)
1254
then
1255
let f = push_function.arguments[index];
1256
1257
a.set_expected_type(f, "{{0}} is not assignable to {{1}}");
1258
a.walk(_visitor);
1259
1260
argument_types[index] = a.value!.type!;
1261
else
1262
// ensure any error messages are committed
1263
a.walk(_visitor);
1264
fi
1265
1266
if a.value? then
1267
arguments[index] = a.value;
1268
fi
1269
od
1270
1271
// A delegate formal was matched partially on the strength of
1272
// the actual being some function type, which only a literal
1273
// can make good on - the re-walk above compiles a literal to
1274
// the delegate and leaves anything else at its own type.
1275
// Reject those here: letting one through would emit a value
1276
// of one delegate type into a slot of another, which the CLR
1277
// does not convert.
1278
for (index, formal) in push_function.arguments |> index() do
1279
if _delegate_shape.is_named_delegate(formal) /\ !formal.is_assignable_from(argument_types[index]) then
1280
_logger.error(
1281
argument_expressions[index].location,
1282
"{argument_types[index]} is not assignable to {formal}");
1283
1284
return null;
1285
fi
1286
od
1287
1288
return _overload_resolver.resolve(argument_location, function_group, argument_types, false, want_instance, false, named_restrict);
1289
si
1290
1291
visit_call(call: Trees.Expressions.CALL) is
1292
// Recursive-call match propagation for self-recursive lambdas
1293
// (`let f = x rec => ... rec(actual) ...`). The
1294
// call-site match propagation below only widens a closure's
1295
// argument type when the formal is still an
1296
// INFERRED_VARIABLE_TYPE placeholder. For a rec call the
1297
// formal is the closure's own parameter Variable, which
1298
// by iter N is already resolved to (often the narrow)
1299
// outer call-site type. Without further widening, a rec
1300
// call with a wider actual fails type-check.
1301
//
1302
// Widen here: push each actual as a candidate on the
1303
// closure parameter's LUB. When the actual isn't
1304
// assignable to the current parameter type, reset the
1305
// parameter's type back to a placeholder so the next
1306
// outer-body-retry iteration's closure_arg_resolver pass
1307
// re-derives from the now-wider LUB.
1308
try_propagate_recursive_call_args(call);
1309
1310
// Arity-aware refinement of MEMBER_CONSTRAINT for the
1311
// `<placeholder>.<name>(args...)` shape. MEMBER.visit
1312
// already emitted MEMBER_CONSTRAINT(name); pin the
1313
// arity here so the resolved type must have `name`
1314
// callable at this arg count, not merely present. The
1315
// receiver may already have been ERROR-typed by
1316
// MEMBER.visit's placeholder branch — read the *member's
1317
// left*'s type to find the placeholder regardless.
1318
if let member: Trees.Expressions.MEMBER = call.function then
1319
if let member.left?, left.value? /\ value.type? then
1320
if let placeholder: Semantic.Types.INFERRED_VARIABLE_TYPE = value.type then
1321
let arity = call.arguments.count;
1322
1323
_logger.mark_consumed_any_if(placeholder.origin.add_constraint(
1324
Semantic.MEMBER_CONSTRAINT(member.identifier.name, arity)
1325
));
1326
fi
1327
fi
1328
fi
1329
1330
let function_value = call.function.value;
1331
1332
if !function_value? \/ !function_value.type? then
1333
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1334
return;
1335
fi
1336
1337
// `|>` threads its subject in as the first argument, which is
1338
// positional; it is spliced into the argument list but not into
1339
// argument_names, so combining it with named written arguments
1340
// is rejected rather than silently misaligned. Checked before
1341
// the constructor dispatch below so it covers constructor calls
1342
// too.
1343
if call.is_thread_first /\ call.argument_names? then
1344
_logger.error(call.location, "named arguments cannot be combined with |>");
1345
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1346
return;
1347
fi
1348
1349
// Bare unit-variant accesses (`COLOR.RED`, `Option.NONE[int]`)
1350
// already lowered to a NEW pointing at the singleton. Empty
1351
// parens on top of that — `COLOR.RED()` — pass the value
1352
// through; supplying any argument is an error because a unit
1353
// variant carries no fields. Generic unit variants with the
1354
// type arguments inferred from context still arrive as a
1355
// TYPE_EXPRESSION (the lower step needs a constraint that
1356
// only the parent has) and fall through to resolve_constructor.
1357
if isa NEW(function_value) then
1358
let new_value = cast NEW(function_value);
1359
1360
if new_value.constructor.owner!.is_unit_variant then
1361
if call.arguments.count == 0 then
1362
call.compile_expressions_state.value = new_value;
1363
return;
1364
fi
1365
1366
_logger.error(
1367
call.location,
1368
"unit variant {new_value.type} takes no arguments"
1369
);
1370
1371
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1372
return;
1373
fi
1374
fi
1375
1376
if function_value.is_type_expression then
1377
(call.function.compile_expressions_state.value, call.compile_expressions_state.value) = resolve_constructor(call.location, call.right_location, function_value.type!, call.arguments, call.argument_names, call.expected_type, call);
1378
1379
return;
1380
fi
1381
1382
let arguments = Collections.LIST[Value]();
1383
let argument_types = Collections.LIST[Type]();
1384
1385
_compile_call_arguments(call.arguments, arguments, argument_types);
1386
1387
// TODO handle if left is actually a type not a function or method
1388
// in which case we should treat this as a constructor call
1389
1390
// we could also treat consuming a bare type as a constructor call
1391
// this would be done in the symbol loader
1392
1393
let load_symbol: Semantic.Symbols.Symbol? mut = null;
1394
1395
if let load: Load.SYMBOL = function_value then
1396
load_symbol = load.symbol;
1397
1398
if load_symbol.is_function_group then
1399
let want_instance: bool mut;
1400
1401
want_instance =
1402
if load.from? then
1403
load.from.is_consumable
1404
else
1405
_symbol_table.current_instance_context?
1406
fi;
1407
1408
let function_group = cast Semantic.Symbols.FUNCTION_GROUP?(load_symbol)!;
1409
1410
let named_restrict: Collections.List[Semantic.Symbols.Function]? mut = null;
1411
1412
if call.argument_names? then
1413
let binding = _named_argument_binder.bind(call.arguments.location, function_group, call.argument_names, want_instance);
1414
1415
if !binding? then
1416
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1417
return;
1418
fi
1419
1420
_apply_named_permutation(call.arguments, arguments, argument_types, binding.permutation, binding.targets[0]);
1421
1422
named_restrict = binding.targets;
1423
fi
1424
1425
// Pass `call.expected_type` (the return-type context
1426
// set by an enclosing assignment / return / typed
1427
// initializer) so the resolver can tie-break
1428
// between candidates with identical arg fit but
1429
// different return types — e.g.
1430
// `Tasks.TASK.from_exception(ex)` in a function
1431
// returning `Tasks.TASK[int]` prefers the generic
1432
// `from_exception[T]` overload over the non-
1433
// generic one.
1434
let overload_result mut = _overload_resolver.resolve(call.arguments.location, function_group, argument_types, true, want_instance, false, named_restrict, call.expected_type);
1435
1436
if !overload_result? then
1437
overload_result = try_overload_after_null(function_group, arguments, argument_types, want_instance, named_restrict, call.arguments.expressions, call.arguments.location, call);
1438
fi
1439
1440
if overload_result == null then
1441
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1442
return;
1443
fi
1444
1445
if overload_result.needs_retry then
1446
overload_result = try_overload_on_partial(overload_result, function_group, arguments, argument_types, want_instance, named_restrict, call.arguments.expressions, call.arguments.location, call);
1447
1448
if !overload_result? then
1449
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1450
return;
1451
fi
1452
fi
1453
1454
let function = overload_result.function;
1455
1456
_resolve_deferred_defaults(function, call.arguments.expressions, arguments, argument_types);
1457
1458
_visitor.note_reference_arguments(call, function);
1459
1460
if function.is_unsafe_constraints then
1461
_logger.warn(call.location, "unchecked-constraints", "call to {function} has unchecked constraints");
1462
fi
1463
1464
// A function whose type arguments were bound by
1465
// inference keeps `is_generic` set with concrete
1466
// `generic_arguments`; an explicitly specialized one
1467
// has `is_generic` cleared and was already checked
1468
// at `FUNCTION_GROUP.try_specialize`.
1469
if
1470
function.is_generic /\
1471
function.generic_arguments.count == function.generic_argument_names.count
1472
then
1473
Semantic.Symbols.GENERIC_CONSTRAINT_CHECKER().check_arguments(
1474
call.location,
1475
_logger,
1476
function,
1477
function.generic_argument_names,
1478
function.generic_arguments
1479
);
1480
fi
1481
1482
let accessor_class = _symbol_table.current_accessor;
1483
1484
if !function.is_accessible_to(accessor_class) then
1485
_logger.error(call.function.location, "{function} is not accessible here");
1486
fi
1487
1488
_symbol_use_locations.add_symbol_use(call.function.right_location, function);
1489
1490
// A callee selected through `?.` short-circuits
1491
// the whole call - argument evaluation included -
1492
// on an absent receiver, so the call value is
1493
// built inside the coalescing wrap against the
1494
// unwrapped receiver. A static callee never
1495
// consumes the tested receiver.
1496
let coalesce_member = _try_coalescing_member(call);
1497
1498
if coalesce_member? then
1499
let wrapped = _access.build_coalesce_wrap(
1500
coalesce_member,
1501
function.is_instance,
1502
from => function.call(call.function.location, from, arguments, null, _function_caller)
1503
);
1504
1505
if wrapped? then
1506
call.compile_expressions_state.value = wrapped;
1507
return;
1508
fi
1509
fi
1510
1511
// A static call has no receiver value of its own -
1512
// `load.from` is always null - but a static virtual
1513
// interface member reached through a bound type
1514
// parameter (`T.parse(...)`) needs the qualifier's
1515
// type to emit the CLR's `constrained.` call shape.
1516
// Recover it from the callee expression's own left
1517
// operand rather than through the discarded static
1518
// load, since only a type-variable qualifier is
1519
// ever relevant here.
1520
let call_receiver: Value? mut = load.from;
1521
1522
if !call_receiver? then
1523
if let member: Trees.Expressions.MEMBER = call.function then
1524
if let left_type: Type = member.left.value?.type /\ left_type.is_type_variable then
1525
call_receiver = member.left.value;
1526
fi
1527
fi
1528
fi
1529
1530
call.compile_expressions_state.value = function.call(call.function.location, call_receiver, arguments, null, _function_caller);
1531
return;
1532
fi
1533
fi
1534
1535
let function_type = function_value.type;
1536
1537
// Run before the is_error check below so a callee whose
1538
// return-slot is ERROR but whose formal-arg slots still
1539
// carry placeholders gets its placeholders fed (e.g.
1540
// `x => x.length` has an ERROR-typed body but its arg
1541
// slot is recoverable once a call site supplies the
1542
// actual).
1543
if isa Semantic.Types.NAMED(function_type) then
1544
_propagate_to_placeholder_formals(function_type, argument_types, arguments.count);
1545
fi
1546
1547
// Only short-circuit when the receiver is itself the ERROR
1548
// sentinel — not when an ERROR sits inside an otherwise-usable
1549
// function shape (`Function[good_formals, ERROR_return]`).
1550
// For composites the formal-arg slots are still known, so the
1551
// result-type path below can propagate a usable Function shape
1552
// to the let-init binding. The body-retry loop can then back-
1553
// feed actuals onto placeholder formals on the next iteration.
1554
if function_type? /\ isa Semantic.Types.ERROR(function_type) then
1555
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1556
return;
1557
elif isa Semantic.Types.INFERRED_VARIABLE_TYPE(function_type) then
1558
_propagate_to_unresolved_callee(function_type, argument_types);
1559
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1560
return;
1561
elif !function_type? \/ !isa Semantic.Types.NAMED(function_type) then
1562
_logger.error(call.function.location, "cannot call value of non-function type {function_value.type}");
1563
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1564
return;
1565
fi
1566
1567
let function_generic_type = function_type;
1568
1569
let function_type_arguments = function_generic_type.arguments;
1570
1571
if call.argument_names? /\ (function_type.is_action \/ function_type.is_function) then
1572
_logger.error(call.location, "cannot supply argument names here");
1573
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1574
return;
1575
fi
1576
1577
if function_type.is_action then
1578
if function_type_arguments.count != arguments.count then
1579
_logger.error(
1580
call.arguments.location,
1581
"expected {function_type_arguments.count} arguments but {arguments.count} supplied");
1582
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1583
return;
1584
fi
1585
elif function_type.is_function then
1586
if function_type_arguments.count != arguments.count + 1 then
1587
_logger.error(
1588
call.arguments.location,
1589
"expected {function_type_arguments.count - 1} arguments but {arguments.count} supplied");
1590
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1591
return;
1592
fi
1593
else
1594
if load_symbol? /\ load_symbol.is_type then
1595
(call.function.compile_expressions_state.value, call.compile_expressions_state.value) = resolve_constructor(call.location, call.right_location, load_symbol.type!, call.arguments, call.argument_names, call.expected_type, call);
1596
else
1597
_logger.error(call.function.location, "cannot call value of non-function type {function_value.type}");
1598
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1599
fi
1600
1601
return;
1602
fi
1603
1604
let ok mut = true;
1605
1606
for i in 0..arguments.count do
1607
// Back-feed BEFORE the compare so a Closure-call with
1608
// a placeholder parameter type (`let f = x => ...; f(1)`)
1609
// propagates the actual's concrete type to the
1610
// placeholder's origin. The body retry loop's next
1611
// iteration then sees a concrete x's-type and walks
1612
// the lambda body cleanly. Without this the call path
1613
// validated types but propagated nothing — local
1614
// lambdas with use-site-only constraints failed to
1615
// converge.
1616
_overload_resolver.match_propagator.propagate_match(function_generic_type.arguments[i], argument_types[i]);
1617
1618
if cast int(function_generic_type.arguments[i].compare(argument_types[i])) > cast int(Semantic.Types.MATCH.CONVERTABLE)
1619
then
1620
ok = false;
1621
_logger.error(call.arguments.expressions[i].location, "expected argument of type {function_type_arguments[i]} but {argument_types[i]} supplied");
1622
fi
1623
od
1624
1625
if !ok then
1626
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location);
1627
return;
1628
fi
1629
1630
let result_type =
1631
if function_type.is_action then
1632
_innate_symbol_lookup.get_void_type();
1633
else
1634
function_generic_type.arguments[function_type_arguments.count - 1];
1635
fi;
1636
1637
// A function-typed member selected through `?.` arrives
1638
// as a COALESCE_LOAD of the delegate; invoking that
1639
// result would call through the null the absent arm
1640
// produces. Re-seat the invocation inside the
1641
// short-circuit arm instead, consuming the member load
1642
// where the receiver is known present. With a statically
1643
// present receiver the member value is the plain delegate
1644
// load - invoke it directly and widen the result to the
1645
// optional shape the `?.` asked for.
1646
if _try_coalescing_member(call)? then
1647
if let original: IR.Values.COALESCE_LOAD = function_value then
1648
let arm_call = Call.CLOSURE(
1649
original.member_load,
1650
result_type,
1651
function_type.is_action,
1652
function_generic_type,
1653
arguments
1654
);
1655
1656
let rewrapped = _access.rewrap_coalesce_call(original, arm_call);
1657
1658
if rewrapped? then
1659
call.compile_expressions_state.value = rewrapped;
1660
return;
1661
fi
1662
else
1663
let direct = Call.CLOSURE(
1664
function_value,
1665
result_type,
1666
function_type.is_action,
1667
function_generic_type,
1668
arguments
1669
);
1670
1671
let widened = _access.widen_coalesce_result(direct);
1672
1673
call.compile_expressions_state.value =
1674
if widened? then widened else direct fi;
1675
1676
return;
1677
fi
1678
fi
1679
1680
call.compile_expressions_state.value =
1681
Call.CLOSURE(
1682
call.function.value!,
1683
result_type,
1684
function_type.is_action,
1685
function_generic_type,
1686
arguments
1687
);
1688
si
1689
1690
// The MEMBER at call.function when this call selects its
1691
// callee through `?.` - the shape whose short-circuit is
1692
// lowered here at the call rather than at the member access.
1693
_try_coalescing_member(call: Trees.Expressions.CALL) -> Trees.Expressions.MEMBER? is
1694
let member = cast Trees.Expressions.MEMBER?(call.function);
1695
1696
if member? /\ member.is_coalesce then
1697
return member;
1698
fi
1699
1700
return null;
1701
si
1702
1703
// For a function-typed callee whose formal slots include
1704
// INFERRED_VARIABLE_TYPE placeholders (typically a let-bound
1705
// lambda whose arg types couldn't be pinned from the body
1706
// alone), push the corresponding actual arg type onto each
1707
// placeholder formal's origin Variable as a lower bound. The
1708
// body-retry loop's next iteration then sees the placeholder
1709
// resolved and walks the lambda body cleanly.
1710
//
1711
// Closed-root alternatives — union variants or subclasses
1712
// of a closed class — are widened to their root before
1713
// being pushed (see `INFERENCE_HELPERS.widen_to_closed_root`)
1714
// to keep the lambda-arg LUB monotonic across siblings from
1715
// different call sites.
1716
_propagate_to_placeholder_formals(
1717
function_type: Semantic.Types.Type,
1718
argument_types: Collections.List[Semantic.Types.Type],
1719
argument_count: int
1720
) is
1721
let ft_named = cast Semantic.Types.NAMED?(function_type)!;
1722
let ft_args = ft_named.arguments;
1723
let formal_count =
1724
if function_type.is_function then
1725
ft_args.count - 1;
1726
else
1727
ft_args.count;
1728
fi;
1729
1730
if formal_count != argument_count then
1731
return;
1732
fi
1733
1734
for i in 0..argument_count do
1735
let formal = ft_args[i];
1736
let actual = argument_types[i];
1737
1738
if isa Semantic.Types.INFERRED_VARIABLE_TYPE(formal) then
1739
let placeholder = formal;
1740
let push_actual = Semantic.INFERENCE_HELPERS.widen_to_closed_root(actual)!;
1741
_logger.mark_consumed_any_if(placeholder.origin.add_lower_bound(push_actual));
1742
fi
1743
od
1744
si
1745
1746
// When the call's receiver is itself an unresolved placeholder
1747
// (`let f = ...; f(1)` while `f`'s body is still settling, or
1748
// mutually-recursive lambdas where each side's signature
1749
// depends on the other), record two constraints on the
1750
// placeholder's origin:
1751
//
1752
// 1. A synthesised function-type shape from the actual arg
1753
// types + a deferred return type, as a lower bound, so
1754
// the next iteration sees the receiver resolved to a
1755
// function type and the call can compile. Skipped when
1756
// the LUB already has a candidate (typically from a
1757
// direct `v = <lambda>` assignment in the same body) —
1758
// the call's actual arg types may differ from the
1759
// assigned shape and the per-position merge can't bridge
1760
// them, leaving an ambiguous pair in the pool.
1761
//
1762
// 2. A CALL_CONSTRAINT capturing the actual arg types
1763
// unconditionally, so the constraint-aware LUB can later
1764
// filter candidate types to those that actually accept
1765
// this call shape. Its discharge defers conservatively
1766
// when the captured args still contain placeholders.
1767
_propagate_to_unresolved_callee(
1768
placeholder: Semantic.Types.INFERRED_VARIABLE_TYPE,
1769
argument_types: Collections.List[Semantic.Types.Type]
1770
) is
1771
if !placeholder.origin.has_lub_candidate /\ argument_types |> all(a => a.is_settled) then
1772
let function_type_components = Collections.LIST[Semantic.Types.Type](argument_types);
1773
function_type_components.add(Semantic.Types.INFERRED_RETURN_TYPE());
1774
let synthesized = _innate_symbol_lookup.get_function_type(function_type_components);
1775
_logger.mark_consumed_any_if(placeholder.origin.add_lower_bound(synthesized));
1776
fi
1777
1778
let call_args = Collections.LIST[Semantic.Types.Type](argument_types);
1779
_logger.mark_consumed_any_if(placeholder.origin.add_constraint(Semantic.CALL_CONSTRAINT(call_args)));
1780
si
1781
si
1782
si