diff --git a/pkgs/racket-pkgs/racket-test/tests/racket/letrec.rktl b/pkgs/racket-pkgs/racket-test/tests/racket/letrec.rktl index 24d51afaed..d23686c8d4 100644 --- a/pkgs/racket-pkgs/racket-test/tests/racket/letrec.rktl +++ b/pkgs/racket-pkgs/racket-test/tests/racket/letrec.rktl @@ -88,4 +88,11 @@ y) letrec-exn?) +(err/rt-test + (letrec ([a 1] + [b (set! a (lambda () c))] + [c (a)]) + c) + letrec-exn?) + (report-errs) diff --git a/racket/src/racket/src/letrec_check.c b/racket/src/racket/src/letrec_check.c index 6eeb084ff7..166862a7de 100644 --- a/racket/src/racket/src/letrec_check.c +++ b/racket/src/racket/src/letrec_check.c @@ -1319,13 +1319,19 @@ static Scheme_Object *letrec_check_set(Scheme_Object *o, Letrec_Check_Frame *fra Scheme_Object *uvars, Scheme_Object *pvars, Scheme_Object *pos) { Scheme_Set_Bang *sb; - Scheme_Object *val; + Scheme_Object *val, *rhs_uvars, *rhs_pvars, *rhs_pos; int position; sb = (Scheme_Set_Bang *)o; val = sb->val; - val = letrec_check_expr(val, frame, uvars, pvars, pos); + /* Treat `set!` as allowing the right-hand side to escape. (We + could do better if `sb->var` is a variable that we know about.) */ + rhs_uvars = merge_vars(uvars, pvars); + rhs_pvars = rem_vars(pvars); + rhs_pos = scheme_false; + + val = letrec_check_expr(val, frame, rhs_uvars, rhs_pvars, rhs_pos); sb->val = val; if (SAME_TYPE(SCHEME_TYPE(sb->var), scheme_local_type)) {