diff --git a/racket/collects/racket/contract/private/base.rkt b/racket/collects/racket/contract/private/base.rkt index e2b49f0025..bb7fd8c68c 100644 --- a/racket/collects/racket/contract/private/base.rkt +++ b/racket/collects/racket/contract/private/base.rkt @@ -74,8 +74,12 @@ (if clnp #f neg) #t)) (cond - [clnp ((clnp blame) v neg)] - [else (((contract-projection c) blame) v)]))) + [clnp (with-contract-continuation-mark + (cons blame neg) + ((clnp blame) v neg))] + [else (with-contract-continuation-mark + blame + (((contract-projection c) blame) v))]))) (define-syntax (invariant-assertion stx) (syntax-case stx () diff --git a/racket/collects/racket/contract/private/guts.rkt b/racket/collects/racket/contract/private/guts.rkt index d166a9d838..0af245ae55 100644 --- a/racket/collects/racket/contract/private/guts.rkt +++ b/racket/collects/racket/contract/private/guts.rkt @@ -772,11 +772,24 @@ (define contract-continuation-mark-key (make-continuation-mark-key 'contract)) -(define-syntax-rule (with-contract-continuation-mark payload code) +;; Instrumentation strategy: +;; - add instrumentation at entry points to the contract system: +;; - `contract` (`apply-contract`, really) +;; - `contract-out` (`do-partial-app`, really) +;; - all others go through one of the above +;; that instrumentation picks up "top-level" flat contracts (i.e., not part of +;; some higher-order contract) and the "eager" parts of higher-order contracts +;; - add instrumentation inside chaperones/impersonators created by projections +;; that instrumentation picks up the deferred work of higher-order contracts +;; - add instrumentation to `plus-one-arity-functions` +;; those perform checking, but don't rely on chaperones +;; they exist for -> and ->*, and are partially implemented for ->i +;; TODO once they're fully implemented for ->i, will need to instrument them +(define-syntax-rule (with-contract-continuation-mark payload code ...) (begin ;; ;; When debugging a missing blame party error, turn this on, then run ;; ;; the contract test suite. It should find the problematic combinator. ;; (unless (or (pair? payload) (not (blame-missing-party? payload))) ;; (error "internal error: missing blame party" payload)) - (with-continuation-mark contract-continuation-mark-key payload code))) - + (with-continuation-mark contract-continuation-mark-key payload + (let () code ...)))) diff --git a/racket/collects/racket/contract/private/provide.rkt b/racket/collects/racket/contract/private/provide.rkt index 066c37d0f9..8a3c00bc50 100644 --- a/racket/collects/racket/contract/private/provide.rkt +++ b/racket/collects/racket/contract/private/provide.rkt @@ -388,14 +388,19 @@ (λ () (contract-name ctc)) pos-module-source #f #t)) - (define neg-accepter ((p blme) val)) - - ;; we don't have the negative blame here, but we - ;; expect only positive failures from this; do the - ;; check and then toss the results. - (neg-accepter 'incomplete-blame-from-provide.rkt) - - neg-accepter) + (with-contract-continuation-mark + (cons blme 'no-negative-party) ; we don't know the negative party yet + ;; computing neg-accepter may involve some front-loaded checking. instrument + (define neg-accepter ((p blme) val)) + + ;; check as much as we can while knowing only the + ;; contracted value (e.g., function arity) + ;; we don't have the negative blame here, but we + ;; expect only positive failures from this; do the + ;; check and then toss the results. + (neg-accepter 'incomplete-blame-from-provide.rkt) + + neg-accepter)) (define-for-syntax (true-provide/contract provide-stx just-check-errors? who) (syntax-case provide-stx ()