From e7d61bd982e4be3e4a2605af07febae953d7c0b3 Mon Sep 17 00:00:00 2001 From: Andrew Kent Date: Wed, 14 Jan 2015 15:32:34 +0530 Subject: [PATCH] fixed struct field updates --- .../typed-racket/typecheck/tc-envops.rkt | 16 ++++++++++------ typed-racket-test/succeed/struct-update.rkt | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 typed-racket-test/succeed/struct-update.rkt diff --git a/typed-racket-lib/typed-racket/typecheck/tc-envops.rkt b/typed-racket-lib/typed-racket/typecheck/tc-envops.rkt index 3b9e95e4..6b2e9649 100644 --- a/typed-racket-lib/typed-racket/typecheck/tc-envops.rkt +++ b/typed-racket-lib/typed-racket/typecheck/tc-envops.rkt @@ -46,12 +46,16 @@ ;; a polymorphic field. Because subtyping is nominal and accessor ;; functions do not reflect this, this behavior is unobservable ;; except when an a variable aliases the field in a let binding - (build-type make-Struct nm par - (list-update flds idx (match-lambda - [(fld: e acc-id #f) - (make-fld (update e ft pos? rst) acc-id #f)] - [_ (int-err "update on mutable struct field")])) - proc poly pred)] + (let/ec abort + (make-Struct nm par + (list-update flds idx (match-lambda + [(fld: e acc-id #f) + (let ([ft* (update e ft pos? rst)]) + (if (Bottom? ft*) + (abort ft*) + (make-fld ft* acc-id #f)))] + [_ (int-err "update on mutable struct field")])) + proc poly pred))] ;; otherwise [(t '()) diff --git a/typed-racket-test/succeed/struct-update.rkt b/typed-racket-test/succeed/struct-update.rkt new file mode 100644 index 00000000..8650dd69 --- /dev/null +++ b/typed-racket-test/succeed/struct-update.rkt @@ -0,0 +1,17 @@ +#lang typed/racket/base + +;; ensures updates to a struct's field +;; which results in Bottom +;; properly propogates Bottom up + +(define-type ABC (U 'a 'b 'c)) + +(define-struct ABCWrapper ([abc : ABC])) + +(: abc-123-let (ABCWrapper -> (U 1 2 3))) +(define (abc-123-let wrapper) + (let ([abc (ABCWrapper-abc wrapper)]) + (cond + [(eq? abc 'a) 1] + [(eq? abc 'b) 2] + [(eq? abc 'c) 3]))) \ No newline at end of file