diff --git a/compile.rkt b/compile.rkt index 9e7b1c2..7ea7f1a 100644 --- a/compile.rkt +++ b/compile.rkt @@ -712,7 +712,17 @@ (values (reverse constants) rands)))]))) +(define-predicate natural? Natural) +(: arity-matches? (Arity Natural -> Boolean)) +(define (arity-matches? an-arity n) + (cond + [(natural? an-arity) + (= an-arity n)] + [(ArityAtLeast? an-arity) + (>= n (ArityAtLeast-value an-arity))] + [else + (error 'fixme)])) (: compile-statically-known-lam-application @@ -721,8 +731,8 @@ (define (compile-statically-known-lam-application static-knowledge exp cenv target linkage) ;; FIXME: this needs to be turned into a runtime error, not a compile-time error, to preserve ;; Racket semantics. - (unless (= (length (App-operands exp)) - (StaticallyKnownLam-arity static-knowledge)) + (unless (arity-matches? (StaticallyKnownLam-arity static-knowledge) + (length (App-operands exp))) (error 'arity-mismatch "~s expected ~s arguments, but received ~s" (StaticallyKnownLam-name static-knowledge) (StaticallyKnownLam-arity static-knowledge) @@ -1009,7 +1019,9 @@ [(Lam? exp) (make-StaticallyKnownLam (Lam-name exp) (Lam-entry-label exp) - (Lam-num-parameters exp))] + (if (Lam-rest? exp) + (make-ArityAtLeast (Lam-num-parameters exp)) + (Lam-num-parameters exp)))] [(and (LocalRef? exp) (not (LocalRef-unbox? exp))) (let ([entry (list-ref cenv (LocalRef-depth exp))]) diff --git a/il-structs.rkt b/il-structs.rkt index 72ec657..ee5623c 100644 --- a/il-structs.rkt +++ b/il-structs.rkt @@ -364,7 +364,7 @@ ;; statically known things, to generate better code. (define-struct: StaticallyKnownLam ([name : (U Symbol False)] [entry-point : Symbol] - [arity : Natural]) #:transparent) + [arity : Arity]) #:transparent) (define-type CompileTimeEnvironmentEntry (U '? ;; no knowledge