Skip to content

Commit 283631a

Browse files
committed
add an arrow when typechecking case->
For a function that has optional parameter types [t1, t2, t_i ... t_n], if each of [t_i ... t_n] is a supertype of the first rest parameter type, add to the resulting the function type one arrow with [t_i ... t_n] being absorbed into the rest.
1 parent b6b0376 commit 283631a

File tree

3 files changed

+47
-9
lines changed

3 files changed

+47
-9
lines changed

typed-racket-lib/typed-racket/typecheck/tc-lambda-unit.rkt

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
[->* t:->*]
1212
[one-of/c t:one-of/c])
1313
(private type-annotation syntax-properties)
14-
(types resolve type-table)
14+
(types resolve type-table subtype)
1515
(typecheck signatures tc-metafunctions tc-subst)
1616
(env lexical-env tvar-env index-env scoped-tvar-env)
1717
(utils tc-utils)
@@ -625,12 +625,20 @@
625625
(match expected
626626
[(tc-result1:(? DepFun? dep-fun-ty))
627627
(tc/dep-lambda formalss bodies dep-fun-ty)]
628-
[_ (make-Fun
629-
(tc/mono-lambda
630-
(for/list ([f (in-syntax formalss)]
631-
[b (in-syntax bodies)])
632-
(cons (make-formals f) b))
633-
expected))]))
628+
[_
629+
(define arrs (tc/mono-lambda
630+
(for/list ([f (in-syntax formalss)]
631+
[b (in-syntax bodies)])
632+
(cons (make-formals f) b))
633+
expected))
634+
(define arrs^ (append arrs (match (last arrs)
635+
[(Arrow: dom (and (Rest: (list ty tys ...)) rst) kws rng)
636+
(list (make-Arrow (dropf-right dom (lambda (x) (subtype ty x)))
637+
rst
638+
kws
639+
rng))]
640+
[_ null])))
641+
(make-Fun arrs^)]))
634642

635643
(define (plambda-prop stx)
636644
(define d (plambda-property stx))

typed-racket-lib/typed-racket/types/abbrev.rkt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
(require "../utils/utils.rkt"
88
(utils prefab identifier)
99
racket/list
10+
racket/lazy-require
1011
syntax/id-set
1112
racket/match
1213
(prefix-in c: (contract-req))
@@ -24,6 +25,7 @@
2425

2526
(for-syntax racket/base syntax/parse))
2627

28+
(lazy-require ("subtype.rkt" (subtype)))
2729
(provide (all-defined-out)
2830
(all-from-out "base-abbrev.rkt" "match-expanders.rkt"))
2931

@@ -188,11 +190,21 @@
188190
(define/decl -false-propset (-PS -ff -tt))
189191

190192
(define (opt-fn args opt-args result #:rest [rest #f] #:kws [kws null])
191-
(apply cl->* (for/list ([i (in-range (add1 (length opt-args)))])
193+
(define ret (for/list ([i (in-range (add1 (length opt-args)))])
192194
(make-Fun (list (-Arrow (append args (take opt-args i))
193195
result ;; only the LAST arrow gets the rest arg
194196
#:rest (and (= i (length opt-args)) rest)
195-
#:kws kws))))))
197+
#:kws kws)))))
198+
(define ret^ (append ret (cond
199+
[rest
200+
(match-define (Rest: (list ty tys ...)) rest)
201+
(list (make-Fun (list (-Arrow
202+
(dropf-right opt-args (lambda (x) (subtype ty x)))
203+
result
204+
#:rest rest
205+
#:kws kws))))]
206+
[else null])))
207+
(apply cl->* ret^))
196208

197209
(define-syntax-rule (->opt args ... [opt ...] res)
198210
(opt-fn (list args ...) (list opt ...) res))
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#lang typed/racket
2+
3+
(: bar (-> (-> Natural * Any) Any))
4+
(define (bar f)
5+
'any)
6+
7+
(: foo (-> (->* () (Integer Integer) #:rest Natural Any)
8+
Any))
9+
(define (foo f)
10+
(bar f))
11+
12+
(: foo^ (-> Any * Any))
13+
(define foo^
14+
(case-lambda
15+
[() 'one]
16+
[(a) 'two]
17+
[(a b . cs) 'three]))
18+

0 commit comments

Comments
 (0)