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

[SR-7428] Class conforming to protocol with default method implementation no longer compiles with Xcode 9.3 #49971

Closed
swift-ci opened this issue Apr 13, 2018 · 6 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself regression swift 4.1

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-7428
Radar None
Original Reporter chris.lapilla (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment
  • Builds successfully with Xcode 9.2 on any Swift version/platform (swiftlang-900.0.74.1 clang-900.0.39.2)

  • Compilation error with Xcode 9.3 on all Swift versions/platforms (swiftlang-902.0.48 clang-902.0.37.1)

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, 4.1Regression
Assignee @slavapestov
Priority Medium

md5: c7ee6ee47158d038dc3201c8fa542551

is duplicated by:

  • SR-7429 Cannot conform a non-final class to a protocol with a defaulted requirement with a generic placeholder constrained to an associated type
  • SR-7435 Compiler incorrectly disallows nonfinal classes from using default implementations that have same-type constraints on associated types of Self

relates to:

  • SR-7429 Cannot conform a non-final class to a protocol with a defaulted requirement with a generic placeholder constrained to an associated type

Issue Description:

We have a simple protocol with an associated type and one method

protocol Node {
    associatedtype ValueType
    
    func addChild<ChildType>(_ child: ChildType)
         where ChildType: Node, ChildType.ValueType == Self.ValueType
}

a default implementation for that method via a protocol extension

extension Node {
    func addChild<ChildType>(_ child: ChildType) 
         where ChildType: Node, ChildType.ValueType == Self.ValueType
    {
        print("default implementation goes here")
    }
}

and a conforming class

class IntNode: Node {
    typealias ValueType = Int
}

This code compiled under both Swift 3.2 and 4.0 with the Swift tools bundled with Xcode 9.2. However, since updating to Xcode 9.3, the compiler produces the following error, under both Swift 3.3 and 4.1:

error: type 'IntNode' does not conform to protocol 'Node'
class IntNode: Node {

note: candidate has non-matching type '<Self, ChildType> (ChildType) -> ()'
    func addChild<ChildType>(_ child: ChildType) where ChildType: Node, ChildType.ValueType == Self.ValueType {

note: do you want to add protocol stubs?
class IntNode: Node {

This occurs regardless of the underlying platform (we tested on both iOS and MacOS), or whether we compile via Xcode or directly on the command line with swiftc.

@belkadan
Copy link
Contributor

cc @huonw, @DougGregor

@slavapestov
Copy link
Member

The duped bug had a discussion, copy/pasting it here:

The original soundness hole was https://bugs.swift.org/browse/SR-617. The example in this bug report is itself due to a hack that was meant to preserve source compatibility with another corner case. See the big comment here: https://github.com/apple/swift/blob/d33a5c16f25034a2d34a964dfc1ef916387c9a9b/lib/Sema/TypeCheck

@DougGregor
Copy link
Member

The code in question exploited a type-soundness hole in the generics system that we closed as part of https://bugs.swift.org/browse/SR-617. So while the compiler is rejecting code that it previously accepted, the code shouldn't have been accepted in the first place. Specifically, this commit closed the type soundness hole: b5f231d

@slavapestov
Copy link
Member

@DougGregor it's not clear to me what the type soundness hole in this code is.

This compiler change fixes it, so its related to SR-617, but it's not actually my workaround that's responsible:

--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -675,7 +675,7 @@ RequirementMatch swift::matchWitness(TypeChecker &tc,
         auto selfKind = proto->findProtocolSelfReferences(req,
                                              /*allowCovariantParameters=*/false,
                                              /*skipAssocTypes=*/false);
-        if (!selfKind.other) {
+        if (!selfKind.other && false) {
           covariantSelf = classDecl;
         }
       }

It could be a bug in how requirement environments are matching up associated types?

@slavapestov
Copy link
Member

Here is a reduced test case that doesn't involve conformance checking or my fix for SR-617:

protocol P {
  associatedtype Q = Int
}

class C : P {}

extension P {
  func f1<T>(_: T) where T == Q, Self : C {}
  func f2<T>(_: T) where Self : C, T == Q {}
}

f1 has an invalid generic signature whereas f2 is correct. This is a bug in the GSB.

@slavapestov
Copy link
Member

#15970

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
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. compiler The Swift compiler in itself regression swift 4.1
Projects
None yet
Development

No branches or pull requests

5 participants