diff --git a/pkgs/racket-test/tests/racket/contract/name.rkt b/pkgs/racket-test/tests/racket/contract/name.rkt index fe00bc11bf..273462554e 100644 --- a/pkgs/racket-test/tests/racket/contract/name.rkt +++ b/pkgs/racket-test/tests/racket/contract/name.rkt @@ -266,6 +266,8 @@ (test-name 'exact-positive-integer? (integer-in 1 #f)) (test-name '(char-in #\a #\z) (char-in #\a #\z)) (test-name '(and/c 0 exact?) (integer-in 0 0)) + ;; this next one is convenient, using the and/c name would also be okay + (test-name '(integer-in 0 9) (and/c (=/c 0))) (test-name '(real-in 1 10) (real-in 1 10)) (test-name '(between/c 1 10) (between/c 1 10)) (test-name '(string-len/c 3) (string-len/c 3)) diff --git a/pkgs/racket-test/tests/racket/contract/stronger.rkt b/pkgs/racket-test/tests/racket/contract/stronger.rkt index b8b55af941..3afa823ad0 100644 --- a/pkgs/racket-test/tests/racket/contract/stronger.rkt +++ b/pkgs/racket-test/tests/racket/contract/stronger.rkt @@ -23,6 +23,13 @@ (ctest #t contract-stronger? (integer-in #f 0) (integer-in #f #f)) (ctest #t contract-stronger? (integer-in 0 0) (and/c 0 exact?)) (ctest #t contract-stronger? (and/c 0 exact?) (integer-in 0 0)) + (ctest #t contract-stronger? (and/c exact-integer? (>=/c 1) (<=/c 10)) (integer-in 1 10)) + (ctest #t contract-stronger? (integer-in 1 10) (and/c exact-integer? (>=/c 1) (<=/c 10))) + (ctest #t contract-stronger? (and/c exact-integer? (<=/c 10) (>/c 1)) (integer-in 2 10)) + (ctest #t contract-stronger? (integer-in 2 10) (and/c exact-integer? (<=/c 10) (>/c 1))) + (ctest #t contract-stronger? (and/c exact-integer? (/c 1)) (integer-in 2 9)) + (ctest #t contract-stronger? (integer-in 2 9) (and/c exact-integer? (/c 1))) + (ctest #t contract-stronger? (integer-in 2 9) (and/c exact-integer? (/c 1.0))) (ctest #t contract-stronger? exact-integer? (integer-in #f #f)) (ctest #t contract-stronger? (integer-in #f #f) exact-integer?) (ctest #t contract-stronger? (integer-in 0 #f) exact-nonnegative-integer?) diff --git a/racket/collects/racket/contract/private/and.rkt b/racket/collects/racket/contract/private/and.rkt index 843f65ebff..f7aa7a0fd0 100644 --- a/racket/collects/racket/contract/private/and.rkt +++ b/racket/collects/racket/contract/private/and.rkt @@ -247,6 +247,36 @@ [else (make-first-order-and/c contracts preds)])] [else (make-first-order-and/c contracts preds)])] + [(and (pair? (cdr preds)) + (pair? (cddr preds)) + (null? (cdddr preds))) + (cond + [(or (chaperone-of? (car preds) exact-integer?) + (chaperone-of? (cadr preds) exact-integer?) + (chaperone-of? (caddr preds) exact-integer?)) + (define lb #f) + (define ub #f) + (for ([ctc (in-list contracts)]) + (cond + [(between/c-s? ctc) + (define lo (between/c-s-low ctc)) + (define hi (between/c-s-high ctc)) + (cond + [(and (= lo -inf.0) (integer? hi)) + (set! ub (inexact->exact hi))] + [(and (= hi +inf.0) (integer? lo)) + (set! lb (inexact->exact lo))])] + [(-ctc? ctc) + (define x (-ctc-x ctc)) + (when (integer? x) + (cond + [(<-ctc? ctc) (set! ub (- (inexact->exact x) 1))] + [(>-ctc? ctc) (set! lb (+ (inexact->exact x) 1))]))])) + (cond + [(and lb ub) + (integer-in lb ub)] + [else (make-first-order-and/c contracts preds)])] + [else (make-first-order-and/c contracts preds)])] [else (make-first-order-and/c contracts preds)])] [(andmap chaperone-contract? contracts) diff --git a/racket/collects/racket/contract/private/misc.rkt b/racket/collects/racket/contract/private/misc.rkt index cf1885bfa2..ddd22cb88b 100644 --- a/racket/collects/racket/contract/private/misc.rkt +++ b/racket/collects/racket/contract/private/misc.rkt @@ -58,6 +58,9 @@ flat-contract-with-explanation (struct-out between/c-s) + (struct-out -ctc) + (struct-out <-ctc) + (struct-out >-ctc) renamed-between/c) (define-syntax (flat-murec-contract stx)