Skip to content

Commit 6934857

Browse files
committed
Sema: Tweak associated conformance exportability diagnostics
Let's point out the associated type with a separate note, so that we can diagnose other availability failures, such as deprecation and OS version availability.
1 parent 6798ed1 commit 6934857

File tree

5 files changed

+77
-41
lines changed

5 files changed

+77
-41
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2757,12 +2757,8 @@ ERROR(conformance_from_implementation_only_module,none,
27572757
"the conformance is declared as SPI in %3|"
27582758
"the conformance is declared as SPI}4",
27592759
(Type, Identifier, unsigned, Identifier, unsigned))
2760-
ERROR(assoc_conformance_from_implementation_only_module,none,
2761-
"cannot use conformance of %0 to %1 in associated type %3 (inferred as "
2762-
"%4); %select{%2 has been imported as implementation-only|"
2763-
"the conformance is declared as SPI in %2|"
2764-
"the conformance is declared as SPI}5",
2765-
(Type, Identifier, Identifier, Type, Type, unsigned))
2760+
NOTE(assoc_conformance_from_implementation_only_module,none,
2761+
"in associated type %0 (inferred as %1)", (Type, Type))
27662762
ERROR(unexportable_clang_function_type,none,
27672763
"cannot export the underlying C type of the function type %0; "
27682764
"it may use anonymous types or types defined outside of a module",

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4340,21 +4340,19 @@ static void checkExportability(Type depTy, Type replacementTy,
43404340
ASTContext &ctx = SF->getASTContext();
43414341

43424342
Type selfTy = rootConformance->getProtocol()->getProtocolSelfType();
4343-
if (depTy->isEqual(selfTy)) {
4344-
ctx.Diags.diagnose(
4345-
conformanceBeingChecked->getLoc(),
4346-
diag::conformance_from_implementation_only_module,
4347-
rootConformance->getType(),
4348-
rootConformance->getProtocol()->getName(), 0, M->getName(),
4349-
static_cast<unsigned>(originKind));
4350-
} else {
4343+
4344+
ctx.Diags.diagnose(
4345+
conformanceBeingChecked->getLoc(),
4346+
diag::conformance_from_implementation_only_module,
4347+
rootConformance->getType(),
4348+
rootConformance->getProtocol()->getName(), 0, M->getName(),
4349+
static_cast<unsigned>(originKind));
4350+
4351+
if (!depTy->isEqual(selfTy)) {
43514352
ctx.Diags.diagnose(
43524353
conformanceBeingChecked->getLoc(),
43534354
diag::assoc_conformance_from_implementation_only_module,
4354-
rootConformance->getType(),
4355-
rootConformance->getProtocol()->getName(), M->getName(),
4356-
depTy, replacementTy->getCanonicalType(),
4357-
static_cast<unsigned>(originKind));
4355+
depTy, replacementTy->getCanonicalType());
43584356
}
43594357
}
43604358

test/SPI/protocol_requirement.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ public protocol Proto {
104104

105105
public struct BadStruct {}
106106
@_spi(Horse) extension BadStruct : OtherProto {}
107-
public struct BadConforms : Proto { // expected-error {{cannot use conformance of 'BadStruct' to 'OtherProto' in associated type 'Self.A.Element' (inferred as 'BadStruct'); the conformance is declared as SPI}}
107+
public struct BadConforms : Proto { // expected-error {{cannot use conformance of 'BadStruct' to 'OtherProto' here; the conformance is declared as SPI}}
108+
// expected-note@-1 {{in associated type 'Self.A.Element' (inferred as 'BadStruct')}}
108109
public typealias A = [BadStruct]
109110
}
110111

test/Sema/implementation-only-import-in-decls.swift

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,23 @@ protocol InternalAssociatedTypeProto {
217217
public struct PublicInferredAssociatedTypeImpl {
218218
public func takesAssoc(_: NormalStruct) {}
219219
}
220-
extension PublicInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}}
221-
extension PublicInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}}
220+
extension PublicInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}}
221+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
222+
223+
extension PublicInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}}
224+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
225+
222226
extension PublicInferredAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay
223227

224228
@usableFromInline struct UFIInferredAssociatedTypeImpl {
225229
public func takesAssoc(_: NormalStruct) {}
226230
}
227-
extension UFIInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}}
228-
extension UFIInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}}
231+
extension UFIInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}}
232+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
233+
234+
extension UFIInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}}
235+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
236+
229237
extension UFIInferredAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay
230238

231239
struct InternalInferredAssociatedTypeImpl {
@@ -239,8 +247,12 @@ public struct PublicExplicitAssociatedTypeImpl {
239247
public typealias Assoc = NormalStruct
240248
public func takesAssoc(_: NormalStruct) {}
241249
}
242-
extension PublicExplicitAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}}
243-
extension PublicExplicitAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}}
250+
extension PublicExplicitAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}}
251+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
252+
253+
extension PublicExplicitAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}}
254+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
255+
244256
extension PublicExplicitAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay
245257

246258

@@ -251,7 +263,8 @@ public protocol BaseProtoWithNoRequirement {
251263
public protocol RefinedProto: BaseProtoWithNoRequirement where Assoc: NormalProto {
252264
}
253265

254-
public struct RefinedProtoImpl: RefinedProto { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}}
266+
public struct RefinedProtoImpl: RefinedProto { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}}
267+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
255268
public func takesAssoc(_: NormalStruct) {}
256269
}
257270

@@ -266,18 +279,26 @@ public protocol SlightlyMoreComplicatedRequirement {
266279
associatedtype Assoc: Collection where Assoc.Element: NormalProto
267280
func takesAssoc(_: Assoc)
268281
}
269-
public struct SlightlyMoreComplicatedRequirementImpl: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'NormalStruct'); 'BADLibrary' has been imported as implementation-only}}
282+
public struct SlightlyMoreComplicatedRequirementImpl: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}}
283+
// expected-note@-1 {{in associated type 'Self.Assoc.Element' (inferred as 'NormalStruct')}}
284+
270285
public func takesAssoc(_: [NormalStruct]) {}
271286
}
272-
public struct RequirementsHandleSubclassesToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'SubclassOfNormalClass'); 'BADLibrary' has been imported as implementation-only}}
287+
public struct RequirementsHandleSubclassesToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}}
288+
// expected-note@-1 {{in associated type 'Self.Assoc.Element' (inferred as 'SubclassOfNormalClass')}}
289+
273290
public func takesAssoc(_: [SubclassOfNormalClass]) {}
274291
}
275292

276-
public struct RequirementsHandleSpecializationsToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'ConditionalGenericStruct<NormalStruct>'); 'BADLibrary' has been imported as implementation-only}}
293+
public struct RequirementsHandleSpecializationsToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}}
294+
// expected-note@-1 {{in associated type 'Self.Assoc.Element' (inferred as 'ConditionalGenericStruct<NormalStruct>')}}
295+
277296
public func takesAssoc(_: [ConditionalGenericStruct<NormalStruct>]) {}
278297
}
279298

280-
public struct ClassConstrainedGenericArg<T: NormalClass>: PublicAssociatedTypeProto { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'T'); 'BADLibrary' has been imported as implementation-only}}
299+
public struct ClassConstrainedGenericArg<T: NormalClass>: PublicAssociatedTypeProto { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' here; 'BADLibrary' has been imported as implementation-only}}
300+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'T')}}
301+
281302
public func takesAssoc(_: T) {}
282303
}
283304

test/Sema/spi-in-decls.swift

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,24 @@ protocol InternalAssociatedTypeProto {
251251
public struct PublicInferredAssociatedTypeImpl {
252252
public func takesAssoc(_: NormalStruct) {}
253253
}
254-
extension PublicInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
255-
extension PublicInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
254+
extension PublicInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
255+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
256+
257+
extension PublicInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
258+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
259+
256260
extension PublicInferredAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay
257261

258262
@usableFromInline struct UFIInferredAssociatedTypeImpl {
259263
public func takesAssoc(_: NormalStruct) {}
260264
}
261-
extension UFIInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
262-
extension UFIInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
265+
266+
extension UFIInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
267+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
268+
269+
extension UFIInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
270+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
271+
263272
extension UFIInferredAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay
264273

265274
struct InternalInferredAssociatedTypeImpl {
@@ -273,8 +282,12 @@ public struct PublicExplicitAssociatedTypeImpl {
273282
public typealias Assoc = NormalStruct
274283
public func takesAssoc(_: NormalStruct) {}
275284
}
276-
extension PublicExplicitAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
277-
extension PublicExplicitAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
285+
extension PublicExplicitAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
286+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
287+
288+
extension PublicExplicitAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
289+
// expected-note@-1 {{in associated type 'Self.Assoc'}}
290+
278291
extension PublicExplicitAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay
279292

280293

@@ -285,7 +298,8 @@ public protocol BaseProtoWithNoRequirement {
285298
public protocol RefinedProto: BaseProtoWithNoRequirement where Assoc: NormalProto {
286299
}
287300

288-
public struct RefinedProtoImpl: RefinedProto { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
301+
public struct RefinedProtoImpl: RefinedProto { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
302+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'NormalStruct')}}
289303
public func takesAssoc(_: NormalStruct) {}
290304
}
291305

@@ -300,17 +314,23 @@ public protocol SlightlyMoreComplicatedRequirement {
300314
associatedtype Assoc: Collection where Assoc.Element: NormalProto
301315
func takesAssoc(_: Assoc)
302316
}
303-
public struct SlightlyMoreComplicatedRequirementImpl: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
317+
public struct SlightlyMoreComplicatedRequirementImpl: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
318+
// expected-note@-1 {{in associated type 'Self.Assoc.Element' (inferred as 'NormalStruct')}}
304319
public func takesAssoc(_: [NormalStruct]) {}
305320
}
306-
public struct RequirementsHandleSubclassesToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'SubclassOfNormalClass'); the conformance is declared as SPI}}
321+
public struct RequirementsHandleSubclassesToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' here; the conformance is declared as SPI}}
322+
// expected-note@-1 {{in associated type 'Self.Assoc.Element' (inferred as 'SubclassOfNormalClass')}}
307323
public func takesAssoc(_: [SubclassOfNormalClass]) {}
308324
}
309325

310-
public struct RequirementsHandleSpecializationsToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'ConditionalGenericStruct<NormalStruct>'); the conformance is declared as SPI}}
326+
public struct RequirementsHandleSpecializationsToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
327+
// expected-note@-1 {{in associated type 'Self.Assoc.Element' (inferred as 'ConditionalGenericStruct<NormalStruct>')}}
328+
311329
public func takesAssoc(_: [ConditionalGenericStruct<NormalStruct>]) {}
312330
}
313331

314-
public struct ClassConstrainedGenericArg<T: NormalClass>: PublicAssociatedTypeProto { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'T'); the conformance is declared as SPI}}
332+
public struct ClassConstrainedGenericArg<T: NormalClass>: PublicAssociatedTypeProto { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' here; the conformance is declared as SPI}}
333+
// expected-note@-1 {{in associated type 'Self.Assoc' (inferred as 'T')}}
334+
315335
public func takesAssoc(_: T) {}
316336
}

0 commit comments

Comments
 (0)