Skip to content

Commit b34b6e5

Browse files
committed
Make it an error to redeclare properties with the same name as a value generic
Update value_generics.swift
1 parent 1aaf2c9 commit b34b6e5

File tree

5 files changed

+50
-16
lines changed

5 files changed

+50
-16
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3598,7 +3598,7 @@ class LookupAllConformancesInContextRequest
35983598
class CheckRedeclarationRequest
35993599
: public SimpleRequest<
36003600
CheckRedeclarationRequest,
3601-
evaluator::SideEffect(ValueDecl *, NominalTypeDecl *),
3601+
evaluator::SideEffect(ValueDecl *),
36023602
RequestFlags::SeparatelyCached | RequestFlags::DependencySource |
36033603
RequestFlags::DependencySink> {
36043604
public:
@@ -3611,8 +3611,7 @@ class CheckRedeclarationRequest
36113611
/// \p SelfNominalType is \c VD->getDeclContext()->getSelfNominalType().
36123612
/// Passed as a parameter in here so this request doesn't tigger self nominal
36133613
/// type computation.
3614-
evaluator::SideEffect evaluate(Evaluator &evaluator, ValueDecl *VD,
3615-
NominalTypeDecl *SelfNominalType) const;
3614+
evaluator::SideEffect evaluate(Evaluator &evaluator, ValueDecl *VD) const;
36163615

36173616
public:
36183617
// Separate caching.

lib/AST/NameLookup.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,10 +2743,10 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
27432743
auto gpList = current->getGenericParams();
27442744

27452745
if (gpList && !member.isSpecial()) {
2746-
if (auto gp = gpList->lookUpGenericParam(member.getBaseIdentifier())) {
2747-
if (gp->isValue()) {
2748-
decls.push_back(gp);
2749-
}
2746+
auto gp = gpList->lookUpGenericParam(member.getBaseIdentifier());
2747+
2748+
if (gp && gp->isValue()) {
2749+
decls.push_back(gp);
27502750
}
27512751
}
27522752

lib/AST/TypeCheckRequests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1579,7 +1579,7 @@ void CheckRedeclarationRequest::writeDependencySink(
15791579
return;
15801580

15811581
if (currentDC->isTypeContext()) {
1582-
if (auto nominal = std::get<1>(getStorage())) {
1582+
if (auto nominal = currentDC->getSelfNominalTypeDecl()) {
15831583
tracker.addUsedMember(nominal, current->getBaseName());
15841584
}
15851585
} else {

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -691,8 +691,7 @@ static void checkRedeclaration(PrecedenceGroupDecl *group) {
691691

692692
/// Check whether \c current is a redeclaration.
693693
evaluator::SideEffect
694-
CheckRedeclarationRequest::evaluate(Evaluator &eval, ValueDecl *current,
695-
NominalTypeDecl *SelfNominalType) const {
694+
CheckRedeclarationRequest::evaluate(Evaluator &eval, ValueDecl *current) const {
696695
// Ignore invalid and anonymous declarations.
697696
if (current->isInvalid() || !current->hasName())
698697
return std::make_tuple<>();
@@ -1135,6 +1134,26 @@ CheckRedeclarationRequest::evaluate(Evaluator &eval, ValueDecl *current,
11351134
break;
11361135
}
11371136
}
1137+
1138+
// Look to see if this type has a value generic with the same name and that
1139+
// the current value is a property.
1140+
if (currentDC->isTypeContext() && currentDC->isGenericContext() &&
1141+
isa<VarDecl>(current)) {
1142+
auto gpList = currentDC->getAsDecl()->getAsGenericContext()->getGenericParams();
1143+
1144+
if (gpList && !current->getBaseName().isSpecial()) {
1145+
auto gp = gpList->lookUpGenericParam(current->getBaseIdentifier());
1146+
1147+
if (gp && gp->isValue()) {
1148+
ctx.Diags.diagnoseWithNotes(
1149+
current->diagnose(diag::invalid_redecl, current), [&]() {
1150+
gp->diagnose(diag::invalid_redecl_prev, gp);
1151+
});
1152+
current->setInvalid();
1153+
}
1154+
}
1155+
}
1156+
11381157
return std::make_tuple<>();
11391158
}
11401159

@@ -2348,11 +2367,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23482367
// Force some requests, which can produce diagnostics.
23492368

23502369
// Check redeclaration.
2351-
(void)evaluateOrDefault(
2352-
Ctx.evaluator,
2353-
CheckRedeclarationRequest{
2354-
VD, VD->getDeclContext()->getSelfNominalTypeDecl()},
2355-
{});
2370+
(void)evaluateOrDefault(Ctx.evaluator, CheckRedeclarationRequest{VD}, {});
23562371

23572372
// Compute access level.
23582373
(void) VD->getFormalAccess();

test/Sema/value_generics.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,18 @@ func testC4<let T: Int>(with c: C<T, T>) {
120120

121121
struct D<let N: Int & P> {} // expected-error {{non-protocol, non-class type 'Int' cannot be used within a protocol-constrained type}}
122122

123-
struct E<A, let b: Int> {}
123+
struct E<A, let b: Int> { // expected-note {{'b' previously declared here}}
124+
// expected-note@-1 {{'b' previously declared here}}
125+
static var b: Int { // expected-error {{invalid redeclaration of 'b'}}
126+
// expected-note@-1 {{'b' declared here}}
127+
123
128+
}
129+
130+
let b: String // expected-error {{invalid redeclaration of 'b'}}
131+
// expected-note@-1 {{'b' declared here}}
132+
133+
func b() {} // expected-note {{'b' declared here}}
134+
}
124135

125136
func testE1() -> Int {
126137
E<Int, 123>.b // OK
@@ -133,3 +144,12 @@ func testE2() -> Int {
133144
func testE3<let c: Int>(_: E<Int, c>.Type = E<Int, c>.self) -> Int {
134145
E<Int, c>.b // OK
135146
}
147+
148+
func testShadowing<let a: Int>(_: A<a>) {
149+
var a: Int {
150+
123
151+
}
152+
153+
print(a) // OK
154+
print(a.self) // OK
155+
}

0 commit comments

Comments
 (0)