Skip to content

Commit c70699c

Browse files
committed
[Strict memory safety] Improve Fix-Its for implied conformances
The Fix-It was adding @unsafe prior to the extension, which is incorrect. Make sure we apply @unsafe at the right location for the explicit conformance. Fixes rdar://151800162
1 parent 3688f6a commit c70699c

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2695,10 +2695,28 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
26952695
}
26962696

26972697
if (!unsafeUses.empty()) {
2698-
Context.Diags.diagnose(
2698+
// Primary diagnostic along with a Fix-It to add @unsafe in the appropriate
2699+
// place.
2700+
{
2701+
auto diag = Context.Diags.diagnose(
26992702
conformance->getLoc(), diag::conformance_involves_unsafe,
2700-
conformance->getType(), Proto)
2701-
.fixItInsert(conformance->getProtocolNameLoc(), "@unsafe ");
2703+
conformance->getType(), Proto);
2704+
2705+
// Find the original explicit conformance, where we can add the Fix-It.
2706+
auto explicitConformance = conformance;
2707+
while (explicitConformance->getSourceKind() ==
2708+
ConformanceEntryKind::Implied) {
2709+
explicitConformance =
2710+
explicitConformance->ProtocolConformance::getImplyingConformance();
2711+
}
2712+
2713+
if (explicitConformance->getSourceKind() ==
2714+
ConformanceEntryKind::Explicit) {
2715+
diag.fixItInsert(explicitConformance->getProtocolNameLoc(),
2716+
"@unsafe ");
2717+
}
2718+
}
2719+
27022720
for (const auto& unsafeUse : unsafeUses)
27032721
diagnoseUnsafeUse(unsafeUse);
27042722
}

test/Unsafe/safe.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,17 @@ func testSwitch(se: SomeEnum) {
349349
default: break
350350
}
351351
}
352+
353+
@unsafe class SomeClass {}
354+
@unsafe class SomeClassWrapper { }
355+
356+
protocol Associated {
357+
associatedtype Associated
358+
}
359+
360+
protocol CustomAssociated: Associated { }
361+
362+
// expected-warning@+1{{conformance of 'SomeClass' to protocol 'Associated' involves unsafe code}}{{22-22=@unsafe }}
363+
extension SomeClass: CustomAssociated {
364+
typealias Associated = SomeClassWrapper // expected-note{{unsafe type 'SomeClass.Associated' (aka 'SomeClassWrapper') cannot satisfy safe associated type 'Associated'}}
365+
}

0 commit comments

Comments
 (0)