Skip to content

Commit 10fc3fa

Browse files
committed
[GenericSig Builder] Make resolve() less representative-dependent.
`GenericSignatureBuilder::resolve()` was always jumping to the representative, to treat typealias representatives as special. However, doing this means that we put the same-type constraint on the wrong potential archetype (with the wrong source). Eliminate the use of `getRepresentative()`. This unfortunately causes us to need recursive resolution, because we can't always depend on jumping to the representative to avoid it.
1 parent 23f3ba5 commit 10fc3fa

File tree

2 files changed

+27
-25
lines changed

2 files changed

+27
-25
lines changed

lib/AST/GenericSignatureBuilder.cpp

+26-24
Original file line numberDiff line numberDiff line change
@@ -580,8 +580,6 @@ struct GenericSignatureBuilder::ResolvedType {
580580
}
581581

582582
static ResolvedType forPotentialArchetype(PotentialArchetype *pa) {
583-
assert(!(pa->getParent() && pa->getTypeAliasDecl()) &&
584-
"typealias is only considered resolved when new");
585583
return ResolvedType(pa);
586584
}
587585

@@ -899,7 +897,14 @@ static void concretizeNestedTypeFromConcreteParent(
899897
witnessType = DependentMemberType::get(concreteParent, assocType);
900898
}
901899

902-
builder.addSameTypeRequirement(nestedPA, witnessType, source);
900+
builder.addSameTypeRequirement(nestedPA, witnessType, source,
901+
[&](Type type1, Type type2) {
902+
builder.getASTContext().Diags.diagnose(
903+
source->getLoc(),
904+
diag::requires_same_type_conflict,
905+
nestedPA->getDependentType(/*FIXME: */{ }, true),
906+
type1, type2);
907+
});
903908
}
904909

905910
auto GenericSignatureBuilder::PotentialArchetype::getNestedType(
@@ -1431,34 +1436,23 @@ auto GenericSignatureBuilder::resolve(UnresolvedType paOrT,
14311436
}
14321437
}
14331438

1434-
pa = pa->getRepresentative();
1435-
if (!pa->getParent() || !pa->getTypeAliasDecl())
1439+
auto rep = pa->getRepresentative();
1440+
if (!rep->getParent() || !rep->getTypeAliasDecl())
14361441
return ResolvedType::forPotentialArchetype(pa);
14371442

14381443
// We're assuming that an equivalence class with a type alias representative
14391444
// doesn't have a "true" (i.e. associated type) potential archetype.
1440-
assert(llvm::all_of(pa->getEquivalenceClass(),
1445+
assert(llvm::all_of(rep->getEquivalenceClass(),
14411446
[&](PotentialArchetype *pa) {
14421447
return pa->getParent() && pa->getTypeAliasDecl();
14431448
}) &&
14441449
"unexpected typealias representative with non-typealias equivalent");
14451450

1446-
// The right-hand side of the typealias could itself be an archetype
1447-
// (e.g. protocol P { associatedtype A; typealias B = A }), so we need to
1448-
// resolve that. However, the archetype should always be resolved far enough
1449-
// upon creation to not be another type alias (verified by the ResolvedType
1450-
// constructors below), and hence this function doesn't need to be recursive.
1451-
auto concrete = pa->getConcreteType();
1452-
auto rhsPA = resolveArchetype(concrete);
1453-
if (!rhsPA) {
1454-
// FIXME: same as hackTypeFromGenericTypeAlias
1455-
if (pa->getTypeAliasDecl()->getGenericParams())
1456-
return ResolvedType::forConcreteTypeFromGenericTypeAlias(concrete);
1451+
// Recursively resolve the concrete type.
1452+
if (auto concrete = pa->getConcreteType())
1453+
return resolve(concrete);
14571454

1458-
return ResolvedType::forConcreteType(concrete);
1459-
}
1460-
1461-
return ResolvedType::forPotentialArchetype(rhsPA);
1455+
return ResolvedType::forPotentialArchetype(pa);
14621456
}
14631457

14641458
void GenericSignatureBuilder::addGenericParameter(GenericTypeParamDecl *GenericParam) {
@@ -1853,7 +1847,13 @@ bool GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
18531847
for (auto T2Nested : equivT2->NestedTypes) {
18541848
auto T1Nested = T1->getNestedType(T2Nested.first, *this);
18551849
if (addSameTypeRequirement(T1Nested, T2Nested.second.front(),
1856-
sameNestedTypeSource))
1850+
sameNestedTypeSource,
1851+
[&](Type type1, Type type2) {
1852+
Diags.diagnose(Source->getLoc(),
1853+
diag::requires_same_type_conflict,
1854+
T1Nested->getDependentType(/*FIXME: */{ }, true),
1855+
type1, type2);
1856+
}))
18571857
return true;
18581858
}
18591859
}
@@ -2029,8 +2029,10 @@ bool GenericSignatureBuilder::addSameTypeRequirement(
20292029
bool GenericSignatureBuilder::addSameTypeRequirement(ResolvedType paOrT1,
20302030
ResolvedType paOrT2,
20312031
const RequirementSource *source) {
2032-
return addSameTypeRequirement(paOrT1, paOrT2, source, [&](Type, Type) {
2033-
llvm_unreachable("unexpected concrete type mismatch");
2032+
return addSameTypeRequirement(paOrT1, paOrT2, source,
2033+
[&](Type type1, Type type2) {
2034+
Diags.diagnose(source->getLoc(), diag::requires_same_concrete_type,
2035+
type1, type2);
20342036
});
20352037
}
20362038

test/Constraints/same_types.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func fail1<
6363
func fail2<
6464
T: Fooable, U: Fooable
6565
>(_ t: T, u: U) -> (X, Y)
66-
where T.Foo == U.Foo, T.Foo == X, U.Foo == Y { // expected-error{{generic parameter 'T.Foo' cannot be equal to both 'X' and 'Y'}}
66+
where T.Foo == U.Foo, T.Foo == X, U.Foo == Y { // expected-error{{generic parameter 'U.Foo' cannot be equal to both 'X' and 'Y'}}
6767
return (t.foo, u.foo) // expected-error{{cannot convert return expression of type 'X' to return type 'Y'}}
6868
}
6969

0 commit comments

Comments
 (0)