Fixes strange error messages for invalid generic method definitions

Closes PR 13681

Please merge to v5.3.4
(cherry picked from commit d84494dd44)
This commit is contained in:
Claire Alvis 2013-04-12 14:13:09 -04:00 committed by Ryan Culpepper
parent 70ab423b71
commit 2001098046
2 changed files with 47 additions and 3 deletions

View File

@ -4,7 +4,8 @@
racket/local
racket/syntax
syntax/stx)
(only-in "define-struct.rkt" define/generic))
(only-in "define-struct.rkt" define/generic)
(only-in racket/function arity-includes?))
(define-for-syntax (keyword-stx? v)
(keyword? (syntax->datum v)))
@ -136,7 +137,20 @@
(let*-values ([(p) (lambda fake-args #f)]
[(generic-arity-spec) (procedure-arity p)]
[(generic-required-kws generic-allowed-kws) (procedure-keywords p)])
(lambda (f)
(lambda (method-name f)
(unless (procedure? f)
(raise-arguments-error
'name
"generic method definition is not a function"
"method" method-name
"given" f))
(unless (arity-includes? (procedure-arity f) generic-arity-spec)
(raise-arguments-error
'name
"method definition has an incorrect arity"
"method" method-name
"given arity" (procedure-arity f)
"expected arity" generic-arity-spec))
(procedure-reduce-keyword-arity f generic-arity-spec generic-required-kws generic-allowed-kws))))
...
#,@(if prop-defined-already?
@ -159,7 +173,7 @@
(vector-length generic-vector)))
(vector (let ([mthd-generic (vector-ref generic-vector generic-idx)])
(and mthd-generic
(generic-arity-coerce mthd-generic)))
(generic-arity-coerce 'generic mthd-generic)))
...))
null #t))
;; overrides the interface predicate so that any of the default
@ -185,6 +199,7 @@
;; Define generic functions
(define generic
(generic-arity-coerce
'generic
(make-keyword-procedure
(lambda (kws kws-args . given-args)
(define this (list-ref given-args generic-this-idx))

View File

@ -11,4 +11,33 @@
(check-exn #rx"not a name for a generics group"
(lambda () (convert-compile-time-error
(struct foo () #:methods bad))))
(check-exn #rx"method definition has an incorrect arity"
(lambda () (convert-compile-time-error
(let ()
(define-generics foobar
[foo foobar x])
(struct inst ()
#:methods gen:foobar
[(define (foo) 0)])
'ignore))))
(check-exn #rx"method definition has an incorrect arity"
(lambda () (convert-compile-time-error
(let ()
(define-generics foobar
[foo foobar x]
[bar foobar x])
(struct inst ()
#:methods gen:foobar
[(define (foo foobar x) 0)
(define (bar foobar) 1)])
'ignore))))
(check-exn #rx"generic method definition is not a function"
(lambda () (convert-compile-time-error
(let ()
(define-generics foobar
[foo foobar x])
(struct inst ()
#:methods gen:foobar
[(define foo 0)])
'ignore))))
)