Skip to content

[SwiftLexicalLookup] New unqualified lookup implementation validation #77140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Dec 18, 2024

Conversation

MAJKFL
Copy link
Contributor

@MAJKFL MAJKFL commented Oct 21, 2024

This PR introduces a function used to validate output of SwiftLexicalLookup lookup against ASTScope unqualified lookup. It’s part of the GSoC project I worked on with @DougGregor. The goal is to be able to automatically compare outputs of the two implementations, run it for large amounts of source files and fix any discrepancies to bring the new implementation closer to the current one. To perform validation, use -enable-experimental-feature UnqualifiedLookupValidation.

Example output of a failed validation for a file from the Swift standard library:

-----> Lookup started at: 1706:7 ("debugPrint") finishInSequentialScope: false
     |           ASTScope           |      SwiftLexicalLookup
> ✅ |          k 1699:10           |          k 1699:10
> ✅ |          v 1699:13           |          v 1699:13
> ❌ |         first 1698:9         |         type 1690:18
> ❌ |        result 1697:9         |         self 1689:17
> ❌ |         type 1690:18         |         ↕️ V 1689:49
> ❌ |         self 1689:17         |         ↕️ K 1689:46
> ℹ️ | Omitted SwiftLexicalLookup name: Self 1683:1
> ❌ |          V 1689:49           |      Look memb: 1684:11
> ❌ |          K 1689:46           |            -----
> ℹ️ | Omitted ASTScope name: K 1689:46
> ℹ️ | Omitted ASTScope name: V 1689:49
> ❌ | End here: Look memb: 1684:11 |            -----

This PR depends on PR 2883 in swift-syntax that brings #if handling through SwiftIfConfig to SwiftLexicalLookup.

Copy link
Contributor

@slavapestov slavapestov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really excited about SwiftLexicalLookup, I just have some minor nitpicks

BridgedConsumedLookupResult(swift::Identifier name,
swift::SourceLoc sourceLoc,
SwiftInt flag
) : Name(BridgedIdentifier(name)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: we typically put the ) on the same line and : on the following. @gottesmm can also help you set up clang-format if you'd rather fix stylistic issues automatically

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for pointing this out! I manually run clang-format now for this part of the file. Is there maybe a way to automate this process and run with every commit or just run it on my changes?

if (auto *extDecl = dyn_cast<ExtensionDecl>(scopeDC)) {
recordedElements.push_back(BridgedConsumedLookupResult(
Identifier(), extDecl->getExtendedTypeRepr()->getLoc(),
0b10 + result));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the magic constant should be named, or you could use a bitfield or something

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good idea. I documented those on the Swift side, but forgot about explaining them here. I moved 0b10 to a constant shouldLookInMembers and also renamed result to endOfLookup.

} else if parent.is(FunctionDeclSyntax.self) || parent.is(SubscriptDeclSyntax.self)
|| result.scope.range.contains(lookupToken.position)
{
// If a result from function generic parameter clause or lookup started within it, reverse introduced names.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the old code has some funky behaviors :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we've encountered some really fun behavior of ASTScope when working on the library.

This particular case happens when looking up generic parameter from generic parameter clause which is part of a function or subscript or the lookup is started within the clause:

func foo<A, B: Int>(a: A, b: B) {
  print(a, b)
}

ASTScope for some reason decides to first introduce generic parameters in wrong order just to introduce them correctly right afterwards :). Interestingly, similar behavior doesn't happen inside nominal type declarations.

-----> Lookup started at: 2:3 ("print") finishInSequentialScope: false
     |           ASTScope           |      SwiftLexicalLookup      
> ✅ |            a 1:21            |            a 1:21            
> ✅ |            b 1:27            |            b 1:27            
> ✅ |            B 1:13            |           ↕️ B 1:13           
> ✅ |            A 1:10            |           ↕️ A 1:10           
> ℹ️ | Omitted ASTScope name: A 1:10
> ℹ️ | Omitted ASTScope name: B 1:13

With those comments, this validation function slowly becomes a documentation of "weird" ASTScope behavior. It might be necessary to revisit some of those heuristics in the future if it turns out there's a valid reason for this behavior and we should actually adjust SwiftLexicalLookup. That's why I tried to be more explicit in this part of the validation algorithm.

… in `LoggingASTScopeDeclConsumer`. Format `BridgedConsumedLookupResult`.
@MAJKFL MAJKFL requested a review from slavapestov October 23, 2024 10:39
@DougGregor
Copy link
Member

swiftlang/swift-syntax#2883

@swift-ci please build toolchain

@DougGregor
Copy link
Member

swiftlang/swift-syntax#2883

@swift-ci please smoke test

@MAJKFL
Copy link
Contributor Author

MAJKFL commented Nov 1, 2024

swiftlang/swift-syntax#2883

@swift-ci please build toolchain

@MAJKFL
Copy link
Contributor Author

MAJKFL commented Nov 13, 2024

@swift-ci Please test

@MAJKFL
Copy link
Contributor Author

MAJKFL commented Nov 13, 2024

@swift-ci Please smoke test

@MAJKFL
Copy link
Contributor Author

MAJKFL commented Nov 13, 2024

swiftlang/swift-syntax#2883

@swift-ci Please smoke test

@DougGregor
Copy link
Member

swiftlang/swift-syntax#2883

@swift-ci Please smoke test Windows

@MAJKFL
Copy link
Contributor Author

MAJKFL commented Nov 14, 2024

@swift-ci Please smoke test

@MAJKFL
Copy link
Contributor Author

MAJKFL commented Nov 14, 2024

@swift-ci Please smoke test Windows

@MAJKFL
Copy link
Contributor Author

MAJKFL commented Nov 15, 2024

@swift-ci Please smoke test

@DougGregor
Copy link
Member

@swift-ci please test Windows

Copy link
Member

@DougGregor DougGregor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is excellent. I have one request, though: can you add a test that demonstrates that this experimental mode is working? It doesn't have to be comprehensive, but it should have some nontrivial Swift code in it and use %target-typecheck-verify-swift -enable-experimental-feature UnqualifiedLookupValidation. That will make sure this functionality doesn't regress based on other changes to the compiler code base.

Over time, we can add this experimental feature to more places to improve our testing coverage.

@MAJKFL
Copy link
Contributor Author

MAJKFL commented Nov 26, 2024

@swift-ci Please smoke test

@MAJKFL
Copy link
Contributor Author

MAJKFL commented Dec 5, 2024

@swift-ci Please smoke test

@MAJKFL
Copy link
Contributor Author

MAJKFL commented Dec 13, 2024

@swift-ci Please smoke test

@MAJKFL MAJKFL merged commit 5dbe202 into swiftlang:main Dec 18, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants