@@ -217,6 +217,10 @@ namespace {
217
217
218
218
// / @{ Type parsing.
219
219
bool parseASTType (CanType &result);
220
+ bool parseASTType (CanType &result, SourceLoc &TypeLoc) {
221
+ TypeLoc = P.Tok .getLoc ();
222
+ return parseASTType (result);
223
+ }
220
224
bool parseSILType (SILType &Result,
221
225
GenericEnvironment *&genericEnv,
222
226
bool IsFuncDecl = false );
@@ -1277,71 +1281,24 @@ bool SILParser::parseSubstitutions(SmallVectorImpl<ParsedSubstitution> &parsed,
1277
1281
return false ;
1278
1282
}
1279
1283
1280
- // / Get ProtocolConformance for a replacement type.
1281
- static ProtocolConformance*
1282
- getConformanceOfReplacement (Parser &P, Type subReplacement,
1283
- ProtocolDecl *proto) {
1284
- auto conformance = P.SF .getParentModule ()->lookupConformance (
1285
- subReplacement, proto, nullptr );
1286
- if (conformance && conformance->isConcrete ())
1287
- return conformance->getConcrete ();
1288
- return nullptr ;
1289
- }
1290
-
1291
- static bool isImpliedBy (ProtocolDecl *proto, ArrayRef<ProtocolDecl*> derived) {
1292
- for (auto derivedProto : derived) {
1293
- if (derivedProto == proto || derivedProto->inheritsFrom (proto))
1294
- return true ;
1295
- }
1296
- return false ;
1297
- }
1298
-
1299
- static bool allowAbstractConformance (Parser &P, Type subReplacement,
1300
- ProtocolDecl *proto) {
1301
- if (!subReplacement->hasDependentProtocolConformances ())
1302
- return false ;
1303
-
1304
- // AnyObject is implicitly conformed to by anything with a class bound.
1305
- if (proto->isSpecificProtocol (KnownProtocolKind::AnyObject) &&
1306
- subReplacement->isAnyClassReferenceType ()) {
1307
- return true ;
1308
- }
1309
-
1310
- if (auto archetype = subReplacement->getAs <ArchetypeType>()) {
1311
- return isImpliedBy (proto, archetype->getConformsTo ());
1312
- }
1313
-
1314
- SmallVector<ProtocolDecl *, 4 > existentialProtos;
1315
- if (subReplacement->isExistentialType (existentialProtos)) {
1316
- return isImpliedBy (proto, existentialProtos);
1317
- }
1318
-
1319
- return false ;
1320
- }
1321
-
1322
1284
// / Collect conformances by looking up the conformance from replacement
1323
1285
// / type and protocol decl.
1324
1286
static bool getConformancesForSubstitution (Parser &P,
1325
1287
ArrayRef<ProtocolDecl *> protocols,
1326
1288
Type subReplacement,
1327
1289
SourceLoc loc,
1328
1290
SmallVectorImpl<ProtocolConformanceRef> &conformances) {
1329
- for (auto proto : protocols) {
1330
- // Try looking up a concrete conformance.
1331
- if (auto conformance =
1332
- getConformanceOfReplacement (P, subReplacement, proto)) {
1333
- conformances.push_back (ProtocolConformanceRef (conformance));
1334
- continue ;
1335
- }
1291
+ auto M = P.SF .getParentModule ();
1336
1292
1337
- // If the replacement type has dependent conformances, we might be
1338
- // able to use an abstract conformance.
1339
- if (allowAbstractConformance (P, subReplacement, proto) ) {
1340
- conformances.push_back (ProtocolConformanceRef (proto) );
1293
+ for ( auto proto : protocols) {
1294
+ auto conformance = M-> lookupConformance (subReplacement, proto, nullptr );
1295
+ if (conformance ) {
1296
+ conformances.push_back (*conformance );
1341
1297
continue ;
1342
1298
}
1343
1299
1344
- P.diagnose (loc, diag::sil_substitution_mismatch);
1300
+ P.diagnose (loc, diag::sil_substitution_mismatch, subReplacement,
1301
+ proto->getName ());
1345
1302
return true ;
1346
1303
}
1347
1304
@@ -1403,25 +1360,20 @@ bool getApplySubstitutionsFromParsed(
1403
1360
}
1404
1361
1405
1362
static ArrayRef<ProtocolConformanceRef>
1406
- collectExistentialConformances (Parser &P,
1407
- CanType conformingType, CanType protocolType) {
1363
+ collectExistentialConformances (Parser &P, CanType conformingType, SourceLoc loc,
1364
+ CanType protocolType) {
1408
1365
SmallVector<ProtocolDecl *, 2 > protocols;
1409
1366
bool isExistential = protocolType->isAnyExistentialType (protocols);
1410
1367
assert (isExistential);
1411
1368
(void )isExistential;
1412
1369
if (protocols.empty ())
1413
1370
return {};
1414
-
1415
- MutableArrayRef<ProtocolConformanceRef> conformances =
1416
- P.Context .AllocateUninitialized <ProtocolConformanceRef>(protocols.size ());
1417
-
1418
- for (unsigned i : indices (protocols)) {
1419
- auto proto = protocols[i];
1420
- auto conformance = getConformanceOfReplacement (P, conformingType, proto);
1421
- conformances[i] = ProtocolConformanceRef (proto, conformance);
1422
- }
1423
-
1424
- return conformances;
1371
+
1372
+ SmallVector<ProtocolConformanceRef, 2 > conformances;
1373
+ getConformancesForSubstitution (P, protocols, conformingType,
1374
+ loc, conformances);
1375
+
1376
+ return P.Context .AllocateCopy (conformances);
1425
1377
}
1426
1378
1427
1379
// / sil-loc ::= 'loc' string-literal ':' [0-9]+ ':' [0-9]+
@@ -3568,10 +3520,11 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
3568
3520
}
3569
3521
case ValueKind::InitExistentialAddrInst: {
3570
3522
CanType Ty;
3523
+ SourceLoc TyLoc;
3571
3524
if (parseTypedValueRef (Val, B) ||
3572
3525
P.parseToken (tok::comma, diag::expected_tok_in_sil_instr, " ," ) ||
3573
3526
P.parseToken (tok::sil_dollar, diag::expected_tok_in_sil_instr, " $" ) ||
3574
- parseASTType (Ty) ||
3527
+ parseASTType (Ty, TyLoc ) ||
3575
3528
parseSILDebugLocation (InstLoc, B))
3576
3529
return true ;
3577
3530
@@ -3586,7 +3539,7 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
3586
3539
3587
3540
// Collect conformances for the type.
3588
3541
ArrayRef<ProtocolConformanceRef> conformances
3589
- = collectExistentialConformances (P, Ty,
3542
+ = collectExistentialConformances (P, Ty, TyLoc,
3590
3543
Val->getType ().getSwiftRValueType ());
3591
3544
3592
3545
ResultVal = B.createInitExistentialAddr (InstLoc, Val, Ty, LoweredTy,
@@ -3596,17 +3549,18 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
3596
3549
case ValueKind::AllocExistentialBoxInst: {
3597
3550
SILType ExistentialTy;
3598
3551
CanType ConcreteFormalTy;
3552
+ SourceLoc TyLoc;
3599
3553
3600
3554
if (parseSILType (ExistentialTy) ||
3601
3555
P.parseToken (tok::comma, diag::expected_tok_in_sil_instr, " ," ) ||
3602
3556
P.parseToken (tok::sil_dollar, diag::expected_tok_in_sil_instr, " $" ) ||
3603
- parseASTType (ConcreteFormalTy) ||
3557
+ parseASTType (ConcreteFormalTy, TyLoc ) ||
3604
3558
parseSILDebugLocation (InstLoc, B))
3605
3559
return true ;
3606
3560
3607
3561
// Collect conformances for the type.
3608
3562
ArrayRef<ProtocolConformanceRef> conformances
3609
- = collectExistentialConformances (P, ConcreteFormalTy,
3563
+ = collectExistentialConformances (P, ConcreteFormalTy, TyLoc,
3610
3564
ExistentialTy.getSwiftRValueType ());
3611
3565
3612
3566
ResultVal = B.createAllocExistentialBox (InstLoc, ExistentialTy,
@@ -3617,17 +3571,19 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
3617
3571
case ValueKind::InitExistentialRefInst: {
3618
3572
CanType FormalConcreteTy;
3619
3573
SILType ExistentialTy;
3574
+ SourceLoc TyLoc;
3575
+
3620
3576
if (parseTypedValueRef (Val, B) ||
3621
3577
P.parseToken (tok::colon, diag::expected_tok_in_sil_instr, " :" ) ||
3622
3578
P.parseToken (tok::sil_dollar, diag::expected_tok_in_sil_instr, " $" ) ||
3623
- parseASTType (FormalConcreteTy) ||
3579
+ parseASTType (FormalConcreteTy, TyLoc ) ||
3624
3580
P.parseToken (tok::comma, diag::expected_tok_in_sil_instr, " ," ) ||
3625
3581
parseSILType (ExistentialTy) ||
3626
3582
parseSILDebugLocation (InstLoc, B))
3627
3583
return true ;
3628
3584
3629
3585
ArrayRef<ProtocolConformanceRef> conformances
3630
- = collectExistentialConformances (P, FormalConcreteTy,
3586
+ = collectExistentialConformances (P, FormalConcreteTy, TyLoc,
3631
3587
ExistentialTy.getSwiftRValueType ());
3632
3588
3633
3589
// FIXME: Conformances in InitExistentialRefInst is currently not included
@@ -3638,10 +3594,11 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
3638
3594
break ;
3639
3595
}
3640
3596
case ValueKind::InitExistentialMetatypeInst: {
3597
+ SourceLoc TyLoc;
3641
3598
SILType ExistentialTy;
3642
3599
if (parseTypedValueRef (Val, B) ||
3643
3600
P.parseToken (tok::comma, diag::expected_tok_in_sil_instr, " ," ) ||
3644
- parseSILType (ExistentialTy) ||
3601
+ parseSILType (ExistentialTy, TyLoc ) ||
3645
3602
parseSILDebugLocation (InstLoc, B))
3646
3603
return true ;
3647
3604
@@ -3654,7 +3611,7 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
3654
3611
}
3655
3612
3656
3613
ArrayRef<ProtocolConformanceRef> conformances
3657
- = collectExistentialConformances (P, formalConcreteType,
3614
+ = collectExistentialConformances (P, formalConcreteType, TyLoc,
3658
3615
ExistentialTy.getSwiftRValueType ());
3659
3616
3660
3617
ResultVal = B.createInitExistentialMetatype (InstLoc, Val, ExistentialTy,
@@ -4388,9 +4345,8 @@ static NormalProtocolConformance *parseNormalProtocolConformance(Parser &P,
4388
4345
// Calling lookupConformance on a BoundGenericType will return a specialized
4389
4346
// conformance. We use UnboundGenericType to find the normal conformance.
4390
4347
Type lookupTy = ConformingTy;
4391
- if (auto bound = dyn_cast<BoundGenericType>(lookupTy.getPointer ()))
4392
- lookupTy = UnboundGenericType::get (bound->getDecl (), bound->getParent (),
4393
- P.Context );
4348
+ if (auto bound = lookupTy->getAs <BoundGenericType>())
4349
+ lookupTy = bound->getDecl ()->getDeclaredType ();
4394
4350
auto lookup = P.SF .getParentModule ()->lookupConformance (
4395
4351
lookupTy, proto, nullptr );
4396
4352
if (!lookup) {
0 commit comments