Skip to content

SR-12802: Disambiguate functions with lvalue and rvalue reference parameters in the same overload set #59954

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

Closed
wants to merge 1 commit into from

Conversation

cabmeurer
Copy link
Contributor

This patch is to start the work on fixing the way we import C++ method overload imports that use rvalue references, by passing by value, however this may not be the best approach. I have updated the tests that use the push_back but this is causing a crash.

Related to #55247

@zoecarver @hyp

@cabmeurer

This comment was marked as outdated.

@cabmeurer cabmeurer marked this pull request as draft July 8, 2022 00:37
Copy link
Contributor

@zoecarver zoecarver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks!

@zoecarver
Copy link
Contributor

Sorry, I missed your comment. I think you need to update this check: https://github.com/apple/swift/blob/main/lib/SIL/IR/SILFunctionType.cpp#L1327-L1332

@cabmeurer cabmeurer force-pushed the cabmeurer/SR-12802 branch from 0c1b431 to 228a636 Compare July 14, 2022 04:31
@cabmeurer

This comment was marked as outdated.

@hyp hyp added the c++ interop Feature: Interoperability with C++ label Jul 14, 2022
@cabmeurer cabmeurer force-pushed the cabmeurer/SR-12802 branch 4 times, most recently from f03337c to f8e007a Compare July 21, 2022 03:23
@cabmeurer cabmeurer force-pushed the cabmeurer/SR-12802 branch from f8e007a to 3816ee9 Compare August 3, 2022 05:22
return true;
}
*/
if (clangTy->isReferenceType()) {
Copy link
Contributor Author

@cabmeurer cabmeurer Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is correct. Currently all Cxx/Interop/stdlib tests are passing, but currently still investigating the sil gen here

}

// CHECK: sil hidden @$s4main9setCxxRefyyF : $@convention(thin) () -> ()
// CHECK: [[REF:%.*]] = function_ref @{{_Z15setStaticIntRefRi|\?setStaticIntRef@@YAXAEAH@Z}} : $@convention(c) (@inout Int32) -> ()
// CHECK: apply [[REF]](%{{[0-9]+}}) : $@convention(c) (@inout Int32) -> ()
// CHECK: [[REF:%.*]] = function_ref @{{_Z15setStaticIntRefRi|\?setStaticIntRef@@YAXAEAH@Z}} : $@convention(c) (Int32) -> ()
Copy link
Contributor Author

@cabmeurer cabmeurer Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now passing, but I have a few questions:

  1. If I understand correctly these are executable tests to check the sil?
  2. Why don't I need the @in keyword here compared to the tests I updated on lines 61 and 62?

@cabmeurer cabmeurer force-pushed the cabmeurer/SR-12802 branch 2 times, most recently from 3a0c959 to dd4c3c1 Compare August 6, 2022 08:23
@cabmeurer cabmeurer marked this pull request as ready for review August 6, 2022 08:24
@cabmeurer
Copy link
Contributor Author

cabmeurer commented Aug 6, 2022

@zoecarver @hyp When you have sometime, I left some comments/questions:

So if I understand this correctly... We are wanting to check for immutable borrowed parameters and pass them indirectly.
The original check in SILFunctionType essential satisfies this by the original condition:

  if (clangTy->isReferenceType() &&
       clangTy->getPointeeType().isConstQualified())
     return true;

However when I have updated the ImportType, to pass Rvalue References by value, this check ends up failing in this area. I have made some progress with updating tests and have written this check:

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

            return true;
        }
    }

Any ideas or suggestions?

@cabmeurer cabmeurer requested a review from zoecarver August 6, 2022 08:48
@@ -59,11 +59,11 @@ CxxAmbiguousMethodTestSuite.test("Out Param Increment: (Int, Int, inout Int) ->
expectEqual(0, instance.numberOfMutableMethodsCalled())

// Non mutable version should NOT change count
instance.increment(0, 1, &out);
instance.increment(0, 1, out);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should all of these still be imported as inout?

Copy link
Contributor

@zoecarver zoecarver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for such a slow review. This looks good to me!

@zoecarver
Copy link
Contributor

@swift-ci please test.

@ktoso
Copy link
Contributor

ktoso commented Sep 6, 2022

Nice, that'd be very helpful for some APIs I hit recently, looking forward to this!

@cabmeurer cabmeurer force-pushed the cabmeurer/SR-12802 branch 4 times, most recently from de6a3b1 to 91b2b6c Compare September 24, 2022 03:46
@cabmeurer cabmeurer force-pushed the cabmeurer/SR-12802 branch 2 times, most recently from 0ac84bd to 33d440a Compare September 25, 2022 03:30
@cabmeurer
Copy link
Contributor Author

@zoecarver could you run CI when you get a chance?

@cabmeurer
Copy link
Contributor Author

Created a post to discuss some of the issues I'm running into: Swift Forums

@@ -2301,8 +2301,11 @@ ClangImporter::Implementation::importParameterType(
}

paramTy = refType->getPointeeType();
if (!paramTy.isConstQualified())
if ((isa<clang::LValueReferenceType>(paramTy) &&
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I found that checking for canonical allowed the certain methods that should remain inout to be import as such, and some overload methods to import with just value.

    paramTy = refType->getPointeeType();
    if ((paramTy.isCanonical() && 
        !paramTy->isRValueReferenceType())) {
      isInOut = true;
    }
  }

For example.HasAmbiguousMethods is now imported correctly:

struct HasAmbiguousMethods {
  init()
  func increment(_ a: Int32) -> Int32
  mutating func incrementMutating(_ a: Int32) -> Int32
  mutating func incrementMutating(_ a: Int32, _ b: Int32, _ c: inout Int32)
  func increment(_ a: Int32, _ b: Int32, _ c: inout Int32)
  mutating func incrementMutating(_ a: inout Int32, _ b: Int32)
  func increment(_ a: inout Int32, _ b: Int32)
  func numberOfMutableMethodsCalled() -> Int32
  mutating func numberOfMutableMethodsCalledMutating() -> Int32
}
struct HasAmbiguousMethods2 {
  init()
  func increment(_ a: Int32) -> Int32
}

And the push_back overloads are also correct:

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

However a larger number of test are failing, so I assume checking for canonical type isn’t the expected behavior either:

Failed Tests (21):
  Swift(macosx-arm64) :: Interop/Cxx/class/protocol-conformance-typechecker.swift
  Swift(macosx-arm64) :: Interop/Cxx/ergonomics/implicit-computed-properties-module-interface.swift
  Swift(macosx-arm64) :: Interop/Cxx/operators/member-inline.swift
  Swift(macosx-arm64) :: Interop/Cxx/reference/const-ref-parameter.swift
  Swift(macosx-arm64) :: Interop/Cxx/reference/reference-irgen.swift
  Swift(macosx-arm64) :: Interop/Cxx/reference/reference-module-interface.swift
  Swift(macosx-arm64) :: Interop/Cxx/reference/reference-silgen-cxx-objc-ctors+init.swift
  Swift(macosx-arm64) :: Interop/Cxx/reference/reference-silgen.swift
  Swift(macosx-arm64) :: Interop/Cxx/reference/reference.swift
  Swift(macosx-arm64) :: Interop/Cxx/stdlib/overlay/custom-collection-module-interface.swift
  Swift(macosx-arm64) :: Interop/Cxx/stdlib/overlay/custom-collection.swift
  Swift(macosx-arm64) :: Interop/Cxx/stdlib/overlay/custom-iterator-module-interface.swift
  Swift(macosx-arm64) :: Interop/Cxx/stdlib/overlay/custom-sequence-module-interface.swift
  Swift(macosx-arm64) :: Interop/Cxx/stdlib/overlay/custom-sequence-typechecker.swift
  Swift(macosx-arm64) :: Interop/Cxx/stdlib/overlay/custom-sequence.swift
  Swift(macosx-arm64) :: Interop/Cxx/stdlib/use-std-map.swift
  Swift(macosx-arm64) :: Interop/Cxx/templates/defaulted-template-type-parameter.swift
  Swift(macosx-arm64) :: Interop/Cxx/templates/dependent-types.swift
  Swift(macosx-arm64) :: Interop/Cxx/templates/function-template.swift
  Swift(macosx-arm64) :: Interop/Cxx/templates/member-templates-silgen.swift
  Swift(macosx-arm64) :: Interop/Cxx/templates/template-type-parameter-not-in-signature.swift


Testing Time: 21.08s
  Unsupported:  24
  Passed     : 238
  Failed     :  21

@zoecarver any ideas/suggestions?

@cabmeurer cabmeurer closed this May 11, 2023
@cabmeurer cabmeurer deleted the cabmeurer/SR-12802 branch May 11, 2023 23:35
@cabmeurer
Copy link
Contributor Author

cabmeurer commented May 11, 2023

resolved with #65578

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ interop Feature: Interoperability with C++
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants