From 40b8ae7a33125887a94099cd818e4a13ca6f69a1 Mon Sep 17 00:00:00 2001 From: shhyou Date: Sat, 8 Sep 2018 18:50:02 -0500 Subject: [PATCH] Coerce the arg in contract-random-generate/choose --- pkgs/racket-doc/scribblings/reference/contracts.scrbl | 10 ++++++++-- .../tests/racket/contract/random-generate.rkt | 11 +++++++++++ racket/collects/racket/contract/private/generate.rkt | 3 ++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/contracts.scrbl b/pkgs/racket-doc/scribblings/reference/contracts.scrbl index ca0211b5ee..4b0458a3ff 100644 --- a/pkgs/racket-doc/scribblings/reference/contracts.scrbl +++ b/pkgs/racket-doc/scribblings/reference/contracts.scrbl @@ -3567,8 +3567,14 @@ ended up returning @racket[contract-random-generate-fail]. (or/c #f (-> c))]{ This function is like @racket[contract-random-generate], but it is intended to be used with combinators that generate values based on sub-contracts - they have. It cannot be called, except during contract - generation. It will never fail, but it might escape back to an enclosing + they have. It must be called when @racket[contract-random-generate] + (and @racket[contract-exercise]) creates the generators. In other words, + @racket[contract-random-generate/choose] is available only after the + @racket[_generate] (and @racket[_exercise]) function received the + @racket[_fuel] and before it returned the thunk (or the exerciser). + + @racket[contract-random-generate/choose] will never fail, + but it might escape back to an enclosing call or to the original call to @racket[contract-random-generate]. It chooses one of several possible generation strategies, and thus it may not diff --git a/pkgs/racket-test/tests/racket/contract/random-generate.rkt b/pkgs/racket-test/tests/racket/contract/random-generate.rkt index 1b3a034836..39940cea07 100644 --- a/pkgs/racket-test/tests/racket/contract/random-generate.rkt +++ b/pkgs/racket-test/tests/racket/contract/random-generate.rkt @@ -492,3 +492,14 @@ (λ (_) 'thing) 'pos 'neg)) + +;; a test for contract-random-generate/choose +(let () + (struct make-gen-choose/c () + #:property prop:chaperone-contract + (build-chaperone-contract-property + #:late-neg-projection + (λ (ctc) (λ (b) (λ (v np) v))) + #:generate + (λ (ctc) (λ (fuel) (contract-random-generate/choose number? 10))))) + (check-not-exn (λ () (test-contract-generation (make-gen-choose/c))))) diff --git a/racket/collects/racket/contract/private/generate.rkt b/racket/collects/racket/contract/private/generate.rkt index 62fdccd9f0..3a537937cb 100644 --- a/racket/collects/racket/contract/private/generate.rkt +++ b/racket/collects/racket/contract/private/generate.rkt @@ -194,7 +194,8 @@ ; #f if no value could be generated ;; if it returns a thunk, the thunk will not return contract-random-generate-fail? (define (contract-random-generate/choose ctc fuel) - (define direct ((contract-struct-generate ctc) fuel)) + (define def-ctc (coerce-contract 'contract-random-generate/choose ctc)) + (define direct ((contract-struct-generate def-ctc) fuel)) (define env-can? (can-generate/env? ctc)) (define env (generate-env)) (unless (contract-random-generate-env? env)