@@ -6240,6 +6240,20 @@ void GenericSignatureBuilder::ExplicitRequirement::dump(
6240
6240
out << rhs.get <LayoutConstraint>();
6241
6241
}
6242
6242
6243
+ static bool typeImpliesLayoutConstraint (Type t, LayoutConstraint layout) {
6244
+ if (layout->isRefCounted () && t->satisfiesClassConstraint ())
6245
+ return true ;
6246
+
6247
+ return false ;
6248
+ }
6249
+
6250
+ static bool typeConflictsWithLayoutConstraint (Type t, LayoutConstraint layout) {
6251
+ if (layout->isClass () && !t->satisfiesClassConstraint ())
6252
+ return true ;
6253
+
6254
+ return false ;
6255
+ }
6256
+
6243
6257
void GenericSignatureBuilder::computeRedundantRequirements () {
6244
6258
assert (!Impl->computedRedundantRequirements &&
6245
6259
" Already computed redundant requirements" );
@@ -6397,9 +6411,12 @@ void GenericSignatureBuilder::computeRedundantRequirements() {
6397
6411
concreteTypeRequirement);
6398
6412
}
6399
6413
6414
+ Optional<ExplicitRequirement> layoutRequirement;
6415
+
6400
6416
if (equivClass.layout ) {
6401
6417
SmallVector<Constraint<LayoutConstraint>, 2 > exact;
6402
6418
SmallVector<Constraint<LayoutConstraint>, 2 > lessSpecific;
6419
+ SmallVector<Constraint<LayoutConstraint>, 2 > impliedByConcrete;
6403
6420
6404
6421
for (const auto &constraint : equivClass.layoutConstraints ) {
6405
6422
auto *source = constraint.source ;
@@ -6416,6 +6433,12 @@ void GenericSignatureBuilder::computeRedundantRequirements() {
6416
6433
if (derivedViaConcrete)
6417
6434
continue ;
6418
6435
6436
+ if (resolvedConcreteType) {
6437
+ if (typeImpliesLayoutConstraint (resolvedConcreteType, layout)) {
6438
+ impliedByConcrete.push_back (constraint);
6439
+ }
6440
+ }
6441
+
6419
6442
if (layout == equivClass.layout ) {
6420
6443
exact.push_back (constraint);
6421
6444
continue ;
@@ -6431,12 +6454,16 @@ void GenericSignatureBuilder::computeRedundantRequirements() {
6431
6454
std::make_pair (req, equivClass.layout ));
6432
6455
}
6433
6456
6434
- // FIXME: Check for a conflict via the concrete type.
6435
6457
lessSpecific.push_back (constraint);
6436
6458
}
6437
6459
6438
- graph.addConstraintsFromEquivClass (RequirementKind::Layout,
6439
- exact, lessSpecific);
6460
+ layoutRequirement =
6461
+ graph.addConstraintsFromEquivClass (RequirementKind::Layout,
6462
+ exact, lessSpecific);
6463
+
6464
+ graph.handleConstraintsImpliedByConcrete (RequirementKind::Layout,
6465
+ impliedByConcrete,
6466
+ concreteTypeRequirement);
6440
6467
}
6441
6468
6442
6469
if (resolvedConcreteType && resolvedSuperclass) {
@@ -6445,6 +6472,13 @@ void GenericSignatureBuilder::computeRedundantRequirements() {
6445
6472
{*concreteTypeRequirement, *superclassRequirement,
6446
6473
resolvedConcreteType, resolvedSuperclass});
6447
6474
}
6475
+ } else if (resolvedConcreteType && equivClass.layout ) {
6476
+ if (typeConflictsWithLayoutConstraint (resolvedConcreteType,
6477
+ equivClass.layout )) {
6478
+ Impl->ConflictingConcreteTypeRequirements .push_back (
6479
+ {*concreteTypeRequirement, *layoutRequirement,
6480
+ resolvedConcreteType, equivClass.layout });
6481
+ }
6448
6482
}
6449
6483
}
6450
6484
@@ -7267,8 +7301,6 @@ void GenericSignatureBuilder::diagnoseConflictingConcreteTypeRequirements() cons
7267
7301
SourceLoc loc = pair.concreteTypeRequirement .getSource ()->getLoc ();
7268
7302
SourceLoc otherLoc = pair.otherRequirement .getSource ()->getLoc ();
7269
7303
7270
- Type otherRHS = pair.otherRHS .get <Type>();
7271
-
7272
7304
if (loc.isInvalid () && otherLoc.isInvalid ())
7273
7305
continue ;
7274
7306
@@ -7280,18 +7312,30 @@ void GenericSignatureBuilder::diagnoseConflictingConcreteTypeRequirements() cons
7280
7312
switch (pair.otherRequirement .getKind ()) {
7281
7313
case RequirementKind::Superclass: {
7282
7314
Context.Diags .diagnose (subjectLoc, diag::type_does_not_inherit,
7283
- subjectType, pair.resolvedConcreteType , otherRHS);
7315
+ subjectType, pair.resolvedConcreteType ,
7316
+ pair.otherRHS .get <Type>());
7284
7317
7285
7318
if (otherLoc.isValid ()) {
7286
7319
Context.Diags .diagnose (otherLoc, diag::superclass_redundancy_here,
7287
- subjectType, otherRHS);
7320
+ subjectType, pair.otherRHS .get <Type>());
7321
+ }
7322
+
7323
+ break ;
7324
+ }
7325
+
7326
+ case RequirementKind::Layout: {
7327
+ Context.Diags .diagnose (subjectLoc, diag::type_is_not_a_class,
7328
+ subjectType, pair.resolvedConcreteType , Type ());
7329
+
7330
+ if (otherLoc.isValid ()) {
7331
+ Context.Diags .diagnose (otherLoc, diag::previous_layout_constraint,
7332
+ subjectType, pair.otherRHS .get <LayoutConstraint>());
7288
7333
}
7289
7334
7290
7335
break ;
7291
7336
}
7292
7337
7293
7338
case RequirementKind::Conformance:
7294
- case RequirementKind::Layout:
7295
7339
case RequirementKind::SameType:
7296
7340
llvm_unreachable (" TODO" );
7297
7341
}
0 commit comments