diff --git a/pkgs/racket-test/tests/racket/contract/name.rkt b/pkgs/racket-test/tests/racket/contract/name.rkt index 8e7636eb06..4f413551af 100644 --- a/pkgs/racket-test/tests/racket/contract/name.rkt +++ b/pkgs/racket-test/tests/racket/contract/name.rkt @@ -32,6 +32,9 @@ (or/c (-> (>=/c 5) (>=/c 5)) boolean?)) (test-name '(or/c boolean? (-> (>=/c 5) (>=/c 5))) (or/c boolean? (-> (>=/c 5) (>=/c 5)))) + (test-name 'boolean? (or/c #f #t)) + (test-name 'boolean? (or/c #t #f)) + (test-name '(or/c #t #f 'x) (or/c #t #f 'x)) (test-name '(if/c integer? odd? (-> integer? integer?)) (if/c integer? odd? (-> integer? integer?))) diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index ed92d7c453..e963333275 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -78,7 +78,10 @@ raise-predicate-blame-error-failure - n->th) + n->th + + false/c-contract + true/c-contract) (define (contract-custom-write-property-proc stct port mode) (define (write-prefix) @@ -304,6 +307,7 @@ (unless listof-any (error 'coerce-contract/f::listof-any "too soon!")) listof-any] + [(chaperone-of? x boolean?) boolean?/c] [(chaperone-of? x pair?) (unless consc-anyany (error 'coerce-contract/f::consc-anyany "too soon!")) @@ -320,6 +324,7 @@ (error 'coerce-contract/f::list/c-empty "too soon!")) list/c-empty] [(not x) false/c-contract] + [(equal? x #t) true/c-contract] [(or (symbol? x) (boolean? x) (keyword? x)) (make-eq-contract x (if (name-default? name) @@ -496,6 +501,7 @@ #:list-contract? (λ (c) (null? (eq-contract-val c))))) (define false/c-contract (make-eq-contract #f #f)) +(define true/c-contract (make-eq-contract #t #t)) (define-struct equal-contract (val name) #:property prop:custom-write contract-custom-write-property-proc @@ -664,7 +670,7 @@ (define (build-flat-contract name pred [generate #f]) (make-predicate-contract name pred generate #f)) - +(define boolean?/c (make-predicate-contract 'boolean? boolean? #f #t)) (define (contract-name ctc) (contract-struct-name diff --git a/racket/collects/racket/contract/private/opters.rkt b/racket/collects/racket/contract/private/opters.rkt index 0db98e3566..849a67cbb1 100644 --- a/racket/collects/racket/contract/private/opters.rkt +++ b/racket/collects/racket/contract/private/opters.rkt @@ -144,10 +144,14 @@ #:stronger-ribs stronger-ribs #:chaperone chaperone? #:no-negative-blame? no-negative-blame - #:name (or name-from-hos + #:name (or name-from-hos (if (= (length names) 1) (car names) - #`(list 'or/c #,@names)))))) + #`(let ([names (list #,@names)]) + (if (or (equal? names '(#f #t)) + (equal? names '(#t #f))) + 'boolean? + (cons 'or/c names)))))))) (syntax-case stx (or/c) [(or/c p ...) diff --git a/racket/collects/racket/contract/private/orc.rkt b/racket/collects/racket/contract/private/orc.rkt index 4077120e65..d54f7d8807 100644 --- a/racket/collects/racket/contract/private/orc.rkt +++ b/racket/collects/racket/contract/private/orc.rkt @@ -34,7 +34,17 @@ (define pred (make-flat-predicate flat-contracts)) (cond [(null? ho-contracts) - (make-flat-or/c pred flat-contracts)] + (cond + [(and (pair? flat-contracts) + (pair? (cdr flat-contracts)) + (null? (cddr flat-contracts)) + (or (and (equal? false/c-contract (car flat-contracts)) + (equal? true/c-contract (cadr flat-contracts))) + (and (equal? false/c-contract (cadr flat-contracts)) + (equal? true/c-contract (car flat-contracts))))) + (coerce-contract 'or/c boolean?)] + [else + (make-flat-or/c pred flat-contracts)])] [(null? (cdr ho-contracts)) (define name (apply build-compound-type-name 'or/c args)) (if (chaperone-contract? (car ho-contracts))