Skip to content

#require broken when accessing optional property #623

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

Closed
macguru opened this issue Aug 20, 2024 · 1 comment · Fixed by #625
Closed

#require broken when accessing optional property #623

macguru opened this issue Aug 20, 2024 · 1 comment · Fixed by #625
Labels
bug 🪲 Something isn't working

Comments

@macguru
Copy link

macguru commented Aug 20, 2024

Description

The following code does not compile currently. It produces an incorrect warning and an error inside the #expect macro compilation:

protocol MyType {
    func function() -> Something
}

protocol Something {
    var optional: Any? { get }
}

@MainActor @Test func mainExample() throws {
    let object: MyType?
    _ = try #require(object?.function().optional) // Warning: No calls to throwing functions occur within 'try' expression
    // Error: Value of optional type '(any Something)?' must be unwrapped to a value of type 'any Something'
}

As far as my testing goes, this needs a chaining of three things inside the #require:

  • an optional base value
  • a function returning a non-optional value (which is transitively optional, because of the base)
  • an optional property defined on the function's return value

I tried to be general here, but a common scenario is some object that has a function like makeArray() -> [Int] which is then accessed using first (e.g because we know there's just one element in this particular situation).

Expected behavior

The code should compile. The workaround is to split this into two expectations at any point in the chain. For example like so:

@MainActor @Test func mainExample() throws {
    let object: MyType?
    let some = try #require(object?.function())
    _ = try #require(some.optional)
}

Actual behavior

No response

Steps to reproduce

No response

swift-testing version/commit hash

Xcode 16 beta 5

Swift & OS version (output of swift --version ; uname -a)

swift-driver version: 1.113 Apple Swift version 6.0 (swiftlang-6.0.0.7.6 clang-1600.0.24.1)
Target: arm64-apple-macosx15.0
Darwin Mac.localdomain 24.0.0 Darwin Kernel Version 24.0.0: Wed Aug 7 03:08:56 PDT 2024; root:xnu-11215.1.9~22/RELEASE_ARM64_T6020 arm64

@macguru macguru added the bug 🪲 Something isn't working label Aug 20, 2024
@grynspan
Copy link
Contributor

_exprFromOptionalChainedExpr() is supposed to handle this case, but it's possible swift-syntax has changed in a way that's broken our code.

grynspan added a commit that referenced this issue Aug 21, 2024
This PR generalizes the optional chaining detection used in the implementation
of unwrapping `#require()` such that it works with more than just member access
expressions.

Resolves #623.
grynspan added a commit that referenced this issue Aug 26, 2024
This PR generalizes the optional chaining detection used in the implementation
of unwrapping `#require()` such that it works with more than just member access
expressions.

Resolves #623.
grynspan added a commit that referenced this issue Aug 27, 2024
This PR generalizes the optional chaining detection used in the
implementation of unwrapping `#require()` such that it works with more
than just member access expressions.

Resolves #623.

### Checklist:

- [x] Code and documentation should follow the style of the [Style
Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md).
- [x] If public symbols are renamed or modified, DocC references should
be updated.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🪲 Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants