Change inference to take into account index vs regular vars.

original commit: 99e499a503b8b319bc0e512b698e5543634e3654
This commit is contained in:
Sam Tobin-Hochstadt 2010-06-02 12:47:43 -04:00
parent 9b93ec46d3
commit d26ad0e213
4 changed files with 47 additions and 23 deletions

View File

@ -3,12 +3,11 @@
(require scheme/require
(except-in
(path-up
"utils/utils.rkt" "utils/tc-utils.rkt"
"utils/utils.rkt" "utils/tc-utils.rkt" "types/utils.rkt"
"rep/free-variance.rkt" "rep/type-rep.rkt" "rep/filter-rep.rkt" "rep/rep-utils.rkt"
"types/convenience.rkt" "types/union.rkt" "types/subtype.rkt" "types/remove-intersect.rkt" "types/resolve.rkt"
"env/type-name-env.rkt" "env/index-env.rkt" "env/tvar-env.rkt")
make-env)
(path-up "types/utils.rkt")
"constraint-structs.rkt"
"signatures.rkt"
scheme/match
@ -499,26 +498,28 @@
(cset-meet* (for/list ([s S] [t T]) (cgen V X s t))))
;; X : variables to infer
;; Y : indices to infer
;; S : actual argument types
;; T : formal argument types
;; R : result type
;; must-vars : variables that must be in the substitution
;; must-idxs : index variables that must be in the substitution
;; expected : boolean
;; returns a substitution
;; if R is #f, we don't care about the substituion
;; just return a boolean result
(define (infer X S T R must-vars [expected #f])
(define (infer X Y S T R must-vars must-idxs [expected #f])
(with-handlers ([exn:infer? (lambda _ #f)])
(let ([cs (cgen/list null X S T)])
(let ([cs (cgen/list null X Y S T)])
(if (not expected)
(subst-gen cs R must-vars)
(subst-gen (cset-meet cs (cgen null X R expected)) R must-vars)))))
(subst-gen cs R (append must-vars must-idxs))
(subst-gen (cset-meet cs (cgen null X Y R expected)) R must-vars)))))
;; like infer, but T-var is the vararg type:
(define (infer/vararg X S T T-var R must-vars [expected #f])
(define (infer/vararg X Y S T T-var R must-vars must-idxs [expected #f])
(define new-T (if T-var (extend S T T-var) T))
(and ((length S) . >= . (length T))
(infer X S new-T R must-vars expected)))
(infer X Y S new-T R must-vars must-idxs expected)))
;; like infer, but dotted-var is the bound on the ...
;; and T-dotted is the repeated type
@ -538,10 +539,4 @@
(subst-gen cs R must-vars)
(subst-gen (cset-meet cs (cgen null X R expected)) R must-vars)))))
(define (infer/simple S T R)
(infer (fv/list T) S T R))
(define (i s t r)
(infer/simple (list s) (list t) r))
;(trace cgen)

View File

@ -1,6 +1,7 @@
#lang scheme/base
(require scheme/unit scheme/contract "constraint-structs.rkt" "../utils/utils.rkt")
(require (rep type-rep) (utils unit-utils))
#lang racket/base
(require racket/unit racket/contract racket/require
"constraint-structs.rkt"
(path-up "utils/utils.rkt" "utils/unit-utils.rkt" "rep/type-rep.rkt"))
(provide (all-defined-out))
(define-signature dmap^
@ -29,13 +30,40 @@
([cnt restrict (Type? Type? . -> . Type?)]))
(define-signature infer^
([cnt infer (((listof symbol?) (listof Type?) (listof Type?) Type? (listof symbol?)) ((or/c #f Type?)) . ->* . any)]
[cnt infer/vararg (((listof symbol?)
([cnt infer ((;; variables from the forall
(listof symbol?)
;; indexes from the forall
(listof symbol?)
;; actual argument types from call site
(listof Type?)
;; domain
(listof Type?)
;; range
Type?
;; free variables
(listof symbol?)
;; free indexes
(listof symbol?))
;; optional expected type
((or/c #f Type?))
. ->* . any)]
[cnt infer/vararg ((;; variables from the forall
(listof symbol?)
;; indexes from the forall
(listof symbol?)
;; actual argument types from call site
(listof Type?)
;; domain
(listof Type?)
;; rest
(or/c #f Type?)
;; range
Type?
;; free variables
(listof symbol?)
;; free indexes
(listof symbol?))
;; [optional] expected type
((or/c #f Type?)) . ->* . any)]
[cnt infer/dots (((listof symbol?)
symbol?

View File

@ -824,11 +824,11 @@
[else (= (length dom) (length argtys))]))
;; only try to infer the free vars of the rng (which includes the vars in filters/objects)
;; note that we have to use argtys-t here, since argtys is a list of tc-results
(lambda (dom rng rest drest a)
(lambda (dom rng rest drest a)
(if drest
(infer/dots fixed-vars dotted-var argtys-t dom (car drest) rng (fv rng)
#:expected (and expected (tc-results->values expected)))
(infer/vararg vars argtys-t dom rest rng (fv rng)
(infer/vararg fixed-vars (list dotted-var) argtys-t dom rest rng (fv rng) (fi rng)
(and expected (tc-results->values expected)))))
t argtys expected)]
;; regular polymorphic functions without dotted rest, and without mandatory keyword args

View File

@ -12,7 +12,7 @@
scheme/contract
(for-syntax scheme/base syntax/parse))
(provide fv fv/list
(provide fv fv/list fi
substitute
substitute-dots
substitute-dotted
@ -68,7 +68,7 @@
;; implements angle bracket substitution from the formalism
;; substitute-dots : Listof[Type] Option[type] Name Type -> Type
(d/c (substitute-dots images rimage name target)
((listof Type/c) (or/c #f (cons/c Type/c symbol?)) symbol? Type? . -> . Type?)
((listof Type/c) (or/c #f Type/c) symbol? Type? . -> . Type?)
(define (sb t) (substitute-dots images rimage name t))
(if (or (hash-ref (free-idxs* target) name #f) (hash-ref (free-vars* target) name #f))
(type-case (#:Type sb #:Filter (sub-f sb)) target
@ -293,6 +293,7 @@
;; fv : Type -> Listof[Name]
(define (fv t) (hash-map (free-vars* t) (lambda (k v) k)))
(define (fi t) (for/list ([(k v) (in-hash (free-idxs* t))]) k))
;; fv/list : Listof[Type] -> Listof[Name]
(define (fv/list ts) (hash-map (combine-frees (map free-vars* ts)) (lambda (k v) k)))