diff --git a/default-recommendations/let-binding-suggestions-test.rkt b/default-recommendations/let-binding-suggestions-test.rkt index 65839b7..254041b 100644 --- a/default-recommendations/let-binding-suggestions-test.rkt +++ b/default-recommendations/let-binding-suggestions-test.rkt @@ -235,6 +235,19 @@ test: "self-shadowing let*-values binding clause isn't refactorable" ------------------------------ +test: "let binding that only appears self shadowing before expansion (issue #230)" +------------------------------ +(define (f b) + (let ([x (let ([x 1]) (+ x 1))]) + (+ x 1))) +------------------------------ +------------------------------ +(define (f b) + (define x (let ([x 1]) (+ x 1))) + (+ x 1)) +------------------------------ + + test: "let* with later right-hand-sides referring to earlier bindings is refactorable" ------------------------------ (define (f a) diff --git a/default-recommendations/private/let-binding.rkt b/default-recommendations/private/let-binding.rkt index 1634a8a..c36c956 100644 --- a/default-recommendations/private/let-binding.rkt +++ b/default-recommendations/private/let-binding.rkt @@ -52,13 +52,14 @@ (pattern [all-ids:id-list rhs:expr] #:do [(log-resyntax-debug - "refactorable-let-expression: checking binding-clause not self shadowing: ~a" + "refactorable-let-expression: checking binding-clause not self-shadowing: ~a" this-syntax)] #:when (for*/and ([rhs-free-id (in-free-id-set (syntax-free-identifiers (attribute rhs)))] [id (in-list (attribute all-ids.id))]) - (log-resyntax-debug "refactorable-let-expression: checking identifier not shadowed: ~a" - rhs-free-id) - (identifier-binding-unchanged-in-context? rhs-free-id id)) + (log-resyntax-debug + "refactorable-let-expression: checking identifier ~a not shadowed by ~a" + rhs-free-id id) + (identifier-would-self-shadow? id rhs-free-id #:full-right-hand-side (attribute rhs))) #:cut #:with (id ...) (attribute all-ids.id) #:with definition @@ -107,6 +108,12 @@ #:original #,this-syntax))) + +(define (identifier-would-self-shadow? id rhs-id #:full-right-hand-side rhs) + (or (identifier-binding-unchanged-in-context? rhs-id id) + (not (free-identifier=? rhs-id (identifier-in-context rhs-id rhs))))) + + (define (identifier-binding-unchanged-in-context? id context) (define add-context (make-syntax-delta-introducer context #false)) (free-identifier=? id (add-context id)))