Skip to content
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

compiler doesn't flag multiple calls to consuming func #71306

Closed
eecs441staff opened this issue Feb 1, 2024 · 2 comments
Closed

compiler doesn't flag multiple calls to consuming func #71306

eecs441staff opened this issue Feb 1, 2024 · 2 comments

Comments

@eecs441staff
Copy link

eecs441staff commented Feb 1, 2024

Description

When struct S below is declared ~Copyable, Xcode 15.3 beta tags its instance (s) as being consumed more than once. But if S is declared without ~Copyable, Xcode doesn't give an error message and the consuming function value() can be called more than once on the instance.

Reproduction

struct S: ~Copyable {
    let v = "hi"
    consuming func value() -> String { return v }
}

func f() {
    let s = S()   // Xcode 15.3 beta error message: 's' consumed more than once
    print(s.value())
    print(s.value())
}

f()

but:

struct Sc  { // or class
    let v = "hi"
    consuming func value() -> String { return v }
}

func g() {
    let s = Sc()             // no error message
    print(s.value())
    print(s.value())      // prints out a second time
}

g()

Expected behavior

Xcode gives the same error message in both cases and the second call to s.value() an error (as per SE-0377).

Environment

Xcode 15.3 beta on macOS 14.4 beta CLI.

Additional information

No response

@eecs441staff eecs441staff added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Feb 1, 2024
@tbkka tbkka removed bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Feb 1, 2024
@tbkka
Copy link
Contributor

tbkka commented Feb 1, 2024

This is expected. The compiler is allowed to freely make copies of a Copyable type. I've added comments below to clarify how this works in this case:

func g() {
    let s = Sc()
    // Because `s` will be used again, the compiler will actually
    // create a copy for this first call.  That copy gets consumed here:
    print(s.value())
    // The original value can then be consumed here:
    print(s.value())
}

@eecs441staff
Copy link
Author

Thanks. I realized a copy has been made after posting the issue. The following prevents the compiler from making a copy of s:

func h(_ s: consuming Sc) {  // error: s consumed more than once
    print(s.value())   // consumed here
    print(s.value())   // consumed again here
}
h(Sc())

Perhaps there Is a compiler flag/Xcode setting that gives a warning when a copy is made for a value about to be consumed? Thanks.

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

No branches or pull requests

2 participants