Skip to content

Add a test for property access on ~Escapable types#1155

Open
natecook1000 wants to merge 61 commits intoswiftlang:jgrynspan/162-redesign-value-capturefrom
natecook1000:property-of-nonescapable-test
Open

Add a test for property access on ~Escapable types#1155
natecook1000 wants to merge 61 commits intoswiftlang:jgrynspan/162-redesign-value-capturefrom
natecook1000:property-of-nonescapable-test

Conversation

@natecook1000
Copy link
Member

This tests using a ~Escapable type as the LHS of a property access inside the #expect and #require macros. A ~Escapable return value from #require is unsupported.

Checklist:

  • Code and documentation should follow the style of the Style Guide.
  • If public symbols are renamed or modified, DocC references should be updated.

grynspan and others added 8 commits May 23, 2025 01:36
This PR completely rewrites how we capture expectation conditions. For example, given the
following expectation:

```swift
```

We currently detect that there is a binary operation and emit code that calls the binary
operator as a closure and passes the left-hand value and right-hand value, then checks
that the result of the operation is `true`.

This is sufficient for simpler expressions like that one, but more complex ones (including
any that involve `try` or `await` keywords) cannot be expanded correctly. With this PR,
such expressions _can_ generally be expanded correctly.

The change involves rewriting the macro condition as a closure to which is passed a local,
mutable "context" value. Subexpressions of the condition expression are then rewritten by
walking the syntax tree of the expression (using typical swift-syntax API) and replacing
them with calls into the context value that pass in the value and related state.

If the expectation ultimately fails, the collected data is transformed into an instance of
the SPI type `Expression` that contains the source code of the expression and interesting
subexpressions as well as the runtime values of those subexpressions.

Nodes in the syntax tree are identified by a unique ID which is composed of the
swift-syntax ID for that node as well as all its parent nodes in a compact bitmask format.
These IDs can be transformed into graph/trie key paths when expression/subexpression
relationships need to be reconstructed on failure, meaning that a single rewritten node
doesn't otherwise need to know its "place" in the overall expression.

There remain a few caveats (that also generally affect the current implementation):

- Mutating member functions are syntactically indistinguishable from non-mutating ones and
  miscompile when rewritten;
- Expressions involving move-only types are also indistinguishable, but need lifetime
  management to be rewritten correctly; and
- Expressions where the `try` or `await` keyword is _outside_ the `#expect` macro cannot
  be expanded correctly because the macro cannot see those keywords during expansion.

The first issue might be resolvable in the future using pointer tricks, although I don't
hold a lot of hope for it. The second issue is probably resolved by non-escaping types.
The third issue is an area of active exploration for us and the macros/swift-syntax team.
This tests using a ~Escapable type as the LHS of a property access
inside the `#expect` and `#require` macros. A ~Escapable return value
from `#require` is unsupported.
@stmontgomery
Copy link
Contributor

@swift-ci please test

@stmontgomery stmontgomery added enhancement New feature or request macros 🔭 Related to Swift macros such as @Test or #expect labels Jun 13, 2025
@stmontgomery stmontgomery added this to the Swift 6.x milestone Jun 13, 2025
@grynspan
Copy link
Contributor

I believe this test is dependent on #840, right?

@natecook1000
Copy link
Member Author

Right! I believe it's aimed at that branch, not main. Should I direct it somewhere else?

@grynspan
Copy link
Contributor

grynspan commented Jul 9, 2025

Nope, just confirming the dependency is why the test failed. You could redirect the PR to merge to that branch, and then it would pass?

@grynspan
Copy link
Contributor

grynspan commented Jul 9, 2025

@swift-ci test

@grynspan grynspan requested a review from jerryjrchen as a code owner January 19, 2026 19:04
@grynspan grynspan force-pushed the jgrynspan/162-redesign-value-capture branch from 3ae7e90 to 9209cf3 Compare February 6, 2026 17:57
@grynspan grynspan force-pushed the jgrynspan/162-redesign-value-capture branch 3 times, most recently from 5d450c9 to c9d3cec Compare February 23, 2026 18:35
@grynspan grynspan force-pushed the jgrynspan/162-redesign-value-capture branch from dbcc432 to b369b13 Compare February 26, 2026 02:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request macros 🔭 Related to Swift macros such as @Test or #expect

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants