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

Accessing computed property sometimes causes unexpected consume of borrowed value #73292

Open
ORBAT opened this issue Apr 26, 2024 · 2 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. ownership Feature: Ownership modifiers and semantics

Comments

@ORBAT
Copy link

ORBAT commented Apr 26, 2024

Description

I've found two cases of values getting consumed when reading computed properties, and they seem like they're not correct behavior based on my reading of SE-0377 and SE-0390.

  • case 1 is a method with a borrowed some Proto parameter calling a getter on the borrowed value
  • case 2 is a borrowing method in a struct A<T> that has a stored property v: T

Reproduction

Case 1: borrowed parameter with opaque type

struct Example {
  protocol Proto {
    // doesn't work with { borrowing get } either
    var count: Int { get }
  }

  func takeProto(_ p: borrowing some Proto) -> Int {
    p.count
  }
}

Result is

error: 'p' is borrowed and cannot be consumed
  func takeProto(_ p: borrowing some Proto) -> Int {
                   ^

note: consumed here
    p.count
      ^

Interestingly using p: borrowing any Proto leads to a different error. Should I make another issue for this as the error suggests?

error: usage of no-implicit-copy value that the compiler can't verify. 
This is a compiler bug. Please file a bug with a small example of the bug

Case 2: borrowing method in a generic struct with stored property of generic type

struct Broken<Base> {
  let base: Base
  var compd: Int { 666 }
  borrowing func doSomething() -> Int { compd }
}
error: 'self' is borrowed and cannot be consumed
  borrowing func doSomething() -> Int { compd }
                 ^
note: consumed here
  borrowing func doSomething() -> Int { compd }
                                        ^

Expected behavior

Case 1

Expected no error

Case 2

Expected no error, like in the following cases that compile fine:

class Class<Base> {
  let base: Base
  var computed: Int { 666 } 

  borrowing func doSomething() -> Int { computed }

  init(base: Base) {
    self.base = base
  }
}

struct NoProp<Base> {
  var computed: Int { 666 }
  borrowing func doSomething() -> Int { computed }
}

struct NotGeneric {
  var computed: Int { 666 }
  borrowing func doSomething() -> Int { computed }
}

Environment

swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0

Additional information

Forum post

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

tbkka commented Apr 26, 2024

CC: @atrick @jckarter

@hborla hborla added ownership Feature: Ownership modifiers and semantics and removed triage needed This issue needs more specific labels labels Apr 27, 2024
@ORBAT
Copy link
Author

ORBAT commented May 14, 2024

I noticed that the first example's takeProto compiles fine on 5.10 if I (ab)use a closure and do { p.count }() instead of p.count:

struct Example {
  protocol Proto {
    var count: Int { get }
  }

  func takeProto(_ p: borrowing some Proto) -> Int {
    { p.count }()
  }
}

However, when I tried the same trick with the latest 6.0-dev (swift-6.0-DEVELOPMENT-SNAPSHOT-2024-04-30-a / org.swift.600202404301a), the compiler crashes with an assertion failure Assertion failed: (fnConv.getSILType(Params[i + firstCapture], typeExpansionContext) == captures[i].getType() && "capture doesn't match param type"), function claimCaptureParams, file SILGenApply.cpp, line 4803. The same happens with the second example if I use { compd }(). Using -swift-version 6 makes no difference.

Full swiftc output

Apple Swift version 6.0-dev (LLVM 7b8e6346027d2b1, Swift 763421cee31dc8f)
Target: arm64-apple-macosx14.0
/Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-04-30-a.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file Struct+Main.swift -target arm64-apple-macosx14.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk -color-diagnostics -empty-abi-descriptor -resource-dir /Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-04-30-a.xctoolchain/usr/lib/swift -Xcc -v -module-name main -target-sdk-version 14.4 -target-sdk-name macosx14.4 -external-plugin-path '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server' -external-plugin-path '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server' -plugin-path /Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-04-30-a.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-04-30-a.xctoolchain/usr/local/lib/swift/host/plugins -o /var/folders/b1/zckxsnfj1gg94dr8z6qm3d9w0000gp/T/TemporaryDirectory.v72Ypd/Struct+Main-1.o
error: compile command failed due to signal 6 (use -v to see invocation)
Apple clang version 17.0.0 (https://github.com/apple/llvm-project.git 7b8e6346027d2b1b50905bbac557e4c35f84bec0)
Target: arm64-apple-macosx14.0
Thread model: posix
InstalledDir: /Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-04-30-a.xctoolchain/usr/bin
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk/usr/local/include"
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-04-30-a.xctoolchain/usr/lib/swift
 /Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-04-30-a.xctoolchain/usr/lib/swift/clang/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk/usr/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk/System/Library/Frameworks (framework directory)
End of search list.
Assertion failed: (fnConv.getSILType(Params[i + firstCapture], typeExpansionContext) == captures[i].getType() && "capture doesn't match param type"), function claimCaptureParams, file SILGenApply.cpp, line 4803.
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0.	Program arguments: /Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-04-30-a.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file Struct+Main.swift -target arm64-apple-macosx14.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk -color-diagnostics -empty-abi-descriptor -resource-dir /Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-04-30-a.xctoolchain/usr/lib/swift -Xcc -v -module-name main -target-sdk-version 14.4 -target-sdk-name macosx14.4 -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -plugin-path /Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-04-30-a.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-04-30-a.xctoolchain/usr/local/lib/swift/host/plugins -o /var/folders/b1/zckxsnfj1gg94dr8z6qm3d9w0000gp/T/TemporaryDirectory.v72Ypd/Struct+Main-1.o
1.	Apple Swift version 6.0-dev (LLVM 7b8e6346027d2b1, Swift 763421cee31dc8f)
2.	Compiling with effective version 5.10
3.	While evaluating request ASTLoweringRequest(Lowering AST to SIL for file "Struct+Main.swift")
4.	While silgen emitFunction SIL function "@$s4main7ExampleV9takeProtoySixAC0D0RzlF".
 for 'takeProto(_:)' (at Struct+Main.swift:7:3)
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  swift-frontend           0x00000001084693b4 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x0000000108467b80 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x00000001084699fc SignalHandler(int) + 304
3  libsystem_platform.dylib 0x0000000180bcf584 _sigtramp + 56
4  libsystem_pthread.dylib  0x0000000180b9ec20 pthread_kill + 288
5  libsystem_c.dylib        0x0000000180aaba20 abort + 180
6  libsystem_c.dylib        0x0000000180aaad10 err + 0
7  swift-frontend           0x000000010856b218 (anonymous namespace)::CallEmission::emitArgumentsForNormalApply(swift::Lowering::AbstractionPattern, swift::CanTypeWrapper<swift::SILFunctionType>, swift::ForeignInfo const&, llvm::SmallVectorImpl<swift::Lowering::ManagedValue>&, std::__1::optional<swift::SILLocation>&) (.cold.14) + 0
8  swift-frontend           0x0000000103631c64 (anonymous namespace)::CallEmission::emitArgumentsForNormalApply(swift::Lowering::AbstractionPattern, swift::CanTypeWrapper<swift::SILFunctionType>, swift::ForeignInfo const&, llvm::SmallVectorImpl<swift::Lowering::ManagedValue>&, std::__1::optional<swift::SILLocation>&) + 1568
9  swift-frontend           0x000000010361d4b4 (anonymous namespace)::CallEmission::apply(swift::Lowering::SGFContext) + 1800
10 swift-frontend           0x000000010361bb48 swift::Lowering::SILGenFunction::emitApplyExpr(swift::ApplyExpr*, swift::Lowering::SGFContext) + 2028
11 swift-frontend           0x0000000103672ca0 swift::Lowering::SILGenFunction::emitRValue(swift::Expr*, swift::Lowering::SGFContext) + 40
12 swift-frontend           0x00000001036f9e20 swift::Lowering::SILGenFunction::emitReturnExpr(swift::SILLocation, swift::Expr*) + 496
13 swift-frontend           0x00000001036f8110 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 6568
14 swift-frontend           0x00000001036f78d0 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4456
15 swift-frontend           0x00000001036f675c swift::Lowering::SILGenFunction::emitStmt(swift::Stmt*) + 24
16 swift-frontend           0x0000000103697750 swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 432
17 swift-frontend           0x0000000103609ed0 swift::Lowering::SILGenModule::emitFunctionDefinition(swift::SILDeclRef, swift::SILFunction*) + 6324
18 swift-frontend           0x000000010360ad14 swift::Lowering::SILGenModule::emitOrDelayFunction(swift::SILDeclRef) + 252
19 swift-frontend           0x00000001036085e4 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 196
20 swift-frontend           0x000000010370b468 (anonymous namespace)::SILGenType::visitFuncDecl(swift::FuncDecl*) + 28
21 swift-frontend           0x00000001037083b4 (anonymous namespace)::SILGenType::emitType() + 276
22 swift-frontend           0x0000000103708294 swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 24
23 swift-frontend           0x000000010360d654 swift::ASTLoweringRequest::evaluate(swift::Evaluator&, swift::ASTLoweringDescriptor) const + 880
24 swift-frontend           0x00000001036f61b4 swift::SimpleRequest<swift::ASTLoweringRequest, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>> (swift::ASTLoweringDescriptor), (swift::RequestFlags)9>::evaluateRequest(swift::ASTLoweringRequest const&, swift::Evaluator&) + 148
25 swift-frontend           0x0000000103612f48 swift::ASTLoweringRequest::OutputType swift::Evaluator::getResultUncached<swift::ASTLoweringRequest, swift::ASTLoweringRequest::OutputType swift::evaluateOrFatal<swift::ASTLoweringRequest>(swift::Evaluator&, swift::ASTLoweringRequest)::'lambda'()>(swift::ASTLoweringRequest const&, swift::ASTLoweringRequest::OutputType swift::evaluateOrFatal<swift::ASTLoweringRequest>(swift::Evaluator&, swift::ASTLoweringRequest)::'lambda'()) + 340
26 swift-frontend           0x000000010360df58 swift::performASTLowering(swift::FileUnit&, swift::Lowering::TypeConverter&, swift::SILOptions const&, swift::IRGenOptions const*) + 96
27 swift-frontend           0x0000000102ffbb8c swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 568
28 swift-frontend           0x000000010300cdfc withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 160
29 swift-frontend           0x0000000102ffe1c8 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 708
30 swift-frontend           0x0000000102ffd134 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2368
31 swift-frontend           0x0000000102e1792c swift::mainEntry(int, char const**) + 3096
32 dyld                     0x00000001808160e0 start + 2360

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. ownership Feature: Ownership modifiers and semantics
Projects
None yet
Development

No branches or pull requests

3 participants