mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[DiagnosticsQoI] SR-3359: Add a fix-it to remove @discardableResult on functions that return Void or Never (#6681)
This commit adds a fix-it to remove @discardableResult on functions that return Void or Never. The fix-it is at the warning level. A test was added to verify that the fix-it removes the @discardableResult. This issue was reported in SR-3359: https://bugs.swift.org/browse/SR-3359 Changes: TypeCheckAttr.cpp: implemented AttributeChecker::visitDiscardableResultAttr to add a fix-it to remove @discardableResult on functions returning Void or Never. DiagnosticsSema.def: Added a warning with a diagnostic message. LoggingWrappers.swift.gyb, HashedCollections.swift.gyb: Removed @discardableResult on functions returning Void. fixits-apply-all.swift, fixits-apply-all.swift.result: Added tests to verify that @discardableResult is removed from functions returning Void or Never.
This commit is contained in:
committed by
Jordan Rose
parent
f462ce7852
commit
0e09bbbb83
@@ -3295,6 +3295,14 @@ NOTE(availability_protocol_requirement_here, none,
|
|||||||
NOTE(availability_conformance_introduced_here, none,
|
NOTE(availability_conformance_introduced_here, none,
|
||||||
"conformance introduced here", ())
|
"conformance introduced here", ())
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// @discardableResult
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
WARNING(discardable_result_on_void_never_function, none,
|
||||||
|
"@discardableResult declared on a function returning %select{Never|Void}0 is unnecessary",
|
||||||
|
(bool))
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Resilience diagnostics
|
// Resilience diagnostics
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -726,7 +726,6 @@ public:
|
|||||||
IGNORED_ATTR(Testable)
|
IGNORED_ATTR(Testable)
|
||||||
IGNORED_ATTR(WarnUnqualifiedAccess)
|
IGNORED_ATTR(WarnUnqualifiedAccess)
|
||||||
IGNORED_ATTR(ShowInInterface)
|
IGNORED_ATTR(ShowInInterface)
|
||||||
IGNORED_ATTR(DiscardableResult)
|
|
||||||
#undef IGNORED_ATTR
|
#undef IGNORED_ATTR
|
||||||
|
|
||||||
void visitAvailableAttr(AvailableAttr *attr);
|
void visitAvailableAttr(AvailableAttr *attr);
|
||||||
@@ -763,6 +762,8 @@ public:
|
|||||||
void visitSpecializeAttr(SpecializeAttr *attr);
|
void visitSpecializeAttr(SpecializeAttr *attr);
|
||||||
|
|
||||||
void visitVersionedAttr(VersionedAttr *attr);
|
void visitVersionedAttr(VersionedAttr *attr);
|
||||||
|
|
||||||
|
void visitDiscardableResultAttr(DiscardableResultAttr *attr);
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
@@ -1534,6 +1535,20 @@ void AttributeChecker::visitVersionedAttr(VersionedAttr *attr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AttributeChecker::visitDiscardableResultAttr(DiscardableResultAttr *attr) {
|
||||||
|
if (auto *FD = dyn_cast<FuncDecl>(D)) {
|
||||||
|
if (auto result = FD->getResultInterfaceType()) {
|
||||||
|
auto resultIsVoid = result->isVoid();
|
||||||
|
if (resultIsVoid || result->isUninhabited()) {
|
||||||
|
auto warn = diag::discardable_result_on_void_never_function;
|
||||||
|
auto diagnostic = TC.diagnose(D->getStartLoc(), warn, resultIsVoid);
|
||||||
|
diagnostic.fixItRemove(attr->getRangeWithAt());
|
||||||
|
attr->setInvalid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TypeChecker::checkDeclAttributes(Decl *D) {
|
void TypeChecker::checkDeclAttributes(Decl *D) {
|
||||||
AttributeChecker Checker(*this, D);
|
AttributeChecker Checker(*this, D);
|
||||||
|
|
||||||
|
|||||||
@@ -541,7 +541,6 @@ public struct ${Self}<
|
|||||||
return base.removeFirst()
|
return base.removeFirst()
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
public mutating func removeFirst(_ n: Int) {
|
public mutating func removeFirst(_ n: Int) {
|
||||||
Log.removeFirstN[selfType] += 1
|
Log.removeFirstN[selfType] += 1
|
||||||
base.removeFirst(n)
|
base.removeFirst(n)
|
||||||
|
|||||||
@@ -243,7 +243,6 @@ internal protocol _HashBuffer {
|
|||||||
@discardableResult
|
@discardableResult
|
||||||
mutating func removeValue(forKey key: Key) -> Value?
|
mutating func removeValue(forKey key: Key) -> Value?
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
mutating func removeAll(keepingCapacity keepCapacity: Bool)
|
mutating func removeAll(keepingCapacity keepCapacity: Bool)
|
||||||
|
|
||||||
var count: Int { get }
|
var count: Int { get }
|
||||||
|
|||||||
@@ -20,3 +20,7 @@ func goo(_ e: Error) {
|
|||||||
|
|
||||||
@warn_unused_result(message="test message")
|
@warn_unused_result(message="test message")
|
||||||
func warn_unused_result_removal() -> Int { return 5 }
|
func warn_unused_result_removal() -> Int { return 5 }
|
||||||
|
|
||||||
|
@discardableResult func discardableResultOnVoidFunc() {}
|
||||||
|
|
||||||
|
@discardableResult func discardableResultOnNeverFunc() -> Never { fatalError() }
|
||||||
|
|||||||
@@ -20,3 +20,7 @@ func goo(_ e: Error) {
|
|||||||
|
|
||||||
|
|
||||||
func warn_unused_result_removal() -> Int { return 5 }
|
func warn_unused_result_removal() -> Int { return 5 }
|
||||||
|
|
||||||
|
func discardableResultOnVoidFunc() {}
|
||||||
|
|
||||||
|
func discardableResultOnNeverFunc() -> Never { fatalError() }
|
||||||
|
|||||||
Reference in New Issue
Block a user