Skip to content

Commit 9067d6f

Browse files
authored
Merge pull request #12991 from DougGregor/conditional-conformance-fixes
2 parents 1d6c7c5 + 1ee30a3 commit 9067d6f

File tree

6 files changed

+52
-11
lines changed

6 files changed

+52
-11
lines changed

lib/AST/Type.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3015,8 +3015,6 @@ static Type getMemberForBaseType(LookupConformanceFn lookupConformances,
30153015

30163016
if (!conformance) return failed();
30173017
if (!conformance->isConcrete()) return failed();
3018-
assert(conformance->getConditionalRequirements().empty() &&
3019-
"unhandled conditional requirements");
30203018

30213019
// Retrieve the type witness.
30223020
auto witness =

lib/ParseSIL/ParseSIL.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5661,8 +5661,25 @@ bool SILParserTUState::parseSILWitnessTable(Parser &P) {
56615661
EntryKeyword.str() == "conditional_conformance") {
56625662
if (P.parseToken(tok::l_paren, diag::expected_sil_witness_lparen))
56635663
return true;
5664-
CanType assoc = parseAssociatedTypePath(P, WitnessState, proto);
5665-
if (!assoc)
5664+
CanType assocOrSubject;
5665+
if (EntryKeyword.str() == "associated_type_protocol") {
5666+
assocOrSubject = parseAssociatedTypePath(P, WitnessState, proto);
5667+
} else {
5668+
// Parse AST type.
5669+
ParserResult<TypeRepr> TyR = P.parseType();
5670+
if (TyR.isNull())
5671+
return true;
5672+
TypeLoc Ty = TyR.get();
5673+
if (swift::performTypeLocChecking(P.Context, Ty,
5674+
/*isSILMode=*/false,
5675+
/*isSILType=*/false,
5676+
witnessEnv,
5677+
&P.SF))
5678+
return true;
5679+
5680+
assocOrSubject = Ty.getType()->getCanonicalType();
5681+
}
5682+
if (!assocOrSubject)
56665683
return true;
56675684
if (P.parseToken(tok::colon, diag::expected_sil_witness_colon))
56685685
return true;
@@ -5685,11 +5702,13 @@ bool SILParserTUState::parseSILWitnessTable(Parser &P) {
56855702

56865703
if (EntryKeyword.str() == "associated_type_protocol")
56875704
witnessEntries.push_back(
5688-
SILWitnessTable::AssociatedTypeProtocolWitness{assoc, proto,
5705+
SILWitnessTable::AssociatedTypeProtocolWitness{assocOrSubject,
5706+
proto,
56895707
conformance});
56905708
else
56915709
conditionalConformances.push_back(
5692-
SILWitnessTable::ConditionalConformance{assoc, conformance});
5710+
SILWitnessTable::ConditionalConformance{assocOrSubject,
5711+
conformance});
56935712

56945713
continue;
56955714
}

lib/Sema/CSApply.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -474,9 +474,6 @@ namespace {
474474
tc.conformsToProtocol(baseTy, proto, cs.DC,
475475
(ConformanceCheckFlags::InExpression|
476476
ConformanceCheckFlags::Used));
477-
assert((!conformance ||
478-
conformance->getConditionalRequirements().empty()) &&
479-
"unhandled conditional conformance");
480477
if (conformance && conformance->isConcrete()) {
481478
if (auto witness =
482479
conformance->getConcrete()->getWitnessDecl(decl, &tc)) {

lib/Sema/CSDiag.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4844,7 +4844,7 @@ bool FailureDiagnosis::diagnoseArgumentGenericRequirements(
48444844
AFD = dyn_cast<AbstractFunctionDecl>(candidate);
48454845
}
48464846

4847-
if (!AFD || !AFD->isGeneric() || !AFD->hasInterfaceType())
4847+
if (!AFD || !AFD->getGenericSignature() || !AFD->hasInterfaceType())
48484848
return false;
48494849

48504850
auto env = AFD->getGenericEnvironment();

lib/Sema/MiscDiagnostics.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1418,7 +1418,15 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
14181418
/// x == nil // also !=
14191419
///
14201420
void checkOptionalPromotions(ApplyExpr *call) {
1421-
auto DRE = dyn_cast<DeclRefExpr>(call->getSemanticFn());
1421+
// We only care about binary expressions.
1422+
if (!isa<BinaryExpr>(call)) return;
1423+
1424+
// Dig out the function we're calling.
1425+
auto fnExpr = call->getSemanticFn();
1426+
if (auto dotSyntax = dyn_cast<DotSyntaxCallExpr>(fnExpr))
1427+
fnExpr = dotSyntax->getSemanticFn();
1428+
1429+
auto DRE = dyn_cast<DeclRefExpr>(fnExpr);
14221430
auto args = dyn_cast<TupleExpr>(call->getArg());
14231431
if (!DRE || !DRE->getDecl()->isOperator() ||
14241432
!args || args->getNumElements() != 2)

test/SIL/Parser/witness_tables.sil

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,22 @@ sil_witness_table DeadMethodClass: Proto module witness_tables {
9696
method #Proto.abc!1: nil
9797
}
9898

99+
protocol P {
100+
}
101+
102+
struct ConditionalStruct<T> {
103+
init()
104+
}
105+
106+
extension ConditionalStruct : P where T : P {
107+
}
108+
109+
// CHECK-LABEL: sil_witness_table hidden <T where T : P> ConditionalStruct<T>: P module witness_tables {
110+
// CHECK-NEXT: conditional_conformance (T: P): dependent
111+
// CHECL-NEXT: }
112+
sil_witness_table hidden <T where T : P> ConditionalStruct<T>: P module t4 {
113+
conditional_conformance (T: P): dependent
114+
}
115+
116+
sil_default_witness_table hidden P {
117+
}

0 commit comments

Comments
 (0)