Skip to content

Commit 1797c4c

Browse files
committed
[NoncopyableGenerics] fix swiftinterface
1 parent 7bdc04d commit 1797c4c

File tree

7 files changed

+155
-73
lines changed

7 files changed

+155
-73
lines changed

include/swift/AST/InverseMarking.h

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,25 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#ifndef SWIFT_LIB_SEMA_INVERSEMARKING_H
14-
#define SWIFT_LIB_SEMA_INVERSEMARKING_H
13+
#ifndef SWIFT_AST_INVERSEMARKING_H
14+
#define SWIFT_AST_INVERSEMARKING_H
1515

1616
#include "swift/AST/KnownProtocols.h"
1717
#include "swift/Basic/SourceLoc.h"
1818
#include "swift/Basic/OptionalEnum.h"
1919

2020
namespace swift {
2121

22+
class NoncopyableAnnotationRequest;
23+
2224
/// Describes the way an inverse and its corresponding positive contraint
2325
/// appears on a TypeDecl, i.e., the way it was marked.
2426
struct InverseMarking {
2527
enum class Kind : uint8_t {
2628
None, // No inverse marking is present
2729
Inferred, // Inverse is inferred based on generic parameters.
2830
Explicit, // Inverse is explicitly present.
29-
30-
LAST = Explicit
31+
LegacyExplicit, // An equivalent, explicit legacy annotation is present.
3132
};
3233

3334
// Describes what kind of mark was found, if any.
@@ -43,15 +44,18 @@ struct InverseMarking {
4344
Mark(Kind k, SourceLoc l = SourceLoc())
4445
: kind(k), loc(l) {};
4546

46-
// Is there an inferred or explicit marking?
47-
bool isPresent() const {
48-
return getKind() != Kind::None;
49-
}
50-
operator bool() { return isPresent(); }
51-
5247
Kind getKind() const {
5348
return kind.getValueOr(Kind::None);
5449
}
50+
bool is(Kind k) const {
51+
return getKind() == k;
52+
}
53+
54+
// Is there an inferred or explicit marking?
55+
bool isPresent() const {
56+
return !is(Kind::None);
57+
}
58+
operator bool() const { return isPresent(); }
5559

5660
SourceLoc getLoc() const { return loc; }
5761

@@ -68,34 +72,29 @@ struct InverseMarking {
6872
}
6973

7074
void setIfUnset(Mark other) {
71-
if (kind.hasValue())
75+
if (!other.kind.hasValue())
7276
return;
73-
kind = other.kind;
74-
loc = other.loc;
77+
setIfUnset(other.kind.getValue(), other.loc);
7578
}
7679

77-
Mark with(Kind k) {
78-
kind = k;
79-
return *this;
80+
Mark with(Kind k) const {
81+
return Mark(k, loc);
8082
}
8183
};
8284

8385
private:
8486
Mark inverse;
8587
Mark positive;
88+
89+
// This friend initializes the marks.
90+
friend NoncopyableAnnotationRequest;
8691
public:
8792

8893
// Creates an empty marking.
8994
InverseMarking() {}
9095

91-
Mark &getInverse() { return inverse; }
92-
Mark &getPositive() { return positive; }
93-
94-
// Merge the results of another marking into this one.
95-
void merge(InverseMarking other) const {
96-
other.inverse.setIfUnset(other.inverse);
97-
other.positive.setIfUnset(other.positive);
98-
}
96+
Mark const& getInverse() const { return inverse; }
97+
Mark const& getPositive() const { return positive; }
9998

10099
static InverseMarking forInverse(Kind kind, SourceLoc loc = SourceLoc()) {
101100
InverseMarking marking;
@@ -107,4 +106,4 @@ struct InverseMarking {
107106

108107
}
109108

110-
#endif //SWIFT_LIB_SEMA_INVERSEMARKING_H
109+
#endif //SWIFT_AST_INVERSEMARKING_H

include/swift/AST/Type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,7 @@ class CanType : public Type {
541541
CanType getNominalParent() const; // in Types.h
542542
NominalTypeDecl *getAnyNominal() const;
543543
GenericTypeDecl *getAnyGeneric() const;
544+
TypeDecl *getAnyTypeDecl() const;
544545

545546
bool isForeignReferenceType(); // in Types.h
546547

include/swift/AST/Types.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,11 @@ class alignas(1 << TypeAlignInBits) TypeBase
12331233
/// declaration.
12341234
GenericTypeDecl *getAnyGeneric();
12351235

1236+
// If this a GenericType, ModuleType, or GenericTypeParamType, return the
1237+
// type declaration.
1238+
// NOTE: Will not attempt to find an AssociatedTypeDecl.
1239+
TypeDecl *getAnyTypeDecl();
1240+
12361241
/// removeArgumentLabels - Retrieve a version of this type with all
12371242
/// argument labels removed.
12381243
Type removeArgumentLabels(unsigned numArgumentLabels);
@@ -7423,9 +7428,9 @@ inline GenericTypeDecl *TypeBase::getAnyGeneric() {
74237428
return getCanonicalType().getAnyGeneric();
74247429
}
74257430

7426-
//inline TypeDecl *TypeBase::getAnyTypeDecl() {
7427-
// return getCanonicalType().getAnyTypeDecl();
7428-
//}
7431+
inline TypeDecl *TypeBase::getAnyTypeDecl() {
7432+
return getCanonicalType().getAnyTypeDecl();
7433+
}
74297434

74307435
inline bool TypeBase::isBuiltinIntegerType(unsigned n) {
74317436
if (auto intTy = dyn_cast<BuiltinIntegerType>(getCanonicalType()))

lib/AST/ASTPrinter.cpp

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "swift/AST/GenericEnvironment.h"
3030
#include "swift/AST/GenericParamList.h"
3131
#include "swift/AST/GenericSignature.h"
32+
#include "swift/AST/InverseMarking.h"
3233
#include "swift/AST/MacroDefinition.h"
3334
#include "swift/AST/Module.h"
3435
#include "swift/AST/NameLookup.h"
@@ -3329,33 +3330,58 @@ static bool usesFeatureFlowSensitiveConcurrencyCaptures(Decl *decl) {
33293330
return false;
33303331
}
33313332

3332-
static bool usesFeatureMoveOnly(Decl *decl) {
3333+
/// \param isRelevantInverse the function used to inspect a mark corresponding
3334+
/// to an inverse to determine whether it "has" an inverse that we care about.
3335+
static bool hasInverseCopyable(
3336+
Decl *decl,
3337+
std::function<bool(InverseMarking const&)> isRelevantInverse) {
3338+
33333339
if (auto *extension = dyn_cast<ExtensionDecl>(decl)) {
33343340
if (auto *nominal = extension->getSelfNominalTypeDecl())
3335-
if (nominal->canBeNoncopyable())
3341+
if (isRelevantInverse(nominal->getNoncopyableMarking()))
33363342
return true;
33373343
}
33383344

33393345
if (auto typeDecl = dyn_cast<TypeDecl>(decl)) {
3340-
if (typeDecl->canBeNoncopyable())
3346+
if (isRelevantInverse(typeDecl->getNoncopyableMarking()))
33413347
return true;
3348+
3349+
// Check the protocol's associated types too.
3350+
if (auto proto = dyn_cast<ProtocolDecl>(decl)) {
3351+
auto hasNoncopyable = llvm::any_of(proto->getAssociatedTypeMembers(),
3352+
[&](AssociatedTypeDecl *assocTyDecl) {
3353+
return isRelevantInverse(assocTyDecl->getNoncopyableMarking());
3354+
});
3355+
if (hasNoncopyable)
3356+
return true;
3357+
}
33423358
}
33433359

33443360
if (auto value = dyn_cast<ValueDecl>(decl)) {
3345-
// Check for move-only types in the types of this declaration.
3361+
// Check for noncopyable types in the types of this declaration.
33463362
if (Type type = value->getInterfaceType()) {
3347-
bool hasMoveOnly = type.findIf([](Type type) {
3348-
return type->isNoncopyable();
3363+
bool hasNoncopyable = type.findIf([&](Type type) {
3364+
if (auto typeDecl = type->getAnyTypeDecl())
3365+
if (isRelevantInverse(typeDecl->getNoncopyableMarking()))
3366+
return true;
3367+
3368+
return false;
33493369
});
33503370

3351-
if (hasMoveOnly)
3371+
if (hasNoncopyable)
33523372
return true;
33533373
}
33543374
}
33553375

33563376
return false;
33573377
}
33583378

3379+
static bool usesFeatureMoveOnly(Decl *decl) {
3380+
return hasInverseCopyable(decl, [](auto &marking) -> bool {
3381+
return marking.getInverse().is(InverseMarking::Kind::LegacyExplicit);
3382+
});
3383+
}
3384+
33593385
static bool usesFeatureLazyImmediate(Decl *D) { return false; }
33603386

33613387
static bool usesFeatureMoveOnlyClasses(Decl *decl) {
@@ -3393,9 +3419,17 @@ static bool usesFeatureMoveOnlyPartialConsumption(Decl *decl) {
33933419
}
33943420

33953421
static bool usesFeatureNoncopyableGenerics(Decl *decl) {
3396-
// FIXME: need to look for suppressed entries on generic parameters or
3397-
// inheritance clauses!
3398-
return false;
3422+
return hasInverseCopyable(decl, [](auto &marking) -> bool {
3423+
switch (marking.getInverse().getKind()) {
3424+
case InverseMarking::Kind::None:
3425+
case InverseMarking::Kind::LegacyExplicit: // covered by MoveOnly
3426+
return false;
3427+
3428+
case InverseMarking::Kind::Explicit:
3429+
case InverseMarking::Kind::Inferred:
3430+
return true;
3431+
}
3432+
});
33993433
}
34003434

34013435
static bool usesFeatureOneWayClosureParameters(Decl *decl) {

lib/AST/Type.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ GenericTypeDecl *CanType::getAnyGeneric() const {
9191
return nullptr;
9292
}
9393

94+
TypeDecl *CanType::getAnyTypeDecl() const {
95+
// NOTE: there is no simple way to determine if it's an AssociatedTypeDecl.
96+
if (auto genericTy = getAnyGeneric())
97+
return genericTy;
98+
if (auto gtpt = dyn_cast<GenericTypeParamType>(*this))
99+
return gtpt->getDecl();
100+
if (auto module = dyn_cast<ModuleType>(*this))
101+
return module->getModule();
102+
return nullptr;
103+
}
104+
94105
//===----------------------------------------------------------------------===//
95106
// Various Type Methods.
96107
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)