diff --git a/collects/tests/typed-racket/succeed/cyclic-list.rkt b/collects/tests/typed-racket/succeed/cyclic-list.rkt new file mode 100644 index 00000000..18e84f3f --- /dev/null +++ b/collects/tests/typed-racket/succeed/cyclic-list.rkt @@ -0,0 +1,8 @@ +#lang typed/racket + +(define-type CyclicSymbols (Rec X (Pair Symbol X))) + +(: mycar : (CyclicSymbols -> Symbol)) +(define (mycar lst) + (car lst)) + diff --git a/collects/typed-racket/types/match-expanders.rkt b/collects/typed-racket/types/match-expanders.rkt index 57ddb4d8..615b2f5c 100644 --- a/collects/typed-racket/types/match-expanders.rkt +++ b/collects/typed-racket/types/match-expanders.rkt @@ -7,6 +7,7 @@ racket/match (types resolve) (contract-req) + racket/set (for-syntax racket/base syntax/parse racket/list)) (provide Listof: List: MListof:) @@ -27,11 +28,13 @@ #'(app untuple (? values elem-pats))]))) (define (untuple t) - (match (resolve t) - [(Value: '()) null] - [(Pair: a b) (cond [(untuple b) => (lambda (l) (cons a l))] - [else #f])] - [_ #f])) + (let loop ((t t) (seen (set))) + (and (not (set-member? seen (Type-seq t))) + (match (resolve t) + [(Value: '()) null] + [(Pair: a b) (cond [(loop b (set-add seen (Type-seq t))) => (lambda (l) (cons a l))] + [else #f])] + [_ #f])))) (define-match-expander MListof: (lambda (stx)