Fixes #434 (Type of literal char is not the literal char itself) using solution from Alex Knauth.

This commit is contained in:
Georges Dupéron 2017-03-31 11:55:20 +02:00
parent 6a0dc61102
commit 92e184e639
2 changed files with 23 additions and 1 deletions

View File

@ -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))

View File

@ -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)))