Skip to content

Unexpected compiler diagnostics when checking async Bools with Swift Testing’s #expect #81765

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

Open
yakovmanshin opened this issue May 24, 2025 · 0 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels

Comments

@yakovmanshin
Copy link

Description

When Swift Testing’s #expect macro is used to check actors’ Bool values (accessed asynchronously), seemingly equivalent expressions (isEnabled vs. isEnabled == true) result in unexpected—inconsistent, misleading, or missing—compiler diagnostics.

Reproduction

import Testing

actor Service {
    var isEnabled = true
}

struct ServiceTests {
    
    let service = Service()
    
    @Test func isEnabled1() async {
        // No inline warnings or errors;
        // Errors on build: “(…) can not be referenced from a nonisolated context”:
        #expect(service.isEnabled)
        #expect(!service.isEnabled)
        
        // These build fine (no warnings or errors, inline or build-time):
        #expect(await service.isEnabled)
        #expect(await !service.isEnabled)
        #expect(!(await service.isEnabled))
        
        // Misleading inline warnings: “No 'async' operations occur within 'await' expression”;
        // Errors on build: “(…) can not be referenced from a nonisolated context”:
        await #expect(service.isEnabled)
        await #expect(!service.isEnabled)
    }
    
    // With explicit equality checks, the compiler produces more reasonable diagnostics:
    @Test func isEnabled2() async {
        // Inline errors “Expression is 'async' (…)"; suggest fix-its:
        #expect(service.isEnabled == true)
        #expect(service.isEnabled != true)
        #expect(service.isEnabled == false)
        
        // The fix-its hoist `await`s, resulting in:
        await #expect(service.isEnabled == true)
        await #expect(service.isEnabled != true)
        await #expect(service.isEnabled == false)
        
        // But these work too:
        #expect(await service.isEnabled == true)
        #expect((await service.isEnabled) == true)
        #expect(await service.isEnabled != true)
        #expect((await service.isEnabled) != true)
        #expect(await service.isEnabled == false)
        #expect((await service.isEnabled) == false)
    }
    
}

Expected behavior

The plain isEnabled checks produce the same (correct) diagnostics as the isEnabled == true expressions.

Environment

  • macOS 15.5 (24F74)
  • Xcode 16.4 (16F6)
  • Swift 6.1
swift-driver version: 1.120.5 Apple Swift version 6.1 (swiftlang-6.1.0.110.21 clang-1700.0.13.3)
Target: x86_64-apple-macosx15.0

Additional information

No response

@yakovmanshin yakovmanshin added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels May 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels
Projects
None yet
Development

No branches or pull requests

1 participant