racket/generic: fix kw args with #:defaults
Closes PR 13737
This commit is contained in:
parent
c9cfaa2d36
commit
6bc6e8e07e
|
@ -200,17 +200,14 @@
|
||||||
(define generic
|
(define generic
|
||||||
(generic-arity-coerce
|
(generic-arity-coerce
|
||||||
'generic
|
'generic
|
||||||
|
;; We could put `generic-args` here for the method header, but
|
||||||
|
;; since we need to keyword-apply the method in the method table,
|
||||||
|
;; it doesn't help. Thus we use `make-keyword-procedure`.
|
||||||
|
;;
|
||||||
|
;; If keyword-apply ends up being a bottleneck, consider
|
||||||
|
;; adding the second argument to `make-keyword-procedure` again.
|
||||||
(make-keyword-procedure
|
(make-keyword-procedure
|
||||||
(lambda (kws kws-args . given-args)
|
(lambda (kws kws-args . given-args)
|
||||||
(define this (list-ref given-args generic-this-idx))
|
|
||||||
(if (name? this)
|
|
||||||
(let ([m (vector-ref (get-generics this) generic-idx)])
|
|
||||||
(if m
|
|
||||||
(keyword-apply m kws kws-args given-args)
|
|
||||||
(error 'generic "not implemented for ~e" this)))
|
|
||||||
(raise-argument-error 'generic name-str this)))
|
|
||||||
; XXX (non-this ... this . rst)
|
|
||||||
(lambda given-args
|
|
||||||
(define this (list-ref given-args generic-this-idx))
|
(define this (list-ref given-args generic-this-idx))
|
||||||
(cond
|
(cond
|
||||||
[#,(if prop-defined-already?
|
[#,(if prop-defined-already?
|
||||||
|
@ -218,10 +215,10 @@
|
||||||
#'(-name? this))
|
#'(-name? this))
|
||||||
(let ([m (vector-ref (get-generics this) generic-idx)])
|
(let ([m (vector-ref (get-generics this) generic-idx)])
|
||||||
(if m
|
(if m
|
||||||
(apply m given-args)
|
(keyword-apply m kws kws-args given-args)
|
||||||
(error 'generic "not implemented for ~e" this)))]
|
(error 'generic "not implemented for ~e" this)))]
|
||||||
;; default cases
|
;; default cases
|
||||||
[(pred? this) (apply cond-impl given-args)]
|
[(pred? this) (keyword-apply cond-impl kws kws-args given-args)]
|
||||||
...
|
...
|
||||||
[else (raise-argument-error 'generic name-str this)])))))
|
[else (raise-argument-error 'generic name-str this)])))))
|
||||||
...)))]))
|
...)))]))
|
||||||
|
|
36
collects/tests/generic/pr13737.rkt
Normal file
36
collects/tests/generic/pr13737.rkt
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#lang racket
|
||||||
|
|
||||||
|
(require racket/generic
|
||||||
|
rackunit)
|
||||||
|
|
||||||
|
;; This tests PR 13737 (keyword arguments and #:defaults did
|
||||||
|
;; not work together)
|
||||||
|
|
||||||
|
(define-generics thing
|
||||||
|
(foo thing #:stuff other)
|
||||||
|
#:defaults
|
||||||
|
{[number?
|
||||||
|
(define (foo thing #:stuff other) (+ thing other))]})
|
||||||
|
|
||||||
|
(check-equal? (foo 1 #:stuff 2) 3)
|
||||||
|
|
||||||
|
;; This tests that the keyword & defaults issue doesn't occur for
|
||||||
|
;; forged generics either
|
||||||
|
|
||||||
|
(let ()
|
||||||
|
(local-require racket/private/generic)
|
||||||
|
|
||||||
|
(define-values (prop:foo foo? foo-accessor)
|
||||||
|
(make-struct-type-property
|
||||||
|
'foo
|
||||||
|
#f))
|
||||||
|
|
||||||
|
(define-generics (foo gen:foo prop:foo foo?
|
||||||
|
#:defined-table dummy
|
||||||
|
#:defaults ([number? (define (meth foo #:kw kw) kw)])
|
||||||
|
#:prop-defined-already? foo-accessor
|
||||||
|
#:define-contract #f)
|
||||||
|
(meth foo #:kw kw))
|
||||||
|
|
||||||
|
(check-equal? (meth 3 #:kw 5) 5))
|
||||||
|
|
|
@ -16,4 +16,6 @@
|
||||||
"from-unstable.rkt"
|
"from-unstable.rkt"
|
||||||
"poly-contracts.rkt"
|
"poly-contracts.rkt"
|
||||||
"empty-interface.rkt"
|
"empty-interface.rkt"
|
||||||
"top-level.rkt")
|
"top-level.rkt"
|
||||||
|
"pr13737.rkt")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user