diff --git a/racket/collects/racket/stream.rkt b/racket/collects/racket/stream.rkt index 18d0b17bf7..a2d9220c78 100644 --- a/racket/collects/racket/stream.rkt +++ b/racket/collects/racket/stream.rkt @@ -240,45 +240,46 @@ (define (add-stream-context blame) (blame-add-context blame "a value generated by")) -(define (check-stream/c ctc val blame) - (unless (stream? val) - (raise-blame-error blame val '(expected "a stream" given: "~e") val))) - (define (stream/c-stronger? a b) (contract-stronger? (base-stream/c-content a) (base-stream/c-content b))) -; streams are lazy, so we need to contract the rest of the stream lazily (which can be a list) -(define (contract-stream-rest v ctc blame) +(define ((late-neg-projection impersonate/chaperone-stream) ctc) (define elem-ctc (base-stream/c-content ctc)) - (define new-ctc (if (list? v) (listof elem-ctc) ctc)) - (((contract-projection new-ctc) blame) v)) - -(define ((ho-projection impersonate/chaperone-stream) ctc) - (let ([elem-ctc (base-stream/c-content ctc)]) - (λ (blame) - (define stream-blame (add-stream-context blame)) - (define pos-elem-proj ((contract-projection elem-ctc) stream-blame)) - (λ (val) - (check-stream/c ctc val stream-blame) - (if (list? val) - (contract-stream-rest val ctc stream-blame) - (impersonate/chaperone-stream - val - (λ (v) (pos-elem-proj v)) - (λ (v) (contract-stream-rest v ctc stream-blame)) - impersonator-prop:contracted ctc - impersonator-prop:blame stream-blame)))))) + (define listof-elem-ctc (listof elem-ctc)) + (define elem-ctc-late-neg (get/build-late-neg-projection elem-ctc)) + (define listof-elem-ctc-late-neg (get/build-late-neg-projection listof-elem-ctc)) + (λ (blame) + (define stream-blame (add-stream-context blame)) + (define elem-ctc-late-neg-acceptor (elem-ctc-late-neg stream-blame)) + (define listof-elem-ctc-neg-acceptor (listof-elem-ctc-late-neg stream-blame)) + (define (stream/c-late-neg-proj-val-acceptor val neg-party) + (unless (stream? val) + (raise-blame-error blame #:missing-party neg-party + val '(expected "a stream" given: "~e") val)) + (if (list? val) + (listof-elem-ctc-neg-acceptor val neg-party) + (impersonate/chaperone-stream + val + (λ (v) (elem-ctc-late-neg-acceptor v neg-party)) + (λ (v) + (if (list? v) + (listof-elem-ctc-neg-acceptor v neg-party) + (stream/c-late-neg-proj-val-acceptor v neg-party))) + impersonator-prop:contracted ctc + impersonator-prop:blame stream-blame))) + stream/c-late-neg-proj-val-acceptor)) (struct base-stream/c (content)) (struct chaperone-stream/c base-stream/c () #:property prop:custom-write custom-write-property-proc #:property prop:chaperone-contract - (build-chaperone-contract-property - #:name stream/c-name - #:first-order stream? - #:stronger stream/c-stronger? - #:projection (ho-projection chaperone-stream))) + (parameterize ([skip-projection-wrapper? #t]) + (build-chaperone-contract-property + #:name stream/c-name + #:first-order stream? + #:stronger stream/c-stronger? + #:late-neg-projection (late-neg-projection chaperone-stream)))) (struct impersonator-stream/c base-stream/c () #:property prop:custom-write custom-write-property-proc @@ -287,7 +288,7 @@ #:name stream/c-name #:first-order stream? #:stronger stream/c-stronger? - #:projection (ho-projection impersonate-stream))) + #:late-neg-projection (late-neg-projection impersonate-stream))) (define (stream/c elem) (define ctc (coerce-contract 'stream/c elem))