diff --git a/pkgs/racket-test-core/tests/racket/basic.rktl b/pkgs/racket-test-core/tests/racket/basic.rktl index 906adfcbd1..d5bd2d6efb 100644 --- a/pkgs/racket-test-core/tests/racket/basic.rktl +++ b/pkgs/racket-test-core/tests/racket/basic.rktl @@ -1431,11 +1431,17 @@ (for-each (lambda (i) (vector-set! v i (* i i))) '(0 1 2 3 4)) v)) - +(test '(1 2 3) map (lambda (s #:c [c string->number]) (c s)) '("1" "2" "3")) (define (map-tests map) - (let ([size? exn:application:mismatch?] - [non-list? type?]) + (define ((name-and pred) exn) + (and (pred exn) + (regexp-match? (format "^~a:" name) (exn-message exn)))) + (let ([size? (name-and exn:application:mismatch?)] + [non-list? (name-and type?)] + [keywords? (lambda (exn) + (and (exn:fail:contract? exn) + (regexp-match #rx"expects keyword arguments" (exn-message exn))))]) (err/rt-test (map (lambda (x y) (+ x y)) '(1 2) '1)) (err/rt-test (map (lambda (x y) (+ x y)) '2 '(1 2))) (err/rt-test (map (lambda (x y) (+ x y)) '(1 2) '(1 2 3)) size?) @@ -1449,7 +1455,9 @@ (err/rt-test (map (lambda (x y) (+ x y))) exn:application:arity?) (err/rt-test (map (lambda () 10) null) exn:application:mismatch?) (err/rt-test (map (case-lambda [() 9] [(x y) 10]) '(1 2 3)) exn:application:mismatch?) - (err/rt-test (map (lambda (x) 10) '(1 2) '(3 4)) exn:application:mismatch?))) + (err/rt-test (map (lambda (x) 10) '(1 2) '(3 4)) exn:application:mismatch?) + (err/rt-test (map (lambda (x #:y y) 10) '(1 2)) keywords?) + (err/rt-test (map (lambda (x #:y y) 10) '()) keywords?))) (map-tests map) (map-tests for-each) (map-tests andmap) diff --git a/pkgs/racket-test-core/tests/racket/procs.rktl b/pkgs/racket-test-core/tests/racket/procs.rktl index c036065f15..25e6dcaa6e 100644 --- a/pkgs/racket-test-core/tests/racket/procs.rktl +++ b/pkgs/racket-test-core/tests/racket/procs.rktl @@ -145,7 +145,7 @@ null))]) (test a procedure-arity (car p)) (when (number? a) - (let ([rx (regexp (format " mismatch;.*(expected number(?!.*expected:)|expected: ~a)" + (let ([rx (regexp (format " mismatch;.*(expected number(?!.*expected:)|expected: ~a|required keywords:)" (if (zero? a) "(0|no)" (if method? (sub1 a) a))))] [bad-args (cons 'extra (for/list ([i (in-range a)]) 'a))]) (test #t regexp-match? rx diff --git a/racket/collects/racket/private/map.rkt b/racket/collects/racket/private/map.rkt index 39d68a9e8c..2a9948c439 100644 --- a/racket/collects/racket/private/map.rkt +++ b/racket/collects/racket/private/map.rkt @@ -5,6 +5,7 @@ (module map '#%kernel (#%require "small-scheme.rkt" "define.rkt" "performance-hint.rkt" + "kw.rkt" '#%paramz (for-syntax '#%kernel)) @@ -193,10 +194,14 @@ "procedure" f)) (loop len (cdr ls) (add1 i)))))) (unless (procedure-arity-includes? f (length ls)) + (define-values (required-keywords optional-keywords) (procedure-keywords f)) (apply raise-arguments-error who - (string-append "argument mismatch;\n" - " the given procedure's expected number of arguments does not match" - " the given number of lists") + (if (pair? required-keywords) + (string-append "argument mismatch;\n" + " the given procedure expects keyword arguments") + (string-append "argument mismatch;\n" + " the given procedure's expected number of arguments does not match" + " the given number of lists")) "given procedure" (unquoted-printing-string (or (let ([n (object-name f)]) (and (symbol? n) @@ -205,6 +210,8 @@ (append (let ([a (procedure-arity f)]) (cond + [(pair? required-keywords) + null] [(integer? a) (list "expected" a)] [(arity-at-least? a) @@ -212,7 +219,26 @@ (string-append "at least " (number->string (arity-at-least-value a)))))] [else null])) - (list "given" (length ls)) + (cond + [(pair? required-keywords) + null] + [else + (list "given" (length ls))]) + (cond + [(pair? required-keywords) + (list "required keywords" + (unquoted-printing-string + (apply string-append + (cdr + (let loop ([kws required-keywords]) + (cond + [(null? kws) null] + [else (list* " " + (string-append "#:" + (keyword->string (car kws))) + (loop (cdr kws)))]))))))] + [else + null]) (let ([w (quotient (error-print-width) (length ls))]) (if (w . > . 10) (list "argument lists..."