mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
218 lines
10 KiB
Swift
218 lines
10 KiB
Swift
// 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
|