1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
|
// 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
|