Importing of r value references as values overrides other imports that should be imported using references in SR-12802

Hello,

I have been working on a PR to start the work on issue SR-12802: Disambiguate functions with lvalue and rvalue reference parameters in the same overload set. I have made some progress however I am looking for some suggestions/feedback for how to resolve a few issues around Cxx/Intrerop/tests:

Here’s a brief overview:

//In ImportType.cpp - Checking to if param is inout:
//Checking if the type is non const l value


  paramTy = refType->getPointeeType();
    if (isa<clang::LValueReferenceType>(paramTy) &&
        !paramTy.isConstQualified()) {
      isInOut = true;
    }

Which gives us the desired import for push_back overload

C++:

void push_back (value_type&& val);

Swift:

mutating func push_back(_ /__x/: std.__1.__CxxTemplateInstNSt3__16vectorIdNS_9allocatorIdEEEE.value_type)

We then update the SIL to pass const references indirectly :

//In SILFunctionType:

  if (clangTy->isReferenceType()) {
    if (clangTy->getPointeeType().isConstQualified() ||
        clangTy->isRValueReferenceType()) {
      return true;
    }
  }

Side note:
Right now there's no way to express immutable borrowed params, so we have to have this hack. Eventually, we should just express these correctly:

This solution generally solves the issue stated for passing rvalue refs by value, however I have been stuck trying to update the tests. For example in Interop/Cxx/class/method/ambiguous-methods.swift there are a two tests that are failing:

Out Param Increment: (Int, Int, inout Int) -> Void
Inout Param Increment: (inout Int, Int) -> Void

It comes down to how the methods being imported with these changes. So for Out Param Increment: (Int, Int, inout Int) -> Void

C++:

void increment(int a, int b, int &c) const {
    c = a + b;
  }

Swift:

func increment(_ a: Int32, _ b: Int32, _ c: Int32)

So with the current changes, namely the check in ImportType.cpp the Check for non const and l value also transforms this method but it should be imported as inout.

So it seems like there should be another check for the import type? Or is there something else I am missing?

if (clangTy->getPointeeType().isConstQualified() ||
        clangTy->isRValueReferenceType()) {

Is that an || instead of an && like in the previous snippet intentionally?

1 Like

Ahh yeah, so when I had this as an AND, we would get crash when using the method, for example:

In /Interop/Cxx/stdlib/

Command Output (stdout):
--
[ RUN      ] StdVector.init
[       OK ] StdVector.init
[ RUN      ] StdVector.push back
stderr>>> CRASHED: SIGSEGV
the test crashed unexpectedly
[     FAIL ] StdVector.push back
[ RUN      ] StdVector.map
stderr>>> CRASHED: SIGSEGV
the test crashed unexpectedly
[     FAIL ] StdVector.map
StdVector: Some tests failed, aborting
UXPASS: []
FAIL: ["push back", "map"]
SKIP: []

Sorry about the confusion

1 Like

Adding some more information, there is probably an additional check we need to add so that methods like
void increment(int a, int b, int &c) const will still be imported as inout.

Dumping the original types for AmbiguousMethods module:

LValueReferenceType 0x1420f96f0 'int &' imported
`-BuiltinType 0x142015110 'int'
LValueReferenceType 0x1420f96f0 'int &' imported
`-BuiltinType 0x142015110 'int'
LValueReferenceType 0x1420f96f0 'int &' imported
`-BuiltinType 0x142015110 'int'
LValueReferenceType 0x1420f96f0 'int &' imported
`-BuiltinType 0x142015110 'int'
LValueReferenceType 0x1420fbd80 'const struct HasAmbiguousMethods &'
`-QualType 0x1420be831 'const struct HasAmbiguousMethods' const
  `-RecordType 0x1420be830 'struct HasAmbiguousMethods' imported
    `-CXXRecord 0x1420be718 'HasAmbiguousMethods'
LValueReferenceType 0x1420fc630 'const struct HasAmbiguousMethods2 &'
`-QualType 0x1420fc2b1 'const struct HasAmbiguousMethods2' const
  `-RecordType 0x1420fc2b0 'struct HasAmbiguousMethods2' imported
    `-CXXRecord 0x1420fc198 'HasAmbiguousMethods2'
LValueReferenceType 0x11d810310 'const struct __NSConstantString_tag &'
`-QualType 0x1420bc9a1 'const struct __NSConstantString_tag' const
  `-RecordType 0x1420bc9a0 'struct __NSConstantString_tag'
    `-CXXRecord 0x1420bc8f0 '__NSConstantString_tag'