Skip to content

Commit 4da9181

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. (cherry picked from commit dd38697) (cherry picked from commit e1395ea)
1 parent cbf234b commit 4da9181

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);
@@ -2440,7 +2442,8 @@ void GenericSignatureBuilder::PotentialArchetype::dump(llvm::raw_ostream &Out,
24402442

24412443
#pragma mark Equivalence classes
24422444
EquivalenceClass::EquivalenceClass(PotentialArchetype *representative)
2443-
: recursiveConcreteType(false), recursiveSuperclassType(false)
2445+
: recursiveConcreteType(false), invalidConcreteType(false),
2446+
recursiveSuperclassType(false)
24442447
{
24452448
members.push_back(representative);
24462449
}
@@ -3367,6 +3370,7 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
33673370
SameTypeConflictCheckedLater());
33683371
} else {
33693372
equivClass->concreteType = equivClass2->concreteType;
3373+
equivClass->invalidConcreteType = equivClass2->invalidConcreteType;
33703374
}
33713375

33723376
equivClass->concreteTypeConstraints.insert(
@@ -5263,8 +5267,9 @@ void GenericSignatureBuilder::enumerateRequirements(llvm::function_ref<
52635267
? knownAnchor->concreteTypeSource
52645268
: RequirementSource::forAbstract(archetype);
52655269

5266-
// Drop recursive concrete-type constraints.
5267-
if (equivClass->recursiveConcreteType)
5270+
// Drop recursive and invalid concrete-type constraints.
5271+
if (equivClass->recursiveConcreteType ||
5272+
equivClass->invalidConcreteType)
52685273
continue;
52695274

52705275
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)