* Add the ability to substitute in starred types for dotted when

we've inferred it.
 * Try and consolidate a lot of the error printing with domain mismatches.
This commit is contained in:
Stevie Strickland 2008-06-19 19:14:32 -04:00
parent 0f142d97e3
commit 654d7e2f46
2 changed files with 70 additions and 110 deletions

View File

@ -120,6 +120,27 @@
;(trace tc-args)
(define (stringify-domain dom rst drst)
(let ([doms-string (if (null? dom) "" (string-append (stringify dom) " "))])
(cond [drst
(format "~a~a ... ~a" doms-string (car drst) (cdr drst))]
[rst
(format "~a~a *" doms-string rst)]
[else (stringify dom)])))
(define (domain-mismatches ty doms rests drests arg-tys tail-ty tail-bound)
(cond
[(null? doms)
(int-err "How could doms be null: ~a ~a" ty)]
[(= 1 (length doms))
(format "Domain: ~a~nArguments: ~a~n"
(stringify-domain (car doms) (car rests) (car drests))
(stringify-domain arg-tys (if (not tail-bound) tail-ty #f) (if tail-bound (cons tail-ty tail-bound) #f)))]
[else
(format "Domains:~nArguments: ~a~n"
(stringify (map stringify-domain doms rests drests) "~n~t")
(stringify-domain arg-tys (if (not tail-bound) tail-ty #f) (if tail-bound (cons tail-ty tail-bound) #f)))]))
(define (tc/apply f args)
(define f-ty (tc-expr f))
;; produces the first n-1 elements of the list, and the last element
@ -128,80 +149,8 @@
(if (null? (cdr l))
(values (reverse acc) (car l))
(loop (cdr l) (cons (car l) acc)))))
(define (printable-h dom r-ty r-bound)
(let ([doms-string (if (null? dom) "" (string-append (stringify dom) " "))])
(cond [r-bound
(format "~a~a ... ~a" doms-string r-ty r-bound)]
[r-ty
(format "~a~a *" doms-string r-ty)]
[else (stringify dom)])))
(define (printable dom rst drst)
(cond [rst (printable-h dom rst #f)]
[drst (printable-h dom (car drst) (cdr drst))]
[else (printable-h dom #f #f)]))
(define-values (fixed-args tail) (split (syntax->list args)))
(define (apply-error doms rests drests arg-tys tail-ty tail-bound)
(if (and (not (null? doms)) (null? (cdr doms)))
(tc-error/expr
#:return (ret (Un))
(string-append
"bad arguments to apply~n - function expected ~a as fixed arguments and ~a as a rest argument,~n"
" - given ~a as fixed arguments and ~a as a rest argument~n")
(if (null? (car doms))
"nothing"
(stringify (car doms)))
(cond [(car rests)
(format "~a *" (car rests))]
[(car drests)
(format "~a ... ~a" (car (car drests)) (cdr (car drests)))]
[else "nothing"])
(if (null? arg-tys)
"nothing"
(stringify arg-tys))
(if tail-bound
(format "~a ... ~a" tail-ty tail-bound)
tail-ty))
(tc-error/expr
#:return (ret (Un))
"no function domain matched in apply~ndomains were: ~n\t~a~narguments were: \n\t~a\n"
(stringify (map printable doms rests drests) "\n\t")
(stringify (append arg-tys (list (if tail-bound
(string-append tail-ty " ... " tail-bound)
tail-ty)))))))
(define (apply-error/poly doms rests drests arg-tys tail-ty tail-bound)
(cond
[(null? doms) (int-err "how could doms be null: ~a ~a" doms f-ty)]
[(= 1 (length doms))
(cond
[(car rests)
(tc-error/expr
#:return (ret (Un))
"polymorphic function domain did not match in apply~ndomain was: ~a~nrest argument was: ~a~narguments were ~a~n"
(car doms) (car rests) (printable-h arg-tys tail-ty tail-bound))]
[(car drests)
(tc-error/expr
#:return (ret (Un))
"polymorphic function domain did not match in apply~ndomain was: ~a~nrest argument was: ~a ... ~a~narguments were ~a~n"
(car doms) (car (car drests)) (cdr (car drests)) (printable-h arg-tys tail-ty tail-bound))]
[else
(tc-error/expr
#:return (ret (Un))
"polymorphic function domain did not match in apply~ndomain was: ~a~narguments were ~a~n"
(car doms) (printable-h arg-tys tail-ty tail-bound))])]
[else
(tc-error/expr
#:return (ret (Un))
"no polymorphic function domain matched in apply~ndomains were: ~a~narguments were ~a~n"
(stringify
(for/list ([dom doms] [rest rests] [drest drests])
(cond
[rest
(format "~a rest argument: ~a" (stringify dom) rest)]
[drest
(format "~a rest argument: ~a ... ~a" (stringify dom) (car drest) (cdr drest))]
[else (stringify dom)]))
"\n")
(printable-h arg-tys tail-ty tail-bound))]))
(match f-ty
[(tc-result: (Function: (list (arr: doms rngs rests drests thn-effs els-effs) ...)))
(when (null? doms)
@ -213,7 +162,10 @@
(let-values ([(tail-ty tail-bound)
(with-handlers ([exn:fail? (lambda _ (values (tc-expr/t tail) #f))])
(tc/dots tail))])
(apply-error doms rests drests arg-tys tail-ty tail-bound))]
(tc-error/expr #:return (ret (Un))
(string-append
"Bad arguments to function in apply:~n"
(domain-mismatches f-ty doms rests drests arg-tys tail-ty tail-bound))))]
[(and (car rests*)
(let-values ([(tail-ty tail-bound)
(with-handlers ([exn:fail? (lambda _ (values #f #f))])
@ -250,7 +202,10 @@
(cond [(null? doms*)
(match f-ty
[(tc-result: (Poly-names: _ (Function: (list (arr: doms rngs rests drests _ _) ..1))))
(apply-error/poly doms rests drests arg-tys tail-ty tail-bound)])]
(tc-error/expr #:return (ret (Un))
(string-append
"Bad arguments to polymorphic function in apply:~n"
(domain-mismatches f-ty doms rests drests arg-tys tail-ty tail-bound)))])]
;; the actual work, when we have a * function and a list final argument
[(and (car rests*)
(not tail-bound)
@ -300,7 +255,10 @@
(cond [(null? doms*)
(match f-ty
[(tc-result: (PolyDots-names: _ (Function: (list (arr: doms rngs rests drests _ _) ..1))))
(apply-error/poly doms rests drests arg-tys tail-ty tail-bound)])]
(tc-error/expr #:return (ret (Un))
(string-append
"Bad arguments to polymorphic function in apply:~n"
(domain-mismatches f-ty doms rests drests arg-tys tail-ty tail-bound)))])]
;; the actual work, when we have a * function and a list final argument
[(and (car rests*)
(not tail-bound)
@ -387,7 +345,7 @@
[_ (tc-error/expr #:return (ret (Un))
"Wrong number of arguments to parameter - expected 0 or 1, got ~a"
(length argtypes))])]
[(tc-result: (Function: (list (arr: doms rngs rests #f latent-thn-effs latent-els-effs) ..1)) thn-eff els-eff)
[(tc-result: (and t (Function: (list (arr: doms rngs rests (and drests #f) latent-thn-effs latent-els-effs) ..1))) thn-eff els-eff)
(if (= 1 (length doms))
(let-values ([(thn-eff els-eff)
(tc-args argtypes arg-thn-effs arg-els-effs (car doms) (car rests)
@ -401,16 +359,15 @@
(cond [(null? doms*)
(tc-error/expr
#:return (ret (Un))
"no function domain matched - domains were:~n~a~narguments were ~a"
(stringify
(for/list ([d doms] [r rests])
(format "~a ~a*"(stringify d) r))
"\n")
argtypes)]
(string-append "No function domains matched in function application:"
(domain-mismatches t doms rests drests argtypes #f #f)))]
[(subtypes/varargs argtypes (car doms*) (car rests*)) (ret (car rngs))]
[else (loop (cdr doms*) (cdr rngs) (cdr rests*))])))]
[(and rft (tc-result: (or (Poly: vars (Function: (list (arr: doms rngs #f #f thn-effs els-effs) ...)))
(PolyDots: (list vars ... _) (Function: (list (arr: doms rngs #f #f thn-effs els-effs) ...))))))
[(and rft (tc-result: (and t
(or (Poly: vars
(Function: (list (arr: doms rngs #f #f thn-effs els-effs) ...)))
(PolyDots: (list vars ... _)
(Function: (list (arr: doms rngs #f #f thn-effs els-effs) ...)))))))
;(printf "Typechecking poly app~nftype: ~a~n" ftype)
;(printf "ftype again: ~a~n" ftype)
;(printf "resolved ftype: ~a : ~a~n" (equal? rft ftype) rft)
@ -421,14 +378,17 @@
argtypes)
(let loop ([doms* doms] [rngs* rngs])
(cond [(null? doms*)
(match-let ([(tc-result: (Poly-names: msg-vars (Function: (list (arr: msg-doms msg-rngs #f #f _ _) ...)))) ftype])
(if (= 1 (length doms))
(tc-error/expr #:return (ret (Un))
"Polymorphic function could not be applied to arguments:~nExpected: ~a ~nActual: ~a"
(stringify (car msg-doms)) (stringify argtypes))
(tc-error/expr #:return (ret (Un))
"no polymorphic function domain matched - possible domains were: ~n~a~narguments were: ~n~a"
(stringify (map stringify msg-doms) "\n") (stringify argtypes))))]
(match t
[(Poly-names: msg-vars (Function: (list (arr: msg-doms msg-rngs msg-rests msg-drests _ _) ...)))
(tc-error/expr #:return (ret (Un))
(string-append "Polymorphic function over ~a could not be applied to arguments:~n"
(domain-mismatches t msg-doms msg-rests msg-drests argtypes #f #f))
(stringify msg-vars))]
[(PolyDots-names: msg-vars (Function: (list (arr: msg-doms msg-rngs msg-rests msg-drests _ _) ...)))
(tc-error/expr #:return (ret (Un))
(string-append "Polymorphic function over ~a ... could not be applied to arguments:~n"
(domain-mismatches t msg-doms msg-rests msg-drests argtypes #f #f))
(stringify msg-vars))])]
[(and (= (length (car doms*))
(length argtypes))
(infer (fv/list (cons (car rngs*) (car doms*))) argtypes (car doms*) (car rngs*) expected))
@ -455,8 +415,9 @@
)]|#
[else (loop (cdr doms*) (cdr rngs*))]))]
;; polymorphic varargs
[(tc-result: (or (Poly: vars (Function: (list (arr: dom rng rest #f thn-eff els-eff))))
(PolyDots: (list vars ... _) (Function: (list (arr: dom rng rest #f thn-eff els-eff))))))
[(tc-result: (and t
(or (Poly: vars (Function: (list (arr: dom rng rest #f thn-eff els-eff))))
(PolyDots: (list vars ... _) (Function: (list (arr: dom rng rest #f thn-eff els-eff)))))))
(for-each (lambda (x) (unless (not (Poly? x))
(tc-error "Polymorphic argument ~a to polymorphic function not allowed" x)))
argtypes)
@ -474,8 +435,9 @@
(int-err "Inconsistent substitution - arguments not subtypes"))
(ret (subst-all substitution rng)))]
[else (tc-error/expr #:return (ret (Un))
"no polymorphic function domain matched - domain was: ~a rest type was: ~a arguments were ~a"
(stringify dom) rest (stringify argtypes))]))]
(string-append
"No polymorphic function domain matched in function application:~n"
(domain-mismatches t (list dom) (list rest) (list #f) argtypes #f #f)))]))]
;; polymorphic ... type
[(tc-result: (and t (PolyDots: (and vars (list fixed-vars ... dotted-var))
(Function: (list (arr: dom rng #f (cons dty dbound) thn-eff els-eff))))))
@ -498,9 +460,8 @@
(Function: (list (arr: dom rng #f (cons dty dbound) thn-eff els-eff))))
(tc-error/expr #:return (ret (Un))
(string-append
"no polymorphic function domain matched -~n"
"domain was: ~a ~ndotted rest type was: ~a ... ~a~narguments were ~a")
(stringify dom) dty dbound (stringify argtypes))])]))]
"No polymorphic function domain matched in function application:~n"
(domain-mismatches t (list dom) (list #f) (list (cons dty dbound)) argtypes #f #f)))])]))]
[(tc-result: (Poly: vars (Function: (list (arr: doms rngs rests #f thn-effs els-effs) ...))))
(tc-error/expr #:return (ret (Un)) "polymorphic vararg case-lambda application not yet supported")]
[(tc-result: (Poly: vars (Function: (list (arr: doms rngs #f drests thn-effs els-effs) ...))))
@ -510,7 +471,8 @@
(match-let ([(list (tc-result: ts) ...) (map (lambda (f) (outer-loop
(ret f e1 e2) argtypes arg-thn-effs arg-els-effs args)) fs)])
(ret (apply Un ts)))]
[(tc-result: f-ty _ _) (tc-error/expr #:return (ret (Un)) "Cannot apply expression of type ~a, since it is not a function type" f-ty)]))))
[(tc-result: f-ty _ _) (tc-error/expr #:return (ret (Un))
"Cannot apply expression of type ~a, since it is not a function type" f-ty)]))))
;(trace tc/funapp)

View File

@ -49,9 +49,9 @@
(map (lambda (e) (sub-eff sb e)) els-eff)))])
target))
;; substitute-dots : Listof[Type] Name Type -> Type
(define (substitute-dots images name target)
(define (sb t) (substitute-dots images name t))
;; substitute-dots : Listof[Type] Option[type] Name Type -> Type
(define (substitute-dots images rimage name target)
(define (sb t) (substitute-dots images rimage name t))
(if (hash-ref (free-vars* target) name #f)
(type-case sb target
[#:arr dom rng rest drest thn-eff els-eff
@ -63,7 +63,7 @@
(let ([expanded (sb (car drest))])
(map (lambda (img) (substitute img name expanded)) images)))
(sb rng)
#f
rimage
#f
(map (lambda (e) (sub-eff sb e)) thn-eff)
(map (lambda (e) (sub-eff sb e)) els-eff))
@ -102,10 +102,8 @@
(define (subst-all s t)
(for/fold ([t t]) ([e s])
(match e
[(list v (list imgs ...) #f)
(substitute-dots imgs v t)]
[(list v (list ts) starred)
(int-err "subst-all: nyi")]
[(list v (list imgs ...) starred)
(substitute-dots imgs starred v t)]
[(list v img)
(substitute img v t)])))
@ -129,7 +127,7 @@
(let* ([fixed-tys (take types (length fixed))]
[rest-tys (drop types (length fixed))]
[body* (subst-all (map list fixed fixed-tys) body)])
(substitute-dots rest-tys dotted body*))]
(substitute-dots rest-tys #f dotted body*))]
[_ (int-err "instantiate-poly: requires Poly type, got ~a" t)]))
(define (instantiate-poly-dotted t types image var)