17
17
import org .aya .syntax .concrete .Pattern ;
18
18
import org .aya .syntax .concrete .stmt .decl .DataDecl ;
19
19
import org .aya .syntax .core .Jdg ;
20
+ import org .aya .syntax .core .annotation .Bound ;
21
+ import org .aya .syntax .core .annotation .Closed ;
20
22
import org .aya .syntax .core .def .*;
21
23
import org .aya .syntax .core .pat .Pat ;
22
24
import org .aya .syntax .core .pat .PatMatcher ;
@@ -59,10 +61,11 @@ public class PatternTycker implements Problematic, Stateful {
59
61
/// [org.aya.syntax.core.term.LocalTerm])
60
62
private final @ NotNull SignatureIterator telescope ;
61
63
62
- /** Substitution for parameter, in the same order as parameter */
63
- private final @ NotNull MutableList <Jdg > paramSubst ;
64
+ /// Substitution for parameter, in the same order as parameter
65
+ private final @ NotNull MutableList <@ Closed Jdg > paramSubst ;
64
66
65
- /// Substitution for `as` pattern
67
+ /// Substitution for `as` pattern.
68
+ /// Assertion: `asSubst.parent == null`
66
69
private final @ NotNull LocalLet asSubst ;
67
70
68
71
/// Almost equivalent to {@code telescope.peek()}, but we may instantiate it.
@@ -101,8 +104,8 @@ public PatternTycker(
101
104
}
102
105
103
106
public record TyckResult (
104
- @ NotNull ImmutableSeq <Pat > wellTyped ,
105
- @ NotNull ImmutableSeq <Jdg > paramSubst ,
107
+ @ NotNull ImmutableSeq <@ Closed Pat > wellTyped ,
108
+ @ NotNull ImmutableSeq <@ Closed Jdg > paramSubst ,
106
109
@ NotNull LocalLet asSubst ,
107
110
boolean hasError
108
111
) { }
@@ -114,7 +117,7 @@ public record TyckResult(
114
117
* @param type the type of {@param pattern}, it probably contains {@link MetaPatTerm}
115
118
* @return a well-typed {@link Pat}, but still need to be inline!
116
119
*/
117
- private @ NotNull Pat doTyck (@ NotNull WithPos <Pattern > pattern , @ NotNull Term type ) {
120
+ private @ NotNull @ Closed Pat doTyck (@ NotNull WithPos <Pattern > pattern , @ NotNull @ Closed Term type ) {
118
121
return switch (pattern .data ()) {
119
122
case Pattern .Absurd _ -> {
120
123
var selection = makeSureEmpty (type , pattern );
@@ -215,19 +218,19 @@ private void consumeParam() {
215
218
telescope .next ();
216
219
}
217
220
218
- private record FindNextParam (@ NotNull ImmutableSeq <Pat > generated , @ NotNull Kind kind ) {
221
+ private record FindNextParam (@ NotNull ImmutableSeq <@ Closed Pat > generated , @ NotNull Kind kind ) {
219
222
public enum Kind {
220
223
Success , TooManyPattern , TooManyImplicit
221
224
}
222
225
}
223
226
224
- /// Find next param until the predicate success
227
+ /// Find next param until the predicate success.
225
228
///
226
229
/// @return (generated implicit patterns, status)
227
230
/// @apiNote before call: {@link #currentParam} is the last checked parameter
228
231
/// after call: {@link #currentParam} is the first unchecked parameter which {@param until} success on
229
232
private @ NotNull FindNextParam findNextParam (@ Nullable WithPos <Pattern > pattern , @ NotNull Predicate <Param > until ) {
230
- var generatedPats = MutableList .<Pat >create ();
233
+ var generatedPats = MutableList .<@ Closed Pat >create ();
231
234
232
235
peekNextParam ();
233
236
// loop invariant: currentParam is the first unchecked parameter if not null
@@ -263,11 +266,12 @@ public enum Kind {
263
266
@ NotNull PatternIterator patterns ,
264
267
@ Nullable WithPos <Pattern > outerPattern
265
268
) {
266
- var wellTyped = MutableList .<Pat >create ();
269
+ var wellTyped = MutableList .<@ Closed Pat >create ();
267
270
// last user given pattern, that is, not aya generated
268
271
@ Nullable Arg <WithPos <Pattern >> lastPat = null ;
269
272
270
273
// loop invariant: [patterns] points to the last checked pattern, same for [telescope]
274
+ // "points to" means the last element it consumes holds the property.
271
275
outer :
272
276
while (patterns .hasNext ()) {
273
277
var currentPat = patterns .peek ();
@@ -283,7 +287,7 @@ public enum Kind {
283
287
var fnp = findNextParam (currentPat .term (), p ->
284
288
p .explicit () == currentPat .explicit ());
285
289
// || telescope.isFromPusheen() == patterns.isFromPusheen()
286
- // ^this check implies the first one
290
+ // ^this check is implied by the first one
287
291
288
292
ImmutableSeq <Pat > generated = null ;
289
293
@@ -312,8 +316,10 @@ public enum Kind {
312
316
break ;
313
317
}
314
318
315
- wellTyped .append (tyckPattern (currentPat .term ()));
319
+ wellTyped .append (tyckPattern (currentPat .term ())); // tyckPattern consumes [currentParam] by move [telescope] forward
316
320
patterns .next (); // consume pattern
321
+
322
+ // now: [patterns] points to the last checked pattern, same for [telescope]
317
323
}
318
324
319
325
// now: ! patterns.hasNext()
@@ -323,12 +329,18 @@ public enum Kind {
323
329
// all not pusheen patterns have their parameters
324
330
325
331
// is there any explicit parameters?
332
+ // this process also generate pattern for tailing implicit parameters
326
333
var generated = findNextParam (null , p ->
327
334
p .explicit () || telescope .isFromPusheen ());
328
335
// ^this check implies the first one
329
336
330
337
// what kind of parameter you found?
331
338
if (generated .kind == FindNextParam .Kind .Success && !telescope .isFromPusheen ()) {
339
+ // [findNextParam] success means at least one parameter is peeked,
340
+ // thus `telescope.hasNext()` is true before the call to `findNextParam`.
341
+ // Therefore, now: ! patterns.hasNext(),
342
+ // other two cases are ruled out by `telescope.hasNext()` and `! telescope.isFromPusheen()`
343
+
332
344
// no you can't!
333
345
WithPos <Pattern > errorPattern = lastPat == null
334
346
? Objects .requireNonNull (outerPattern )
@@ -348,6 +360,7 @@ public enum Kind {
348
360
return done (wellTyped );
349
361
}
350
362
363
+ /// Must be called before using [#currentParam]
351
364
private @ NotNull Closer instCurrentParam () {
352
365
currentParam = currentParam .descent (t -> t .instTele (paramSubst .view ().map (Jdg ::wellTyped )));
353
366
return CLOSER ;
@@ -361,18 +374,19 @@ private class Closer implements AutoCloseable {
361
374
/**
362
375
* Checking {@param pattern} with {@link PatternTycker#currentParam}
363
376
*/
364
- private @ NotNull Pat tyckPattern (@ NotNull WithPos <Pattern > pattern ) {
377
+ private @ NotNull @ Closed Pat tyckPattern (@ NotNull WithPos <Pattern > pattern ) {
365
378
try (var _ = instCurrentParam ()) {
366
379
var result = doTyck (pattern , currentParam .type ());
367
380
addArgSubst (result , currentParam .type ());
368
381
return result ;
369
382
}
370
383
}
371
384
372
- private @ NotNull Pat doGeneratePattern (@ NotNull Term type , @ NotNull String name , @ NotNull SourcePos pos ) {
385
+ private @ NotNull @ Closed Pat doGeneratePattern (@ NotNull @ Closed Term type , @ NotNull String name , @ NotNull SourcePos pos ) {
373
386
var freshVar = nameGen .bindName (name );
374
387
if (exprTycker .whnf (type ) instanceof DataCall dataCall ) {
375
388
// this pattern would be a Con, it can be inferred
389
+ // the db-closeness of Pat.Meta is determined by [dataCall], not its solution.
376
390
return new Pat .Meta (MutableValue .create (), freshVar .name (), dataCall , pos );
377
391
} else {
378
392
// If the type is not a DataCall, then the only available pattern is Pat.Bind
@@ -386,7 +400,7 @@ private class Closer implements AutoCloseable {
386
400
* we generate a MetaPat for each,
387
401
* so that they can be inferred during {@link ClauseTycker}
388
402
*/
389
- private @ NotNull Pat generatePattern () {
403
+ private @ NotNull @ Closed Pat generatePattern () {
390
404
try (var _ = instCurrentParam ()) {
391
405
// TODO: I NEED A SOURCE POS!!
392
406
var pat = doGeneratePattern (currentParam .type (), currentParam .name (), SourcePos .NONE );
@@ -396,7 +410,7 @@ private class Closer implements AutoCloseable {
396
410
}
397
411
398
412
private @ NotNull ImmutableSeq <Pat > tyckInner (
399
- @ NotNull ImmutableSeq <Param > telescope ,
413
+ @ NotNull ImmutableSeq <@ Bound Param > telescope ,
400
414
@ NotNull ImmutableSeq <Arg <WithPos <Pattern >>> patterns ,
401
415
@ NotNull WithPos <Pattern > outerPattern
402
416
) {
@@ -407,25 +421,25 @@ private class Closer implements AutoCloseable {
407
421
return tyckResult .wellTyped ;
408
422
}
409
423
410
- private void addArgSubst (@ NotNull Pat pattern , @ NotNull Term type ) {
424
+ private void addArgSubst (@ NotNull @ Closed Pat pattern , @ NotNull @ Closed Term type ) {
411
425
paramSubst .append (new Jdg .Default (PatToTerm .visit (pattern ), type ));
412
426
}
413
427
414
- private void addAsSubst (@ NotNull LocalVar as , @ NotNull Pat pattern , @ NotNull Term type ) {
428
+ private void addAsSubst (@ NotNull LocalVar as , @ NotNull Pat pattern , @ NotNull @ Closed Term type ) {
415
429
asSubst .put (as , new Jdg .Default (PatToTerm .visit (pattern ), type ), false );
416
430
}
417
431
418
- private @ NotNull TyckResult done (@ NotNull MutableList <Pat > wellTyped ) {
432
+ private @ NotNull TyckResult done (@ NotNull MutableList <@ Closed Pat > wellTyped ) {
419
433
return new TyckResult (wellTyped .toSeq (), paramSubst .toSeq (), asSubst , hasError );
420
434
}
421
435
422
436
private record Selection (
423
- @ NotNull DataCall data ,
424
- @ NotNull ImmutableSeq <Term > ownerArgs ,
425
- @ NotNull ConCallLike .Head conHead
437
+ @ NotNull @ Closed DataCall data ,
438
+ @ NotNull ImmutableSeq <@ Closed Term > ownerArgs ,
439
+ @ NotNull ConCallLike .@ Closed Head conHead
426
440
) { }
427
441
428
- private @ Nullable ConCallLike .Head makeSureEmpty (Term type , @ NotNull WithPos <Pattern > pattern ) {
442
+ private @ Nullable ConCallLike .Head makeSureEmpty (@ Closed Term type , @ NotNull WithPos <Pattern > pattern ) {
429
443
if (!(exprTycker .whnf (type ) instanceof DataCall dataCall )) {
430
444
foundError (new PatternProblem .SplittingOnNonData (pattern , type ));
431
445
return null ;
@@ -450,7 +464,7 @@ private record Selection(
450
464
return null ;
451
465
}
452
466
453
- private @ Nullable Selection makeSureAvail (Term type , @ NotNull ConDefLike name , @ NotNull WithPos <Pattern > pattern ) {
467
+ private @ Nullable Selection makeSureAvail (@ Closed Term type , @ NotNull ConDefLike name , @ NotNull WithPos <Pattern > pattern ) {
454
468
if (!(exprTycker .whnf (type ) instanceof DataCall dataCall )) {
455
469
foundError (new PatternProblem .SplittingOnNonData (pattern , type ));
456
470
return null ;
@@ -462,8 +476,8 @@ private record Selection(
462
476
463
477
return switch (checkAvail (dataCall , name , exprTycker .state )) {
464
478
case Result .Ok (var subst ) -> new Selection (
465
- ( DataCall ) dataCall . instTeleFrom ( name . selfTeleSize () , subst . view ()) ,
466
- subst , new ConCallLike .Head (name , dataCall .ulift (), subst ));
479
+ dataCall , subst ,
480
+ new ConCallLike .Head (name , dataCall .ulift (), subst ));
467
481
case Result .Err (_ ) -> {
468
482
// Here, name != null, and is not in the list of checked body
469
483
foundError (new PatternProblem .UnavailableCon (pattern , dataCall ));
@@ -491,7 +505,7 @@ private record Selection(
491
505
* Check whether {@param con} is available under {@param type}
492
506
*/
493
507
public static @ NotNull Result <ImmutableSeq <Term >, State > checkAvail (
494
- @ NotNull DataCall type , @ NotNull ConDefLike con , @ NotNull TyckState state
508
+ @ NotNull @ Closed DataCall type , @ NotNull ConDefLike con , @ NotNull TyckState state
495
509
) {
496
510
return switch (con ) {
497
511
case JitCon jitCon -> jitCon .isAvailable (new Normalizer (state ), type .args ());
@@ -507,7 +521,7 @@ private record Selection(
507
521
};
508
522
}
509
523
510
- private @ NotNull Pat randomPat (Term param ) {
524
+ private @ NotNull Pat randomPat (@ Closed Term param ) {
511
525
return new Pat .Bind (nameGen .bindName (param ), param );
512
526
}
513
527
0 commit comments