From 8c9eeb2edd78efb0e6560f3799cc6e857c66a4b4 Mon Sep 17 00:00:00 2001 From: Holly Borla Date: Wed, 20 Dec 2023 15:53:02 -0800 Subject: [PATCH] [ASTScope] In the `isBeforeInSource` predicate, use the end location of the original source location of a macro expansion when walking up the ancestor list. The original source range of a macro expansion buffer contains the entire range of the code that is replaced by the expansion. In some cases, the original code is type checked, so ASTScope needs to represent both the original code and the macro-expanded code in the scope tree. For accessor macros, the original code -- the initializer expression of the property -- is type checked, but not before macro expansion, so unqualified lookup must deal with the scope tree for the initializer and the expanded accessors. The accessors are inserted in the tree after the initializer scope, but the `isBeforeInSource` was using the start location of the original source range for macro expansions, so the accessor scopes were incorrectly considered to be ordered before a source location in the initializer expression, which caused unqualified lookup of local variables within the initializer to fail. --- lib/Basic/SourceLoc.cpp | 4 ++-- test/stdlib/Observation/Observable.swift | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/Basic/SourceLoc.cpp b/lib/Basic/SourceLoc.cpp index 4649e58dfddab..5af45683505f9 100644 --- a/lib/Basic/SourceLoc.cpp +++ b/lib/Basic/SourceLoc.cpp @@ -797,11 +797,11 @@ static bool isBeforeInSource( SourceLoc firstLocInLCA = firstMismatch == firstAncestors.end() ? firstLoc : sourceMgr.getGeneratedSourceInfo(*firstMismatch) - ->originalSourceRange.getStart(); + ->originalSourceRange.getEnd(); SourceLoc secondLocInLCA = secondMismatch == secondAncestors.end() ? secondLoc : sourceMgr.getGeneratedSourceInfo(*secondMismatch) - ->originalSourceRange.getStart(); + ->originalSourceRange.getEnd(); return sourceMgr.isBeforeInBuffer(firstLocInLCA, secondLocInLCA) || (allowEqual && firstLocInLCA == secondLocInLCA); } diff --git a/test/stdlib/Observation/Observable.swift b/test/stdlib/Observation/Observable.swift index 50c140f15640e..4cd0f2f9dca0e 100644 --- a/test/stdlib/Observation/Observable.swift +++ b/test/stdlib/Observation/Observable.swift @@ -215,6 +215,16 @@ class RecursiveOuter { class GuardedAvailability { } +@Observable class TestASTScopeLCA { + // Make sure ASTScope unqualified lookup can find local variables + // inside initial values with closures when accessor macros are + // involved. + var state : Bool = { + let value = true + return value + }() +} + @main struct Validator { @MainActor