Skip to content

Commit e9f4687

Browse files
committed
[GSB] Avoid unresolved dependent member types in generic signatures.
The GenericSignatureBuilder is allowing unresolved dependent member types to creep into generic signatures, which eventually blows up in name mangling. Prefer to pick dependent member types that are fully-resolved when choosing anchors. This is a spot fix; a better approach would eliminate the notion of unresolved dependent member types entirely from PotentialArchetype. That's tracked by rdar://problem/35839277. Fixes rdar://problem/36549499. (cherry picked from commit 8b04dd3)
1 parent 28aff90 commit e9f4687

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5233,11 +5233,28 @@ void GenericSignatureBuilder::checkConformanceConstraints(
52335233
}
52345234
}
52355235

5236+
/// Compare dependent types for use in anchors.
5237+
///
5238+
/// FIXME: This is a hack that will go away once we eliminate potential
5239+
/// archetypes that refer to concrete type declarations.
5240+
static int compareAnchorDependentTypes(Type type1, Type type2) {
5241+
// We don't want any unresolved dependent member types to be anchors, so
5242+
// prefer that they don't get through.
5243+
bool hasUnresolvedDependentMember1 =
5244+
type1->findUnresolvedDependentMemberType() != nullptr;
5245+
bool hasUnresolvedDependentMember2 =
5246+
type2->findUnresolvedDependentMemberType() != nullptr;
5247+
if (hasUnresolvedDependentMember1 != hasUnresolvedDependentMember2)
5248+
return hasUnresolvedDependentMember2 ? -1 : +1;
5249+
5250+
return compareDependentTypes(type1, type2);
5251+
}
5252+
52365253
namespace swift {
52375254
bool operator<(const DerivedSameTypeComponent &lhs,
52385255
const DerivedSameTypeComponent &rhs) {
5239-
return compareDependentTypes(getUnresolvedType(lhs.anchor, { }),
5240-
getUnresolvedType(rhs.anchor, { })) < 0;
5256+
return compareAnchorDependentTypes(getUnresolvedType(lhs.anchor, { }),
5257+
getUnresolvedType(rhs.anchor, { })) < 0;
52415258
}
52425259
} // namespace swift
52435260

@@ -5373,7 +5390,7 @@ static void computeDerivedSameTypeComponents(
53735390
componentOf[depType] = componentIndex;
53745391

53755392
// If this is a better anchor, record it.
5376-
if (compareDependentTypes(
5393+
if (compareAnchorDependentTypes(
53775394
depType,
53785395
getUnresolvedType(components[componentIndex].anchor, { })) < 0)
53795396
components[componentIndex].anchor = pa;
@@ -5692,7 +5709,7 @@ static void collapseSameTypeComponents(
56925709
auto &newComponent = newComponents[newRepresentativeIndex];
56935710

56945711
// If the old component has a better anchor, keep it.
5695-
if (compareDependentTypes(
5712+
if (compareAnchorDependentTypes(
56965713
getUnresolvedType(oldComponent.anchor, { }),
56975714
getUnresolvedType(newComponent.anchor, { })) < 0)
56985715
newComponent.anchor = oldComponent.anchor;
@@ -6092,7 +6109,7 @@ static int compareSameTypeComponents(const SameTypeComponentRef *lhsPtr,
60926109
rhsPtr->first->derivedSameTypeComponents[rhsPtr->second].anchor,
60936110
{ });
60946111

6095-
return compareDependentTypes(lhsType, rhsType);
6112+
return compareAnchorDependentTypes(lhsType, rhsType);
60966113
}
60976114

60986115
void GenericSignatureBuilder::enumerateRequirements(
@@ -6321,6 +6338,9 @@ static void collectRequirements(GenericSignatureBuilder &builder,
63216338
if (depTy->hasError())
63226339
return;
63236340

6341+
assert(!depTy->findUnresolvedDependentMemberType() &&
6342+
"Unresolved dependent member type in requirements");
6343+
63246344
Type repTy;
63256345
if (auto concreteTy = type.dyn_cast<Type>()) {
63266346
// Maybe we were equated to a concrete or dependent type...
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-swift-frontend %s -emit-ir -o /dev/null
2+
protocol S {
3+
associatedtype I: IteratorProtocol
4+
typealias E = I.Element
5+
}
6+
7+
func foo<T: S>(_ s: T) -> Int where T.E == Int {
8+
return 42
9+
}

0 commit comments

Comments
 (0)