Skip to content

Commit aa865a2

Browse files
committed
GSB: Stop computing 'derived via concrete' sources
1 parent 710621c commit aa865a2

File tree

3 files changed

+19
-80
lines changed

3 files changed

+19
-80
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,8 +1241,7 @@ class GenericSignatureBuilder::RequirementSource final
12411241
/// requirement redundant, because without said original requirement, the
12421242
/// derived requirement ceases to hold.
12431243
bool isSelfDerivedSource(GenericSignatureBuilder &builder,
1244-
Type type,
1245-
bool &derivedViaConcrete) const;
1244+
Type type) const;
12461245

12471246
/// For a requirement source that describes the requirement \c type:proto,
12481247
/// retrieve the minimal subpath of this requirement source that will
@@ -1254,8 +1253,7 @@ class GenericSignatureBuilder::RequirementSource final
12541253
const RequirementSource *getMinimalConformanceSource(
12551254
GenericSignatureBuilder &builder,
12561255
Type type,
1257-
ProtocolDecl *proto,
1258-
bool &derivedViaConcrete) const;
1256+
ProtocolDecl *proto) const;
12591257

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

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 15 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -936,10 +936,8 @@ bool RequirementSource::shouldDiagnoseRedundancy(bool primary) const {
936936
}
937937

938938
bool RequirementSource::isSelfDerivedSource(GenericSignatureBuilder &builder,
939-
Type type,
940-
bool &derivedViaConcrete) const {
941-
return getMinimalConformanceSource(builder, type, /*proto=*/nullptr,
942-
derivedViaConcrete)
939+
Type type) const {
940+
return getMinimalConformanceSource(builder, type, /*proto=*/nullptr)
943941
!= this;
944942
}
945943

@@ -989,10 +987,7 @@ static bool isSelfDerivedProtocolRequirementInProtocol(
989987
const RequirementSource *RequirementSource::getMinimalConformanceSource(
990988
GenericSignatureBuilder &builder,
991989
Type currentType,
992-
ProtocolDecl *proto,
993-
bool &derivedViaConcrete) const {
994-
derivedViaConcrete = false;
995-
990+
ProtocolDecl *proto) const {
996991
// If it's not a derived requirement, it's not self-derived.
997992
if (!isDerivedRequirement()) return this;
998993

@@ -1059,15 +1054,6 @@ const RequirementSource *RequirementSource::getMinimalConformanceSource(
10591054
ArchetypeResolutionKind::WellFormed);
10601055
assert(parentEquivClass && "Not a well-formed type?");
10611056

1062-
if (requirementSignatureSelfProto) {
1063-
if (parentEquivClass->concreteType)
1064-
derivedViaConcrete = true;
1065-
else if (parentEquivClass->superclass &&
1066-
builder.lookupConformance(parentEquivClass->superclass,
1067-
source->getProtocolDecl()))
1068-
derivedViaConcrete = true;
1069-
}
1070-
10711057
// The parent potential archetype must conform to the protocol in which
10721058
// this requirement resides. Add this constraint.
10731059
if (auto startOfPath =
@@ -1136,7 +1122,7 @@ const RequirementSource *RequirementSource::getMinimalConformanceSource(
11361122
redundantSubpath->first,
11371123
redundantSubpath->second);
11381124
return shorterSource
1139-
->getMinimalConformanceSource(builder, currentType, proto, derivedViaConcrete);
1125+
->getMinimalConformanceSource(builder, currentType, proto);
11401126
}
11411127

11421128
// It's self-derived but we don't have a redundant subpath to eliminate.
@@ -5797,13 +5783,10 @@ static void expandSameTypeConstraints(GenericSignatureBuilder &builder,
57975783
bool alreadyFound = false;
57985784
const RequirementSource *conformsSource = nullptr;
57995785
for (const auto &constraint : conforms.second) {
5800-
bool derivedViaConcrete = false;
5801-
58025786
auto *minimal = constraint.source->getMinimalConformanceSource(
5803-
builder, constraint.getSubjectDependentType({ }), proto,
5804-
derivedViaConcrete);
5787+
builder, constraint.getSubjectDependentType({ }), proto);
58055788

5806-
if (minimal == nullptr || derivedViaConcrete)
5789+
if (minimal == nullptr)
58075790
continue;
58085791

58095792
if (minimal->getAffectedType()->isEqual(dependentType)) {
@@ -6028,18 +6011,14 @@ void GenericSignatureBuilder::computeRedundantRequirements(
60286011
requirementSignatureSelfProto,
60296012
[&](const Constraint<ProtocolDecl *> &constraint) {
60306013
// FIXME: Remove this.
6031-
bool derivedViaConcrete;
60326014
auto minimalSource =
60336015
constraint.source->getMinimalConformanceSource(
60346016
*this,
60356017
constraint.getSubjectDependentType({ }),
6036-
proto, derivedViaConcrete);
6018+
proto);
60376019
if (minimalSource != constraint.source)
60386020
return true;
60396021

6040-
if (derivedViaConcrete)
6041-
return true;
6042-
60436022
return false;
60446023
});
60456024

@@ -6613,27 +6592,21 @@ void GenericSignatureBuilder::processDelayedRequirements() {
66136592

66146593
namespace {
66156594
/// Remove self-derived sources from the given vector of constraints.
6616-
///
6617-
/// \returns true if any derived-via-concrete constraints were found.
66186595
template<typename T>
6619-
bool removeSelfDerived(GenericSignatureBuilder &builder,
6596+
void removeSelfDerived(GenericSignatureBuilder &builder,
66206597
std::vector<Constraint<T>> &constraints,
66216598
ProtocolDecl *proto,
6622-
bool dropDerivedViaConcrete = true,
66236599
bool allCanBeSelfDerived = false) {
66246600
auto genericParams = builder.getGenericParams();
6625-
bool anyDerivedViaConcrete = false;
6626-
Optional<Constraint<T>> remainingConcrete;
66276601
SmallVector<Constraint<T>, 4> minimalSources;
66286602
constraints.erase(
66296603
std::remove_if(constraints.begin(), constraints.end(),
66306604
[&](const Constraint<T> &constraint) {
6631-
bool derivedViaConcrete;
66326605
auto minimalSource =
66336606
constraint.source->getMinimalConformanceSource(
66346607
builder,
66356608
constraint.getSubjectDependentType(genericParams),
6636-
proto, derivedViaConcrete);
6609+
proto);
66376610
if (minimalSource != constraint.source) {
66386611
// The minimal source is smaller than the original source, so the
66396612
// original source is self-derived.
@@ -6650,21 +6623,8 @@ namespace {
66506623
return true;
66516624
}
66526625

6653-
if (!derivedViaConcrete)
6654-
return false;
6655-
6656-
anyDerivedViaConcrete = true;
6657-
6658-
if (!dropDerivedViaConcrete)
6659-
return false;
6660-
6661-
// Drop derived-via-concrete requirements.
6662-
if (!remainingConcrete)
6663-
remainingConcrete = constraint;
6664-
6665-
++NumSelfDerived;
6666-
return true;
6667-
}),
6626+
return false;
6627+
}),
66686628
constraints.end());
66696629

66706630
// If we found any minimal sources, add them now, avoiding introducing any
@@ -6684,13 +6644,8 @@ namespace {
66846644
}
66856645
}
66866646

6687-
// If we only had concrete conformances, put one back.
6688-
if (constraints.empty() && remainingConcrete)
6689-
constraints.push_back(*remainingConcrete);
6690-
66916647
assert((!constraints.empty() || allCanBeSelfDerived) &&
66926648
"All constraints were self-derived!");
6693-
return anyDerivedViaConcrete;
66946649
}
66956650
} // end anonymous namespace
66966651

@@ -7253,9 +7208,7 @@ static void computeDerivedSameTypeComponents(
72537208
// construction of self-derived sources really don't work, because we
72547209
// discover more information later, so we need a more on-line or
72557210
// iterative approach.
7256-
bool derivedViaConcrete;
7257-
if (concrete.source->isSelfDerivedSource(builder, subjectType,
7258-
derivedViaConcrete))
7211+
if (concrete.source->isSelfDerivedSource(builder, subjectType))
72597212
continue;
72607213

72617214
// If it has a better source than we'd seen before for this component,
@@ -7589,13 +7542,10 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
75897542
if (!equivClass->derivedSameTypeComponents.empty())
75907543
return;
75917544

7592-
bool anyDerivedViaConcrete = false;
75937545
// Remove self-derived constraints.
7594-
if (removeSelfDerived(*this, equivClass->sameTypeConstraints,
7595-
/*proto=*/nullptr,
7596-
/*dropDerivedViaConcrete=*/false,
7597-
/*allCanBeSelfDerived=*/true))
7598-
anyDerivedViaConcrete = true;
7546+
removeSelfDerived(*this, equivClass->sameTypeConstraints,
7547+
/*proto=*/nullptr,
7548+
/*allCanBeSelfDerived=*/true);
75997549

76007550
// Sort the constraints, so we get a deterministic ordering of diagnostics.
76017551
llvm::array_pod_sort(equivClass->sameTypeConstraints.begin(),
@@ -7673,16 +7623,6 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
76737623
IntercomponentEdge(firstComponentIdx, secondComponentIdx, constraint));
76747624
}
76757625

7676-
// If there were any derived-via-concrete constraints, drop them now before
7677-
// we emit other diagnostics.
7678-
if (anyDerivedViaConcrete) {
7679-
// Remove derived-via-concrete constraints.
7680-
(void)removeSelfDerived(*this, equivClass->sameTypeConstraints,
7681-
/*proto=*/nullptr,
7682-
/*dropDerivedViaConcrete=*/true,
7683-
/*allCanBeSelfDerived=*/true);
7684-
}
7685-
76867626
// Walk through each of the components, checking the intracomponent edges.
76877627
// This will diagnose any explicitly-specified requirements within a
76887628
// component, all of which are redundant.
@@ -7880,7 +7820,6 @@ void GenericSignatureBuilder::checkConcreteTypeConstraints(
78807820

78817821
removeSelfDerived(*this, equivClass->concreteTypeConstraints,
78827822
/*proto=*/nullptr,
7883-
/*dropDerivedViaConcrete=*/true,
78847823
/*allCanBeSelfDerived=*/true);
78857824

78867825
// 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)