mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add feature for rethrows protocols and use it in module interface generation
This commit is contained in:
@@ -39,5 +39,6 @@ LANGUAGE_FEATURE(AsyncAwait, 296, "async/await", true)
|
|||||||
LANGUAGE_FEATURE(MarkerProtocol, 0, "@_marker protocol", true)
|
LANGUAGE_FEATURE(MarkerProtocol, 0, "@_marker protocol", true)
|
||||||
LANGUAGE_FEATURE(Actors, 0, "actors", langOpts.EnableExperimentalConcurrency)
|
LANGUAGE_FEATURE(Actors, 0, "actors", langOpts.EnableExperimentalConcurrency)
|
||||||
LANGUAGE_FEATURE(ConcurrentFunctions, 0, "@concurrent functions", true)
|
LANGUAGE_FEATURE(ConcurrentFunctions, 0, "@concurrent functions", true)
|
||||||
|
LANGUAGE_FEATURE(RethrowsProtocol, 0, "@rethrows protocol", true)
|
||||||
|
|
||||||
#undef LANGUAGE_FEATURE
|
#undef LANGUAGE_FEATURE
|
||||||
|
|||||||
@@ -2511,6 +2511,57 @@ static bool usesFeatureConcurrentFunctions(Decl *decl) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool usesFeatureRethrowsProtocol(
|
||||||
|
Decl *decl, SmallPtrSet<Decl *, 16> &checked) {
|
||||||
|
// Make sure we don't recurse.
|
||||||
|
if (!checked.insert(decl).second)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (auto proto = dyn_cast<ProtocolDecl>(decl)) {
|
||||||
|
if (proto->getAttrs().hasAttribute<AtRethrowsAttr>())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
|
||||||
|
if (auto proto = ext->getSelfProtocolDecl())
|
||||||
|
if (usesFeatureRethrowsProtocol(proto, checked))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto genericSig = decl->getInnermostDeclContext()
|
||||||
|
->getGenericSignatureOfContext()) {
|
||||||
|
for (const auto &req : genericSig->getRequirements()) {
|
||||||
|
if (req.getKind() == RequirementKind::Conformance &&
|
||||||
|
usesFeatureRethrowsProtocol(
|
||||||
|
req.getSecondType()->getAs<ProtocolType>()->getDecl(), checked))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto value = dyn_cast<ValueDecl>(decl)) {
|
||||||
|
if (Type type = value->getInterfaceType()) {
|
||||||
|
bool hasRethrowsProtocol = type.findIf([&](Type type) {
|
||||||
|
if (auto nominal = type->getAnyNominal()) {
|
||||||
|
if (usesFeatureRethrowsProtocol(nominal, checked))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasRethrowsProtocol)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool usesFeatureRethrowsProtocol(Decl *decl) {
|
||||||
|
SmallPtrSet<Decl *, 16> checked;
|
||||||
|
return usesFeatureRethrowsProtocol(decl, checked);
|
||||||
|
}
|
||||||
|
|
||||||
/// Determine the set of "new" features used on a given declaration.
|
/// Determine the set of "new" features used on a given declaration.
|
||||||
///
|
///
|
||||||
/// Note: right now, all features we check for are "new". At some point, we'll
|
/// Note: right now, all features we check for are "new". At some point, we'll
|
||||||
|
|||||||
@@ -67,6 +67,16 @@ public class OldSchool: MP {
|
|||||||
public func takeClass() async { }
|
public func takeClass() async { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK: #if compiler(>=5.3) && $RethrowsProtocol
|
||||||
|
// CHECK-NEXT: @rethrows public protocol RP
|
||||||
|
@rethrows public protocol RP {
|
||||||
|
func f() throws
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK: #if compiler(>=5.3) && $RethrowsProtocol
|
||||||
|
// CHECK-NEXT: public func acceptsRP
|
||||||
|
public func acceptsRP<T: RP>(_: T) { }
|
||||||
|
|
||||||
// CHECK-NOT: #if compiler(>=5.3) && $MarkerProtocol
|
// CHECK-NOT: #if compiler(>=5.3) && $MarkerProtocol
|
||||||
// CHECK: extension Array : FeatureTest.MP where Element : FeatureTest.MP {
|
// CHECK: extension Array : FeatureTest.MP where Element : FeatureTest.MP {
|
||||||
extension Array: FeatureTest.MP where Element : FeatureTest.MP { }
|
extension Array: FeatureTest.MP where Element : FeatureTest.MP { }
|
||||||
|
|||||||
Reference in New Issue
Block a user