When I was studying the generated assembly from Swift compiler, I found that some structs are being copied on stack before the equality check. I am having a hard time reproducing it, sorry for not providing with a demo at this time.
The affected struct does not implement ==
, so the compiler synthesizes one. I was wondering if playing with the ownership modifier on the parameters would help diagnose the problem (swift/lib/Sema/DerivedConformanceEquatableHashable.cpp
):
auto getParamDecl = [&](StringRef s) -> ParamDecl * {
auto *param = new (C) ParamDecl(SourceLoc(),
SourceLoc(), Identifier(), SourceLoc(),
C.getIdentifier(s), parentDC);
- param->setSpecifier(ParamSpecifier::Default);
+ param->setSpecifier(ParamSpecifier::Borrowing);
param->setInterfaceType(selfIfaceTy);
param->setImplicit();
return param;
};
... then it refuses to bootstrap the compiler.
[14/305][ 4%][7.623s] Building swift module _CompilerRegexParser
FAILED: bootstrapping1/SwiftCompilerSources/_CompilerRegexParser.o <unknown>:0: warning: the '-enable-experimental-cxx-interop' flag is deprecated; please pass '-cxx-interoperability-mode=' instead
<unknown>:0: note: Swift will maintain source compatibility for imported APIs based on the selected compatibility mode, so updating the Swift compiler will not change how APIs are imported
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'a' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
<unknown>:0: error: 'b' is borrowed and cannot be consumed
<unknown>:0: note: consumed here
[15/305][ 4%][11.203s] Building swift module Basic
<unknown>:0: warning: the '-enable-experimental-cxx-interop' flag is deprecated; please pass '-cxx-interoperability-mode=' instead
<unknown>:0: note: Swift will maintain source compatibility for imported APIs based on the selected compatibility mode, so updating the Swift compiler will not change how APIs are imported
ninja: build stopped: subcommand failed.
ERROR: command terminated with a non-zero exit status 1, aborting
It seems that the synthesized comparison function is performing consuming operations (which should be unexpected?) on the arguments which incurs the copy I found in the production code.