Skip to content

Commit 338d426

Browse files
authored
Merge pull request #70278 from kavon/refactor-InverseType
[NCGenerics] fold InverseType into PCT
2 parents b6d0afb + 63b3e76 commit 338d426

39 files changed

+540
-419
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3158,11 +3158,11 @@ ERROR(requires_not_suitable_archetype,none,
31583158
(Type))
31593159

31603160
ERROR(requires_not_suitable_inverse_subject,none,
3161-
"cannot apply inverse %1 to type %0 in conformance requirement",
3162-
(Type, Type))
3161+
"cannot apply inverse '~%1' to type %0 in conformance requirement",
3162+
(Type, StringRef))
31633163

31643164
ERROR(requires_not_suitable_inverse_outer_subject,none,
3165-
"cannot add inverse constraint '%0: %1' "
3165+
"cannot add inverse constraint '%0: ~%1' "
31663166
"on generic parameter '%0' defined in outer scope",
31673167
(StringRef, StringRef))
31683168

@@ -7558,6 +7558,11 @@ ERROR(accessor_macro_not_single_var, none,
75587558
ERROR(noncopyable_but_copyable, none,
75597559
"%kind0 required to be 'Copyable' but is marked with '~Copyable'",
75607560
(const ValueDecl *))
7561+
ERROR(noncopyable_generic_but_copyable, none,
7562+
"%0 required to be '%1' but is marked with '~%1'",
7563+
(Type, StringRef))
7564+
WARNING(redundant_inverse_constraint,none,
7565+
"redundant constraint %0 : '~%1'", (Type, StringRef))
75617566
ERROR(noncopyable_class, none,
75627567
"classes cannot be noncopyable",
75637568
())

include/swift/AST/ExistentialLayout.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ struct ExistentialLayout {
3737
}
3838

3939
ExistentialLayout(CanProtocolType type);
40-
ExistentialLayout(CanInverseType type);
4140
ExistentialLayout(CanProtocolCompositionType type);
4241
ExistentialLayout(CanParameterizedProtocolType type);
4342

include/swift/AST/LayoutConstraint.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,10 @@ class LayoutConstraintInfo
171171
std::string getString(const PrintOptions &PO = PrintOptions()) const;
172172

173173
/// Return the name of this layout constraint.
174-
StringRef getName(bool useClassLayoutName = false) const;
174+
StringRef getName(bool internalName = false) const;
175175

176176
/// Return the name of a layout constraint with a given kind.
177-
static StringRef getName(LayoutConstraintKind Kind, bool useClassLayoutName = false);
177+
static StringRef getName(LayoutConstraintKind Kind, bool internalName = false);
178178

179179
static bool isKnownLayout(LayoutConstraintKind Kind);
180180

include/swift/AST/PrintOptions.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,8 @@ struct PrintOptions {
328328
/// Whether to print generic requirements in a where clause.
329329
bool PrintGenericRequirements = true;
330330

331-
/// Whether to print the real layout name instead of AnyObject
332-
/// for class layout
333-
bool PrintClassLayoutName = false;
331+
/// Whether to print the internal layout name instead of AnyObject, etc.
332+
bool PrintInternalLayoutName = false;
334333

335334
/// Suppress emitting @available(*, noasync)
336335
bool SuppressNoAsyncAvailabilityAttr = false;

include/swift/AST/Requirement.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
namespace swift {
2929

30+
enum class InvertibleProtocolKind : uint8_t;
31+
3032
/// Return type of Requirement::checkRequirement().
3133
enum class CheckRequirementResult : uint8_t {
3234
/// The requirement was fully satisfied.
@@ -222,6 +224,31 @@ struct StructuralRequirement {
222224
/// diagnosed as redundant, since we want to give users the option of
223225
/// spelling out these requirements explicitly.
224226
bool inferred = false;
227+
228+
/// A flag indicating whether this requirement was produced via the expansion
229+
/// of default conformances to invertible protocols.
230+
bool fromDefault = false;
231+
};
232+
233+
struct InverseRequirement {
234+
Type subject;
235+
ProtocolDecl *protocol;
236+
SourceLoc loc;
237+
238+
InverseRequirement(Type subject, ProtocolDecl *protocol, SourceLoc loc);
239+
240+
InvertibleProtocolKind getKind() const;
241+
242+
static void enumerateDefaultedParams(TypeDecl *decl,
243+
SmallVectorImpl<Type> &result);
244+
245+
static void expandDefault(Type gp,
246+
SourceLoc loc,
247+
SmallVectorImpl<StructuralRequirement> &result);
248+
249+
static void expandDefaults(ASTContext &ctx,
250+
ArrayRef<Type> gps,
251+
SmallVectorImpl<StructuralRequirement> &result);
225252
};
226253

227254
} // end namespace swift

include/swift/AST/TypeMatcher.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -495,14 +495,6 @@ class TypeMatcher {
495495
sugaredFirstType);
496496
}
497497

498-
bool visitInverseType(CanInverseType firstInverse,
499-
Type secondType,
500-
Type sugaredFirstType) {
501-
// NOTE: If this visitor is reached, determine whether it should've been
502-
// before implementing this.
503-
llvm_unreachable("Yahaha! You found me!");
504-
}
505-
506498
bool visitLValueType(CanLValueType firstLValue, Type secondType,
507499
Type sugaredFirstType) {
508500
if (auto secondLValue = secondType->getAs<LValueType>()) {

include/swift/AST/TypeNodes.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ ARTIFICIAL_TYPE(SILMoveOnlyWrapped, Type)
180180
ALWAYS_CANONICAL_ARTIFICIAL_TYPE(SILPack, Type)
181181
ARTIFICIAL_TYPE(SILToken, Type)
182182
TYPE(ProtocolComposition, Type)
183-
UNCHECKED_TYPE(Inverse, Type)
184183
TYPE(ParameterizedProtocol, Type)
185184
TYPE(Existential, Type)
186185
TYPE(LValue, Type)

include/swift/AST/Types.h

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,48 +1532,6 @@ class NominalOrBoundGenericNominalType : public AnyGenericType {
15321532
};
15331533
DEFINE_EMPTY_CAN_TYPE_WRAPPER(NominalOrBoundGenericNominalType, AnyGenericType)
15341534

1535-
/// InverseType represents the "inverse" of a ProtocolType as a constraint.
1536-
/// An inverse represents the _absence_ of an implicit constraint to the given
1537-
/// protocol.
1538-
///
1539-
/// Otherwise, an inverse is not a real type! It's an annotation for other types
1540-
/// to signal whether an implicit requirement on that type should be omitted.
1541-
/// Because that annotation is expressed in the surface language as if it _were_
1542-
/// a type (that is, as a type constraint) we still model it as a Type through
1543-
/// typechecking.
1544-
class InverseType final : public TypeBase {
1545-
Type protocol;
1546-
1547-
InverseType(Type type,
1548-
const ASTContext *canonicalContext,
1549-
RecursiveTypeProperties properties)
1550-
: TypeBase(TypeKind::Inverse, canonicalContext, properties),
1551-
protocol(type) {
1552-
assert(protocol->is<ProtocolType>());
1553-
}
1554-
1555-
public:
1556-
/// Produce an inverse constraint type for the given protocol type.
1557-
static Type get(Type protocolType);
1558-
1559-
1560-
/// Obtain the underlying \c ProtocolType that was inverted.
1561-
Type getInvertedProtocol() const {
1562-
return protocol;
1563-
}
1564-
1565-
/// Get known kind of inverse this type represents.
1566-
InvertibleProtocolKind getInverseKind() const;
1567-
1568-
// Implement isa/cast/dyncast/etc.
1569-
static bool classof(const TypeBase *T) {
1570-
return T->getKind() == TypeKind::Inverse;
1571-
}
1572-
};
1573-
BEGIN_CAN_TYPE_WRAPPER(InverseType, Type)
1574-
PROXY_CAN_TYPE_SIMPLE_GETTER(getInvertedProtocol)
1575-
END_CAN_TYPE_WRAPPER(InverseType, Type)
1576-
15771535
/// ErrorType - Represents the type of an erroneously constructed declaration,
15781536
/// expression, or type. When creating ErrorTypes, an associated error
15791537
/// diagnostic should always be emitted. That way when later stages of
@@ -5813,6 +5771,9 @@ class ProtocolCompositionType final : public TypeBase,
58135771
/// Constructs a protocol composition corresponding to the `AnyObject` type.
58145772
static Type theAnyObjectType(const ASTContext &C);
58155773

5774+
/// Constructs a protocol composition corresponding to the `~IP` type.
5775+
static Type getInverseOf(const ASTContext &C, InvertibleProtocolKind IP);
5776+
58165777
/// Canonical protocol composition types are minimized only to a certain
58175778
/// degree to preserve ABI compatibility. This routine enables performing
58185779
/// slower, but stricter minimization at need (e.g. redeclaration checking).
@@ -7296,8 +7257,7 @@ inline bool TypeBase::isConstraintType() const {
72967257
inline bool CanType::isConstraintTypeImpl(CanType type) {
72977258
return (isa<ProtocolType>(type) ||
72987259
isa<ProtocolCompositionType>(type) ||
7299-
isa<ParameterizedProtocolType>(type) ||
7300-
isa<InverseType>(type));
7260+
isa<ParameterizedProtocolType>(type));
73017261
}
73027262

73037263
inline bool TypeBase::isExistentialType() {
@@ -7313,7 +7273,6 @@ inline bool CanType::isExistentialTypeImpl(CanType type) {
73137273
isa<ProtocolCompositionType>(type) ||
73147274
isa<ExistentialType>(type) ||
73157275
isa<ParameterizedProtocolType>(type);
7316-
// TODO(kavon): treat InverseType as an existential, etc?
73177276
}
73187277

73197278
inline bool CanType::isAnyExistentialTypeImpl(CanType type) {

lib/AST/ASTContext.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,6 @@ struct ASTContext::Implementation {
460460
llvm::DenseMap<std::pair<ClassDecl*, Type>, ClassType*> ClassTypes;
461461
llvm::DenseMap<std::pair<ProtocolDecl*, Type>, ProtocolType*> ProtocolTypes;
462462
llvm::DenseMap<Type, ExistentialType *> ExistentialTypes;
463-
llvm::DenseMap<Type, InverseType *> InverseTypes;
464463
llvm::FoldingSet<UnboundGenericType> UnboundGenericTypes;
465464
llvm::FoldingSet<BoundGenericType> BoundGenericTypes;
466465
llvm::FoldingSet<ProtocolCompositionType> ProtocolCompositionTypes;
@@ -3842,28 +3841,6 @@ Type ExistentialMetatypeType::getExistentialInstanceType() {
38423841
return ExistentialType::get(getInstanceType());
38433842
}
38443843

3845-
InvertibleProtocolKind InverseType::getInverseKind() const {
3846-
return *getInvertibleProtocolKind(*protocol->getKnownProtocol());
3847-
}
3848-
3849-
Type InverseType::get(Type invertedProto) {
3850-
auto &C = invertedProto->getASTContext();
3851-
3852-
auto properties = invertedProto->getRecursiveProperties();
3853-
auto arena = getArena(properties);
3854-
3855-
auto &entry = C.getImpl().getArena(arena).InverseTypes[invertedProto];
3856-
if (entry)
3857-
return entry;
3858-
3859-
const ASTContext *canonicalContext =
3860-
invertedProto->isCanonical() ? &C : nullptr;
3861-
3862-
return entry = new (C, arena) InverseType(invertedProto,
3863-
canonicalContext,
3864-
properties);
3865-
}
3866-
38673844
ModuleType *ModuleType::get(ModuleDecl *M) {
38683845
ASTContext &C = M->getASTContext();
38693846

lib/AST/ASTDumper.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4375,12 +4375,6 @@ namespace {
43754375
printFoot();
43764376
}
43774377

4378-
void visitInverseType(InverseType *T, StringRef label) {
4379-
printCommon("inverse_type", label);
4380-
printRec(T->getInvertedProtocol());
4381-
printFoot();
4382-
}
4383-
43844378
void visitLValueType(LValueType *T, StringRef label) {
43854379
printCommon("lvalue_type", label);
43864380
printRec(T->getObjectType());

lib/AST/ASTMangler.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,9 +1401,6 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
14011401
case TypeKind::LValue:
14021402
llvm_unreachable("@lvalue types should not occur in function interfaces");
14031403

1404-
case TypeKind::Inverse:
1405-
llvm_unreachable("inverse types should not appear in interfaces");
1406-
14071404
case TypeKind::InOut:
14081405
appendType(cast<InOutType>(tybase)->getObjectType(), sig, forDecl);
14091406
return appendOperator("z");

lib/AST/ASTPrinter.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6317,11 +6317,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
63176317
Printer << "_";
63186318
}
63196319

6320-
void visitInverseType(InverseType *T) {
6321-
Printer << "~";
6322-
visit(T->getInvertedProtocol());
6323-
}
6324-
63256320
void visitPlaceholderType(PlaceholderType *T) {
63266321
if (Options.PrintTypesForDebugging) {
63276322
Printer << "<<placeholder for ";
@@ -7680,15 +7675,15 @@ void LayoutConstraint::print(raw_ostream &OS,
76807675

76817676
void LayoutConstraintInfo::print(ASTPrinter &Printer,
76827677
const PrintOptions &PO) const {
7683-
Printer << getName(PO.PrintClassLayoutName);
7678+
Printer << getName(PO.PrintInternalLayoutName);
76847679
switch (getKind()) {
76857680
case LayoutConstraintKind::UnknownLayout:
76867681
case LayoutConstraintKind::RefCountedObject:
76877682
case LayoutConstraintKind::NativeRefCountedObject:
76887683
case LayoutConstraintKind::Class:
76897684
case LayoutConstraintKind::NativeClass:
76907685
case LayoutConstraintKind::Trivial:
7691-
return;
7686+
return; // non-parameterized cases
76927687
case LayoutConstraintKind::TrivialOfAtMostSize:
76937688
case LayoutConstraintKind::TrivialOfExactSize:
76947689
Printer << "(";

lib/AST/Attr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1261,7 +1261,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
12611261
Printer << "@_noMetadata ";
12621262
}
12631263
auto OptionsCopy = Options;
1264-
OptionsCopy.PrintClassLayoutName = typeErased;
1264+
OptionsCopy.PrintInternalLayoutName = typeErased;
12651265
req.print(Printer, OptionsCopy);
12661266
},
12671267
[&] { Printer << ", "; });

lib/AST/ExistentialGeneralization.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,6 @@ class Generalizer : public CanTypeVisitor<Generalizer, Type> {
110110
origType->hasExplicitAnyObject());
111111
}
112112

113-
Type visitInverseType(CanInverseType type) {
114-
// TODO(kavon): determine how to handle inverses for ExistentialGeneralization
115-
llvm_unreachable("unimplemented");
116-
}
117-
118113
// Generalize the type arguments of nominal types.
119114
Type visitBoundGenericType(CanBoundGenericType origType) {
120115
return generalizeGenericArguments(origType->getDecl(), origType);

lib/AST/LayoutConstraint.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,16 @@ LayoutConstraint getLayoutConstraint(Identifier ID, ASTContext &Ctx) {
5151
LayoutConstraintKind::UnknownLayout, Ctx);
5252
}
5353

54-
StringRef LayoutConstraintInfo::getName(bool useClassLayoutName) const {
55-
return getName(getKind(), useClassLayoutName);
54+
StringRef LayoutConstraintInfo::getName(bool internalName) const {
55+
return getName(getKind(), internalName);
5656
}
5757

58-
StringRef LayoutConstraintInfo::getName(LayoutConstraintKind Kind, bool useClassLayoutName) {
58+
StringRef LayoutConstraintInfo::getName(LayoutConstraintKind Kind, bool internalName) {
5959
switch (Kind) {
6060
case LayoutConstraintKind::UnknownLayout:
6161
return "_UnknownLayout";
6262
case LayoutConstraintKind::Class:
63-
return useClassLayoutName ? "_Class" : "AnyObject";
63+
return internalName ? "_Class" : "AnyObject";
6464
case LayoutConstraintKind::NativeClass:
6565
return "_NativeClass";
6666
case LayoutConstraintKind::RefCountedObject:

0 commit comments

Comments
 (0)