Skip to content

Commit dd38697

Browse files
committed
[GSB] Don't add invalid concrete requirements.
When a concrete requirement is invalid due to the concrete type lacking a conformance to a particular, required protocol, don't emit that incorrect requirement---it causes invalid states further down the line. Fixes SR-5014 / rdar://problem/32402482. While here, fix a comment that Huon noticed trailed off into oblivion.
1 parent 2f00a08 commit dd38697

File tree

4 files changed

+14
-8
lines changed

4 files changed

+14
-8
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ class GenericSignatureBuilder {
182182
/// the concrete type.
183183
unsigned recursiveConcreteType : 1;
184184

185+
/// Whether we have an invalid concrete type.
186+
unsigned invalidConcreteType : 1;
187+
185188
/// Whether we have detected recursion during the substitution of
186189
/// the superclass type.
187190
unsigned recursiveSuperclassType : 1;

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,7 @@ GenericSignatureBuilder::resolveConcreteConformance(PotentialArchetype *pa,
13501350
concrete, proto->getName());
13511351
}
13521352

1353+
paEquivClass->invalidConcreteType = true;
13531354
return nullptr;
13541355
}
13551356

@@ -1754,7 +1755,8 @@ static void concretizeNestedTypeFromConcreteParent(
17541755
}
17551756
}
17561757

1757-
// Error condition: parent did not conform to this protocol, so they
1758+
// Error condition: parent did not conform to this protocol, so there is no
1759+
// way to resolve the nested type via concrete conformance.
17581760
if (!parentConcreteSource) return;
17591761

17601762
auto source = parentConcreteSource->viaParent(builder, assocType);
@@ -2448,7 +2450,8 @@ void GenericSignatureBuilder::PotentialArchetype::dump(llvm::raw_ostream &Out,
24482450

24492451
#pragma mark Equivalence classes
24502452
EquivalenceClass::EquivalenceClass(PotentialArchetype *representative)
2451-
: recursiveConcreteType(false), recursiveSuperclassType(false)
2453+
: recursiveConcreteType(false), invalidConcreteType(false),
2454+
recursiveSuperclassType(false)
24522455
{
24532456
members.push_back(representative);
24542457
}
@@ -3371,6 +3374,7 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
33713374
SameTypeConflictCheckedLater());
33723375
} else {
33733376
equivClass->concreteType = equivClass2->concreteType;
3377+
equivClass->invalidConcreteType = equivClass2->invalidConcreteType;
33743378
}
33753379

33763380
equivClass->concreteTypeConstraints.insert(
@@ -5267,8 +5271,9 @@ void GenericSignatureBuilder::enumerateRequirements(llvm::function_ref<
52675271
? knownAnchor->concreteTypeSource
52685272
: RequirementSource::forAbstract(archetype);
52695273

5270-
// Drop recursive concrete-type constraints.
5271-
if (equivClass->recursiveConcreteType)
5274+
// Drop recursive and invalid concrete-type constraints.
5275+
if (equivClass->recursiveConcreteType ||
5276+
equivClass->invalidConcreteType)
52725277
continue;
52735278

52745279
f(RequirementKind::SameType, archetype, concreteType, source);

test/Constraints/same_types.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func test4<T: Barrable>(_ t: T) -> Y where T.Bar == Y {
7777

7878
func fail3<T: Barrable>(_ t: T) -> X
7979
where T.Bar == X { // expected-error {{'X' does not conform to required protocol 'Fooable'}}
80-
return t.bar
80+
return t.bar // expected-error{{cannot convert return expression of type 'T.Bar' }}
8181
}
8282

8383
func test5<T: Barrable>(_ t: T) -> X where T.Bar.Foo == X {

validation-test/compiler_crashers_2/0101-sr5014.swift renamed to validation-test/compiler_crashers_2_fixed/0101-sr5014.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
// RUN: not --crash %target-swift-frontend -emit-ir -primary-file %s
2-
3-
// REQUIRES: asserts
1+
// RUN: not %target-swift-frontend -emit-ir -primary-file %s
42

53
struct Version {
64
}

0 commit comments

Comments
 (0)