Skip to content

Commit aedba4d

Browse files
committed
GSB: Stop computing 'derived via concrete' sources
1 parent 8d7733d commit aedba4d

File tree

3 files changed

+21
-85
lines changed

3 files changed

+21
-85
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,8 +1229,7 @@ class GenericSignatureBuilder::RequirementSource final
12291229
/// requirement redundant, because without said original requirement, the
12301230
/// derived requirement ceases to hold.
12311231
bool isSelfDerivedSource(GenericSignatureBuilder &builder,
1232-
Type type,
1233-
bool &derivedViaConcrete) const;
1232+
Type type) const;
12341233

12351234
/// For a requirement source that describes the requirement \c type:proto,
12361235
/// retrieve the minimal subpath of this requirement source that will
@@ -1242,8 +1241,7 @@ class GenericSignatureBuilder::RequirementSource final
12421241
const RequirementSource *getMinimalConformanceSource(
12431242
GenericSignatureBuilder &builder,
12441243
Type type,
1245-
ProtocolDecl *proto,
1246-
bool &derivedViaConcrete) const;
1244+
ProtocolDecl *proto) const;
12471245

12481246
/// Retrieve a source location that corresponds to the requirement.
12491247
SourceLoc getLoc() const;

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 17 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -930,10 +930,8 @@ bool RequirementSource::shouldDiagnoseRedundancy(bool primary) const {
930930
}
931931

932932
bool RequirementSource::isSelfDerivedSource(GenericSignatureBuilder &builder,
933-
Type type,
934-
bool &derivedViaConcrete) const {
935-
return getMinimalConformanceSource(builder, type, /*proto=*/nullptr,
936-
derivedViaConcrete)
933+
Type type) const {
934+
return getMinimalConformanceSource(builder, type, /*proto=*/nullptr)
937935
!= this;
938936
}
939937

@@ -983,10 +981,7 @@ static bool isSelfDerivedProtocolRequirementInProtocol(
983981
const RequirementSource *RequirementSource::getMinimalConformanceSource(
984982
GenericSignatureBuilder &builder,
985983
Type currentType,
986-
ProtocolDecl *proto,
987-
bool &derivedViaConcrete) const {
988-
derivedViaConcrete = false;
989-
984+
ProtocolDecl *proto) const {
990985
// If it's not a derived requirement, it's not self-derived.
991986
if (!isDerivedRequirement()) return this;
992987

@@ -1053,15 +1048,6 @@ const RequirementSource *RequirementSource::getMinimalConformanceSource(
10531048
ArchetypeResolutionKind::WellFormed);
10541049
assert(parentEquivClass && "Not a well-formed type?");
10551050

1056-
if (requirementSignatureSelfProto) {
1057-
if (parentEquivClass->concreteType)
1058-
derivedViaConcrete = true;
1059-
else if (parentEquivClass->superclass &&
1060-
builder.lookupConformance(parentEquivClass->superclass,
1061-
source->getProtocolDecl()))
1062-
derivedViaConcrete = true;
1063-
}
1064-
10651051
// The parent potential archetype must conform to the protocol in which
10661052
// this requirement resides. Add this constraint.
10671053
if (auto startOfPath =
@@ -1130,7 +1116,7 @@ const RequirementSource *RequirementSource::getMinimalConformanceSource(
11301116
redundantSubpath->first,
11311117
redundantSubpath->second);
11321118
return shorterSource
1133-
->getMinimalConformanceSource(builder, currentType, proto, derivedViaConcrete);
1119+
->getMinimalConformanceSource(builder, currentType, proto);
11341120
}
11351121

11361122
// It's self-derived but we don't have a redundant subpath to eliminate.
@@ -2824,13 +2810,10 @@ static void concretizeNestedTypeFromConcreteParent(
28242810
const RequirementSource *parentConcreteSource = nullptr;
28252811

28262812
for (const auto &constraint : parentEquiv->conformsTo.find(proto)->second) {
2827-
bool derivedViaConcrete = false;
2828-
28292813
auto *minimal = constraint.source->getMinimalConformanceSource(
2830-
builder, constraint.getSubjectDependentType({ }), proto,
2831-
derivedViaConcrete);
2814+
builder, constraint.getSubjectDependentType({ }), proto);
28322815

2833-
if (minimal == nullptr || derivedViaConcrete)
2816+
if (minimal == nullptr)
28342817
continue;
28352818

28362819
if (!isSuperclassConstrained) {
@@ -5679,13 +5662,10 @@ static void expandSameTypeConstraints(GenericSignatureBuilder &builder,
56795662
bool alreadyFound = false;
56805663
const RequirementSource *conformsSource = nullptr;
56815664
for (const auto &constraint : conforms.second) {
5682-
bool derivedViaConcrete = false;
5683-
56845665
auto *minimal = constraint.source->getMinimalConformanceSource(
5685-
builder, constraint.getSubjectDependentType({ }), proto,
5686-
derivedViaConcrete);
5666+
builder, constraint.getSubjectDependentType({ }), proto);
56875667

5688-
if (minimal == nullptr || derivedViaConcrete)
5668+
if (minimal == nullptr)
56895669
continue;
56905670

56915671
if (minimal->getAffectedType()->isEqual(dependentType)) {
@@ -5910,18 +5890,14 @@ void GenericSignatureBuilder::computeRedundantRequirements(
59105890
requirementSignatureSelfProto,
59115891
[&](const Constraint<ProtocolDecl *> &constraint) {
59125892
// FIXME: Remove this.
5913-
bool derivedViaConcrete;
59145893
auto minimalSource =
59155894
constraint.source->getMinimalConformanceSource(
59165895
*this,
59175896
constraint.getSubjectDependentType({ }),
5918-
proto, derivedViaConcrete);
5897+
proto);
59195898
if (minimalSource != constraint.source)
59205899
return true;
59215900

5922-
if (derivedViaConcrete)
5923-
return true;
5924-
59255901
return false;
59265902
});
59275903

@@ -6495,27 +6471,21 @@ void GenericSignatureBuilder::processDelayedRequirements() {
64956471

64966472
namespace {
64976473
/// Remove self-derived sources from the given vector of constraints.
6498-
///
6499-
/// \returns true if any derived-via-concrete constraints were found.
65006474
template<typename T>
6501-
bool removeSelfDerived(GenericSignatureBuilder &builder,
6475+
void removeSelfDerived(GenericSignatureBuilder &builder,
65026476
std::vector<Constraint<T>> &constraints,
65036477
ProtocolDecl *proto,
6504-
bool dropDerivedViaConcrete = true,
65056478
bool allCanBeSelfDerived = false) {
65066479
auto genericParams = builder.getGenericParams();
6507-
bool anyDerivedViaConcrete = false;
6508-
Optional<Constraint<T>> remainingConcrete;
65096480
SmallVector<Constraint<T>, 4> minimalSources;
65106481
constraints.erase(
65116482
std::remove_if(constraints.begin(), constraints.end(),
65126483
[&](const Constraint<T> &constraint) {
6513-
bool derivedViaConcrete;
65146484
auto minimalSource =
65156485
constraint.source->getMinimalConformanceSource(
65166486
builder,
65176487
constraint.getSubjectDependentType(genericParams),
6518-
proto, derivedViaConcrete);
6488+
proto);
65196489
if (minimalSource != constraint.source) {
65206490
// The minimal source is smaller than the original source, so the
65216491
// original source is self-derived.
@@ -6532,21 +6502,8 @@ namespace {
65326502
return true;
65336503
}
65346504

6535-
if (!derivedViaConcrete)
6536-
return false;
6537-
6538-
anyDerivedViaConcrete = true;
6539-
6540-
if (!dropDerivedViaConcrete)
6541-
return false;
6542-
6543-
// Drop derived-via-concrete requirements.
6544-
if (!remainingConcrete)
6545-
remainingConcrete = constraint;
6546-
6547-
++NumSelfDerived;
6548-
return true;
6549-
}),
6505+
return false;
6506+
}),
65506507
constraints.end());
65516508

65526509
// If we found any minimal sources, add them now, avoiding introducing any
@@ -6566,13 +6523,8 @@ namespace {
65666523
}
65676524
}
65686525

6569-
// If we only had concrete conformances, put one back.
6570-
if (constraints.empty() && remainingConcrete)
6571-
constraints.push_back(*remainingConcrete);
6572-
65736526
assert((!constraints.empty() || allCanBeSelfDerived) &&
65746527
"All constraints were self-derived!");
6575-
return anyDerivedViaConcrete;
65766528
}
65776529
} // end anonymous namespace
65786530

@@ -7135,9 +7087,7 @@ static void computeDerivedSameTypeComponents(
71357087
// construction of self-derived sources really don't work, because we
71367088
// discover more information later, so we need a more on-line or
71377089
// iterative approach.
7138-
bool derivedViaConcrete;
7139-
if (concrete.source->isSelfDerivedSource(builder, subjectType,
7140-
derivedViaConcrete))
7090+
if (concrete.source->isSelfDerivedSource(builder, subjectType))
71417091
continue;
71427092

71437093
// If it has a better source than we'd seen before for this component,
@@ -7471,13 +7421,10 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
74717421
if (!equivClass->derivedSameTypeComponents.empty())
74727422
return;
74737423

7474-
bool anyDerivedViaConcrete = false;
74757424
// Remove self-derived constraints.
7476-
if (removeSelfDerived(*this, equivClass->sameTypeConstraints,
7477-
/*proto=*/nullptr,
7478-
/*dropDerivedViaConcrete=*/false,
7479-
/*allCanBeSelfDerived=*/true))
7480-
anyDerivedViaConcrete = true;
7425+
removeSelfDerived(*this, equivClass->sameTypeConstraints,
7426+
/*proto=*/nullptr,
7427+
/*allCanBeSelfDerived=*/true);
74817428

74827429
// Sort the constraints, so we get a deterministic ordering of diagnostics.
74837430
llvm::array_pod_sort(equivClass->sameTypeConstraints.begin(),
@@ -7555,16 +7502,6 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
75557502
IntercomponentEdge(firstComponentIdx, secondComponentIdx, constraint));
75567503
}
75577504

7558-
// If there were any derived-via-concrete constraints, drop them now before
7559-
// we emit other diagnostics.
7560-
if (anyDerivedViaConcrete) {
7561-
// Remove derived-via-concrete constraints.
7562-
(void)removeSelfDerived(*this, equivClass->sameTypeConstraints,
7563-
/*proto=*/nullptr,
7564-
/*dropDerivedViaConcrete=*/true,
7565-
/*allCanBeSelfDerived=*/true);
7566-
}
7567-
75687505
// Walk through each of the components, checking the intracomponent edges.
75697506
// This will diagnose any explicitly-specified requirements within a
75707507
// component, all of which are redundant.
@@ -7762,7 +7699,6 @@ void GenericSignatureBuilder::checkConcreteTypeConstraints(
77627699

77637700
removeSelfDerived(*this, equivClass->concreteTypeConstraints,
77647701
/*proto=*/nullptr,
7765-
/*dropDerivedViaConcrete=*/true,
77667702
/*allCanBeSelfDerived=*/true);
77677703

77687704
// This can occur if the combination of a superclass requirement and

test/Generics/requirement_inference.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,9 @@ struct X24<T: P20> : P24 {
328328
// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X24<τ_0_0.B>, τ_0_0.B : P20>
329329
protocol P25a {
330330
associatedtype A: P24 // expected-warning{{redundant conformance constraint 'Self.A' : 'P24'}}
331+
// expected-note@-1 {{conformance constraint 'Self.B' : 'P20' implied here}}
331332
associatedtype B: P20 where A == X24<B> // expected-note{{conformance constraint 'Self.A' : 'P24' implied here}}
333+
// expected-warning@-1 {{redundant conformance constraint 'Self.B' : 'P20'}}
332334
}
333335

334336
// CHECK-LABEL: .P25b@

0 commit comments

Comments
 (0)