[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
This commit is contained in:
Doug Gregor
2025-05-30 17:34:24 -07:00
parent 73031240fa
commit 9af5884555
2 changed files with 35 additions and 3 deletions

View File

@@ -2691,10 +2691,28 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
}
if (!unsafeUses.empty()) {
Context.Diags.diagnose(
// Primary diagnostic along with a Fix-It to add @unsafe in the appropriate
// place.
{
auto diag = Context.Diags.diagnose(
conformance->getLoc(), diag::conformance_involves_unsafe,
conformance->getType(), Proto)
.fixItInsert(conformance->getProtocolNameLoc(), "@unsafe ");
conformance->getType(), Proto);
// Find the original explicit conformance, where we can add the Fix-It.
auto explicitConformance = conformance;
while (explicitConformance->getSourceKind() ==
ConformanceEntryKind::Implied) {
explicitConformance =
explicitConformance->ProtocolConformance::getImplyingConformance();
}
if (explicitConformance->getSourceKind() ==
ConformanceEntryKind::Explicit) {
diag.fixItInsert(explicitConformance->getProtocolNameLoc(),
"@unsafe ");
}
}
for (const auto& unsafeUse : unsafeUses)
diagnoseUnsafeUse(unsafeUse);
}

View File

@@ -359,3 +359,17 @@ func testSwitch(se: SomeEnum) {
if case unsafe someEnumValue = unsafe se { }
}
@unsafe class SomeClass {}
@unsafe class SomeClassWrapper { }
protocol Associated {
associatedtype Associated
}
protocol CustomAssociated: Associated { }
// expected-warning@+1{{conformance of 'SomeClass' to protocol 'Associated' involves unsafe code}}{{22-22=@unsafe }}
extension SomeClass: CustomAssociated {
typealias Associated = SomeClassWrapper // expected-note{{unsafe type 'SomeClass.Associated' (aka 'SomeClassWrapper') cannot satisfy safe associated type 'Associated'}}
}