From 92e184e6396c5195132d0684a02df183b3efb624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Fri, 31 Mar 2017 11:55:20 +0200 Subject: [PATCH] Fixes #434 (Type of literal char is not the literal char itself) using solution from Alex Knauth. --- .../typed-racket/typecheck/tc-literal.rkt | 2 +- .../succeed/literal-char-gh-issue-434.rkt | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 typed-racket-test/succeed/literal-char-gh-issue-434.rkt diff --git a/typed-racket-lib/typed-racket/typecheck/tc-literal.rkt b/typed-racket-lib/typed-racket/typecheck/tc-literal.rkt index fe5d7d66..847cfb27 100644 --- a/typed-racket-lib/typed-racket/typecheck/tc-literal.rkt +++ b/typed-racket-lib/typed-racket/typecheck/tc-literal.rkt @@ -28,7 +28,7 @@ ;; tc-literal: racket-value-syntax [type] -> type (define (tc-literal v-stx [expected #f]) (define-syntax-class exp - (pattern (~and i (~or :number :str :bytes)) + (pattern (~and i (~or :number :str :bytes :char)) #:fail-unless expected #f #:fail-unless (let ([n (syntax-e #'i)]) (subtype (-val n) expected #:obj (if (exact-integer? n) (-lexp n) -empty-obj))) #f)) diff --git a/typed-racket-test/succeed/literal-char-gh-issue-434.rkt b/typed-racket-test/succeed/literal-char-gh-issue-434.rkt new file mode 100644 index 00000000..ced7b379 --- /dev/null +++ b/typed-racket-test/succeed/literal-char-gh-issue-434.rkt @@ -0,0 +1,22 @@ +#lang typed/racket +;; The precise type for chars should be the char itself: +(ann #\nul #\nul) +(ann #\a #\a) +(ann #\b '#\b) +;; Up-casting as Char should still work: +(ann #\nul Char) +(ann #\a Char) +(ann (ann #\b '#\b) Char) + +;; Check that the inferred type is still implicitly widened to Char by default, +;; for backwards compatibility (previously, all chars had the type Char): +;; * Check that when passed as a #:∀ type, the inferred type is Char +(ann (let #:∀ (C) ([c : C #\a]) + (λ ([x : C]) x)) + (→ Char Char)) +;; * Check that loops which rely on the first iteration having the wider Char +;; type still work: +(let loop : Void ([c #\a]) + (if (equal? c #\a) + (loop #\b) + (void))) \ No newline at end of file