diff --git a/typed-racket-doc/typed-racket/scribblings/reference/special-forms.scrbl b/typed-racket-doc/typed-racket/scribblings/reference/special-forms.scrbl index 0c502ed0..aa676217 100644 --- a/typed-racket-doc/typed-racket/scribblings/reference/special-forms.scrbl +++ b/typed-racket-doc/typed-racket/scribblings/reference/special-forms.scrbl @@ -497,13 +497,21 @@ for function types. the types @racket[t], and also provides all of the @racket[v]s.} @defform/none[#{v : t}]{ This declares that the variable @racket[v] has type -@racket[t]. This is legal only for binding occurrences of @racket[_v].} +@racket[t]. This is legal only for binding occurrences of @racket[_v]. + +If a dispatch macro on @racket[#\{] already exists in the current +@tech[#:doc '(lib "scribblings/reference/reference.scrbl")]{readtable}, this +syntax will be disabled.} @defform[(ann e t)]{Ensure that @racket[e] has type @racket[t], or some subtype. The entire expression has type @racket[t]. This is legal only in expression contexts.} -@defform/none[#{e :: t}]{A reader abbreviation for @racket[(ann e t)].} +@defform/none[#{e :: t}]{A reader abbreviation for @racket[(ann e t)]. + +If a dispatch macro on @racket[#\{] already exists in the current +@tech[#:doc '(lib "scribblings/reference/reference.scrbl")]{readtable}, this +syntax will be disabled.} @defform[(cast e t)]{The entire expression has the type @racket[t], while @racket[e] may have any type. The value of the entire expression is the value diff --git a/typed-racket-lib/typed-racket/typed-reader.rkt b/typed-racket-lib/typed-racket/typed-reader.rkt index a72c31bb..7cb6e934 100644 --- a/typed-racket-lib/typed-racket/typed-reader.rkt +++ b/typed-racket-lib/typed-racket/typed-reader.rkt @@ -77,7 +77,15 @@ (list src line col pos (and pos (- p pos)))))])) (define (readtable) - (make-readtable (current-readtable) #\{ 'dispatch-macro parse-id-type)) + ; don't install the reader macro if a dispatch macro on the open brace has already been installed + (define current-table (current-readtable)) + (define-values (c reader-proc dispatch-proc) + (if current-table + (readtable-mapping current-table #\{) + (values #f #f #f))) + (if dispatch-proc + current-table + (make-readtable current-table #\{ 'dispatch-macro parse-id-type))) (define (*read inp) (parameterize ([current-readtable (readtable)]) diff --git a/typed-racket-test/succeed/annotation-syntax-override.rkt b/typed-racket-test/succeed/annotation-syntax-override.rkt new file mode 100644 index 00000000..722d2f38 --- /dev/null +++ b/typed-racket-test/succeed/annotation-syntax-override.rkt @@ -0,0 +1,21 @@ +#lang racket + +(require rackunit + typed-racket/typed-reader) + +(test-case + "Annotation reader syntax" + (define stx (read-syntax 'in (open-input-string "#{x : T}"))) + (check-equal? (syntax-e stx) 'x) + (check-equal? (syntax-property stx 'type-label) 'T)) + +(test-case + "Overridden annotation reader syntax" + (define (read* c in . args) + (read-char in) + 'replacement) + (define stx + (parameterize ([current-readtable + (make-readtable #f #\{ 'dispatch-macro read*)]) + (read-syntax 'in (open-input-string "#{}")))) + (check-equal? (syntax-e stx) 'replacement))