mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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'}}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user