@@ -244,12 +244,13 @@ static ConstructorComparison compareConstructors(ConstructorDecl *ctor1,
244
244
return ConstructorComparison::Same;
245
245
}
246
246
247
- // / Given a set of declarations whose names and signatures have matched,
247
+ // / Given a set of declarations whose names and interface types have matched,
248
248
// / figure out which of these declarations have been shadowed by others.
249
249
template <typename T>
250
- static void
251
- recordShadowedDeclsAfterSignatureMatch (ArrayRef<T> decls, const DeclContext *dc,
252
- llvm::SmallPtrSetImpl<T> &shadowed) {
250
+ static void recordShadowedDeclsAfterTypeMatch (
251
+ ArrayRef<T> decls,
252
+ const DeclContext *dc,
253
+ llvm::SmallPtrSetImpl<T> &shadowed) {
253
254
assert (decls.size () > 1 && " Nothing collided" );
254
255
255
256
// Compare each declaration to every other declaration. This is
@@ -491,6 +492,48 @@ recordShadowedDeclsAfterSignatureMatch(ArrayRef<T> decls, const DeclContext *dc,
491
492
}
492
493
}
493
494
495
+ // / Given a set of declarations whose names and generic signatures have matched,
496
+ // / figure out which of these declarations have been shadowed by others.
497
+ static void recordShadowedDeclsAfterSignatureMatch (
498
+ ArrayRef<ValueDecl *> decls,
499
+ const DeclContext *dc,
500
+ llvm::SmallPtrSetImpl<ValueDecl *> &shadowed) {
501
+ assert (decls.size () > 1 && " Nothing collided" );
502
+
503
+ // Categorize all of the declarations based on their overload types.
504
+ llvm::SmallDenseMap<CanType, llvm::TinyPtrVector<ValueDecl *>> collisions;
505
+ llvm::SmallVector<CanType, 2 > collisionTypes;
506
+
507
+ for (auto decl : decls) {
508
+ assert (!isa<TypeDecl>(decl));
509
+
510
+ CanType type;
511
+
512
+ // FIXME: The type of a variable or subscript doesn't include
513
+ // enough context to distinguish entities from different
514
+ // constrained extensions, so use the overload signature's
515
+ // type. This is layering a partial fix upon a total hack.
516
+ if (auto asd = dyn_cast<AbstractStorageDecl>(decl))
517
+ type = asd->getOverloadSignatureType ();
518
+ else
519
+ type = decl->getInterfaceType ()->getCanonicalType ();
520
+
521
+ // Record this declaration based on its signature.
522
+ auto &known = collisions[type];
523
+ if (known.size () == 1 ) {
524
+ collisionTypes.push_back (type);
525
+ }
526
+ known.push_back (decl);
527
+ }
528
+
529
+ // Check whether we have shadowing for signature collisions.
530
+ for (auto type : collisionTypes) {
531
+ ArrayRef<ValueDecl *> collidingDecls = collisions[type];
532
+ recordShadowedDeclsAfterTypeMatch (collidingDecls, dc,
533
+ shadowed);
534
+ }
535
+ }
536
+
494
537
// / Look through the given set of declarations (that all have the same name),
495
538
// / recording those that are shadowed by another declaration in the
496
539
// / \c shadowed set.
@@ -526,14 +569,23 @@ static void recordShadowedDecls(ArrayRef<ValueDecl *> decls,
526
569
if (decls.size () < 2 )
527
570
return ;
528
571
572
+ llvm::TinyPtrVector<ValueDecl *> typeDecls;
573
+
529
574
// Categorize all of the declarations based on their overload signatures.
530
- llvm::SmallDenseMap<CanType, llvm::TinyPtrVector<ValueDecl *>> collisions;
531
- llvm::SmallVector<CanType, 2 > collisionTypes;
532
- llvm::SmallDenseMap<NominalTypeDecl *, llvm::TinyPtrVector<ConstructorDecl *>>
575
+ llvm::SmallDenseMap<const GenericSignatureImpl *,
576
+ llvm::TinyPtrVector<ValueDecl *>> collisions;
577
+ llvm::SmallVector<const GenericSignatureImpl *, 2 > collisionSignatures;
578
+ llvm::SmallDenseMap<NominalTypeDecl *,
579
+ llvm::TinyPtrVector<ConstructorDecl *>>
533
580
importedInitializerCollisions;
534
- llvm::TinyPtrVector<NominalTypeDecl *> importedInitializerCollectionTypes ;
581
+ llvm::TinyPtrVector<NominalTypeDecl *> importedInitializerCollisionTypes ;
535
582
536
583
for (auto decl : decls) {
584
+ if (auto *typeDecl = dyn_cast<TypeDecl>(decl)) {
585
+ typeDecls.push_back (typeDecl);
586
+ continue ;
587
+ }
588
+
537
589
// Specifically keep track of imported initializers, which can come from
538
590
// Objective-C init methods, Objective-C factory methods, renamed C
539
591
// functions, or be synthesized by the importer.
@@ -544,50 +596,47 @@ static void recordShadowedDecls(ArrayRef<ValueDecl *> decls,
544
596
auto nominal = ctor->getDeclContext ()->getSelfNominalTypeDecl ();
545
597
auto &knownInits = importedInitializerCollisions[nominal];
546
598
if (knownInits.size () == 1 ) {
547
- importedInitializerCollectionTypes .push_back (nominal);
599
+ importedInitializerCollisionTypes .push_back (nominal);
548
600
}
549
601
knownInits.push_back (ctor);
550
602
}
551
603
}
552
604
553
- CanType signature;
605
+ // If the decl is currently being validated, this is likely a recursive
606
+ // reference and we'll want to skip ahead so as to avoid having its type
607
+ // attempt to desugar itself.
608
+ if (decl->isRecursiveValidation ())
609
+ continue ;
554
610
555
- if (!isa<TypeDecl>(decl)) {
556
- // If the decl is currently being validated, this is likely a recursive
557
- // reference and we'll want to skip ahead so as to avoid having its type
558
- // attempt to desugar itself.
559
- if (decl->isRecursiveValidation ())
560
- continue ;
561
- auto ifaceType = decl->getInterfaceType ();
562
-
563
- // FIXME: the canonical type makes a poor signature, because we don't
564
- // canonicalize away default arguments.
565
- signature = ifaceType->getCanonicalType ();
566
-
567
- // FIXME: The type of a variable or subscript doesn't include
568
- // enough context to distinguish entities from different
569
- // constrained extensions, so use the overload signature's
570
- // type. This is layering a partial fix upon a total hack.
571
- if (auto asd = dyn_cast<AbstractStorageDecl>(decl))
572
- signature = asd->getOverloadSignatureType ();
573
- }
611
+ CanGenericSignature signature;
612
+
613
+ auto *dc = decl->getInnermostDeclContext ();
614
+ if (auto genericSig = dc->getGenericSignatureOfContext ())
615
+ signature = genericSig->getCanonicalSignature ();
574
616
575
617
// Record this declaration based on its signature.
576
- auto &known = collisions[signature];
618
+ auto &known = collisions[signature. getPointer () ];
577
619
if (known.size () == 1 ) {
578
- collisionTypes .push_back (signature);
620
+ collisionSignatures .push_back (signature. getPointer () );
579
621
}
622
+
580
623
known.push_back (decl);
581
624
}
582
625
626
+ // Check whether we have shadowing for type declarations.
627
+ if (typeDecls.size () > 1 ) {
628
+ ArrayRef<ValueDecl *> collidingDecls = typeDecls;
629
+ recordShadowedDeclsAfterTypeMatch (collidingDecls, dc, shadowed);
630
+ }
631
+
583
632
// Check whether we have shadowing for signature collisions.
584
- for (auto signature : collisionTypes ) {
633
+ for (auto signature : collisionSignatures ) {
585
634
ArrayRef<ValueDecl *> collidingDecls = collisions[signature];
586
635
recordShadowedDeclsAfterSignatureMatch (collidingDecls, dc, shadowed);
587
636
}
588
637
589
638
// Check whether we have shadowing for imported initializer collisions.
590
- for (auto nominal : importedInitializerCollectionTypes ) {
639
+ for (auto nominal : importedInitializerCollisionTypes ) {
591
640
recordShadowedDeclsForImportedInits (importedInitializerCollisions[nominal],
592
641
shadowed);
593
642
}
@@ -597,15 +646,15 @@ static void
597
646
recordShadowedDecls (ArrayRef<OperatorDecl *> decls, const DeclContext *dc,
598
647
llvm::SmallPtrSetImpl<OperatorDecl *> &shadowed) {
599
648
// Always considered to have the same signature.
600
- recordShadowedDeclsAfterSignatureMatch (decls, dc, shadowed);
649
+ recordShadowedDeclsAfterTypeMatch (decls, dc, shadowed);
601
650
}
602
651
603
652
static void
604
653
recordShadowedDecls (ArrayRef<PrecedenceGroupDecl *> decls,
605
654
const DeclContext *dc,
606
655
llvm::SmallPtrSetImpl<PrecedenceGroupDecl *> &shadowed) {
607
- // Always considered to have the same signature .
608
- recordShadowedDeclsAfterSignatureMatch (decls, dc, shadowed);
656
+ // Always considered to have the same type .
657
+ recordShadowedDeclsAfterTypeMatch (decls, dc, shadowed);
609
658
}
610
659
611
660
template <typename T, typename Container>
0 commit comments