|
39 | 39 | (define (empty-set) '()) |
40 | 40 |
|
41 | 41 | (define current-seen (make-parameter (empty-set))) |
| 42 | +(define infered-tvar-map (make-parameter (hash))) |
42 | 43 |
|
43 | 44 | ;; Type Type -> Pair<Seq, Seq> |
44 | 45 | ;; construct a pair for the set of seen type pairs |
|
476 | 477 | ;; produces a cset which determines a substitution that makes S a subtype of T |
477 | 478 | ;; implements the V |-_X S <: T => C judgment from Pierce+Turner, extended with |
478 | 479 | ;; the index variables from the TOPLAS paper |
479 | | -(define/cond-contract (cgen context S T [obj #f] [bound #f]) |
| 480 | +(define/cond-contract (cgen context S T [obj #f]) |
480 | 481 | (->* (context? (or/c Values/c ValuesDots? AnyValues?) |
481 | 482 | (or/c Values/c ValuesDots? AnyValues?)) |
482 | 483 | ((or/c #f OptObject?)) |
|
485 | 486 | (define/cond-contract (cg S T [obj #f]) |
486 | 487 | (->* (Type? Type?) ((or/c #f OptObject?)) |
487 | 488 | (or/c #f cset?)) |
488 | | - (cgen context S T obj bound)) |
| 489 | + (cgen context S T obj)) |
489 | 490 | (define/cond-contract (cg/inv S T) |
490 | 491 | (Type? Type? . -> . (or/c #f cset?)) |
491 | 492 | (cgen/inv context S T)) |
|
496 | 497 | (insert empty x S T)) |
497 | 498 |
|
498 | 499 | (define (constrain tvar-a tvar-b #:above above) |
499 | | - (match-define (F: var maybe-type-bound) tvar-a) |
| 500 | + (define (maybe-type-app t) |
| 501 | + (match t |
| 502 | + [(App: t1 (list (F: var))) #:when (hash-has-key? (infered-tvar-map) var) |
| 503 | + (define v (hash-ref (infered-tvar-map) var)) |
| 504 | + (-App t1 (list v))] |
| 505 | + [_ t])) |
| 506 | + |
| 507 | + (match-define (F: var (app maybe-type-app maybe-type-bound)) tvar-a) |
| 508 | + |
500 | 509 | (define-values (default sub sing) (if above |
501 | 510 | (values Univ |
502 | 511 | (thunk (subtype tvar-b maybe-type-bound obj)) |
|
506 | 515 | (curryr singleton var (var-demote tvar-b (context-bounds context)))))) |
507 | 516 | (cond |
508 | 517 | [(not maybe-type-bound) (sing default)] |
509 | | - [(sub) (sing maybe-type-bound)] |
| 518 | + [(sub) |
| 519 | + (infered-tvar-map (hash-set (infered-tvar-map) var maybe-type-bound)) |
| 520 | + (sing maybe-type-bound)] |
510 | 521 | [else #f])) |
511 | 522 |
|
512 | 523 | ;; FIXME -- figure out how to use parameters less here |
|
983 | 994 | (build-subst md)) |
984 | 995 | (build-subst (stream-first (cset-maps C))))) |
985 | 996 |
|
| 997 | + |
986 | 998 | ;; context : the context of what to infer/not infer |
987 | 999 | ;; S : a list of types to be the subtypes of T |
988 | 1000 | ;; T : a list of types |
|
1000 | 1012 | (for/list/fail ([s (in-list S)] |
1001 | 1013 | [t (in-list T)] |
1002 | 1014 | [obj (in-list/rest objs #f)]) |
1003 | | - ;; We meet early to prune the csets to a reasonable size. |
1004 | | - ;; This weakens the inference a bit, but sometimes avoids |
1005 | | - ;; constraint explosion. |
| 1015 | + ;; We meet early to prune the csets to a reasonable size. |
| 1016 | + ;; This weakens the inference a bit, but sometimes avoids |
| 1017 | + ;; constraint explosion. |
1006 | 1018 | (% cset-meet (cgen context s t obj) expected-cset))))) |
1007 | 1019 |
|
1008 | 1020 |
|
|
1048 | 1060 | ;; like infer, but T-var is the vararg type: |
1049 | 1061 | (define (infer/vararg X Y S T T-var R [expected #f] |
1050 | 1062 | #:objs [objs '()]) |
1051 | | - (and ((length S) . >= . (length T)) |
1052 | | - (let* ([fewer-ts (- (length S) (length T))] |
1053 | | - [new-T (match T-var |
1054 | | - [(? Type? var-t) (list-extend S T var-t)] |
1055 | | - [(Rest: rst-ts) |
1056 | | - #:when (zero? (remainder fewer-ts (length rst-ts))) |
1057 | | - (append T (repeat-list rst-ts |
1058 | | - (quotient fewer-ts (length rst-ts))))] |
1059 | | - [_ T])]) |
1060 | | - (infer X Y S new-T R expected #:objs objs)))) |
| 1063 | + (parameterize ([infered-tvar-map (hash)]) |
| 1064 | + (and ((length S) . >= . (length T)) |
| 1065 | + (let* ([fewer-ts (- (length S) (length T))] |
| 1066 | + [new-T (match T-var |
| 1067 | + [(? Type? var-t) (list-extend S T var-t)] |
| 1068 | + [(Rest: rst-ts) |
| 1069 | + #:when (zero? (remainder fewer-ts (length rst-ts))) |
| 1070 | + (append T (repeat-list rst-ts |
| 1071 | + (quotient fewer-ts (length rst-ts))))] |
| 1072 | + [_ T])]) |
| 1073 | + (infer X Y S new-T R expected #:objs objs))))) |
1061 | 1074 |
|
1062 | 1075 | ;; like infer, but dotted-var is the bound on the ... |
1063 | 1076 | ;; and T-dotted is the repeated type |
|
0 commit comments