Track mutable variables across modules.
This commit is contained in:
parent
cd23fd48cf
commit
eed93825ab
25
collects/tests/typed-racket/fail/other-module-mutation.rkt
Normal file
25
collects/tests/typed-racket/fail/other-module-mutation.rkt
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#lang racket/load
|
||||||
|
|
||||||
|
(module mutator typed/racket
|
||||||
|
(define: y : Integer 0)
|
||||||
|
|
||||||
|
(: set-y! (Integer -> Void))
|
||||||
|
(define (set-y! v)
|
||||||
|
(set! y v))
|
||||||
|
|
||||||
|
(provide y set-y!))
|
||||||
|
|
||||||
|
(module user typed/racket
|
||||||
|
(require 'mutator)
|
||||||
|
|
||||||
|
(: foo (Zero -> Zero))
|
||||||
|
(define (foo y)
|
||||||
|
(printf "(foo ~v)~n" y)
|
||||||
|
y)
|
||||||
|
|
||||||
|
(cond [(zero? y) (set-y! 10)
|
||||||
|
(foo y)]
|
||||||
|
[else y]))
|
||||||
|
|
||||||
|
(require 'user)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
racket/file racket/port
|
racket/file racket/port
|
||||||
(for-syntax syntax/kerncase syntax/parse racket/syntax
|
(for-syntax syntax/kerncase syntax/parse racket/syntax
|
||||||
(types abbrev numeric-tower utils)
|
(types abbrev numeric-tower utils)
|
||||||
(utils mutated-vars)
|
(utils mutated-vars) (env mvar-env)
|
||||||
(utils tc-utils) (typecheck typechecker))
|
(utils tc-utils) (typecheck typechecker))
|
||||||
typed-racket/base-env/prims
|
typed-racket/base-env/prims
|
||||||
typed-racket/base-env/base-types
|
typed-racket/base-env/base-types
|
||||||
|
@ -34,8 +34,8 @@
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(check-tc-result-equal? (format "~a ~a" #,(syntax-line stx) 'a)
|
(check-tc-result-equal? (format "~a ~a" #,(syntax-line stx) 'a)
|
||||||
#,(let ([ex (local-expand #'a 'expression null)])
|
#,(let ([ex (local-expand #'a 'expression null)])
|
||||||
(parameterize ([mutated-vars (find-mutated-vars ex)])
|
(find-mutated-vars ex mvar-env)
|
||||||
(tc-expr ex)))
|
(tc-expr ex))
|
||||||
#,(syntax-local-eval #'b)))]))
|
#,(syntax-local-eval #'b)))]))
|
||||||
|
|
||||||
(define (typecheck-special-tests)
|
(define (typecheck-special-tests)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
[-> t:->])
|
[-> t:->])
|
||||||
(utils tc-utils utils)
|
(utils tc-utils utils)
|
||||||
(utils mutated-vars)
|
(utils mutated-vars)
|
||||||
(env type-name-env type-env-structs init-envs)
|
(env type-name-env type-env-structs init-envs mvar-env)
|
||||||
rackunit rackunit/text-ui
|
rackunit rackunit/text-ui
|
||||||
syntax/parse
|
syntax/parse
|
||||||
(for-syntax (utils tc-utils) racket/file racket/port
|
(for-syntax (utils tc-utils) racket/file racket/port
|
||||||
|
@ -75,8 +75,8 @@
|
||||||
[current-namespace (namespace-anchor->namespace anch)]
|
[current-namespace (namespace-anchor->namespace anch)]
|
||||||
[orig-module-stx (quote-syntax e)])
|
[orig-module-stx (quote-syntax e)])
|
||||||
(let ([ex (expand 'e)])
|
(let ([ex (expand 'e)])
|
||||||
(parameterize ([mutated-vars (find-mutated-vars ex)])
|
(find-mutated-vars ex mvar-env)
|
||||||
(values (lambda () (tc-expr ex)) ex))))]))
|
(values (lambda () (tc-expr ex)) ex)))]))
|
||||||
|
|
||||||
(define-syntax (tc-expr/expand stx)
|
(define-syntax (tc-expr/expand stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
|
@ -85,8 +85,8 @@
|
||||||
[current-namespace (namespace-anchor->namespace anch)]
|
[current-namespace (namespace-anchor->namespace anch)]
|
||||||
[orig-module-stx (quote-syntax e)])
|
[orig-module-stx (quote-syntax e)])
|
||||||
(let ([ex (expand 'e)])
|
(let ([ex (expand 'e)])
|
||||||
(parameterize ([mutated-vars (find-mutated-vars ex)])
|
(find-mutated-vars ex mvar-env)
|
||||||
(tc-expr ex))))]))
|
(tc-expr ex)))]))
|
||||||
|
|
||||||
;; check that an expression typechecks correctly
|
;; check that an expression typechecks correctly
|
||||||
(define-syntax (tc-e stx)
|
(define-syntax (tc-e stx)
|
||||||
|
|
9
collects/typed-racket/env/init-envs.rkt
vendored
9
collects/typed-racket/env/init-envs.rkt
vendored
|
@ -5,12 +5,13 @@
|
||||||
"global-env.rkt"
|
"global-env.rkt"
|
||||||
"type-name-env.rkt"
|
"type-name-env.rkt"
|
||||||
"type-alias-env.rkt"
|
"type-alias-env.rkt"
|
||||||
|
"mvar-env.rkt"
|
||||||
(rep type-rep object-rep filter-rep rep-utils)
|
(rep type-rep object-rep filter-rep rep-utils)
|
||||||
(for-template (rep type-rep object-rep filter-rep)
|
(for-template (rep type-rep object-rep filter-rep)
|
||||||
(types union abbrev)
|
(types union abbrev)
|
||||||
racket/shared racket/base)
|
racket/shared racket/base)
|
||||||
(types abbrev)
|
(types abbrev)
|
||||||
racket/syntax
|
racket/syntax racket/dict
|
||||||
mzlib/pconvert racket/match)
|
mzlib/pconvert racket/match)
|
||||||
|
|
||||||
(define (initialize-type-name-env initial-type-names)
|
(define (initialize-type-name-env initial-type-names)
|
||||||
|
@ -102,5 +103,11 @@
|
||||||
(booleans-as-true/false #f))
|
(booleans-as-true/false #f))
|
||||||
#`(begin #,@(filter values (type-env-map f)))))
|
#`(begin #,@(filter values (type-env-map f)))))
|
||||||
|
|
||||||
|
(define (mvar-env-init-code mvar-env)
|
||||||
|
(define (f id v)
|
||||||
|
(and v (bound-in-this-module id)
|
||||||
|
#`(register-mutated-var #'#,id)))
|
||||||
|
#`(begin #,@(filter values (dict-map mvar-env f))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
3
collects/typed-racket/env/lexical-env.rkt
vendored
3
collects/typed-racket/env/lexical-env.rkt
vendored
|
@ -10,11 +10,12 @@
|
||||||
"type-env-structs.rkt"
|
"type-env-structs.rkt"
|
||||||
"global-env.rkt"
|
"global-env.rkt"
|
||||||
"../types/kw-types.rkt"
|
"../types/kw-types.rkt"
|
||||||
|
"mvar-env.rkt"
|
||||||
syntax/id-table
|
syntax/id-table
|
||||||
racket/keyword-transform racket/list
|
racket/keyword-transform racket/list
|
||||||
(for-syntax syntax/parse syntax/parse/experimental/contract racket/base)
|
(for-syntax syntax/parse syntax/parse/experimental/contract racket/base)
|
||||||
(only-in racket/contract ->* -> or/c any/c listof cons/c)
|
(only-in racket/contract ->* -> or/c any/c listof cons/c)
|
||||||
(utils tc-utils mutated-vars)
|
(utils tc-utils)
|
||||||
(only-in (rep type-rep) Type/c)
|
(only-in (rep type-rep) Type/c)
|
||||||
(typecheck tc-metafunctions)
|
(typecheck tc-metafunctions)
|
||||||
(except-in (types utils abbrev) -> ->*))
|
(except-in (types utils abbrev) -> ->*))
|
||||||
|
|
13
collects/typed-racket/env/mvar-env.rkt
vendored
Normal file
13
collects/typed-racket/env/mvar-env.rkt
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require syntax/id-table racket/dict)
|
||||||
|
|
||||||
|
(provide mvar-env register-mutated-var is-var-mutated?)
|
||||||
|
|
||||||
|
(define mvar-env (make-free-id-table))
|
||||||
|
|
||||||
|
(define (register-mutated-var id)
|
||||||
|
(dict-set! mvar-env id #t))
|
||||||
|
|
||||||
|
(define (is-var-mutated? id)
|
||||||
|
(dict-ref mvar-env id #f))
|
|
@ -6,7 +6,7 @@
|
||||||
"../utils/tc-utils.rkt"
|
"../utils/tc-utils.rkt"
|
||||||
(for-template racket/base)
|
(for-template racket/base)
|
||||||
(types numeric-tower utils type-table)
|
(types numeric-tower utils type-table)
|
||||||
(rep type-rep)
|
(rep type-rep) (env mvar-env)
|
||||||
(optimizer utils logging float-complex))
|
(optimizer utils logging float-complex))
|
||||||
|
|
||||||
(provide unboxed-let-opt-expr)
|
(provide unboxed-let-opt-expr)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
(require "../utils/utils.rkt"
|
(require "../utils/utils.rkt"
|
||||||
(rep type-rep)
|
(rep type-rep)
|
||||||
(utils tc-utils)
|
(utils tc-utils)
|
||||||
(env global-env)
|
(env global-env mvar-env)
|
||||||
(except-in (types subtype union resolve utils generalize))
|
(except-in (types subtype union resolve utils generalize))
|
||||||
(private parse-type)
|
(private parse-type)
|
||||||
(contract-req)
|
(contract-req)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
(private type-contract)
|
(private type-contract)
|
||||||
(types utils)
|
(types utils)
|
||||||
(typecheck typechecker provide-handling tc-toplevel)
|
(typecheck typechecker provide-handling tc-toplevel)
|
||||||
(env tvar-env type-name-env type-alias-env env-req)
|
(env tvar-env type-name-env type-alias-env env-req mvar-env)
|
||||||
(utils tc-utils disarm mutated-vars debug)
|
(utils tc-utils disarm mutated-vars debug)
|
||||||
(rep type-rep)
|
(rep type-rep)
|
||||||
(for-syntax racket/base)
|
(for-syntax racket/base)
|
||||||
|
@ -58,8 +58,8 @@
|
||||||
(do-time "Local Expand Done")
|
(do-time "Local Expand Done")
|
||||||
(init)
|
(init)
|
||||||
(do-time "Initialized Envs")
|
(do-time "Initialized Envs")
|
||||||
(parameterize ([mutated-vars (find-mutated-vars fully-expanded-stx)]
|
(find-mutated-vars fully-expanded-stx mvar-env)
|
||||||
[orig-module-stx (or (orig-module-stx) orig-stx)]
|
(parameterize ([orig-module-stx (or (orig-module-stx) orig-stx)]
|
||||||
[expanded-module-stx fully-expanded-stx]
|
[expanded-module-stx fully-expanded-stx]
|
||||||
[debugging? #f])
|
[debugging? #f])
|
||||||
(do-time "Starting `checker'")
|
(do-time "Starting `checker'")
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
(rep type-rep)
|
(rep type-rep)
|
||||||
(types utils abbrev type-table)
|
(types utils abbrev type-table)
|
||||||
(private parse-type type-annotation type-contract)
|
(private parse-type type-annotation type-contract)
|
||||||
(env global-env init-envs type-name-env type-alias-env lexical-env env-req)
|
(env global-env init-envs type-name-env type-alias-env lexical-env env-req mvar-env)
|
||||||
syntax/id-table
|
syntax/id-table
|
||||||
(utils tc-utils mutated-vars)
|
(utils tc-utils mutated-vars)
|
||||||
"provide-handling.rkt"
|
"provide-handling.rkt"
|
||||||
|
@ -350,6 +350,7 @@
|
||||||
#,(env-init-code syntax-provide? provide-tbl def-tbl)
|
#,(env-init-code syntax-provide? provide-tbl def-tbl)
|
||||||
#,(talias-env-init-code)
|
#,(talias-env-init-code)
|
||||||
#,(tname-env-init-code)
|
#,(tname-env-init-code)
|
||||||
|
#,(mvar-env-init-code mvar-env)
|
||||||
#,(make-struct-table-code)
|
#,(make-struct-table-code)
|
||||||
#,@(for/list ([a (in-list aliases)])
|
#,@(for/list ([a (in-list aliases)])
|
||||||
(match a
|
(match a
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
(utils tc-utils)
|
(utils tc-utils)
|
||||||
"base-abbrev.rkt"
|
"base-abbrev.rkt"
|
||||||
(types union numeric-tower)
|
(types union numeric-tower)
|
||||||
|
(env mvar-env)
|
||||||
racket/list
|
racket/list
|
||||||
racket/match
|
racket/match
|
||||||
racket/function
|
racket/function
|
||||||
|
|
|
@ -15,12 +15,6 @@ don't depend on any other portion of the system
|
||||||
(define orig-module-stx (make-parameter #f))
|
(define orig-module-stx (make-parameter #f))
|
||||||
(define expanded-module-stx (make-parameter #f))
|
(define expanded-module-stx (make-parameter #f))
|
||||||
|
|
||||||
;; a parameter holding the mutated variables for the form currently being
|
|
||||||
;; checked
|
|
||||||
(define mutated-vars (make-parameter #hash()))
|
|
||||||
|
|
||||||
(define (is-var-mutated? id) (dict-ref (mutated-vars) id #f))
|
|
||||||
|
|
||||||
(define (stringify l [between " "])
|
(define (stringify l [between " "])
|
||||||
(define (intersperse v l)
|
(define (intersperse v l)
|
||||||
(cond [(null? l) null]
|
(cond [(null? l) null]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user