// RUN: %empty-directory(%t) // RUN: %target-swift-frontend %S/Inputs/placement_module_A.swift -emit-module -parse-as-library -o %t // RUN: %target-swift-frontend -I %t %S/Inputs/placement_module_B.swift -emit-module -parse-as-library -o %t // RUN: %target-swift-frontend -typecheck -primary-file %s %S/Inputs/placement_2.swift -I %t -verify // Tests for the placement of conformances as well as conflicts // between conformances that come from different sources. import placement_module_A import placement_module_B protocol P1 { } protocol P2a : P1 { } protocol P3a : P2a { } protocol P2b : P1 { } protocol P3b : P2b { } protocol P4 : P3a, P3b { } protocol AnyObjectRefinement : AnyObject { } // =========================================================================== // Tests within a single source file // =========================================================================== // --------------------------------------------------------------------------- // Multiple explicit conformances to the same protocol // --------------------------------------------------------------------------- struct Explicit1 : P1 { } // expected-note{{'Explicit1' declares conformance to protocol 'P1' here}} extension Explicit1 : P1 { } // expected-error{{redundant conformance of 'Explicit1' to protocol 'P1'}} struct Explicit2 { } extension Explicit2 : P1 { } // expected-note 2{{'Explicit2' declares conformance to protocol 'P1' here}} extension Explicit2 : P1 { } // expected-error{{redundant conformance of 'Explicit2' to protocol 'P1'}} extension Explicit2 : P1 { } // expected-error{{redundant conformance of 'Explicit2' to protocol 'P1'}} // --------------------------------------------------------------------------- // Multiple implicit conformances, with no ambiguities // --------------------------------------------------------------------------- struct MultipleImplicit1 : P2a { } extension MultipleImplicit1 : P3a { } struct MultipleImplicit2 : P4 { } struct MultipleImplicit3 : P4 { } extension MultipleImplicit3 : P1 { } // --------------------------------------------------------------------------- // Multiple implicit conformances, ambiguity resolved because they // land in the same context. // --------------------------------------------------------------------------- struct MultipleImplicit4 : P2a, P2b { } struct MultipleImplicit5 { } extension MultipleImplicit5 : P2a, P2b { } struct MultipleImplicit6 : P4 { } extension MultipleImplicit6 : P3a { } struct MultipleImplicit7 : P2a { } extension MultipleImplicit7 : P2b { } // --------------------------------------------------------------------------- // Multiple implicit conformances, ambiguity resolved via explicit conformance // --------------------------------------------------------------------------- struct ExplicitMultipleImplicit1 : P2a { } extension ExplicitMultipleImplicit1 : P2b { } extension ExplicitMultipleImplicit1 : P1 { } // resolves ambiguity // --------------------------------------------------------------------------- // Implicit conformances superseded by inherited conformances // --------------------------------------------------------------------------- class ImplicitSuper1 : P3a { } class ImplicitSub1 : ImplicitSuper1 { } extension ImplicitSub1 : P4 { } // okay, introduces new conformance to P4; the rest are superseded // --------------------------------------------------------------------------- // Synthesized conformances superseded by implicit conformances // --------------------------------------------------------------------------- enum SuitA { case Spades, Hearts, Clubs, Diamonds } func <(lhs: SuitA, rhs: SuitA) -> Bool { return false } extension SuitA : Comparable {} // okay, implied conformance to Equatable here is preferred. enum SuitB: Equatable { case Spades, Hearts, Clubs, Diamonds } func <(lhs: SuitB, rhs: SuitB) -> Bool { return false } extension SuitB : Comparable {} // okay, explicitly declared earlier. enum SuitC { case Spades, Hearts, Clubs, Diamonds } func <(lhs: SuitC, rhs: SuitC) -> Bool { return false } extension SuitC : Equatable, Comparable {} // okay, explicitly declared here. // --------------------------------------------------------------------------- // Explicit conformances conflicting with inherited conformances // --------------------------------------------------------------------------- class ExplicitSuper1 : P3a { } class ExplicitSub1 : ImplicitSuper1 { } // expected-note{{'ExplicitSub1' inherits conformance to protocol 'P1' from superclass here}} extension ExplicitSub1 : P1 { } // expected-error{{redundant conformance of 'ExplicitSub1' to protocol 'P1'}} // --------------------------------------------------------------------------- // Suppression of synthesized conformances // --------------------------------------------------------------------------- class SynthesizedClass1 : AnyObject { } class SynthesizedClass2 { } extension SynthesizedClass2 : AnyObject { } // expected-error{{only protocols can inherit from 'AnyObject'}} class SynthesizedClass3 : AnyObjectRefinement { } class SynthesizedClass4 { } extension SynthesizedClass4 : AnyObjectRefinement { } class SynthesizedSubClass1 : SynthesizedClass1, AnyObject { } class SynthesizedSubClass2 : SynthesizedClass2 { } extension SynthesizedSubClass2 : AnyObject { } // expected-error{{only protocols can inherit from 'AnyObject'}} class SynthesizedSubClass3 : SynthesizedClass1, AnyObjectRefinement { } class SynthesizedSubClass4 : SynthesizedClass2 { } extension SynthesizedSubClass4 : AnyObjectRefinement { } enum SynthesizedEnum1 : Int, RawRepresentable { case none = 0 } enum SynthesizedEnum2 : Int { case none = 0 } extension SynthesizedEnum2 : RawRepresentable { } // =========================================================================== // Tests across different source files // =========================================================================== // --------------------------------------------------------------------------- // Multiple explicit conformances to the same protocol // --------------------------------------------------------------------------- struct MFExplicit1 : P1 { } extension MFExplicit2 : P1 { } // expected-error{{redundant conformance of 'MFExplicit2' to protocol 'P1'}} // --------------------------------------------------------------------------- // Multiple implicit conformances, with no ambiguities // --------------------------------------------------------------------------- extension MFMultipleImplicit1 : P3a { } struct MFMultipleImplicit2 : P4 { } extension MFMultipleImplicit3 : P1 { } extension MFMultipleImplicit4 : P3a { } extension MFMultipleImplicit5 : P2b { } // --------------------------------------------------------------------------- // Explicit conformances conflicting with inherited conformances // --------------------------------------------------------------------------- class MFExplicitSuper1 : P3a { } extension MFExplicitSub1 : P1 { } // expected-error{{redundant conformance of 'MFExplicitSub1' to protocol 'P1'}} // --------------------------------------------------------------------------- // Suppression of synthesized conformances // --------------------------------------------------------------------------- class MFSynthesizedClass1 { } extension MFSynthesizedClass2 : AnyObject { } // expected-error{{only protocols can inherit from 'AnyObject'}} class MFSynthesizedClass4 { } extension MFSynthesizedClass4 : AnyObjectRefinement { } extension MFSynthesizedSubClass2 : AnyObject { } // expected-error{{only protocols can inherit from 'AnyObject'}} extension MFSynthesizedSubClass3 : AnyObjectRefinement { } class MFSynthesizedSubClass4 : MFSynthesizedClass2 { } extension MFSynthesizedEnum1 : RawRepresentable { } enum MFSynthesizedEnum2 : Int { case none = 0 } // =========================================================================== // Tests with conformances in imported modules // =========================================================================== extension MMExplicit1 : MMP1 { } // expected-warning{{conformance of 'MMExplicit1' to protocol 'MMP1' was already stated in the type's module 'placement_module_A'}} extension MMExplicit1 : MMP2a { } // expected-warning{{MMExplicit1' to protocol 'MMP2a' was already stated in the type's module 'placement_module_A}} extension MMExplicit1 : MMP3a { } // expected-warning{{conformance of 'MMExplicit1' to protocol 'MMP3a' was already stated in the type's module 'placement_module_A'}} extension MMExplicit1 : @retroactive MMP3b { } // okay extension MMSuper1 : MMP1 { } // expected-warning{{conformance of 'MMSuper1' to protocol 'MMP1' was already stated in the type's module 'placement_module_A'}} extension MMSuper1 : MMP2a { } // expected-warning{{conformance of 'MMSuper1' to protocol 'MMP2a' was already stated in the type's module 'placement_module_A'}} extension MMSuper1 : @retroactive MMP3b { } // okay extension MMSub1 : AnyObject { } // expected-error{{only protocols can inherit from 'AnyObject'}} extension MMSub2 : MMP1 { } // expected-warning{{conformance of 'MMSub2' to protocol 'MMP1' was already stated in the type's module 'placement_module_A'}} extension MMSub2 : MMP2a { } // expected-warning{{conformance of 'MMSub2' to protocol 'MMP2a' was already stated in the type's module 'placement_module_A'}} extension MMSub2 : @retroactive MMP3b { } // okay extension MMSub2 : @retroactive MMAnyObjectRefinement { } // okay extension MMSub3 : MMP1 { } // expected-warning{{conformance of 'MMSub3' to protocol 'MMP1' was already stated in the type's module 'placement_module_A'}} extension MMSub3 : MMP2a { } // expected-warning{{conformance of 'MMSub3' to protocol 'MMP2a' was already stated in the type's module 'placement_module_A'}} extension MMSub3 : @retroactive MMP3b { } // okay extension MMSub3 : AnyObject { } // expected-error{{only protocols can inherit from 'AnyObject'}} extension MMSub4 : MMP1 { } // expected-warning{{conformance of 'MMSub4' to protocol 'MMP1' was already stated in the type's module 'placement_module_B'}} extension MMSub4 : MMP2a { } // expected-warning{{conformance of 'MMSub4' to protocol 'MMP2a' was already stated in the type's module 'placement_module_B'}} extension MMSub4 : @retroactive MMP3b { } // okay extension MMSub4 : AnyObjectRefinement { } // okay