Skip to content

Commit

Permalink
add an arrow when typechecking case->
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
capfredf committed Nov 19, 2020
1 parent b6b0376 commit 283631a
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 9 deletions.
22 changes: 15 additions & 7 deletions typed-racket-lib/typed-racket/typecheck/tc-lambda-unit.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
[->* t:->*]
[one-of/c t:one-of/c])
(private type-annotation syntax-properties)
(types resolve type-table)
(types resolve type-table subtype)
(typecheck signatures tc-metafunctions tc-subst)
(env lexical-env tvar-env index-env scoped-tvar-env)
(utils tc-utils)
Expand Down Expand Up @@ -625,12 +625,20 @@
(match expected
[(tc-result1:(? DepFun? dep-fun-ty))
(tc/dep-lambda formalss bodies dep-fun-ty)]
[_ (make-Fun
(tc/mono-lambda
(for/list ([f (in-syntax formalss)]
[b (in-syntax bodies)])
(cons (make-formals f) b))
expected))]))
[_
(define arrs (tc/mono-lambda
(for/list ([f (in-syntax formalss)]
[b (in-syntax bodies)])
(cons (make-formals f) b))
expected))
(define arrs^ (append arrs (match (last arrs)
[(Arrow: dom (and (Rest: (list ty tys ...)) rst) kws rng)
(list (make-Arrow (dropf-right dom (lambda (x) (subtype ty x)))
rst
kws
rng))]
[_ null])))
(make-Fun arrs^)]))

(define (plambda-prop stx)
(define d (plambda-property stx))
Expand Down
16 changes: 14 additions & 2 deletions typed-racket-lib/typed-racket/types/abbrev.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
(require "../utils/utils.rkt"
(utils prefab identifier)
racket/list
racket/lazy-require
syntax/id-set
racket/match
(prefix-in c: (contract-req))
Expand All @@ -24,6 +25,7 @@

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

(lazy-require ("subtype.rkt" (subtype)))
(provide (all-defined-out)
(all-from-out "base-abbrev.rkt" "match-expanders.rkt"))

Expand Down Expand Up @@ -188,11 +190,21 @@
(define/decl -false-propset (-PS -ff -tt))

(define (opt-fn args opt-args result #:rest [rest #f] #:kws [kws null])
(apply cl->* (for/list ([i (in-range (add1 (length opt-args)))])
(define ret (for/list ([i (in-range (add1 (length opt-args)))])
(make-Fun (list (-Arrow (append args (take opt-args i))
result ;; only the LAST arrow gets the rest arg
#:rest (and (= i (length opt-args)) rest)
#:kws kws))))))
#:kws kws)))))
(define ret^ (append ret (cond
[rest
(match-define (Rest: (list ty tys ...)) rest)
(list (make-Fun (list (-Arrow
(dropf-right opt-args (lambda (x) (subtype ty x)))
result
#:rest rest
#:kws kws))))]
[else null])))
(apply cl->* ret^))

(define-syntax-rule (->opt args ... [opt ...] res)
(opt-fn (list args ...) (list opt ...) res))
Expand Down
18 changes: 18 additions & 0 deletions typed-racket-test/succeed/gh-issue-873.rkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#lang typed/racket

(: bar (-> (-> Natural * Any) Any))
(define (bar f)
'any)

(: foo (-> (->* () (Integer Integer) #:rest Natural Any)
Any))
(define (foo f)
(bar f))

(: foo^ (-> Any * Any))
(define foo^
(case-lambda
[() 'one]
[(a) 'two]
[(a b . cs) 'three]))

0 comments on commit 283631a

Please sign in to comment.