Skip to content
← Back

src/syntax/process/compile-expressions/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 `_(args)`
12
// contextually-typed construction, function / method / closure /
13
// indexer calls, and the shared constructor-resolution path. Split
14
// out of COMPILE_EXPRESSIONS, which delegates visit(construct) and
15
// the enclosed logic of visit(call) here. The try/catch wrapper of
16
// visit(call) — with
17
// its speculation bracket around the argument walk — stays on the
18
// visitor; visit_call is the enclosed logic.
19
class COMPILE_CALLS is
20
_logger: Logger
21
_symbol_table: Semantic.SYMBOL_TABLE
22
_symbol_use_locations: Semantic.SYMBOL_USE_LOCATIONS
23
_innate_symbol_lookup: Semantic.Lookups.InnateSymbolLookup
24
_overload_resolver: Semantic.OVERLOAD_RESOLVER
25
_function_caller: Semantic.FUNCTION_CALLER
26
_owner_constraint_specializer: Semantic.OWNER_CONSTRAINT_SPECIALIZER
27
_owner_type_arg_specializer: Semantic.OWNER_TYPE_ARG_SPECIALIZER
28
_constructor_constraint_retry: Semantic.CONSTRUCTOR_CONSTRAINT_RETRY
29
_under_determination_detector: Semantic.UNDER_DETERMINATION_DETECTOR
30
_type_arg_placeholder_registry: Semantic.TYPE_ARG_PLACEHOLDER_REGISTRY
31
_access: COMPILE_ACCESS
32
_visitor: COMPILE_EXPRESSIONS
33
_named_argument_binder: NAMED_ARGUMENT_BINDER
34
_flow: NARROWING_FLOW
35
_delegate_shape: Semantic.DELEGATE_SHAPE
36
_delegate_push_candidates: Semantic.DELEGATE_PUSH_CANDIDATES
37
_async_literal_candidates: Semantic.ASYNC_LITERAL_CANDIDATES
38
_symbol_loader: Semantic.SYMBOL_LOADER
39
_function_reference_adapter: FUNCTION_REFERENCE_ADAPTER
40
_pack_wrap_builder: PACK_WRAP_BUILDER
41
42
init(
43
logger: Logger,
44
symbol_table: Semantic.SYMBOL_TABLE,
45
symbol_use_locations: Semantic.SYMBOL_USE_LOCATIONS,
46
innate_symbol_lookup: Semantic.Lookups.InnateSymbolLookup,
47
overload_resolver: Semantic.OVERLOAD_RESOLVER,
48
function_caller: Semantic.FUNCTION_CALLER,
49
owner_constraint_specializer: Semantic.OWNER_CONSTRAINT_SPECIALIZER,
50
owner_type_arg_specializer: Semantic.OWNER_TYPE_ARG_SPECIALIZER,
51
under_determination_detector: Semantic.UNDER_DETERMINATION_DETECTOR,
52
type_arg_placeholder_registry: Semantic.TYPE_ARG_PLACEHOLDER_REGISTRY,
53
access: COMPILE_ACCESS,
54
visitor: COMPILE_EXPRESSIONS,
55
flow: NARROWING_FLOW,
56
symbol_loader: Semantic.SYMBOL_LOADER,
57
function_reference_adapter: FUNCTION_REFERENCE_ADAPTER
58
) is
59
super.init()
60
61
_logger = logger
62
_symbol_table = symbol_table
63
_symbol_use_locations = symbol_use_locations
64
_innate_symbol_lookup = innate_symbol_lookup
65
_overload_resolver = overload_resolver
66
_function_caller = function_caller
67
_owner_constraint_specializer = owner_constraint_specializer
68
_owner_type_arg_specializer = owner_type_arg_specializer
69
_constructor_constraint_retry = Semantic.CONSTRUCTOR_CONSTRAINT_RETRY(owner_constraint_specializer)
70
_under_determination_detector = under_determination_detector
71
_type_arg_placeholder_registry = type_arg_placeholder_registry
72
_access = access
73
_visitor = visitor
74
_named_argument_binder = NAMED_ARGUMENT_BINDER(logger)
75
_flow = flow
76
_delegate_shape = Semantic.DELEGATE_SHAPE()
77
_delegate_push_candidates = Semantic.DELEGATE_PUSH_CANDIDATES(_delegate_shape, innate_symbol_lookup)
78
_async_literal_candidates = Semantic.ASYNC_LITERAL_CANDIDATES(innate_symbol_lookup, Semantic.TASK_LIKE_RESOLVER(logger))
79
_symbol_loader = symbol_loader
80
_function_reference_adapter = function_reference_adapter
81
_pack_wrap_builder = PACK_WRAP_BUILDER(symbol_table, symbol_loader, innate_symbol_lookup)
82
si
83
84
// Rebuild a named call's already-collected argument lists - the
85
// AST expressions and the parallel value / type lists - into
86
// the resolved overload's parameter order. `permutation` is
87
// indexed by formal parameter; a negative entry marks a
88
// parameter the call omitted, which is filled with a `default`
89
// value of that parameter's type (taken from `target`).
90
_apply_named_permutation(
91
argument_expressions: Trees.Expressions.LIST,
92
arguments: Collections.LIST[Value],
93
argument_types: Collections.LIST[Type],
94
permutation: Collections.List[int],
95
target: Semantic.Symbols.Function
96
) is
97
let source_expressions = Collections.LIST[Trees.Expressions.Expression](argument_expressions)
98
let source_arguments = Collections.LIST[Value](arguments)
99
let source_argument_types = Collections.LIST[Type](argument_types)
100
101
argument_expressions.expressions.clear()
102
arguments.clear()
103
argument_types.clear()
104
105
for formal_index in 0..permutation.count do
106
let source_index = permutation[formal_index]
107
108
if source_index >= 0 then
109
argument_expressions.expressions.add(source_expressions[source_index])
110
arguments.add(source_arguments[source_index])
111
argument_types.add(source_argument_types[source_index])
112
else
113
let formal_type = target.arguments[formal_index]
114
let stored = target.argument_defaults[formal_index]
115
let default_value = DEFAULT_ARGUMENT_VALUES.build(stored, formal_type, _innate_symbol_lookup)
116
117
let default_expression = Trees.Expressions.DEFAULT(argument_expressions.location, null)
118
default_expression.set_expected_type(formal_type, "")
119
default_expression.compile_expressions_state.value = default_value
120
121
argument_expressions.expressions.add(default_expression)
122
arguments.add(default_value)
123
argument_types.add(formal_type)
124
fi
125
od
126
si
127
128
// `_(args)`: the type is never written, so it comes from the
129
// constraint the parent pushed in. An optional constraint is
130
// peeled - a constructor produces the underlying instance, and
131
// the widening to the optional happens at the assignment site,
132
// so the value carries the non-optional class type rather than
133
// masquerading as `BOX?`.
134
visit_construct(construct: Trees.Expressions.CONSTRUCT) is
135
construct.compile_expressions_state.value = null
136
137
let type: Type? mut
138
139
if let construct.expected_type? then
140
// The type comes from a local's later uses that have not
141
// settled it yet.
142
if expected_type.is_inferred then
143
Semantic.OBLIGATIONS.defer("construct", expected_type, construct.location)
144
construct.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), construct.location)
145
return
146
fi
147
148
type = expected_type.as_non_optional()
149
else
150
_logger.error(construct.location, "cannot infer the type to construct here")
151
construct.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), construct.location)
152
return
153
fi
154
155
if !isa Semantic.Types.NAMED(type) then
156
_logger.error(construct.location, "cannot instantiate {type}")
157
construct.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), construct.location)
158
return
159
fi
160
161
let named_type = type
162
let type_symbol mut = named_type.symbol
163
164
if let abstract_class: Semantic.Symbols.CLASS = type_symbol then
165
if abstract_class.is_abstract then
166
_logger.error(construct.location, "cannot instantiate abstract class {abstract_class.name}", abstract_class.location, "class declared abstract here")
167
fi
168
fi
169
170
let symbol = named_type.scope.find_direct("init")
171
172
let function_group = cast Semantic.Symbols.FUNCTION_GROUP?(symbol)
173
174
let arguments = Collections.LIST[Value]()
175
let argument_types = Collections.LIST[Type]()
176
177
for a in construct.arguments do
178
let value = a.value
179
180
if value? /\ value.type? /\ value.check_is_consumable(_logger, a.location) then
181
arguments.add(value)
182
argument_types.add(value.type!)
183
else
184
let t = Semantic.Types.ERROR()
185
186
arguments.add(DUMMY(t, a.location))
187
188
argument_types.add(t)
189
fi
190
od
191
192
if !function_group? then
193
construct.compile_expressions_state.value = DUMMY(type, construct.location)
194
195
_logger.error(construct.location, "no constructor found init({argument_types |> join(", ")})")
196
197
return
198
fi
199
200
let overload_result = _overload_resolver.resolve(construct.location, function_group, argument_types, false, true, true)
201
202
if overload_result == null then
203
construct.compile_expressions_state.value = DUMMY(type, construct.location)
204
205
return
206
fi
207
208
let function mut = overload_result.function
209
210
function = _owner_constraint_specializer.specialize_from_constraint(construct.location, function, construct.expected_type)
211
212
if isa Semantic.Symbols.GENERIC(function.owner) then
213
type_symbol = cast Semantic.Symbols.Symbol(function.owner)
214
// The GENERIC owner of a resolved constructor always carries
215
// a concrete type (the specialized class) by this point.
216
type = function.owner.type
217
fi
218
219
let is_directly_owned mut = false
220
221
if isa Semantic.Symbols.GENERIC(type_symbol) /\ isa Semantic.Symbols.Symbol(function.owner) then
222
is_directly_owned = type_symbol =~ cast Semantic.Symbols.Symbol(function.owner)
223
else
224
is_directly_owned = type_symbol == function.owner
225
fi
226
227
if !is_directly_owned then
228
_logger.error(construct.location, "cannot call superclass constructor {function}", function.location, "constructor declared here")
229
fi
230
231
construct.compile_expressions_state.value =
232
NEW(
233
// every branch above either sets type or early-returns
234
type,
235
function,
236
arguments
237
)
238
si
239
240
// Sibling-arg specialisation entry: produce the phantom-
241
// origin list for unbound slots from the per-AST cache, then
242
// delegate to `OWNER_TYPE_ARG_SPECIALIZER` for the binding
243
// and specialisation logic. Phantom origins live on the
244
// placeholder registry so match propagation across body-retry
245
// iterations lands on the same Variables; the specialiser
246
// itself is stateless, which lets the binding contract be
247
// unit-tested in isolation.
248
_specialise_candidate_from_concrete_siblings(
249
candidate: Semantic.Symbols.Function,
250
argument_types: Collections.List[Semantic.Types.Type],
251
cache_key: Trees.Node,
252
location: LOCATION
253
) -> Semantic.Symbols.Function? is
254
if isa Semantic.Symbols.GENERIC(candidate.owner) then
255
return candidate
256
fi
257
258
let owner_classy = cast Semantic.Symbols.Classy?(candidate.owner)
259
260
if !owner_classy? \/ !owner_classy.is_generic then
261
return candidate
262
fi
263
264
let origins = _type_arg_placeholder_registry.get_or_create(cache_key, location, owner_classy)
265
266
return _owner_type_arg_specializer.specialize_from_concrete_siblings(candidate, argument_types, origins, location)
267
si
268
269
// Find the single arity- and instance-matching candidate in a
270
// function group, or null if there are zero or multiple. Used
271
// by `visit_call`'s constraint-push retry: when the first
272
// overload resolution fails, having exactly one candidate to
273
// push formal arg types from disambiguates the constraint
274
// direction. Multi-candidate disambiguation under constraint
275
// push is bigger work tracked under #1174.
276
_try_find_single_arity_candidate(
277
group: Semantic.Symbols.FUNCTION_GROUP,
278
arg_count: int,
279
want_instance: bool
280
) -> Semantic.Symbols.Function? is
281
let result: Semantic.Symbols.Function? mut = null
282
let count mut = 0
283
284
for f in group.functions do
285
if !want_instance /\ f.is_instance then
286
continue
287
fi
288
289
if !f.are_arguments_declared then
290
continue
291
fi
292
293
if f.arguments.count != arg_count then
294
continue
295
fi
296
297
result = f
298
count = count + 1
299
od
300
301
if count == 1 then
302
return result
303
fi
304
305
return null
306
si
307
308
// should be called with logger speculating
309
_compile_call_arguments(
310
argument_expressions: Trees.Expressions.LIST,
311
arguments: Collections.LIST[Value],
312
argument_types: Collections.LIST[Type]
313
) is
314
for a in argument_expressions do
315
_compile_one_argument(a, arguments, argument_types)
316
od
317
si
318
319
// True for an argument that takes its type from the context -
320
// a bare `_`, or a `cast(v)` with the target elided - and
321
// failed to infer one on the first walk, because before the
322
// callee was resolved nothing had pushed it an expected type.
323
is_argument_awaiting_context_type(a: Trees.Expressions.Expression) -> bool static is
324
if !a.awaits_context_type then
325
return false
326
fi
327
328
if let value: Value = a.value then
329
if let type: Type = value.type then
330
return type.is_error
331
fi
332
333
return true
334
fi
335
336
return true
337
si
338
339
// True when the call carries at least one argument still
340
// awaiting a type from its context.
341
has_argument_awaiting_context_type(argument_expressions: Collections.List[Trees.Expressions.Expression]) -> bool static =>
342
argument_expressions |> any(a => COMPILE_CALLS.is_argument_awaiting_context_type(a))
343
344
// True for an argument that is a bare reference to an
345
// overloaded function or method group and stayed a
346
// non-consumable group load on the first walk. An overloaded
347
// group only becomes a delegate once a target call shape is
348
// pushed onto it, and before the callee was resolved nothing
349
// had one to push. A single-overload group resolves on the
350
// first walk and never looks like this.
351
is_unresolved_group_argument(a: Trees.Expressions.Expression) -> bool static is
352
if let value: Value = a.value then
353
if let load: Load.SYMBOL = value then
354
return load.symbol.is_function_group
355
fi
356
fi
357
358
return false
359
si
360
361
// True when the call carries at least one unresolved group
362
// reference among its arguments.
363
has_unresolved_group_argument(argument_expressions: Collections.List[Trees.Expressions.Expression]) -> bool static =>
364
argument_expressions |> any(a => COMPILE_CALLS.is_unresolved_group_argument(a))
365
366
// Once overload resolution has settled on a single, unambiguous
367
// `function`, retry any argument that had no type to infer
368
// against on the first walk - the resolved callee's formal
369
// types are available now. Re-walks every argument under a
370
// fresh speculation level, since the roll-back below discards
371
// whatever the first walk logged for the whole call, not just
372
// the waiting arguments.
373
//
374
// Two argument shapes need this. A context-typed one - a bare
375
// `_`, or a `cast(v)` with the target elided - infers its type
376
// from the formal. A bare reference to an overloaded function
377
// or method group turns into a delegate only once the formal's
378
// call shape is pushed onto it, so the group picks its member
379
// the same way an explicit annotation would pick it.
380
//
381
// Such an argument is only ever pushed a type when the resolved
382
// formal at that position is itself concrete: a generic
383
// candidate whose type variable is pinned by a sibling
384
// argument or an enclosing constraint is already specialized
385
// by this point, so the formal there is concrete too, but a
386
// type variable free only in the waiting slot leaves the formal
387
// wild and the argument is left to re-report its original
388
// error - neither a `_` nor a `cast(v)` ever itself contributes
389
// to binding a type variable. A group reference is additionally
390
// gated on the formal being callable - a function type or a
391
// named .NET delegate - since nothing else gives the group a
392
// shape to resolve against.
393
//
394
// A resolved formal with a declared .NET default value (an
395
// optional CLR parameter) takes that value rather than the
396
// type's zero value, so a positionally-written `_` behaves
397
// exactly like omitting the same parameter by name. That
398
// applies to `_` alone: `cast(v)` asks for a conversion of `v`,
399
// so a declared default has nothing to do with it.
400
// Returns true when a bare group argument resolved to a
401
// delegate under the pushed formal - the caller then
402
// re-resolves the call so the callee's own type variables
403
// bind from the delegate's shape rather than staying open.
404
_resolve_deferred_defaults(
405
function: Semantic.Symbols.Function,
406
argument_expressions: Collections.List[Trees.Expressions.Expression],
407
arguments: Collections.LIST[Value],
408
argument_types: Collections.LIST[Type]
409
) -> bool is
410
if
411
!has_argument_awaiting_context_type(argument_expressions) /\
412
!COMPILE_CALLS.has_unresolved_group_argument(argument_expressions)
413
then
414
return false
415
fi
416
417
let use retry_site = RETRY_SITE_STATS.enter("calls.resolve_deferred_defaults", RetrySiteKind.REWALK_WITH_INFORMATION)
418
_logger.roll_back()
419
_logger.speculate()
420
_flow.restore()
421
422
let resolved_group mut = false
423
424
for (index, a) in argument_expressions |> index() do
425
if
426
COMPILE_CALLS.is_unresolved_group_argument(a) /\
427
index < function.arguments.count /\
428
(
429
function.arguments[index].is_function \/
430
_delegate_shape.is_named_delegate(function.arguments[index], _innate_symbol_lookup)
431
)
432
then
433
a.set_expected_type(function.arguments[index], "{{0}} is not assignable to {{1}}")
434
_visitor.rewalk(a)
435
436
if !COMPILE_CALLS.is_unresolved_group_argument(a) then
437
resolved_group = true
438
fi
439
elif
440
COMPILE_CALLS.is_argument_awaiting_context_type(a) /\
441
index < function.arguments.count /\
442
!function.arguments[index].is_wild
443
then
444
let formal_type = function.arguments[index]
445
446
let stored =
447
if
448
isa Trees.Expressions.DEFAULT(a) /\
449
index < function.argument_defaults.count
450
then
451
function.argument_defaults[index]
452
else
453
null
454
fi
455
456
if stored? then
457
a.compile_expressions_state.value = DEFAULT_ARGUMENT_VALUES.build(stored, formal_type, _innate_symbol_lookup)
458
else
459
a.set_expected_type(formal_type, "")
460
_visitor.rewalk(a)
461
fi
462
elif isa Trees.Expressions.DEFAULT(a) then
463
// A `_[T]` argument, or a `DEFAULT` node
464
// `_apply_named_permutation` synthesised to fill an
465
// omitted named argument with the callee's own
466
// declared default value, already carries its
467
// final value. Re-walking either through
468
// `visit_default` would overwrite that value with
469
// the type's zero value - visit_default has no way
470
// to tell "already resolved to the right thing"
471
// from "resolved once, resolve again" - so leave
472
// it untouched. A still-unresolved `_` whose
473
// formal is wild has no value to protect and is
474
// walked below to re-report its own error under
475
// this fresh speculation level.
476
if COMPILE_CALLS.is_argument_awaiting_context_type(a) then
477
_visitor.rewalk(a)
478
fi
479
else
480
// ensure any error messages are committed
481
_visitor.rewalk(a)
482
fi
483
484
if let value: Value = a.value /\ value.type? then
485
arguments[index] = value
486
argument_types[index] = value.type!
487
fi
488
od
489
490
return resolved_group
491
si
492
493
_compile_one_argument(
494
a: Trees.Expressions.Expression,
495
arguments: Collections.LIST[Value],
496
argument_types: Collections.LIST[Type]
497
) is
498
let value = a.value
499
500
if value? /\ value.type? /\ value.check_is_consumable(_logger, a.location) then
501
arguments.add(value)
502
argument_types.add(value.type!)
503
else
504
let t = Semantic.Types.ERROR()
505
506
arguments.add(DUMMY(t, a.location))
507
508
argument_types.add(t)
509
fi
510
si
511
512
// Find the delegate type's own compiler-synthesized
513
// constructor - `.ctor(object, native int)`, the only one a
514
// real .NET delegate type ever declares.
515
_find_delegate_constructor(type: Semantic.Types.Type) -> Semantic.Symbols.Function? is
516
let named = cast Semantic.Types.NAMED?(type)
517
518
if !named? then
519
return null
520
fi
521
522
let symbol = named.scope.find_direct("init")
523
524
if let group: Semantic.Symbols.FUNCTION_GROUP = symbol then
525
if group.count == 1 then
526
return group.functions[0]
527
fi
528
529
return null
530
fi
531
532
return cast Semantic.Symbols.Function?(symbol)
533
si
534
535
// Resolve a member that is either a bare Function or a
536
// single-member FUNCTION_GROUP - the shape `find_member`
537
// returns for a non-overloaded method (mirrors
538
// DELEGATE_SHAPE._find_invoke).
539
_find_single_function_member(type: Semantic.Types.Type, name: string) -> Semantic.Symbols.Function? is
540
let symbol = type.find_member(name)
541
542
if let group: Semantic.Symbols.FUNCTION_GROUP = symbol then
543
if group.count == 1 then
544
return group.functions[0]
545
fi
546
547
return null
548
fi
549
550
return cast Semantic.Symbols.Function?(symbol)
551
si
552
553
// A real .NET delegate type's sole constructor is the
554
// compiler-synthesized `.ctor(object, native int)`, which no
555
// ghūl call site can satisfy (nothing produces a usable
556
// `native int`), so a single-argument constructor call
557
// against a named delegate type is free to mean explicit
558
// conversion: `TargetDelegate(functionValue)`.
559
//
560
// A literal written directly as the argument is pushed the
561
// delegate type as its expected type, the same way an
562
// assignment or argument-formal context does (see
563
// COMPILE_LAMBDAS.visit_function), and constructs the
564
// delegate directly via ldftn/newobj. An existing
565
// function/delegate-typed value has no compile-time method
566
// token to `ldftn` - its method is only known at runtime, via
567
// its own `Method` property - so it is reconstructed over
568
// (Target, MethodHandle function pointer) via the target
569
// delegate's own constructor instead.
570
_resolve_delegate_value_construction(
571
location: LOCATION,
572
type: Semantic.Types.Type,
573
argument_expression: Trees.Expressions.Expression
574
) -> (Value, Value) is
575
if isa Trees.Expressions.FUNCTION(argument_expression) then
576
let use retry_site = RETRY_SITE_STATS.enter("calls.delegate_value_construction", RetrySiteKind.REWALK_WITH_INFORMATION)
577
_logger.roll_back()
578
_logger.speculate()
579
_flow.restore()
580
581
argument_expression.set_expected_type(type, "{{0}} is not assignable to {{1}}")
582
_visitor.rewalk(argument_expression)
583
584
let value = argument_expression.value
585
586
if !value? \/ !value.type? \/ !value.check_is_consumable(_logger, argument_expression.location) then
587
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)))
588
fi
589
590
return (cast Value(DUMMY(type, location)), value)
591
fi
592
593
let value = argument_expression.value
594
595
if !value? \/ !value.type? \/ !value.check_is_consumable(_logger, argument_expression.location) then
596
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)))
597
fi
598
599
let source_type = value.type!
600
601
if !source_type.is_function /\ !_delegate_shape.is_named_delegate(source_type, _innate_symbol_lookup) then
602
_logger.error(argument_expression.location, "no constructor found init({source_type})")
603
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)))
604
fi
605
606
// Compile-time shape check: the two call shapes must
607
// actually agree. `Delegate.CreateDelegate` would have
608
// caught a mismatch for us at construction time, but
609
// going straight to a raw function pointer below bypasses
610
// that check entirely, so it has to happen here instead.
611
let source_shape =
612
if source_type.is_function then
613
source_type
614
else
615
_delegate_shape.try_get_function_type(source_type, _innate_symbol_lookup)
616
fi
617
618
let target_shape = _delegate_shape.try_get_function_type(type, _innate_symbol_lookup)
619
620
if !source_shape? \/ !target_shape? \/ !target_shape.is_assignable_from(source_shape) then
621
_logger.error(argument_expression.location, "{source_type} is not assignable to {type}")
622
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)))
623
fi
624
625
// `Target`/`Method` report only the last entry of a
626
// combined (multicast) delegate's invocation list, so a
627
// source built via `Delegate.Combine` would silently lose
628
// every earlier target. Not guarded against: ghūl has no
629
// syntax to combine delegates, so no ghūl-produced value
630
// reaching here is ever multicast.
631
let target_property = cast Semantic.Symbols.Property?(source_type.find_member("target"))
632
let method_property = cast Semantic.Symbols.Property?(source_type.find_member("method"))
633
634
if !target_property? \/ !method_property? then
635
_logger.error(argument_expression.location, "cannot convert {source_type} to {type}")
636
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)))
637
fi
638
639
let target_value = target_property.load(location, value, _symbol_loader)
640
let method_value = method_property.load(location, value, _symbol_loader)
641
let method_type = method_value.type!
642
643
let handle_property = cast Semantic.Symbols.Property?(method_type.find_member("method_handle"))
644
645
if !handle_property? then
646
_logger.error(argument_expression.location, "cannot convert {source_type} to {type}")
647
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)))
648
fi
649
650
let handle_value = handle_property.load(location, method_value, _symbol_loader)
651
let handle_type = handle_value.type!
652
653
let get_function_pointer_function = _find_single_function_member(handle_type, "get_function_pointer")
654
655
if !get_function_pointer_function? then
656
_logger.error(argument_expression.location, "cannot convert {source_type} to {type}")
657
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)))
658
fi
659
660
let pointer_value = get_function_pointer_function.call(location, handle_value, Collections.LIST[Value](), null, _function_caller)
661
662
let ctor = _find_delegate_constructor(type)
663
664
if !ctor? then
665
_logger.error(argument_expression.location, "cannot convert {source_type} to {type}")
666
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)))
667
fi
668
669
let ctor_arguments = Collections.LIST[Value]()
670
ctor_arguments.add(target_value)
671
ctor_arguments.add(pointer_value)
672
673
let constructed = _function_caller.call_constructor(ctor, ctor_arguments, type)
674
675
return (cast Value(DUMMY(type, location)), constructed)
676
si
677
678
resolve_constructor(
679
location: LOCATION,
680
right_location: LOCATION,
681
type: Semantic.Types.Type mut,
682
argument_expressions: Trees.Expressions.LIST,
683
argument_names: Collections.List[Trees.Identifiers.Identifier]?,
684
constraint: Semantic.Types.Type?,
685
cache_key: Trees.Node
686
) -> (Value, Value) is
687
let result: Value mut
688
689
// An explicit `Foo[...]` callee enters already specialized
690
// and was constraint-checked by `specialize_type`; an
691
// inferred `Foo(...)` callee is specialized below by
692
// overload resolution and is checked post-resolution.
693
let was_generic_on_entry = isa Semantic.Types.GENERIC(type)
694
695
let named_or_null = cast Semantic.Types.NAMED?(type)
696
697
// A callee whose type could not be settled was reported where
698
// it went wrong, so only an error value comes out of here.
699
if !named_or_null? \/ type.is_value_tuple \/ isa Semantic.Types.TUPLE(type) then
700
if !type.is_error then
701
_logger.error(location, "cannot construct {type}")
702
fi
703
704
return (DUMMY(Semantic.Types.ERROR(), location), DUMMY(Semantic.Types.ERROR(), location))
705
fi
706
707
let named_type = named_or_null
708
let type_symbol mut = named_type.symbol
709
710
if
711
!argument_names? /\
712
argument_expressions.expressions.count == 1 /\
713
_delegate_shape.is_named_delegate(type, _innate_symbol_lookup)
714
then
715
return _resolve_delegate_value_construction(location, type, argument_expressions.expressions[0])
716
fi
717
718
if let abstract_class: Semantic.Symbols.CLASS = type_symbol then
719
if abstract_class.is_abstract then
720
_logger.error(location, "cannot instantiate abstract class {abstract_class.name}", abstract_class.location, "class declared abstract here")
721
fi
722
fi
723
724
let symbol = named_type.scope.find_direct("init")
725
726
let function_group = cast Semantic.Symbols.FUNCTION_GROUP?(symbol)
727
728
let arguments = Collections.LIST[Value]()
729
let argument_types = Collections.LIST[Type]()
730
731
_compile_call_arguments(argument_expressions, arguments, argument_types)
732
733
if !function_group? then
734
_logger.error(location, "no constructor found init({argument_types |> join(", ")})")
735
736
return (cast Value(DUMMY(type, location)), cast Value(DUMMY(type, location)))
737
fi
738
739
let named_restrict: Collections.List[Semantic.Symbols.Function]? mut = null
740
741
if argument_names? then
742
let binding = _named_argument_binder.bind(location, function_group, argument_names, true)
743
744
if !binding? then
745
return (cast Value(Load.SYMBOL(null, function_group)), cast Value(DUMMY(type, location)))
746
fi
747
748
_apply_named_permutation(argument_expressions, arguments, argument_types, binding.permutation, binding.targets[0])
749
750
named_restrict = binding.targets
751
fi
752
753
let overload_result mut = _overload_resolver.resolve(location, function_group, argument_types, false, true, true, named_restrict)
754
755
// Sibling-arg fall-back: first resolve returned null AND
756
// there's at least one FUNCTION-literal arg in the call.
757
// The lambda's body walked under no parameter-type
758
// constraint and likely errored, leaving an actual type
759
// that doesn't reflect the real signature; binding fails;
760
// resolver returns null. Try tentatively binding the
761
// candidate's owner-generic args from the *resolvable*
762
// sibling actuals (skipping the failing lambda), fill the
763
// remaining slots with cached phantoms, then push the
764
// substituted formals as constraints to each arg and
765
// re-walk. The second resolve sees the lambda's now-
766
// resolved actual type and binds T from it.
767
//
768
// The lambda guard matters: if no arg is a lambda, the
769
// original null result reflects a genuine type mismatch
770
// (e.g. `Pair([1,2,3], LIST[int]([4,5,6]))` — int[] and
771
// LIST[int] don't unify for T) and the user-facing
772
// diagnostic is correct as-is.
773
if overload_result == null /\ argument_types |> any(a => a.is_function_with_any_implicit_argument_types) then
774
let candidate = _try_find_single_arity_candidate(function_group, argument_types.count, true)
775
776
if candidate? then
777
let specialized_candidate = _specialise_candidate_from_concrete_siblings(candidate, argument_types, cache_key, location)
778
779
if specialized_candidate? /\ specialized_candidate != candidate then
780
let use retry_site = RETRY_SITE_STATS.enter("calls.constructor_sibling_specialisation", RetrySiteKind.REWALK_WITH_INFORMATION)
781
_logger.roll_back()
782
_logger.speculate()
783
_flow.restore()
784
785
for (index, a) in argument_expressions |> index() do
786
let f = specialized_candidate.arguments[index]
787
788
a.set_expected_type(f, "{{0}} is not assignable to {{1}}")
789
790
_visitor.rewalk(a)
791
792
if let a.value? /\ value.type? /\ value.check_is_consumable(_logger, a.location) then
793
arguments[index] = value
794
argument_types[index] = value.type!
795
else
796
let t = Semantic.Types.ERROR()
797
arguments[index] = DUMMY(t, a.location)
798
argument_types[index] = t
799
fi
800
od
801
802
overload_result = _overload_resolver.resolve(location, function_group, argument_types, false, true, true, named_restrict)
803
fi
804
fi
805
fi
806
807
// An empty literal takes `object` as its element type with
808
// nothing around it to say otherwise, so it resolves either no
809
// constructor of the written type or one of the wrong
810
// instantiation. The candidate this call is for - specialised
811
// from the constraint where there is one - is pushed as the
812
// formals and the arguments walked again, the same recovery an
813
// ordinary call makes.
814
if
815
COMPILE_CALLS.has_empty_array_literal_argument(argument_expressions.expressions) /\
816
(overload_result == null \/ constraint?)
817
then
818
let specialised =
819
if constraint? then
820
_constructor_constraint_retry.try_specialise_candidates(
821
location,
822
if named_restrict? then named_restrict else function_group.functions fi,
823
constraint)
824
else
825
null
826
fi
827
828
let candidate =
829
if specialised? /\ specialised.count == 1 then
830
specialised[0]
831
else
832
_try_find_single_arity_candidate(function_group, argument_types.count, true)
833
fi
834
835
if candidate? /\ candidate.arguments.count == argument_expressions.expressions.count then
836
let use retry_site = RETRY_SITE_STATS.enter("calls.constructor_empty_literal", RetrySiteKind.REWALK_WITH_INFORMATION)
837
_logger.roll_back()
838
_logger.speculate()
839
_flow.restore()
840
841
for (index, a) in argument_expressions |> index() do
842
a.set_expected_type(candidate.arguments[index], "{{0}} is not assignable to {{1}}")
843
844
_visitor.rewalk(a)
845
846
if let a.value? /\ value.type? /\ value.check_is_consumable(_logger, a.location) then
847
arguments[index] = value
848
argument_types[index] = value.type!
849
else
850
let t = Semantic.Types.ERROR()
851
arguments[index] = DUMMY(t, a.location)
852
argument_types[index] = t
853
fi
854
od
855
856
overload_result =
857
_overload_resolver.resolve(
858
location,
859
function_group,
860
argument_types,
861
false,
862
true,
863
true,
864
specialised ?? named_restrict)
865
fi
866
fi
867
868
// Return-type-constraint fall-back: first resolve returned
869
// null AND we have a constraint pushed in by an enclosing
870
// return / let-init / assignment. The candidate's owner-
871
// generic args may include slots no actual arg can bind
872
// (e.g. `RESULT.OK(42)` against `RESULT[int, string]` —
873
// OK's arg binds T, the constraint contributes S; without
874
// a contribution from the constraint, binding fails and
875
// the resolver returns null). Pre-specialise each candidate
876
// from the constraint via CONSTRUCTOR_CONSTRAINT_RETRY,
877
// then re-resolve with the specialised list. Now formals
878
// are no-longer-wild concrete types and arg binding
879
// becomes verification.
880
if overload_result == null /\ constraint? then
881
let search = if named_restrict? then named_restrict else function_group.functions fi
882
let pre_specialised = _constructor_constraint_retry.try_specialise_candidates(location, search, constraint)
883
884
if pre_specialised? then
885
let use retry_site = RETRY_SITE_STATS.enter("calls.constructor_constraint_retry", RetrySiteKind.REWALK_WITH_INFORMATION)
886
_logger.roll_back()
887
_logger.speculate()
888
889
overload_result = _overload_resolver.resolve(location, function_group, argument_types, false, true, true, pre_specialised)
890
fi
891
fi
892
893
if overload_result == null then
894
return (cast Value(Load.SYMBOL(null, function_group)), cast Value(DUMMY(type, location)))
895
fi
896
897
if overload_result.needs_retry then
898
let use retry_site = RETRY_SITE_STATS.enter("calls.constructor_needs_retry", RetrySiteKind.REWALK_WITH_INFORMATION)
899
_logger.roll_back()
900
_logger.speculate()
901
_flow.restore()
902
903
for (index, a) in argument_expressions |> index() do
904
// let use debug_despose = debug_enter();
905
if a.value? /\ isa Trees.Expressions.FUNCTION(a) then
906
let f = overload_result.function.arguments[index]
907
908
a.set_expected_type(f, "{{0}} is not assignable to {{1}}")
909
_visitor.rewalk(a)
910
911
argument_types[index] = a.value!.type!
912
else
913
// ensure any error messages are committed
914
_visitor.rewalk(a)
915
fi
916
917
if a.value? then
918
arguments[index] = a.value
919
fi
920
od
921
922
overload_result = _overload_resolver.resolve(location, function_group, argument_types, false, true, true, named_restrict)
923
924
if !overload_result? then
925
return (cast Value(Load.SYMBOL(null, function_group)), cast Value(DUMMY(type, location)))
926
fi
927
fi
928
929
let function mut = overload_result.function
930
931
function = _owner_constraint_specializer.specialize_from_constraint(location, function, constraint)
932
function = _type_arg_placeholder_registry.specialize_with_placeholders(location, function, cache_key)
933
934
let _ = _resolve_deferred_defaults(function, argument_expressions.expressions, arguments, argument_types)
935
936
if isa Semantic.Symbols.GENERIC(function.owner) then
937
type_symbol = cast Semantic.Symbols.Symbol(function.owner)
938
// The GENERIC owner of a resolved constructor always carries
939
// a concrete type (the specialized class) by this point.
940
type = function.owner.type
941
fi
942
943
let is_directly_owned mut = false
944
945
if isa Semantic.Symbols.GENERIC(type_symbol) /\ isa Semantic.Symbols.Symbol(function.owner) then
946
is_directly_owned = type_symbol =~ cast Semantic.Symbols.Symbol(function.owner)
947
else
948
is_directly_owned = type_symbol == function.owner
949
fi
950
951
if !is_directly_owned then
952
_logger.error(location, "cannot call superclass constructor {function}", function.location, "constructor declared here")
953
fi
954
955
_symbol_use_locations.add_symbol_use(right_location, function)
956
_symbol_use_locations.add_symbol_use(right_location, type_symbol.root_unspecialized_symbol)
957
958
959
if !was_generic_on_entry then
960
if let constructed: Semantic.Types.GENERIC = type then
961
if let generic_symbol: Semantic.Symbols.GENERIC = constructed.symbol then
962
generic_symbol.symbol.check_argument_constraints(location, _logger, constructed.arguments)
963
fi
964
fi
965
fi
966
967
return (cast Value(Load.SYMBOL(null, function_group)), _function_caller.call_constructor(function, arguments, type))
968
si
969
970
// True iff any formal arg in the resolver's PARTIAL function
971
// is itself ERROR or contains an ERROR. Signal that the
972
// partial binding was driven from a tainted lambda actual
973
// (a typical free-function-with-lambda inference scenario)
974
// and the PARTIAL formals shouldn't be pushed as constraints
975
// unchanged.
976
_partial_arguments_contain_error(function: Semantic.Symbols.Function) -> bool is
977
if !function.are_arguments_declared then
978
return false
979
fi
980
981
let found = Ghul.BOX(false)
982
983
for arg in function.arguments do
984
arg.walk((t: Type) is
985
if t.is_error then
986
found.value = true
987
fi
988
si)
989
990
if found.value then
991
return true
992
fi
993
od
994
995
return false
996
si
997
998
// True iff any formal arg in the resolver's PARTIAL function
999
// still references one of the function's own generic
1000
// type-variables (i.e. the resolver couldn't bind that slot
1001
// from any sibling actual). Same shape problem as
1002
// `_partial_arguments_contain_error`: pushing the formal as-is
1003
// burdens the lambda's re-walk with a constraint
1004
// (`int -> STEP[T]`) that can't be satisfied by anything
1005
// concrete the body produces. Re-specialise with phantoms in
1006
// those slots so the constraint pushed becomes
1007
// (`int -> STEP[<phantom>]`) — actually informative, and
1008
// open to match propagation from inside the body.
1009
_partial_arguments_contain_unbound_function_type_variable(function: Semantic.Symbols.Function) -> bool is
1010
let found = Ghul.BOX(false)
1011
1012
for arg in function.arguments do
1013
arg.walk((t: Type) is
1014
if t.is_function_generic_argument then
1015
found.value = true
1016
fi
1017
si)
1018
1019
if found.value then
1020
return true
1021
fi
1022
od
1023
1024
return false
1025
si
1026
1027
// True if any of the actual argument expressions is a
1028
// Trees.Expressions.FUNCTION literal. Used to gate the
1029
// constraint-push retry on the recoverable case where a
1030
// not-yet-constrained lambda body walked with placeholder
1031
// args and produced an ERROR-tainted type that the under-
1032
// determination detector wouldn't otherwise recognise as
1033
// recoverable.
1034
//
1035
// Static so it can be exercised by unit tests with hand-built
1036
// expression lists, without spinning up COMPILE_CALLS's full
1037
// dependency graph.
1038
// A caller may hand over a partially built argument list, whose
1039
// unfilled slots have no expression yet.
1040
has_function_literal_argument(argument_expressions: Collections.List[Trees.Expressions.Expression?]?) -> bool static is
1041
if !argument_expressions? then
1042
return false
1043
fi
1044
1045
for a in argument_expressions do
1046
if isa Trees.Expressions.FUNCTION(a) then
1047
return true
1048
fi
1049
od
1050
1051
return false
1052
si
1053
1054
// An empty array literal argument has no elements to infer its
1055
// element type from, so it walks to object[] and fails to match a
1056
// more specific array parameter. Like a function literal, it can be
1057
// re-walked under a pushed formal type, so it is a signal that a
1058
// null overload result might be recoverable.
1059
// As above: an unfilled slot in a partially built list has no
1060
// expression yet.
1061
has_empty_array_literal_argument(argument_expressions: Collections.List[Trees.Expressions.Expression?]?) -> bool static is
1062
if !argument_expressions? then
1063
return false
1064
fi
1065
1066
for a in argument_expressions do
1067
if let sequence: Trees.Expressions.SEQUENCE = a then
1068
if sequence.elements.expressions.count == 0 then
1069
return true
1070
fi
1071
fi
1072
od
1073
1074
return false
1075
si
1076
1077
// An actual whose type still carries a type parameter of the
1078
// function that produced it: a call to a generic function
1079
// nothing in its own arguments could bind, such as
1080
// `zero_of[T](n: int) -> T` called as `takes(zero_of(1))`.
1081
// The formal it is being matched against is the only thing
1082
// that can settle the parameter, so pushing it as the
1083
// argument's expected type and re-walking is what turns the
1084
// call into a resolvable one. A parameter of `caller` itself,
1085
// or of a function `caller` is nested in, is in scope where
1086
// the call is written and needs nothing pushed.
1087
//
1088
// Static, and taking the caller rather than reading it off the
1089
// symbol table, so it can be exercised with hand-built types.
1090
// A caller may hand over a partially built argument list, whose
1091
// unfilled slots have no type yet.
1092
has_unbound_type_argument(
1093
argument_types: Collections.List[Type?]?,
1094
caller: Semantic.Scope?
1095
) -> bool static is
1096
if !argument_types? then
1097
return false
1098
fi
1099
1100
for t in argument_types do
1101
if t? /\ t.has_function_generic_argument_foreign_to(caller) then
1102
return true
1103
fi
1104
od
1105
1106
return false
1107
si
1108
1109
// Walk the scope stack from current_function outward to find
1110
// the recursive closure a `rec` reference here would bind to.
1111
// Mirrors the lookup in `visit(RECURSE)`.
1112
_find_recursive_target() -> Semantic.Symbols.Closure? is
1113
let function = _symbol_table.current_function
1114
1115
if !function? \/ !function.is_closure then
1116
return null
1117
fi
1118
1119
let closure = cast Semantic.Symbols.Closure?(function)!
1120
1121
if closure.is_recursive then
1122
return closure
1123
fi
1124
1125
let stack = _symbol_table.stack
1126
let index mut = stack.count - 1
1127
let seen_self mut = false
1128
1129
while index >= 0 do
1130
let scope = stack[index]
1131
1132
if scope.is_closure then
1133
let c = cast Semantic.Symbols.Closure?(scope)!
1134
1135
if seen_self then
1136
if c.is_recursive then
1137
return c
1138
fi
1139
elif c == closure then
1140
seen_self = true
1141
fi
1142
fi
1143
1144
index = index - 1
1145
od
1146
1147
return null
1148
si
1149
1150
// Push each actual argument of a `rec(actual...)` call onto
1151
// the recursive closure's parameter Variables as a LUB
1152
// candidate. When the actual isn't assignable to the
1153
// parameter's current type, reset that type back to an
1154
// INFERRED_VARIABLE_TYPE placeholder so the next outer-body
1155
// retry iteration's closure_arg_resolver re-derives the
1156
// parameter type from the widened LUB. Handles both self-rec
1157
// and nested-rec (rec referring to an outer recursive
1158
// ancestor) — the target is determined by walking the
1159
// closure stack mirroring `visit(RECURSE)`.
1160
try_propagate_recursive_call_args(call: Trees.Expressions.CALL) is
1161
if !isa Trees.Expressions.RECURSE(call.function) then
1162
return
1163
fi
1164
1165
let closure = _find_recursive_target()
1166
1167
if !closure? then
1168
return
1169
fi
1170
1171
let param_count = closure.argument_names.count
1172
let args = call.arguments.expressions
1173
let arg_count = args.count
1174
1175
let n = if param_count < arg_count then param_count else arg_count fi
1176
1177
let i mut = 0
1178
while i < n do
1179
let name = closure.argument_names[i]
1180
let param = cast Semantic.Symbols.Variable?(closure.find_direct(name))
1181
let arg_expr = args[i]
1182
1183
// Prefer arg_expr.value.type, but fall back to the
1184
// resolved symbol's type when the value's snapshot
1185
// is null — happens for outer-scope locals captured
1186
// into a nested closure before being typed.
1187
let actual: Semantic.Types.Type? mut = null
1188
if let arg_expr?.value? /\ value.type? then
1189
actual = value.type
1190
elif isa Trees.Expressions.IDENTIFIER(arg_expr) then
1191
let id_expr = arg_expr
1192
let sym = _visitor.find(id_expr.identifier)
1193
if sym? then
1194
actual = sym.type
1195
fi
1196
fi
1197
1198
if param? /\ actual? then
1199
if actual.is_settled then
1200
_logger.mark_consumed_any_if(Semantic.INFERENCE_TRACE.add_lower_bound("calls.recursive_call_argument", param, actual))
1201
1202
// Reset the param's type if currently
1203
// resolved to something narrower than the
1204
// actual — leaves it concrete when the
1205
// actual fits. The comparison is against the
1206
// declared type: inside an `if let` on the
1207
// parameter, `param.type` is the narrowed
1208
// variant, which the recursive call's argument
1209
// legitimately widens.
1210
let declared = _flow.declared_type_of(param) ?? param.type
1211
1212
if
1213
declared? /\
1214
!declared.is_sentinel /\
1215
!declared.is_assignable_from(actual)
1216
then
1217
param.set_type(Semantic.Types.INFERRED_VARIABLE_TYPE(param))
1218
_logger.mark_consumed_any()
1219
fi
1220
fi
1221
fi
1222
1223
i = i + 1
1224
od
1225
si
1226
1227
// A call returning a pack slot still to be inferred, written where
1228
// the context already names an N-ary function - `let g: (int, int)
1229
// -> int = once(...)` - takes the pack from the context: the
1230
// parameters of the function the context expects are the tuple
1231
// the pack binds to, and its return bounds the result slot.
1232
feed_pack_from_expected(function: Semantic.Symbols.Function, expected: Semantic.Types.Type?) =>
1233
_feed_pack_from_expected(function, expected)
1234
1235
_feed_pack_from_expected(function: Semantic.Symbols.Function, expected: Semantic.Types.Type?) is
1236
if !expected? \/ !expected.is_function \/ expected.is_action then
1237
return
1238
fi
1239
1240
let returned = function.return_type
1241
1242
if !returned? \/ !Semantic.ARGUMENT_PACK.is_pack_slot(returned) then
1243
return
1244
fi
1245
1246
let arity = Semantic.ARGUMENT_PACK.parameter_count(expected)
1247
1248
if arity < 2 \/ arity > Semantic.ARGUMENT_PACK.MAXIMUM_ARITY then
1249
return
1250
fi
1251
1252
if let placeholder: Semantic.Types.INFERRED_VARIABLE_TYPE = returned.arguments[0] then
1253
if let origin: Semantic.Symbols.INFERRED_TYPE_ARG_ORIGIN = placeholder.origin /\ origin.is_argument_pack then
1254
let elements = Collections.LIST[Semantic.Types.Type]()
1255
1256
for i in 0..arity do
1257
elements.add(expected.arguments[i])
1258
od
1259
1260
let tuple = _innate_symbol_lookup.get_tuple_type(elements, null)
1261
1262
_logger.mark_consumed_any_if(Semantic.INFERENCE_TRACE.add_lower_bound("calls.pack_expected_type", origin, tuple))
1263
fi
1264
fi
1265
1266
if let result: Semantic.Types.INFERRED_VARIABLE_TYPE = returned.arguments[returned.arguments.count - 1] then
1267
_logger.mark_consumed_any_if(Semantic.INFERENCE_TRACE.add_upper_bound("calls.pack_expected_return", result.origin, expected.arguments[expected.arguments.count - 1]))
1268
fi
1269
si
1270
1271
// Resolution against the group binds a type argument only from
1272
// what the arguments say. One nothing binds - a pack whose element
1273
// types only a later call supplies - comes back as the callee's own
1274
// bare parameter, which no variable can take as its type. Where
1275
// the retry specialised the same candidate over the call's
1276
// phantoms, that specialisation carries the slot instead: the
1277
// phantom is what a later use constrains, and the re-walk that
1278
// follows resolves the call again over what it learned.
1279
_prefer_phantom_specialised(
1280
result: Semantic.OVERLOAD_RESOLVE_RESULT?,
1281
push: Semantic.Symbols.Function?
1282
) -> Semantic.OVERLOAD_RESOLVE_RESULT? is
1283
if
1284
result? /\
1285
push? /\
1286
push != result.function /\
1287
push.root_specialized_from == result.function.root_specialized_from /\
1288
COMPILE_CALLS.has_unbound_type_argument([result.function.return_type!], _symbol_table.current_function)
1289
then
1290
_logger.mark_consumed_any()
1291
1292
return Semantic.OVERLOAD_RESOLVE_RESULT(push, result.score, false)
1293
fi
1294
1295
return result
1296
si
1297
1298
// An array literal argument can hold an element whose type is still
1299
// being inferred - an untyped local initialized with `[]`, say. Its
1300
// join then waits on that element, so the literal carries no element
1301
// type and nothing would tell the element what it has to be. The
1302
// resolved formal does: each such element is bounded above by the
1303
// formal's element type, which a later walk settles it from.
1304
_bound_awaiting_sequence_elements(
1305
candidate: Semantic.Symbols.Function,
1306
argument_expressions: Collections.List[Trees.Expressions.Expression]
1307
) is
1308
if candidate.arguments.count != argument_expressions.count then
1309
return
1310
fi
1311
1312
for index in 0..argument_expressions.count do
1313
_bound_sequence_elements(argument_expressions[index], candidate.arguments[index])
1314
od
1315
si
1316
1317
_bound_sequence_elements(argument: Trees.Expressions.Expression, formal: Type?) is
1318
let sequence = cast Trees.Expressions.SEQUENCE?(argument)
1319
1320
if !sequence? \/ !formal? then
1321
return
1322
fi
1323
1324
let element_type = Semantic.SEQUENCE_ELEMENT_BOUND.for_element_type(formal.get_element_type())
1325
1326
if !element_type? then
1327
return
1328
fi
1329
1330
for element in sequence.elements do
1331
if let value = element.value, placeholder: Semantic.Types.INFERRED_VARIABLE_TYPE = value.type then
1332
_logger.mark_consumed_any_if(
1333
Semantic.INFERENCE_TRACE.add_upper_bound("calls.sequence_element", placeholder.origin, element_type)
1334
)
1335
elif isa Trees.Expressions.SEQUENCE(element) then
1336
_bound_sequence_elements(element, element_type)
1337
fi
1338
od
1339
si
1340
1341
// Constraint-push retry: when the first resolve fails AND
1342
// there's exactly one arity-matching candidate AND at least
1343
// one argument's first-walk type is under-determined for
1344
// its corresponding formal type, push that candidate's
1345
// formal arg types as constraints to each call argument
1346
// and re-walk. This catches `apply(Box())` cases where a
1347
// constructor argument's owner generic args were
1348
// under-determined the first time round but become
1349
// resolvable from the formal argument's type. The
1350
// candidate's signature is the only signal we have for
1351
// what the under-determined arg should resolve to —
1352
// multi-candidate disambiguation under constraint push
1353
// is left to a more general overload-as-constraint
1354
// pass under #1174.
1355
// Constraint-push retry for when the initial overload resolution
1356
// returned null. Generalised over the source of the argument
1357
// expressions: calls pass `call.arguments.expressions` /
1358
// `call.arguments.location` / `call` as the cache key; binary
1359
// operators pass `[left, right]`, `binary.location`, the BINARY
1360
// node; unary operators pass `[right]`, `unary.location`, the
1361
// UNARY node. Assumes the caller is inside a `_logger.speculate()`
1362
// level: this method does `_logger.roll_back(); _logger.speculate();`
1363
// to re-enter before re-walking, mirroring the visit_call wrapper.
1364
try_overload_after_null(
1365
function_group: Semantic.Symbols.FUNCTION_GROUP,
1366
arguments: Collections.LIST[Value],
1367
argument_types: Collections.LIST[Type],
1368
want_instance: bool,
1369
named_restrict: Collections.List[Semantic.Symbols.Function]?,
1370
argument_expressions: Collections.List[Trees.Expressions.Expression],
1371
argument_location: LOCATION,
1372
cache_key: Trees.Node
1373
) -> Semantic.OVERLOAD_RESOLVE_RESULT? is
1374
let candidate =
1375
_try_find_single_arity_candidate(function_group, argument_types.count, want_instance) ??
1376
_async_literal_candidates.find(function_group, argument_expressions, want_instance)
1377
let effective_candidate = candidate ?? _delegate_push_candidates.find_single_pushable_candidate(function_group, argument_types, want_instance)
1378
1379
// Trigger the retry when at least one actual
1380
// is a FUNCTION literal even if its first-walk
1381
// type has been ERROR-tainted by a body that
1382
// walked without a constraint. The lambda can
1383
// be re-walked under a pushed formal, so a
1384
// FUNCTION arg is the natural signal that the
1385
// null overload result might be recoverable.
1386
// The pre-existing `any_arg_under_determined`
1387
// path still covers the constructor-arg shape
1388
// (e.g. `apply(Box())`). A named-delegate formal
1389
// mismatched against a bare function-shaped actual
1390
// (a named function reference, or a lambda that
1391
// resolved to its own native shape) is the same kind
1392
// of recoverable gap.
1393
1394
if effective_candidate? /\ (
1395
_under_determination_detector.any_arg_under_determined(effective_candidate, argument_types) \/
1396
COMPILE_CALLS.has_function_literal_argument(argument_expressions) \/
1397
COMPILE_CALLS.has_empty_array_literal_argument(argument_expressions) \/
1398
_delegate_push_candidates.has_push_mismatch(effective_candidate, argument_types) \/
1399
COMPILE_CALLS.has_unresolved_group_argument(argument_expressions) \/
1400
_has_carrier_mismatch_reference(effective_candidate, argument_types, argument_expressions) \/
1401
_has_pack_mismatch_argument(effective_candidate, argument_types, argument_expressions) \/
1402
COMPILE_CALLS.has_unbound_type_argument(argument_types, _symbol_table.current_function)
1403
) then
1404
// Sibling-arg specialisation, symmetric to
1405
// the path in `resolve_constructor`: when
1406
// one actual is a not-yet-resolved FUNCTION
1407
// literal AND the candidate has a generic
1408
// owner, push specialised formals (bound
1409
// from concrete sibling actuals) rather
1410
// than unsubstituted formals containing
1411
// free type variables that the lambda's
1412
// argument-setup would reject as "type
1413
// variable" anyway. Owners that aren't
1414
// generic short-circuit inside
1415
// OWNER_TYPE_ARG_SPECIALIZER and the
1416
// pre-existing behaviour is preserved.
1417
let push_candidate: Semantic.Symbols.Function? mut = effective_candidate
1418
1419
// Two-step specialisation: try
1420
// owner-class generic args first (for
1421
// method calls whose receiver class is
1422
// generic), then if push_candidate is
1423
// still the unsubstituted candidate and
1424
// the candidate has its own generic
1425
// args, try binding those from concrete
1426
// siblings. The function-own path is
1427
// what catches free-function HOFs like
1428
// `generate[T,S]((0,1), state => ...)` —
1429
// S binds from the (0,1) actual, T fills
1430
// from a phantom, and the substituted
1431
// formal-arg-type can then constrain the
1432
// lambda's body re-walk.
1433
push_candidate = _specialise_candidate_from_concrete_siblings(effective_candidate, argument_types, cache_key, argument_location)
1434
1435
if push_candidate == effective_candidate /\ effective_candidate.is_generic then
1436
let phantom_origins = _type_arg_placeholder_registry.get_or_create_for_function(cache_key, argument_location, effective_candidate)
1437
push_candidate = _owner_type_arg_specializer.specialize_function_own_args_from_concrete_siblings(effective_candidate, argument_types, phantom_origins, argument_location)
1438
fi
1439
1440
let use retry_site = RETRY_SITE_STATS.enter("calls.try_overload_after_null", RetrySiteKind.REWALK_WITH_INFORMATION)
1441
_logger.roll_back()
1442
_logger.speculate()
1443
_flow.restore()
1444
1445
// Indexed rather than iterated: an argument may be
1446
// replaced in place below, and the list being walked is
1447
// the call's own.
1448
for index in 0..argument_expressions.count do
1449
let original = argument_expressions[index]
1450
let f = push_candidate!.arguments[index]
1451
1452
// A named function reference whose shape differs
1453
// from the formal only in an optional position's
1454
// carrier has no delegate to load; it is
1455
// eta-expanded here, and the literal that replaces
1456
// it walks under the formal in its place.
1457
let a mut = original
1458
1459
_bound_value_parameters_from_pack(push_candidate!, index, argument_types[index])
1460
1461
_take_spread_reading(push_candidate!, index, original, arguments, argument_types)
1462
1463
if let outer_arity = _nested_pack_adaptation_arity(push_candidate!, index, original, argument_types[index]) then
1464
if
1465
let literal = _function_reference_adapter.try_adapt(original, outer_arity) /\
1466
_splice(cache_key, original, index, literal)
1467
then
1468
a = literal
1469
fi
1470
elif _is_packable_literal(push_candidate!, index, original, argument_types[index], cache_key) then
1471
// compiled taking the tuple, under the formal pushed below
1472
elif let presented = _presented_pack_type(cache_key, push_candidate!, index, original, argument_types[index]) then
1473
// A function value of the pack's elements is judged as
1474
// the function of their tuple it will be presented as.
1475
// The value itself is wrapped once a candidate has won.
1476
argument_types[index] = presented
1477
1478
continue
1479
elif let shape = _carrier_mismatch_shape(original, argument_types[index], f) then
1480
if
1481
let literal =
1482
_function_reference_adapter.try_adapt(
1483
original,
1484
shape.arguments.count - 1
1485
) /\
1486
_splice(cache_key, original, index, literal)
1487
then
1488
a = literal
1489
fi
1490
fi
1491
1492
a.set_expected_type(f, "{{0}} is not assignable to {{1}}")
1493
_mark_packed_literal(push_candidate!, index, a)
1494
1495
_visitor.rewalk(a)
1496
1497
if let a.value? /\ value.type? /\ value.check_is_consumable(_logger, a.location) then
1498
arguments[index] = value
1499
argument_types[index] = value.type!
1500
else
1501
let t = Semantic.Types.ERROR()
1502
1503
arguments[index] = DUMMY(t, a.location)
1504
argument_types[index] = t
1505
fi
1506
od
1507
1508
return _prefer_phantom_specialised(
1509
_overload_resolver.resolve(argument_location, function_group, argument_types, true, want_instance, false, named_restrict),
1510
push_candidate)
1511
fi
1512
1513
return null
1514
si
1515
1516
// Puts `literal` where `original` stood, so the walk below
1517
// reaches it and generate-il emits the closure's body from it.
1518
// A call holds its arguments in a list addressed by index; an
1519
// operator holds each operand in a slot of its own. Any other
1520
// node declines rather than being spliced blind: a literal that
1521
// does not land in the tree is never emitted, and the delegate
1522
// built over it would name a method with no body.
1523
_splice(
1524
cache_key: Trees.Node,
1525
original: Trees.Expressions.Expression,
1526
index: int,
1527
literal: Trees.Expressions.FUNCTION
1528
) -> bool is
1529
if let call: Trees.Expressions.CALL = cache_key then
1530
call.arguments.replace_element(index, literal)
1531
return true
1532
fi
1533
1534
if let binary: Trees.Expressions.BINARY = cache_key then
1535
binary.replace_child(original, literal)
1536
return binary.left == literal \/ binary.right == literal
1537
fi
1538
1539
return false
1540
si
1541
1542
// Whether the pack tuple the formal at `index` takes is decided
1543
// by another of the candidate's formals and that formal has not
1544
// settled it yet - the element type of a pipe whose source is
1545
// still being inferred, say. An operand going into the formal
1546
// then waits for that walk rather than deciding the tuple itself.
1547
_pack_tuple_waits_for_sibling(candidate: Semantic.Symbols.Function, index: int) -> bool is
1548
let formal = if index < candidate.arguments.count then candidate.arguments[index] else null fi
1549
1550
let shape = _target_shape_of(formal)
1551
1552
return
1553
shape? /\
1554
Semantic.ARGUMENT_PACK.is_pack_slot(shape) /\
1555
!shape.arguments[Semantic.ARGUMENT_PACK.fixed_count(shape)].is_settled /\
1556
Semantic.PACK_TUPLE_SOURCE().is_decided_by_another_formal(candidate.arguments, index, shape.arguments[Semantic.ARGUMENT_PACK.fixed_count(shape)])
1557
si
1558
1559
// A function value whose own parameter types are still
1560
// placeholders - a literal stored in a local that nothing has typed
1561
// yet - going into a spread formal whose pack the other arguments
1562
// have already pinned takes its parameter types from the pack's
1563
// tuple, as a literal written in the same slot does.
1564
_bound_value_parameters_from_pack(candidate: Semantic.Symbols.Function, index: int, argument_type: Type?) is
1565
if
1566
!candidate.get_argument_is_pack(index) \/
1567
candidate.get_argument_pack_depth(index) != 0 \/
1568
index >= candidate.arguments.count \/
1569
!argument_type? \/
1570
!argument_type.is_function
1571
then
1572
return
1573
fi
1574
1575
let shape = _target_shape_of(candidate.arguments[index])
1576
1577
if !shape? \/ !Semantic.ARGUMENT_PACK.is_pack_slot(shape) then
1578
return
1579
fi
1580
1581
let fixed = Semantic.ARGUMENT_PACK.fixed_count(shape)
1582
1583
let tuple = shape.arguments[fixed]
1584
1585
// A tuple still carrying the candidate's own unbound type
1586
// parameters names no type the value's parameters could take.
1587
if !tuple.is_settled \/ COMPILE_CALLS.has_unbound_type_argument([tuple], _symbol_table.current_function) then
1588
return
1589
fi
1590
1591
let arity = Semantic.ARGUMENT_PACK.parameter_count(argument_type) - fixed
1592
1593
if arity < 2 \/ tuple.arguments.count != arity then
1594
return
1595
fi
1596
1597
for i in 0..arity do
1598
if let placeholder: Semantic.Types.INFERRED_VARIABLE_TYPE = argument_type.arguments[fixed + i] then
1599
_logger.mark_consumed_any_if(
1600
Semantic.INFERENCE_TRACE.add_lower_bound("calls.pack_value_parameters", placeholder.origin, tuple.arguments[i])
1601
)
1602
fi
1603
od
1604
si
1605
1606
// The function-type shape a formal presents: the formal itself
1607
// when it is a ghul function type, the call shape of a named
1608
// delegate's `invoke` when it is one, and null otherwise.
1609
_target_shape_of(formal: Type?) -> Type? is
1610
if !formal? then
1611
return null
1612
fi
1613
1614
if formal.is_function then
1615
return formal
1616
fi
1617
1618
return _delegate_shape.try_get_function_type(formal, _innate_symbol_lookup)
1619
si
1620
1621
// The formal's call shape, when this argument is a named
1622
// function reference the eta-expansion applies to: it loaded as
1623
// a delegate over a named function with no receiver to
1624
// re-evaluate, and its own shape differs from the formal's only
1625
// in which carrier an optional position uses. Null otherwise.
1626
_carrier_mismatch_shape(
1627
argument: Trees.Expressions.Expression,
1628
argument_type: Type?,
1629
formal: Type?
1630
) -> Type? is
1631
if isa Trees.Expressions.FUNCTION(argument) then
1632
return null
1633
fi
1634
1635
if let delegate: Load.DELEGATE = argument.value then
1636
if !delegate.referenced_function? \/ !isa NULL(delegate.frame) then
1637
return null
1638
fi
1639
else
1640
return null
1641
fi
1642
1643
let shape = _target_shape_of(formal)
1644
1645
if !FUNCTION_REFERENCE_ADAPTER.is_carrier_only_mismatch(argument_type, shape) then
1646
return null
1647
fi
1648
1649
return shape
1650
si
1651
1652
// A literal that cannot be compiled taking the pack's tuple - one
1653
// that calls itself, say - is presented through a thunk like any
1654
// other function value. Where the formal has settled the tuple,
1655
// the literal is first walked under the other reading of the same
1656
// pack, a function of the tuple's elements, so that parameters it
1657
// left untyped take their types from them. Returns the type the
1658
// literal then has, or the one it had.
1659
// How many parameters the formal at `index` takes of its own
1660
// before the pack.
1661
_fixed_count_of(candidate: Semantic.Symbols.Function, index: int) -> int is
1662
if index < candidate.arguments.count then
1663
if let shape = _target_shape_of(candidate.arguments[index]) /\ Semantic.ARGUMENT_PACK.is_pack_slot(shape) then
1664
return Semantic.ARGUMENT_PACK.fixed_count(shape)
1665
fi
1666
fi
1667
1668
return 0
1669
si
1670
1671
_walk_under_spread_reading(
1672
candidate: Semantic.Symbols.Function,
1673
index: int,
1674
argument: Trees.Expressions.Expression,
1675
argument_type: Type?
1676
) -> Type? is
1677
let literal = parenthesised_literal(argument)
1678
1679
if
1680
!literal? \/
1681
PACKED_LITERAL.is_eligible(literal, _fixed_count_of(candidate, index)) \/
1682
!candidate.get_argument_is_pack(index) \/
1683
candidate.get_argument_pack_depth(index) != 0 \/
1684
index >= candidate.arguments.count
1685
then
1686
return argument_type
1687
fi
1688
1689
let shape = _target_shape_of(candidate.arguments[index])
1690
1691
if !Semantic.ARGUMENT_PACK.is_pack_slot(shape) then
1692
return argument_type
1693
fi
1694
1695
let fixed = Semantic.ARGUMENT_PACK.fixed_count(shape!)
1696
1697
let arity = literal.arguments.expressions.count - fixed
1698
1699
// One parameter in the pack's place is the tuple itself, not
1700
// the pack spread out, whatever the tuple destructures into.
1701
if arity < 2 \/ arity > Semantic.ARGUMENT_PACK.MAXIMUM_ARITY then
1702
return argument_type
1703
fi
1704
1705
let tuple = Semantic.SETTLED_PLACEHOLDER_RESOLVER.instance.resolve(shape.arguments[fixed])
1706
1707
if !tuple.is_settled then
1708
return argument_type
1709
fi
1710
1711
let strategy = DESTRUCTURE_RESOLVER.resolve_strategy(tuple, arity)
1712
1713
let types = Collections.LIST[Type]()
1714
1715
for i in 0..fixed do
1716
types.add(shape.arguments[i])
1717
od
1718
1719
for i in 0..arity do
1720
if strategy.is_deconstruct then
1721
if let element = strategy.deconstruct_function!.arguments[i].get_element_type() then
1722
types.add(element)
1723
fi
1724
elif i < strategy.members.count then
1725
if let member = strategy.members[i], member_type = member.type then
1726
types.add(member_type)
1727
fi
1728
fi
1729
od
1730
1731
if types.count != fixed + arity then
1732
return argument_type
1733
fi
1734
1735
types.add(
1736
if shape.is_action then
1737
_innate_symbol_lookup.get_void_type()
1738
else
1739
shape.arguments[shape.arguments.count - 1]
1740
fi
1741
)
1742
1743
literal.set_expected_type(
1744
_innate_symbol_lookup.get_function_type(types, shape.is_pure_function),
1745
"{{0}} is not assignable to {{1}}"
1746
)
1747
1748
_visitor.rewalk(literal)
1749
1750
return literal.value?.type ?? argument_type
1751
si
1752
1753
// The value of `expression`, a function of an argument pack's
1754
// elements, presented as a function of their tuple. Absent where
1755
// the value is not such a function.
1756
present_function_value(expression: Trees.Expressions.Expression) -> Value? is
1757
let value = expression.value
1758
1759
if !value? \/ !value.type? \/ isa IR.Values.PACK_WRAP(value) then
1760
return null
1761
fi
1762
1763
return _pack_wrap_builder.unpack(expression, 0, expression.location, value, 0)
1764
si
1765
1766
1767
_take_spread_reading(
1768
candidate: Semantic.Symbols.Function,
1769
index: int,
1770
argument: Trees.Expressions.Expression,
1771
arguments: Collections.LIST[Value],
1772
argument_types: Collections.LIST[Type]
1773
) is
1774
let walked = _walk_under_spread_reading(candidate, index, argument, argument_types[index])
1775
1776
if walked? /\ walked != argument_types[index] then
1777
argument_types[index] = walked
1778
1779
if let value = argument.value then
1780
arguments[index] = value
1781
fi
1782
fi
1783
si
1784
1785
1786
// The type a function value of the pack's elements is presented at
1787
// in the formal at `index`, where that formal takes the pack as
1788
// one tuple and the value is settled enough to say what the tuple
1789
// is. Absent otherwise.
1790
_presented_pack_type(
1791
owner: Trees.Node?,
1792
candidate: Semantic.Symbols.Function,
1793
index: int,
1794
argument: Trees.Expressions.Expression,
1795
argument_type: Type?
1796
) -> Type? is
1797
// Only a call and an operator have the step, after a candidate
1798
// has won, that wraps the value.
1799
if !isa Trees.Expressions.CALL(owner) /\ !isa Trees.Expressions.BINARY(owner) then
1800
return null
1801
fi
1802
1803
if let literal = parenthesised_literal(argument) then
1804
if PACKED_LITERAL.is_eligible(literal, _fixed_count_of(candidate, index)) then
1805
return null
1806
fi
1807
fi
1808
1809
if !_pack_adaptation_value_arity(candidate, index, argument, argument_type)? then
1810
return null
1811
fi
1812
1813
let fixed = _fixed_count_of(candidate, index)
1814
1815
if let settled = _pack_wrap_builder.packed_type(argument_type, fixed) then
1816
return settled
1817
fi
1818
1819
// A value whose parameter types are still being inferred is
1820
// judged over them all the same, unless another argument is
1821
// what decides the tuple: the pack binds to the tuple of
1822
// placeholders, and the call resolves provisionally, so that a
1823
// later use of its result has a pack to settle. What it is
1824
// judged as is the formal's own shape, whose tuple is the pack
1825
// that use will bind; each placeholder is an obligation of
1826
// this walk.
1827
if parenthesised_literal(argument)? \/ _pack_tuple_waits_for_sibling(candidate, index) then
1828
return null
1829
fi
1830
1831
let provisional = _pack_wrap_builder.packed_type(argument_type, fixed, true)
1832
1833
if provisional? /\ argument_type? then
1834
for i in 0..Semantic.ARGUMENT_PACK.parameter_count(argument_type) do
1835
if argument_type.arguments[i].contains_inferred then
1836
Semantic.OBLIGATIONS.defer("pack_value", argument_type.arguments[i], argument.location)
1837
fi
1838
od
1839
fi
1840
1841
if !provisional? then
1842
return null
1843
fi
1844
1845
return _target_shape_of(candidate.arguments[index])
1846
si
1847
1848
// Wraps each argument of a resolved call that is a function of
1849
// the pack's elements going into a formal that takes their tuple.
1850
present_pack_arguments(
1851
key: Trees.Node,
1852
expressions: Collections.List[Trees.Expressions.Expression],
1853
function: Semantic.Symbols.Function,
1854
arguments: Collections.LIST[Value]
1855
) is
1856
for index in 0..arguments.count do
1857
if !function.get_argument_is_pack(index) \/ function.get_argument_pack_depth(index) != 0 then
1858
continue
1859
fi
1860
1861
let expression = expressions[index]
1862
1863
if !Semantic.ARGUMENT_PACK.adaptation_arity(_target_shape_of(function.arguments[index]), arguments[index].type)? then
1864
continue
1865
fi
1866
1867
if let wrapped = _pack_wrap_builder.unpack(key, index, expression.location, arguments[index], _fixed_count_of(function, index)) then
1868
arguments[index] = wrapped
1869
1870
// Whatever reads the argument.s value afterwards - a fused
1871
// pipe stage takes its callback from there - has to see the
1872
// function the formal was given.
1873
expression.compile_expressions_state.value = wrapped
1874
fi
1875
od
1876
si
1877
1878
// Whether this argument is a literal written with the pack spread
1879
// out that is compiled taking the pack's tuple directly.
1880
_is_packable_literal(
1881
candidate: Semantic.Symbols.Function,
1882
index: int,
1883
argument: Trees.Expressions.Expression,
1884
argument_type: Type?,
1885
owner: Trees.Node?
1886
) -> bool is
1887
if let literal = parenthesised_literal(argument) then
1888
return
1889
PACKED_LITERAL.is_eligible(literal, _fixed_count_of(candidate, index)) /\
1890
_pack_adaptation_arity(candidate, index, argument, argument_type, owner)?
1891
fi
1892
1893
return false
1894
si
1895
1896
// Says, beside the expected type just pushed, that the formal is
1897
// one declared to take an argument pack spread out.
1898
_mark_packed_literal(
1899
candidate: Semantic.Symbols.Function,
1900
index: int,
1901
argument: Trees.Expressions.Expression
1902
) is
1903
if !candidate.get_argument_is_pack(index) then
1904
return
1905
fi
1906
1907
let depth = candidate.get_argument_pack_depth(index)
1908
1909
// Where another argument decides the tuple and has not yet, the
1910
// literal stays as written until a walk on which it has.
1911
if depth == 0 /\ _pack_tuple_waits_for_sibling(candidate, index) then
1912
return
1913
fi
1914
1915
if parenthesised_literal(argument)? then
1916
argument.set_expects_pack(depth)
1917
fi
1918
si
1919
1920
// How many of this argument's parameters the pack stands for, when
1921
// the formal it is going into was declared to take an argument
1922
// pack spread out - `f: T.. -> U` - and absent otherwise.
1923
//
1924
// Such a formal takes a function whose last parameter is the
1925
// tuple the pack binds to. An actual with two or more parameters
1926
// in its place describes the same call with the pack spread out,
1927
// and is presented in the shape the formal asks for. One
1928
// parameter there needs no presenting, and anything past the
1929
// tuple limit has no tuple to bind to.
1930
_pack_adaptation_arity(
1931
candidate: Semantic.Symbols.Function,
1932
index: int,
1933
argument: Trees.Expressions.Expression,
1934
argument_type: Type?,
1935
owner: Trees.Node?
1936
) -> int? is
1937
if !candidate.get_argument_is_pack(index) then
1938
return null
1939
fi
1940
1941
// A marker written past the formal's own function type is
1942
// about the function the actual returns, not the actual, so
1943
// there is nothing to present here.
1944
if candidate.get_argument_pack_depth(index) != 0 then
1945
return null
1946
fi
1947
1948
let formal = if index < candidate.arguments.count then candidate.arguments[index] else null fi
1949
1950
let shape = _target_shape_of(formal)
1951
1952
let arity = Semantic.ARGUMENT_PACK.adaptation_arity(shape, argument_type)
1953
1954
if !arity? then
1955
return null
1956
fi
1957
1958
// Where another argument decides the tuple - the element type
1959
// of a pipe whose source has not yet been inferred - settling
1960
// it from this one would pin a literal's parameters to a
1961
// placeholder, so it waits for a walk on which that argument
1962
// has settled it. Where only this argument can decide it,
1963
// presenting it is how it gets decided.
1964
if _pack_tuple_waits_for_sibling(candidate, index) then
1965
return null
1966
fi
1967
1968
// A literal is compiled where it stands; anything else has to
1969
// name a function.
1970
// A call argument in parentheses - the subject of a `|>` has to
1971
// be written that way - is still one, and so is an operator
1972
// operand, which is always parenthesised. Either way a context
1973
// that pins the pack reaches it through the expected type the
1974
// call or operator carries.
1975
let looks_through =
1976
isa Trees.Expressions.CALL(owner) \/
1977
isa Trees.Expressions.BINARY(owner)
1978
1979
let literal =
1980
if looks_through then
1981
parenthesised_literal(argument)
1982
else
1983
cast Trees.Expressions.FUNCTION?(argument)
1984
fi
1985
1986
if literal? then
1987
return arity
1988
fi
1989
1990
// A method named on an instance is included: the delegate
1991
// over it carries its receiver.
1992
if let delegate: Load.DELEGATE = argument.value then
1993
if delegate.referenced_function? then
1994
return arity
1995
fi
1996
fi
1997
1998
return null
1999
si
2000
2001
// The function literal an argument is, looking through the
2002
// parentheses a single-element group puts around it.
2003
parenthesised_literal(argument: Trees.Expressions.Expression?) -> Trees.Expressions.FUNCTION? static is
2004
if let literal: Trees.Expressions.FUNCTION = argument then
2005
return literal
2006
fi
2007
2008
if let group: Trees.Expressions.TUPLE = argument /\ group.elements.expressions.count == 1 then
2009
return parenthesised_literal(group.elements.expressions[0])
2010
fi
2011
2012
return null
2013
si
2014
2015
// How many of a function-valued operand's parameters the pack
2016
// stands for, when the formal it is going into was declared to
2017
// take an argument pack spread out. The operand is evaluated once
2018
// where it stands and presented through a thunk that captures the
2019
// value. Absent when the formal is not a pack formal or the
2020
// operand is not a function value with two or more parameters in
2021
// the pack's place.
2022
_pack_adaptation_value_arity(
2023
candidate: Semantic.Symbols.Function,
2024
index: int,
2025
argument: Trees.Expressions.Expression,
2026
argument_type: Type?
2027
) -> int? is
2028
if !candidate.get_argument_is_pack(index) then
2029
return null
2030
fi
2031
2032
// A marker written past the formal's own function type is
2033
// about the function the actual returns, not the actual, so
2034
// there is nothing to adapt here.
2035
if candidate.get_argument_pack_depth(index) != 0 then
2036
return null
2037
fi
2038
2039
let formal = if index < candidate.arguments.count then candidate.arguments[index] else null fi
2040
2041
return Semantic.ARGUMENT_PACK.adaptation_arity(_target_shape_of(formal), argument_type)
2042
si
2043
2044
// A call whose callee's declared return type carries the pack
2045
// marker - `retry[T.., U](f: T.. -> U, n: int) -> T.. -> U` -
2046
// resolves to the tuple-in function type the declaration names.
2047
// Where this call binds the pack to a concrete tuple, the
2048
// result is presented as the corresponding N-ary function. Depth past the outermost return
2049
// is left as the tuple-in shape; the marker there names a
2050
// function the result itself returns, one the caller reaches
2051
// through its own call.
2052
_try_wrap_return_pack(
2053
call: Trees.Expressions.CALL,
2054
function: Semantic.Symbols.Function,
2055
call_receiver: IR.Values.Value?,
2056
arguments: Collections.LIST[IR.Values.Value]
2057
) -> bool is
2058
let wrapped = wrap_return_pack(call, function, call.location, call_receiver, arguments)
2059
2060
if !wrapped? then
2061
return false
2062
fi
2063
2064
call.compile_expressions_state.value = wrapped
2065
2066
return true
2067
si
2068
2069
// The call-boundary presentation a pack-marked declared return
2070
// type asks for: `retry[T.., U](f: T.. -> U, n: int) -> T.. -> U`
2071
// resolves to the tuple-in function type the declaration names.
2072
// Where this call binds the pack to a concrete tuple, the result
2073
// is presented as the corresponding N-ary function: the call's
2074
// own value is computed once, where the call stands, and a thunk
2075
// taking the elements packs them and calls it. `key` is the node
2076
// the call is compiled for. Null when this call is not one the
2077
// presentation applies to.
2078
wrap_return_pack(
2079
key: Trees.Node,
2080
function: Semantic.Symbols.Function,
2081
location: Source.LOCATION,
2082
call_receiver: IR.Values.Value?,
2083
arguments: Collections.LIST[IR.Values.Value]
2084
) -> IR.Values.Value? is
2085
if function.return_pack_depth != 0 then
2086
return null
2087
fi
2088
2089
// The pack may have bound to a tuple of placeholders that have
2090
// since settled; the stored composite is not rewritten when
2091
// they do, so it is read through the resolver here.
2092
let declared = if let rt = function.return_type then Semantic.SETTLED_PLACEHOLDER_RESOLVER.instance.resolve(rt) else null fi
2093
2094
if !declared? \/ !Semantic.ARGUMENT_PACK.is_pack_slot(declared) then
2095
return null
2096
fi
2097
2098
let fixed = Semantic.ARGUMENT_PACK.fixed_count(declared)
2099
2100
if !_pack_wrap_builder.spread_type(declared, fixed)? then
2101
return null
2102
fi
2103
2104
return
2105
_pack_wrap_builder.pack(
2106
key,
2107
-1,
2108
location,
2109
function.call(location, call_receiver, arguments, null, _function_caller),
2110
declared,
2111
fixed
2112
)
2113
si
2114
2115
// The tuple the pack formal at `index` binds to. The formal's own
2116
// element type is the answer where the call has already settled
2117
// it; the actual's parameter types are the fallback, which is what
2118
// lets the type argument be inferred when nothing else pins it.
2119
_packed_group_type(
2120
candidate: Semantic.Symbols.Function,
2121
index: int,
2122
argument_type: Type?
2123
) -> Type? is
2124
let formal = if index < candidate.arguments.count then candidate.arguments[index] else null fi
2125
let shape = _target_shape_of(formal)
2126
2127
if let s: Type = shape then
2128
if Semantic.ARGUMENT_PACK.is_pack_slot(s) then
2129
let element = s.arguments[Semantic.ARGUMENT_PACK.fixed_count(s)]
2130
2131
if !element.is_error /\ !element.contains_inferred /\ !element.is_wild then
2132
return element
2133
fi
2134
fi
2135
fi
2136
2137
return Semantic.ARGUMENT_PACK.packed_parameters(argument_type, _fixed_count_of(candidate, index))
2138
si
2139
2140
// A literal compiled taking the pack's tuple was typed before the
2141
// call settled the pack, so element names that only its own
2142
// result gives the pack reach the settled formal but not the
2143
// literal. Where the two differ in nothing but those names, the
2144
// literal's one physical parameter takes the formal's, as it
2145
// would have had the call been written with its type arguments.
2146
_settle_packed_literal_names(function: Semantic.Symbols.Function, argument_expressions: Collections.List[Trees.Expressions.Expression]) is
2147
for index in 0..argument_expressions.count do
2148
if let literal = parenthesised_literal(argument_expressions[index]) then
2149
if
2150
let closure: Semantic.Symbols.Closure = _symbol_table.scope_for(literal) /\
2151
closure.packed_parameters? /\
2152
closure.arguments.count >= 1
2153
then
2154
let settled = _packed_group_type(function, index, null)
2155
2156
let last = closure.arguments.count - 1
2157
2158
if
2159
settled? /\
2160
closure.arguments[last] != settled /\
2161
closure.arguments[last].is_equivalent_to(settled) /\
2162
settled.is_equivalent_to(closure.arguments[last])
2163
then
2164
let physical = Collections.LIST[Type](closure.arguments)
2165
2166
physical[last] = settled
2167
2168
closure.pack_group?.set_type(settled)
2169
closure.arguments = physical
2170
fi
2171
fi
2172
fi
2173
od
2174
si
2175
2176
// A call written with the pack spread out - `apply(f, "a", "b")`
2177
// - describes the same call as the written-out tuple form the
2178
// formal takes. The trailing actuals are collected into a tuple
2179
// literal here, so that everything downstream sees the form it
2180
// already resolves.
2181
_try_normalise_spread(
2182
function_group: Semantic.Symbols.FUNCTION_GROUP,
2183
arguments: Collections.LIST[Value],
2184
argument_types: Collections.LIST[Type],
2185
argument_expressions: Trees.Expressions.LIST,
2186
want_instance: bool
2187
) -> bool is
2188
let candidate: Semantic.Symbols.Function? mut = null
2189
let count mut = 0
2190
2191
for f in function_group.functions do
2192
if !want_instance /\ f.is_instance then
2193
continue
2194
fi
2195
2196
if !f.are_arguments_declared \/ !f.has_spread_argument then
2197
continue
2198
fi
2199
2200
candidate = f
2201
count = count + 1
2202
od
2203
2204
if count != 1 then
2205
return false
2206
fi
2207
2208
let first = candidate!.spread_argument_index
2209
2210
if !Semantic.ARGUMENT_PACK.spread_arity(first, argument_expressions.expressions.count)? then
2211
return false
2212
fi
2213
2214
let elements = Collections.LIST[Trees.Expressions.Expression]()
2215
2216
for i in first..argument_expressions.expressions.count do
2217
elements.add(argument_expressions.expressions[i])
2218
od
2219
2220
let span = argument_expressions.location
2221
let tuple = Trees.Expressions.TUPLE(span, Trees.Expressions.LIST(span, elements), false)
2222
2223
// The trailing actuals are walked a second time below, so
2224
// the failed resolve's diagnostics and the flow state it
2225
// left behind are both dropped first - the same contract
2226
// every other retry in this file walks under.
2227
let use retry_site = RETRY_SITE_STATS.enter("calls.normalise_spread", RetrySiteKind.ALTERNATIVE)
2228
_logger.roll_back()
2229
_logger.speculate()
2230
_flow.restore()
2231
2232
// The leading actuals were walked under the speculation the
2233
// roll back just discarded, and nothing below walks them
2234
// again: walked once more here, so that what they reported
2235
// is not lost with the failed resolve's diagnostics.
2236
for i in 0..first do
2237
let a = argument_expressions.expressions[i]
2238
2239
_visitor.rewalk(a)
2240
2241
if let a.value? /\ value.type? then
2242
arguments[i] = value
2243
argument_types[i] = value.type!
2244
else
2245
let t = Semantic.Types.ERROR()
2246
2247
arguments[i] = DUMMY(t, a.location)
2248
argument_types[i] = t
2249
fi
2250
od
2251
2252
while argument_expressions.expressions.count > first do
2253
argument_expressions.expressions.remove_at(argument_expressions.expressions.count - 1)
2254
arguments.remove_at(arguments.count - 1)
2255
argument_types.remove_at(argument_types.count - 1)
2256
od
2257
2258
_visitor.rewalk(tuple)
2259
2260
argument_expressions.expressions.add(tuple)
2261
2262
if let tuple.value? /\ value.type? then
2263
arguments.add(value)
2264
argument_types.add(value.type!)
2265
else
2266
let t = Semantic.Types.ERROR()
2267
2268
arguments.add(DUMMY(t, span))
2269
argument_types.add(t)
2270
fi
2271
2272
return true
2273
si
2274
2275
// True when at least one argument is one the pack adaptation
2276
// applies to - the signal that a failed resolve is recoverable
2277
// by wrapping it under the candidate's formal.
2278
_has_pack_mismatch_argument(
2279
candidate: Semantic.Symbols.Function,
2280
argument_types: Collections.LIST[Type],
2281
argument_expressions: Collections.List[Trees.Expressions.Expression]
2282
) -> bool is
2283
if candidate.arguments.count != argument_expressions.count then
2284
return false
2285
fi
2286
2287
for i in 0..argument_expressions.count do
2288
if _pack_adaptation_arity(candidate, i, argument_expressions[i], argument_types[i], null)? then
2289
return true
2290
fi
2291
2292
if _pack_adaptation_value_arity(candidate, i, argument_expressions[i], argument_types[i])? then
2293
return true
2294
fi
2295
2296
if _nested_pack_adaptation_arity(candidate, i, argument_expressions[i], argument_types[i])? then
2297
return true
2298
fi
2299
od
2300
2301
return false
2302
si
2303
2304
// The arity to eta-expand an argument with when its formal wrote
2305
// the pack marker past its own function type - `make: (int) -> T..
2306
// -> U` - and the argument is a function, not a literal, that
2307
// returns an N-ary function at that depth. The expansion is a
2308
// literal over the formal's own parameters calling the argument,
2309
// so the N-ary function becomes a literal's body, which the
2310
// return-spine carry fits to the tuple the pack binds to. Absent
2311
// otherwise.
2312
_nested_pack_adaptation_arity(
2313
candidate: Semantic.Symbols.Function,
2314
index: int,
2315
argument: Trees.Expressions.Expression,
2316
argument_type: Type?
2317
) -> int? is
2318
if !candidate.get_argument_is_pack(index) then
2319
return null
2320
fi
2321
2322
let depth = candidate.get_argument_pack_depth(index)
2323
2324
if depth <= 0 \/ parenthesised_literal(argument)? then
2325
return null
2326
fi
2327
2328
if !argument_type? \/ !argument_type.is_function then
2329
return null
2330
fi
2331
2332
let returned mut = argument_type
2333
2334
for _ in 0..depth do
2335
if !returned.is_function \/ returned.is_action \/ returned.arguments.count == 0 then
2336
return null
2337
fi
2338
2339
returned = returned.arguments[returned.arguments.count - 1]
2340
od
2341
2342
if !returned.is_function then
2343
return null
2344
fi
2345
2346
let arity = Semantic.ARGUMENT_PACK.parameter_count(returned)
2347
2348
if arity < 2 \/ arity > Semantic.ARGUMENT_PACK.MAXIMUM_ARITY then
2349
return null
2350
fi
2351
2352
return Semantic.ARGUMENT_PACK.parameter_count(argument_type)
2353
si
2354
2355
// True when at least one argument is such a reference - the
2356
// signal that a failed resolve is recoverable by eta-expanding
2357
// it under the candidate's formal.
2358
_has_carrier_mismatch_reference(
2359
candidate: Semantic.Symbols.Function,
2360
argument_types: Collections.LIST[Type],
2361
argument_expressions: Collections.List[Trees.Expressions.Expression]
2362
) -> bool is
2363
if candidate.arguments.count != argument_expressions.count then
2364
return false
2365
fi
2366
2367
for i in 0..argument_expressions.count do
2368
if _carrier_mismatch_shape(argument_expressions[i], argument_types[i], candidate.arguments[i])? then
2369
return true
2370
fi
2371
od
2372
2373
return false
2374
si
2375
2376
// PARTIAL re-specialisation: the resolver may
2377
// have driven its type-arg binding from a
2378
// tainted lambda actual whose body errored on
2379
// the first walk (the free-function lambda-
2380
// inference gap). Pushing those ERROR-bearing
2381
// formals as constraints to the lambda would
2382
// taint its re-walk too. Detect the case and
2383
// re-specialise from CLEAN siblings via the
2384
// function-own-args specialiser (which skips
2385
// ERROR / placeholder-bearing actuals); push
2386
// that cleaner form.
2387
//
2388
// Same shape for unbound function-own type
2389
// variables: when the resolver couldn't bind a
2390
// slot, the formal still contains the
2391
// candidate's literal `T` / `S` /…, which is
2392
// useless as a constraint downstream
2393
// (literal `T` matches nothing concrete the
2394
// body could produce). Re-specialise so those
2395
// slots become phantoms — open to match propagation
2396
// from inside the lambda body.
2397
// PARTIAL-result retry. Generalised over the source of the
2398
// argument expressions in the same way as `try_overload_after_null`.
2399
// Assumes the caller is inside a `_logger.speculate()` level.
2400
try_overload_on_partial(
2401
overload_result: Semantic.OVERLOAD_RESOLVE_RESULT,
2402
function_group: Semantic.Symbols.FUNCTION_GROUP,
2403
arguments: Collections.LIST[Value],
2404
argument_types: Collections.LIST[Type],
2405
want_instance: bool,
2406
named_restrict: Collections.List[Semantic.Symbols.Function]?,
2407
argument_expressions: Collections.List[Trees.Expressions.Expression],
2408
argument_location: LOCATION,
2409
cache_key: Trees.Node
2410
) -> Semantic.OVERLOAD_RESOLVE_RESULT? is
2411
let push_function mut = overload_result.function
2412
2413
// An asynchronous literal with no declared return type
2414
// settles between same-arity candidates by whether its body
2415
// produces a value. The resolver picked before the literal's
2416
// return type could say, so its pick may be the other one.
2417
if let agreed = _async_literal_candidates.find(function_group, argument_expressions, want_instance) then
2418
if agreed != push_function then
2419
push_function = agreed
2420
2421
if agreed.is_generic then
2422
let phantom_origins = _type_arg_placeholder_registry.get_or_create_for_function(cache_key, argument_location, agreed)
2423
let respecialized = _owner_type_arg_specializer.specialize_function_own_args_from_concrete_siblings(agreed, argument_types, phantom_origins, argument_location)
2424
2425
if respecialized != agreed then
2426
push_function = respecialized
2427
fi
2428
fi
2429
fi
2430
fi
2431
2432
if
2433
_partial_arguments_contain_error(push_function) \/
2434
_partial_arguments_contain_unbound_function_type_variable(push_function)
2435
then
2436
let candidate = _try_find_single_arity_candidate(function_group, argument_types.count, want_instance)
2437
2438
if candidate? /\ candidate.is_generic then
2439
let phantom_origins = _type_arg_placeholder_registry.get_or_create_for_function(cache_key, argument_location, candidate)
2440
let respecialized = _owner_type_arg_specializer.specialize_function_own_args_from_concrete_siblings(candidate, argument_types, phantom_origins, argument_location)
2441
2442
if respecialized != candidate then
2443
push_function = respecialized
2444
fi
2445
fi
2446
fi
2447
2448
let use retry_site = RETRY_SITE_STATS.enter("calls.try_overload_on_partial", RetrySiteKind.REWALK_WITH_INFORMATION)
2449
_logger.roll_back()
2450
_logger.speculate()
2451
_flow.restore()
2452
2453
// Indexed rather than iterated: an argument may be replaced
2454
// in place below, and the list being walked is the call's own.
2455
for index in 0..argument_expressions.count do
2456
let a mut = argument_expressions[index]
2457
2458
// A splice from the after-null retry may have replaced
2459
// the original operand in the tree while this list still
2460
// names the original (the operator path snapshots its
2461
// operands once, before the retries). Read the tree's
2462
// current child so the re-walk and the commit of
2463
// arguments[index] target what stands there.
2464
if let binary: Trees.Expressions.BINARY = cache_key then
2465
// Two operands name the free-function path's
2466
// [left, right]; one names the member path's
2467
// [right], the left being the receiver.
2468
let tree_arg =
2469
if argument_expressions.count == 2 /\ index == 0 then binary.left else binary.right fi
2470
2471
if tree_arg != a then
2472
a = tree_arg
2473
fi
2474
fi
2475
2476
// A delegate formal is pushed onto any argument, not only
2477
// a literal: an expression that merely contains literals
2478
// (an `if` over two of them, say) forwards the constraint
2479
// to them and joins at the delegate type. One that cannot
2480
// act on it re-walks unchanged and is caught by the
2481
// delegate check below.
2482
let argument mut = a
2483
let is_packed mut = false
2484
2485
_bound_value_parameters_from_pack(push_function, index, argument_types[index])
2486
2487
_take_spread_reading(push_function, index, a, arguments, argument_types)
2488
2489
if let presented = _presented_pack_type(cache_key, push_function, index, a, argument_types[index]) then
2490
argument_types[index] = presented
2491
2492
continue
2493
fi
2494
2495
if _is_packable_literal(push_function, index, a, argument_types[index], cache_key) then
2496
is_packed = true
2497
fi
2498
2499
if
2500
is_packed \/
2501
(
2502
argument.value? /\
2503
(
2504
parenthesised_literal(argument)? \/
2505
_delegate_shape.is_named_delegate(push_function.arguments[index], _innate_symbol_lookup)
2506
)
2507
)
2508
then
2509
let f = push_function.arguments[index]
2510
2511
argument.set_expected_type(f, "{{0}} is not assignable to {{1}}")
2512
_mark_packed_literal(push_function, index, argument)
2513
_visitor.rewalk(argument)
2514
2515
if let argument.value? /\ value.type? then
2516
argument_types[index] = value.type!
2517
fi
2518
else
2519
// ensure any error messages are committed
2520
_visitor.rewalk(argument)
2521
fi
2522
2523
if argument.value? then
2524
arguments[index] = argument.value
2525
fi
2526
od
2527
2528
// A delegate formal was matched partially on the strength of
2529
// the actual being some function type, which only a literal
2530
// can make good on - the re-walk above compiles a literal to
2531
// the delegate and leaves anything else at its own type.
2532
// Reject those here: letting one through would emit a value
2533
// of one delegate type into a slot of another, which the CLR
2534
// does not convert.
2535
for (index, formal) in push_function.arguments |> index() do
2536
if _delegate_shape.is_named_delegate(formal, _innate_symbol_lookup) /\ !formal.is_assignable_from(argument_types[index]) then
2537
_logger.error(
2538
argument_expressions[index].location,
2539
"{argument_types[index]} is not assignable to {formal}")
2540
2541
return null
2542
fi
2543
od
2544
2545
return _prefer_phantom_specialised(
2546
_overload_resolver.resolve(argument_location, function_group, argument_types, false, want_instance, false, named_restrict),
2547
push_function)
2548
si
2549
2550
visit_call(call: Trees.Expressions.CALL) is
2551
// The stand-in call a `|>` leaves behind when its right side is
2552
// not a call: the parser has already reported that, and there
2553
// is nothing here to resolve. Anything this pass said about it
2554
// would describe the placeholder rather than the code.
2555
if call.is_poisoned then
2556
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2557
return
2558
fi
2559
2560
// Recursive-call match propagation for self-recursive lambdas
2561
// (`let f = x rec => ... rec(actual) ...`). The
2562
// call-site match propagation below only widens a closure's
2563
// argument type when the formal is still an
2564
// INFERRED_VARIABLE_TYPE placeholder. For a rec call the
2565
// formal is the closure's own parameter Variable, which
2566
// by iter N is already resolved to (often the narrow)
2567
// outer call-site type. Without further widening, a rec
2568
// call with a wider actual fails type-check.
2569
//
2570
// Widen here: push each actual as a candidate on the
2571
// closure parameter's LUB. When the actual isn't
2572
// assignable to the current parameter type, reset the
2573
// parameter's type back to a placeholder so the next
2574
// outer-body-retry iteration's closure_arg_resolver pass
2575
// re-derives from the now-wider LUB.
2576
try_propagate_recursive_call_args(call)
2577
2578
// Arity-aware refinement of MEMBER_CONSTRAINT for the
2579
// `<placeholder>.<name>(args...)` shape. MEMBER.visit
2580
// already emitted MEMBER_CONSTRAINT(name); pin the
2581
// arity here so the resolved type must have `name`
2582
// callable at this arg count, not merely present. The
2583
// receiver may already have been ERROR-typed by
2584
// MEMBER.visit's placeholder branch — read the *member's
2585
// left*'s type to find the placeholder regardless.
2586
if let member: Trees.Expressions.MEMBER = call.function then
2587
if let member.left?, left.value? /\ value.type? then
2588
if let placeholder: Semantic.Types.INFERRED_VARIABLE_TYPE = value.type then
2589
let arity = call.arguments.count
2590
2591
_logger.mark_consumed_any_if(Semantic.INFERENCE_TRACE.add_constraint("calls.member_call_arity", placeholder.origin,
2592
Semantic.MEMBER_CONSTRAINT(member.identifier.name, arity)
2593
))
2594
fi
2595
fi
2596
fi
2597
2598
let function_value = call.function.value
2599
2600
if !function_value? \/ !function_value.type? then
2601
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2602
return
2603
fi
2604
2605
// `|>` threads its subject in as the first argument, which is
2606
// positional; it is spliced into the argument list but not into
2607
// argument_names, so combining it with named written arguments
2608
// is rejected rather than silently misaligned. Checked before
2609
// the constructor dispatch below so it covers constructor calls
2610
// too.
2611
if call.is_thread_first /\ call.argument_names? then
2612
_logger.error(call.location, "named arguments cannot be combined with |>")
2613
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2614
return
2615
fi
2616
2617
// Bare unit-variant accesses (`COLOR.RED`, `Option.NONE[int]`)
2618
// already lowered to a NEW pointing at the singleton. Empty
2619
// parens on top of that — `COLOR.RED()` — pass the value
2620
// through; supplying any argument is an error because a unit
2621
// variant carries no fields. Generic unit variants with the
2622
// type arguments inferred from context still arrive as a
2623
// TYPE_EXPRESSION (the lower step needs a constraint that
2624
// only the parent has) and fall through to resolve_constructor.
2625
if isa NEW(function_value) then
2626
let new_value = cast NEW(function_value)
2627
2628
if new_value.constructor.owner!.is_unit_variant then
2629
if call.arguments.count == 0 then
2630
call.compile_expressions_state.value = new_value
2631
return
2632
fi
2633
2634
_logger.error(
2635
call.location,
2636
"unit variant {new_value.type} takes no arguments"
2637
)
2638
2639
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2640
return
2641
fi
2642
fi
2643
2644
if function_value.is_type_expression then
2645
(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)
2646
2647
return
2648
fi
2649
2650
let arguments = Collections.LIST[Value]()
2651
let argument_types = Collections.LIST[Type]()
2652
2653
// Snapshot the presence-narrowed type before the argument
2654
// walk crosses the fact it was read through.
2655
let function_value_type = function_value.type
2656
2657
_compile_call_arguments(call.arguments, arguments, argument_types)
2658
2659
// A `~>` call's subject arrives as `T?`, but the callee
2660
// takes `T`: the propagation unwraps it before the call,
2661
// so the candidate match sees the unwrapped type. The
2662
// presence test and the extract happen at the wrap, not
2663
// here.
2664
if call.propagates_absence /\ argument_types.count > 0 then
2665
let subject_type = argument_types[0]
2666
2667
if subject_type.is_optional then
2668
let inner =
2669
if subject_type.is_value_type then
2670
subject_type.optional_inner_type
2671
else
2672
subject_type.as_non_optional()
2673
fi
2674
2675
if inner? then
2676
argument_types[0] = inner
2677
fi
2678
fi
2679
fi
2680
2681
// TODO handle if left is actually a type not a function or method
2682
// in which case we should treat this as a constructor call
2683
2684
// we could also treat consuming a bare type as a constructor call
2685
// this would be done in the symbol loader
2686
2687
let load_symbol: Semantic.Symbols.Symbol? mut = null
2688
2689
if let load: Load.SYMBOL = function_value then
2690
load_symbol = load.symbol
2691
2692
if load_symbol.is_function_group then
2693
let want_instance: bool mut
2694
2695
want_instance =
2696
if load.from? then
2697
load.from.is_consumable
2698
else
2699
_symbol_table.current_instance_context?
2700
fi
2701
2702
let function_group = cast Semantic.Symbols.FUNCTION_GROUP?(load_symbol)!
2703
2704
let named_restrict: Collections.List[Semantic.Symbols.Function]? mut = null
2705
2706
if call.argument_names? then
2707
let binding = _named_argument_binder.bind(call.arguments.location, function_group, call.argument_names, want_instance)
2708
2709
if !binding? then
2710
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2711
return
2712
fi
2713
2714
_apply_named_permutation(call.arguments, arguments, argument_types, binding.permutation, binding.targets[0])
2715
2716
named_restrict = binding.targets
2717
fi
2718
2719
// Pass `call.expected_type` (the return-type context
2720
// set by an enclosing assignment / return / typed
2721
// initializer) so the resolver can tie-break
2722
// between candidates with identical arg fit but
2723
// different return types — e.g.
2724
// `Tasks.TASK.from_exception(ex)` in a function
2725
// returning `Tasks.TASK[int]` prefers the generic
2726
// `from_exception[T]` overload over the non-
2727
// generic one.
2728
let overload_result mut = _overload_resolver.resolve(call.arguments.location, function_group, argument_types, true, want_instance, false, named_restrict, call.expected_type)
2729
2730
if !overload_result? then
2731
if _try_normalise_spread(function_group, arguments, argument_types, call.arguments, want_instance) then
2732
overload_result = _overload_resolver.resolve(call.arguments.location, function_group, argument_types, true, want_instance, false, named_restrict, call.expected_type)
2733
fi
2734
fi
2735
2736
if !overload_result? then
2737
overload_result = try_overload_after_null(function_group, arguments, argument_types, want_instance, named_restrict, call.arguments.expressions, call.arguments.location, call)
2738
fi
2739
2740
if overload_result == null then
2741
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2742
return
2743
fi
2744
2745
if overload_result.needs_retry then
2746
overload_result = try_overload_on_partial(overload_result, function_group, arguments, argument_types, want_instance, named_restrict, call.arguments.expressions, call.arguments.location, call)
2747
2748
if !overload_result? then
2749
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2750
return
2751
fi
2752
fi
2753
2754
let function mut = overload_result.function
2755
2756
if _resolve_deferred_defaults(function, call.arguments.expressions, arguments, argument_types) then
2757
// A bare group argument resolved to a delegate
2758
// only now that the formal was known - re-resolve
2759
// so the callee's own type variables bind from the
2760
// delegate's shape rather than staying open.
2761
let re_resolved = _overload_resolver.resolve(call.arguments.location, function_group, argument_types, true, want_instance, false, named_restrict, call.expected_type)
2762
2763
if re_resolved? then
2764
function = re_resolved.function
2765
fi
2766
fi
2767
2768
_visitor.note_reference_arguments(call, function)
2769
_feed_pack_from_expected(function, call.expected_type)
2770
_bound_awaiting_sequence_elements(function, call.arguments.expressions)
2771
2772
if function.is_unsafe_constraints then
2773
_logger.warn(call.location, "unchecked-constraints", "call to {function} has unchecked constraints")
2774
fi
2775
2776
// A function whose type arguments were bound by
2777
// inference keeps `is_generic` set with concrete
2778
// `generic_arguments`; an explicitly specialized one
2779
// has `is_generic` cleared and was already checked
2780
// at `FUNCTION_GROUP.try_specialize`.
2781
if
2782
function.is_generic /\
2783
function.generic_arguments.count == function.generic_argument_names.count
2784
then
2785
Semantic.Symbols.GENERIC_CONSTRAINT_CHECKER().check_arguments(
2786
call.location,
2787
_logger,
2788
function,
2789
function.generic_argument_names,
2790
function.generic_arguments
2791
)
2792
fi
2793
2794
_settle_packed_literal_names(function, call.arguments.expressions)
2795
present_pack_arguments(call, call.arguments.expressions, function, arguments)
2796
2797
let accessor_class = _symbol_table.current_accessor
2798
2799
if !function.is_accessible_to(accessor_class) then
2800
_logger.error(call.function.location, "{function} is not accessible here")
2801
fi
2802
2803
_symbol_use_locations.add_symbol_use(call.function.right_location, function)
2804
2805
// A callee selected through `?.` short-circuits
2806
// the whole call - argument evaluation included -
2807
// on an absent receiver, so the call value is
2808
// built inside the coalescing wrap against the
2809
// unwrapped receiver. A static callee never
2810
// consumes the tested receiver.
2811
let coalesce_member = _try_coalescing_member(call)
2812
2813
if coalesce_member? then
2814
let wrapped = _access.build_coalesce_wrap(
2815
coalesce_member,
2816
function.is_instance,
2817
from => function.call(call.function.location, from, arguments, null, _function_caller)
2818
)
2819
2820
if wrapped? then
2821
call.compile_expressions_state.value = wrapped
2822
return
2823
fi
2824
fi
2825
2826
// A static call has no receiver value of its own -
2827
// `load.from` is always null - but a static virtual
2828
// interface member reached through a bound type
2829
// parameter (`T.parse(...)`) needs the qualifier's
2830
// type to emit the CLR's `constrained.` call shape.
2831
// Recover it from the callee expression's own left
2832
// operand rather than through the discarded static
2833
// load, since only a type-variable qualifier is
2834
// ever relevant here.
2835
let call_receiver: Value? mut = load.from
2836
2837
if !call_receiver? then
2838
if let member: Trees.Expressions.MEMBER = call.function then
2839
if let left_type: Type = member.left.value?.type /\ left_type.is_type_variable then
2840
call_receiver = member.left.value
2841
fi
2842
fi
2843
fi
2844
2845
// A `~>` thread-first call runs the whole call -
2846
// argument evaluation included - inside a presence
2847
// test on the threaded subject, against its
2848
// unwrapped value as the first argument.
2849
if call.propagates_absence then
2850
let wrapped = _access.build_propagating_subject_wrap(
2851
call.arguments.expressions[0],
2852
from => (
2853
let threaded = Collections.LIST[Value](arguments)
2854
threaded[0] = from
2855
function.call(call.function.location, call_receiver, threaded, null, _function_caller)
2856
)
2857
)
2858
2859
if wrapped? then
2860
call.compile_expressions_state.value = wrapped
2861
return
2862
fi
2863
fi
2864
2865
if _try_wrap_return_pack(call, function, call_receiver, arguments) then
2866
return
2867
fi
2868
2869
call.compile_expressions_state.value = function.call(call.function.location, call_receiver, arguments, null, _function_caller)
2870
return
2871
fi
2872
fi
2873
2874
let function_type = function_value_type
2875
2876
// Run before the is_error check below so a callee whose
2877
// return-slot is ERROR but whose formal-arg slots still
2878
// carry placeholders gets its placeholders fed (e.g.
2879
// `x => x.length` has an ERROR-typed body but its arg
2880
// slot is recoverable once a call site supplies the
2881
// actual).
2882
if isa Semantic.Types.NAMED(function_type) then
2883
_propagate_to_placeholder_formals(function_type, argument_types, arguments.count)
2884
fi
2885
2886
// Only short-circuit when the receiver is itself the ERROR
2887
// sentinel — not when an ERROR sits inside an otherwise-usable
2888
// function shape (`Function[good_formals, ERROR_return]`).
2889
// For composites the formal-arg slots are still known, so the
2890
// result-type path below can propagate a usable Function shape
2891
// to the let-init binding. The body-retry loop can then back-
2892
// feed actuals onto placeholder formals on the next iteration.
2893
if isa Semantic.Types.ERROR(function_type) then
2894
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2895
return
2896
elif isa Semantic.Types.INFERRED_VARIABLE_TYPE(function_type) then
2897
_propagate_to_unresolved_callee(function_type, argument_types)
2898
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2899
return
2900
elif !isa Semantic.Types.NAMED(function_type) then
2901
_logger.error(call.function.location, "cannot call value of non-function type {function_value.type}")
2902
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2903
return
2904
fi
2905
2906
let function_generic_type = function_type
2907
2908
let function_type_arguments = function_generic_type.arguments
2909
2910
if call.argument_names? /\ (function_type.is_action \/ function_type.is_function) then
2911
_logger.error(call.location, "cannot supply argument names here")
2912
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2913
return
2914
fi
2915
2916
if function_type.is_action then
2917
if function_type_arguments.count != arguments.count then
2918
_logger.error(
2919
call.arguments.location,
2920
"expected {function_type_arguments.count} arguments but {arguments.count} supplied")
2921
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2922
return
2923
fi
2924
elif function_type.is_function then
2925
if function_type_arguments.count != arguments.count + 1 then
2926
_logger.error(
2927
call.arguments.location,
2928
"expected {function_type_arguments.count - 1} arguments but {arguments.count} supplied")
2929
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2930
return
2931
fi
2932
else
2933
if load_symbol? /\ load_symbol.is_type then
2934
(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)
2935
else
2936
_logger.error(call.function.location, "cannot call value of non-function type {function_value.type}")
2937
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2938
fi
2939
2940
return
2941
fi
2942
2943
let ok mut = true
2944
2945
for i in 0..arguments.count do
2946
// Back-feed BEFORE the compare so a Closure-call with
2947
// a placeholder parameter type (`let f = x => ...; f(1)`)
2948
// propagates the actual's concrete type to the
2949
// placeholder's origin. The body retry loop's next
2950
// iteration then sees a concrete x's-type and walks
2951
// the lambda body cleanly. Without this the call path
2952
// validated types but propagated nothing — local
2953
// lambdas with use-site-only constraints failed to
2954
// converge.
2955
_overload_resolver.match_propagator.propagate_match(function_generic_type.arguments[i], argument_types[i])
2956
2957
2958
if cast int(function_generic_type.arguments[i].compare(argument_types[i])) > cast int(Semantic.Types.MATCH.CONVERTABLE)
2959
then
2960
ok = false
2961
_logger.error(call.arguments.expressions[i].location, "expected argument of type {function_type_arguments[i]} but {argument_types[i]} supplied")
2962
fi
2963
od
2964
2965
if !ok then
2966
call.compile_expressions_state.value = DUMMY(Semantic.Types.ERROR(), call.location)
2967
return
2968
fi
2969
2970
// The closure-invocation argument boundary applies the
2971
// same coercions an ordinary call's does — a bare T
2972
// widening to a value-type optional T? among them — but
2973
// against the function type's formal slots rather than a
2974
// Function symbol's declared arguments.
2975
let formal_types =
2976
if function_type.is_action then
2977
function_generic_type.arguments
2978
else
2979
let count = function_generic_type.arguments.count
2980
let all = Collections.LIST[Semantic.Types.Type](count - 1)
2981
2982
for i in 0..count - 1 do
2983
all.add(function_generic_type.arguments[i])
2984
od
2985
2986
all
2987
fi
2988
2989
let call_arguments = _function_caller.box_arguments(arguments, formal_types)
2990
2991
let result_type =
2992
if function_type.is_action then
2993
_innate_symbol_lookup.get_void_type()
2994
else
2995
function_generic_type.arguments[function_type_arguments.count - 1]
2996
fi
2997
2998
// A function-typed member selected through `?.` arrives
2999
// as a COALESCE_LOAD of the delegate; invoking that
3000
// result would call through the null the absent arm
3001
// produces. Re-seat the invocation inside the
3002
// short-circuit arm instead, consuming the member load
3003
// where the receiver is known present. With a statically
3004
// present receiver the member value is the plain delegate
3005
// load - invoke it directly and widen the result to the
3006
// optional shape the `?.` asked for.
3007
if _try_coalescing_member(call)? then
3008
if let original: IR.Values.COALESCE_LOAD = function_value then
3009
let arm_call = Call.CLOSURE(
3010
original.member_load,
3011
result_type,
3012
function_type.is_action,
3013
function_generic_type,
3014
call_arguments
3015
)
3016
3017
let rewrapped = _access.rewrap_coalesce_call(original, arm_call)
3018
3019
if rewrapped? then
3020
call.compile_expressions_state.value = rewrapped
3021
return
3022
fi
3023
else
3024
let direct = Call.CLOSURE(
3025
function_value,
3026
result_type,
3027
function_type.is_action,
3028
function_generic_type,
3029
call_arguments
3030
)
3031
3032
let widened = _access.widen_coalesce_result(direct)
3033
3034
call.compile_expressions_state.value =
3035
if widened? then widened else direct fi
3036
3037
return
3038
fi
3039
fi
3040
3041
// A `~>` thread-first call through a function-typed value
3042
// (a parameter, local or field, rather than a call to a
3043
// named function or method) runs the whole invocation -
3044
// argument evaluation included - inside a presence test
3045
// on the threaded subject, exactly as the named-function
3046
// path above does.
3047
if call.propagates_absence then
3048
let callee = call.function.value!
3049
3050
let wrapped = _access.build_propagating_subject_wrap(
3051
call.arguments.expressions[0],
3052
from => (
3053
let threaded = Collections.LIST[Value](call_arguments)
3054
threaded[0] = from
3055
Call.CLOSURE(callee, result_type, function_type.is_action, function_generic_type, threaded)
3056
)
3057
)
3058
3059
if wrapped? then
3060
call.compile_expressions_state.value = wrapped
3061
return
3062
fi
3063
fi
3064
3065
call.compile_expressions_state.value =
3066
Call.CLOSURE(
3067
call.function.value!,
3068
result_type,
3069
function_type.is_action,
3070
function_generic_type,
3071
call_arguments
3072
)
3073
si
3074
3075
// The MEMBER at call.function when this call selects its
3076
// callee through `?.` - the shape whose short-circuit is
3077
// lowered here at the call rather than at the member access.
3078
_try_coalescing_member(call: Trees.Expressions.CALL) -> Trees.Expressions.MEMBER? is
3079
let member = cast Trees.Expressions.MEMBER?(call.function)
3080
3081
if member? /\ member.is_coalesce then
3082
return member
3083
fi
3084
3085
return null
3086
si
3087
3088
// For a function-typed callee whose formal slots include
3089
// INFERRED_VARIABLE_TYPE placeholders (typically a let-bound
3090
// lambda whose arg types couldn't be pinned from the body
3091
// alone), push the corresponding actual arg type onto each
3092
// placeholder formal's origin Variable as a lower bound. The
3093
// body-retry loop's next iteration then sees the placeholder
3094
// resolved and walks the lambda body cleanly.
3095
//
3096
// Closed-root alternatives — union variants or subclasses
3097
// of a closed class — are widened to their root before
3098
// being pushed (see `INFERENCE_HELPERS.widen_to_closed_root`)
3099
// to keep the lambda-arg LUB monotonic across siblings from
3100
// different call sites.
3101
_propagate_to_placeholder_formals(
3102
function_type: Semantic.Types.Type,
3103
argument_types: Collections.List[Semantic.Types.Type],
3104
argument_count: int
3105
) is
3106
let ft_named = cast Semantic.Types.NAMED?(function_type)!
3107
let ft_args = ft_named.arguments
3108
let formal_count =
3109
if function_type.is_function /\ !function_type.is_action then
3110
ft_args.count - 1
3111
else
3112
ft_args.count
3113
fi
3114
3115
// A call through a value whose one formal is a pack slot still
3116
// to be inferred takes its arguments as the tuple the pack binds
3117
// to: `let safe = retry((a, b) => a + b, 1); safe(2, 3)` says
3118
// the pack is `(int, int)`, and nothing else does.
3119
if formal_count == 1 /\ argument_count >= 2 then
3120
if let placeholder: Semantic.Types.INFERRED_VARIABLE_TYPE = ft_args[0] then
3121
if let origin: Semantic.Symbols.INFERRED_TYPE_ARG_ORIGIN = placeholder.origin /\ origin.is_argument_pack then
3122
let elements = Collections.LIST[Semantic.Types.Type]()
3123
3124
for actual in argument_types do
3125
elements.add(Semantic.INFERENCE_HELPERS.widen_to_closed_root(actual)!)
3126
od
3127
3128
let tuple = _innate_symbol_lookup.get_tuple_type(elements, null)
3129
3130
_logger.mark_consumed_any_if(Semantic.INFERENCE_TRACE.add_lower_bound("calls.pack_call_arguments", origin, tuple))
3131
3132
return
3133
fi
3134
fi
3135
fi
3136
3137
if formal_count != argument_count then
3138
return
3139
fi
3140
3141
for i in 0..argument_count do
3142
let formal = ft_args[i]
3143
let actual = argument_types[i]
3144
3145
if isa Semantic.Types.INFERRED_VARIABLE_TYPE(formal) then
3146
let placeholder = formal
3147
let push_actual = Semantic.INFERENCE_HELPERS.widen_to_closed_root(actual)!
3148
_logger.mark_consumed_any_if(Semantic.INFERENCE_TRACE.add_lower_bound("calls.placeholder_formal", placeholder.origin, push_actual))
3149
fi
3150
od
3151
si
3152
3153
// When the call's receiver is itself an unresolved placeholder
3154
// (`let f = ...; f(1)` while `f`'s body is still settling, or
3155
// mutually-recursive lambdas where each side's signature
3156
// depends on the other), record two constraints on the
3157
// placeholder's origin:
3158
//
3159
// 1. A synthesised function-type shape from the actual arg
3160
// types + a deferred return type, as a lower bound, so
3161
// the next iteration sees the receiver resolved to a
3162
// function type and the call can compile. Skipped when
3163
// the LUB already has a candidate (typically from a
3164
// direct `v = <lambda>` assignment in the same body) —
3165
// the call's actual arg types may differ from the
3166
// assigned shape and the per-position merge can't bridge
3167
// them, leaving an ambiguous pair in the pool.
3168
//
3169
// 2. A CALL_CONSTRAINT capturing the actual arg types
3170
// unconditionally, so the constraint-aware LUB can later
3171
// filter candidate types to those that actually accept
3172
// this call shape. Its discharge defers conservatively
3173
// when the captured args still contain placeholders.
3174
_propagate_to_unresolved_callee(
3175
placeholder: Semantic.Types.INFERRED_VARIABLE_TYPE,
3176
argument_types: Collections.List[Semantic.Types.Type]
3177
) is
3178
// An argument typed over another function's type parameter -
3179
// the `T[]` a `collect_array[T]` call still resolving reports -
3180
// names no shape the callee could be asked to accept, and a
3181
// constraint recorded from it would never discharge once the
3182
// callee's type settles. A later walk supplies the type the
3183
// argument settles to.
3184
if argument_types |> any(a => a.has_function_generic_argument_foreign_to(_symbol_table.current_scope)) then
3185
return
3186
fi
3187
3188
if !placeholder.origin.has_lub_candidate /\ argument_types |> all(a => a.is_settled) /\
3189
argument_types.count <= Semantic.Lookups.INNATE_TYPE_LIMITS.MAX_FUNCTION_PARAMETERS then
3190
let function_type_components = Collections.LIST[Semantic.Types.Type](argument_types)
3191
function_type_components.add(Semantic.Types.INFERRED_RETURN_TYPE())
3192
let synthesized = _innate_symbol_lookup.get_function_type(function_type_components)
3193
_logger.mark_consumed_any_if(Semantic.INFERENCE_TRACE.add_lower_bound("calls.unresolved_callee_shape", placeholder.origin, synthesized))
3194
fi
3195
3196
let call_args = Collections.LIST[Semantic.Types.Type](argument_types)
3197
_logger.mark_consumed_any_if(Semantic.INFERENCE_TRACE.add_constraint("calls.unresolved_callee_call", placeholder.origin, Semantic.CALL_CONSTRAINT(call_args)))
3198
si
3199
si
3200
si