Skip to content

Commit 82d295f

Browse files
authored
Merge pull request swiftlang#8242 from DougGregor/redundant-superclass-constraints
2 parents b56e74e + 9385849 commit 82d295f

File tree

2 files changed

+34
-32
lines changed

2 files changed

+34
-32
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3555,10 +3555,6 @@ namespace {
35553555
/// potential archetypes in this component equivalent to the concrete type.
35563556
const RequirementSource *concreteTypeSource;
35573557

3558-
/// The (best) requirement source within the component that introduces
3559-
/// the superclass constraint.
3560-
const RequirementSource *superclassSource;
3561-
35623558
friend bool operator<(const SameTypeComponent &lhs,
35633559
const SameTypeComponent &rhs) {
35643560
return compareDependentTypes(&lhs.anchor, &rhs.anchor) < 0;
@@ -3615,7 +3611,7 @@ static SmallVector<SameTypeComponent, 2> getSameTypeComponents(
36153611
auto anchor = sameTypeDFS(pa, components.size(), paToComponent);
36163612

36173613
// Record the anchor.
3618-
components.push_back({anchor, nullptr, nullptr});
3614+
components.push_back({anchor, nullptr});
36193615
}
36203616

36213617
// If there is a concrete type, figure out the best concrete type anchor
@@ -3634,29 +3630,26 @@ static SmallVector<SameTypeComponent, 2> getSameTypeComponents(
36343630
bestConcreteTypeSource = concrete.source;
36353631
}
36363632

3637-
// If there is a superclass and no concrete type, figure out the best
3638-
// superclass source per component.
3639-
if (equivClass->superclass && !equivClass->concreteType) {
3640-
for (const auto &superclass : equivClass->superclassConstraints) {
3641-
// Dig out the component associated with constraint.
3642-
assert(paToComponent.count(superclass.archetype) > 0);
3643-
auto &component = components[paToComponent[superclass.archetype]];
3644-
3645-
// If it has a better source than we'd seen before for this component,
3646-
// keep it.
3647-
auto &bestSuperclassSource = component.superclassSource;
3648-
if (!bestSuperclassSource ||
3649-
superclass.source->compare(bestSuperclassSource) < 0)
3650-
bestSuperclassSource = superclass.source;
3651-
}
3652-
}
3653-
36543633
// Sort the components.
36553634
llvm::array_pod_sort(components.begin(), components.end());
36563635

36573636
return components;
36583637
}
36593638

3639+
namespace {
3640+
/// Retrieve the best requirement source from a set of constraints.
3641+
template<typename T>
3642+
const RequirementSource *getBestConstraintSource(
3643+
ArrayRef<Constraint<T>> constraints) {
3644+
auto bestSource = constraints.front().source;
3645+
for (const auto &constraint : constraints) {
3646+
if (constraint.source->compare(bestSource) < 0)
3647+
bestSource = constraint.source;
3648+
}
3649+
return bestSource;
3650+
}
3651+
}
3652+
36603653
void GenericSignatureBuilder::enumerateRequirements(llvm::function_ref<
36613654
void (RequirementKind kind,
36623655
PotentialArchetype *archetype,
@@ -3730,14 +3723,6 @@ void GenericSignatureBuilder::enumerateRequirements(llvm::function_ref<
37303723
continue;
37313724
}
37323725

3733-
// If we have a superclass, produce a superclass requirement
3734-
if (Type superclass = rep->getSuperclass()) {
3735-
f(RequirementKind::Superclass, archetype, superclass,
3736-
knownAnchor->superclassSource
3737-
? knownAnchor->superclassSource
3738-
: RequirementSource::forAbstract(archetype));
3739-
}
3740-
37413726
// If we're at the last anchor in the component, do nothing;
37423727
auto nextAnchor = knownAnchor;
37433728
++nextAnchor;
@@ -3762,6 +3747,12 @@ void GenericSignatureBuilder::enumerateRequirements(llvm::function_ref<
37623747

37633748
auto equivClass = rep->getEquivalenceClassIfPresent();
37643749

3750+
// If we have a superclass, produce a superclass requirement
3751+
if (equivClass && equivClass->superclass) {
3752+
f(RequirementKind::Superclass, archetype, equivClass->superclass,
3753+
getBestConstraintSource<Type>(equivClass->superclassConstraints));
3754+
}
3755+
37653756
// If we have a layout constraint, produce a layout requirement.
37663757
if (equivClass && equivClass->layout) {
37673758
// Find the best source among the constraints that describe the layout
@@ -3772,7 +3763,9 @@ void GenericSignatureBuilder::enumerateRequirements(llvm::function_ref<
37723763
bestSource = constraint.source;
37733764
}
37743765

3775-
f(RequirementKind::Layout, archetype, equivClass->layout, bestSource);
3766+
f(RequirementKind::Layout, archetype, equivClass->layout,
3767+
getBestConstraintSource<LayoutConstraint>(
3768+
equivClass->layoutConstraints));
37763769
}
37773770

37783771
// Enumerate conformance requirements.
@@ -3792,7 +3785,9 @@ void GenericSignatureBuilder::enumerateRequirements(llvm::function_ref<
37923785
bestSource = constraint.source;
37933786
}
37943787

3795-
protocolSources.insert({conforms.first, bestSource});
3788+
protocolSources.insert(
3789+
{conforms.first,
3790+
getBestConstraintSource<ProtocolDecl *>(conforms.second)});
37963791
}
37973792
}
37983793

test/Generics/superclass_constraint.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,10 @@ protocol P7 {
126126
// expected-note@-2{{superclass constraint 'Self.Assoc' : 'A' written here}}
127127
// expected-error@-3{{'Self.Assoc' cannot be a subclass of both 'Other' and 'A'}}
128128
}
129+
130+
// CHECK: superclassConformance4
131+
// CHECK: Generic signature: <T, U where T : P3, U : P3, T.T : C, T.T == U.T>
132+
func superclassConformance4<T: P3, U: P3>(_: T, _: U)
133+
where T.T: C, // expected-note{{superclass constraint 'T.T' : 'C' written here}}
134+
U.T: C, // expected-warning{{redundant superclass constraint 'U.T' : 'C'}}
135+
T.T == U.T { }

0 commit comments

Comments
 (0)