Skip to content

Commit 917c937

Browse files
committed
Allow shadowing checks to deal with operator decls
Add overloads of `removeShadowedDecls` that deal with operator and precedencegroup decls, and template the existing shadowing logic such that it can process them.
1 parent 0c403fe commit 917c937

File tree

3 files changed

+80
-16
lines changed

3 files changed

+80
-16
lines changed

include/swift/AST/Decl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7048,6 +7048,10 @@ class PrecedenceGroupDecl : public Decl {
70487048
return Name;
70497049
}
70507050

7051+
// This is needed to allow templated code to work with both ValueDecls and
7052+
// PrecedenceGroupDecls.
7053+
DeclBaseName getBaseName() const { return Name; }
7054+
70517055
SourceLoc getLBraceLoc() const { return LBraceLoc; }
70527056
SourceLoc getRBraceLoc() const { return RBraceLoc; }
70537057

@@ -7205,6 +7209,10 @@ class OperatorDecl : public Decl {
72057209
SourceLoc getNameLoc() const { return NameLoc; }
72067210
Identifier getName() const { return name; }
72077211

7212+
// This is needed to allow templated code to work with both ValueDecls and
7213+
// OperatorDecls.
7214+
DeclBaseName getBaseName() const { return name; }
7215+
72087216
/// Get the list of identifiers after the colon in the operator declaration.
72097217
///
72107218
/// This list includes the names of designated types. For infix operators, the

include/swift/AST/NameLookup.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,26 @@ bool removeOverriddenDecls(SmallVectorImpl<ValueDecl*> &decls);
455455
bool removeShadowedDecls(SmallVectorImpl<ValueDecl*> &decls,
456456
const DeclContext *dc);
457457

458+
/// Remove any operators in the given set that are shadowed by
459+
/// other operators in that set.
460+
///
461+
/// \param decls The set of operators being considered.
462+
/// \param dc The DeclContext from which the lookup was performed.
463+
///
464+
/// \returns true if any shadowed declarations were removed.
465+
bool removeShadowedDecls(TinyPtrVector<OperatorDecl *> &decls,
466+
const DeclContext *dc);
467+
468+
/// Remove any precedence groups in the given set that are shadowed by
469+
/// other precedence groups in that set.
470+
///
471+
/// \param decls The set of precedence groups being considered.
472+
/// \param dc The DeclContext from which the lookup was performed.
473+
///
474+
/// \returns true if any shadowed declarations were removed.
475+
bool removeShadowedDecls(TinyPtrVector<PrecedenceGroupDecl *> &decls,
476+
const DeclContext *dc);
477+
458478
/// Finds decls visible in the given context and feeds them to the given
459479
/// VisibleDeclConsumer. If the current DeclContext is nested in a function,
460480
/// the SourceLoc is used to determine which declarations in that function

lib/AST/NameLookup.cpp

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,10 @@ static ConstructorComparison compareConstructors(ConstructorDecl *ctor1,
247247

248248
/// Given a set of declarations whose names and signatures have matched,
249249
/// figure out which of these declarations have been shadowed by others.
250-
static void recordShadowedDeclsAfterSignatureMatch(
251-
ArrayRef<ValueDecl *> decls,
252-
const DeclContext *dc,
253-
llvm::SmallPtrSetImpl<ValueDecl *> &shadowed) {
250+
template <typename T>
251+
static void
252+
recordShadowedDeclsAfterSignatureMatch(ArrayRef<T> decls, const DeclContext *dc,
253+
llvm::SmallPtrSetImpl<T> &shadowed) {
254254
assert(decls.size() > 1 && "Nothing collided");
255255

256256
// Compare each declaration to every other declaration. This is
@@ -354,9 +354,9 @@ static void recordShadowedDeclsAfterSignatureMatch(
354354
// This is due to the fact that in Swift 4, we only gave custom overload
355355
// types to properties in extensions of generic types, otherwise we
356356
// used the null type.
357-
if (!ctx.isSwiftVersionAtLeast(5)) {
358-
auto secondSig = secondDecl->getOverloadSignature();
359-
auto firstSig = firstDecl->getOverloadSignature();
357+
if (!ctx.isSwiftVersionAtLeast(5) && isa<ValueDecl>(firstDecl)) {
358+
auto secondSig = cast<ValueDecl>(secondDecl)->getOverloadSignature();
359+
auto firstSig = cast<ValueDecl>(firstDecl)->getOverloadSignature();
360360
if (firstSig.IsVariable && secondSig.IsVariable)
361361
if (firstSig.InExtensionOfGenericType !=
362362
secondSig.InExtensionOfGenericType)
@@ -583,8 +583,8 @@ static void recordShadowedDecls(ArrayRef<ValueDecl *> decls,
583583

584584
// Check whether we have shadowing for signature collisions.
585585
for (auto signature : collisionTypes) {
586-
recordShadowedDeclsAfterSignatureMatch(collisions[signature], dc,
587-
shadowed);
586+
ArrayRef<ValueDecl *> collidingDecls = collisions[signature];
587+
recordShadowedDeclsAfterSignatureMatch(collidingDecls, dc, shadowed);
588588
}
589589

590590
// Check whether we have shadowing for imported initializer collisions.
@@ -594,11 +594,25 @@ static void recordShadowedDecls(ArrayRef<ValueDecl *> decls,
594594
}
595595
}
596596

597-
bool swift::removeShadowedDecls(SmallVectorImpl<ValueDecl*> &decls,
598-
const DeclContext *dc) {
597+
static void
598+
recordShadowedDecls(ArrayRef<OperatorDecl *> decls, const DeclContext *dc,
599+
llvm::SmallPtrSetImpl<OperatorDecl *> &shadowed) {
600+
// Always considered to have the same signature.
601+
recordShadowedDeclsAfterSignatureMatch(decls, dc, shadowed);
602+
}
603+
604+
static void
605+
recordShadowedDecls(ArrayRef<PrecedenceGroupDecl *> decls,
606+
const DeclContext *dc,
607+
llvm::SmallPtrSetImpl<PrecedenceGroupDecl *> &shadowed) {
608+
// Always considered to have the same signature.
609+
recordShadowedDeclsAfterSignatureMatch(decls, dc, shadowed);
610+
}
611+
612+
template <typename T, typename Container>
613+
static bool removeShadowedDeclsImpl(Container &decls, const DeclContext *dc) {
599614
// Collect declarations with the same (full) name.
600-
llvm::SmallDenseMap<DeclName, llvm::TinyPtrVector<ValueDecl *>>
601-
collidingDeclGroups;
615+
llvm::SmallDenseMap<DeclName, llvm::TinyPtrVector<T>> collidingDeclGroups;
602616
bool anyCollisions = false;
603617
for (auto decl : decls) {
604618
// Record this declaration based on its full name.
@@ -614,7 +628,7 @@ bool swift::removeShadowedDecls(SmallVectorImpl<ValueDecl*> &decls,
614628
return false;
615629

616630
// Walk through the declarations again, marking any declarations that shadow.
617-
llvm::SmallPtrSet<ValueDecl *, 4> shadowed;
631+
llvm::SmallPtrSet<T, 4> shadowed;
618632
for (auto decl : decls) {
619633
auto known = collidingDeclGroups.find(decl->getName());
620634
if (known == collidingDeclGroups.end()) {
@@ -633,8 +647,8 @@ bool swift::removeShadowedDecls(SmallVectorImpl<ValueDecl*> &decls,
633647
// Remove shadowed declarations from the list of declarations.
634648
bool anyRemoved = false;
635649
decls.erase(std::remove_if(decls.begin(), decls.end(),
636-
[&](ValueDecl *vd) {
637-
if (shadowed.count(vd) > 0) {
650+
[&](T decl) {
651+
if (shadowed.count(decl) > 0) {
638652
anyRemoved = true;
639653
return true;
640654
}
@@ -646,6 +660,28 @@ bool swift::removeShadowedDecls(SmallVectorImpl<ValueDecl*> &decls,
646660
return anyRemoved;
647661
}
648662

663+
bool swift::removeShadowedDecls(SmallVectorImpl<ValueDecl *> &decls,
664+
const DeclContext *dc) {
665+
return removeShadowedDeclsImpl<ValueDecl *>(decls, dc);
666+
}
667+
668+
bool swift::removeShadowedDecls(TinyPtrVector<OperatorDecl *> &decls,
669+
const DeclContext *dc) {
670+
#ifndef NDEBUG
671+
// Make sure all the operators have the same fixity.
672+
if (decls.size() > 1) {
673+
for (auto *op : decls)
674+
assert(op->getFixity() == decls[0]->getFixity());
675+
}
676+
#endif
677+
return removeShadowedDeclsImpl<OperatorDecl *>(decls, dc);
678+
}
679+
680+
bool swift::removeShadowedDecls(TinyPtrVector<PrecedenceGroupDecl *> &decls,
681+
const DeclContext *dc) {
682+
return removeShadowedDeclsImpl<PrecedenceGroupDecl *>(decls, dc);
683+
}
684+
649685
namespace {
650686
enum class DiscriminatorMatch {
651687
NoDiscriminator,

0 commit comments

Comments
 (0)