Skip to content

Commit f5fe4b1

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

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
@@ -3548,7 +3548,7 @@ class LookupAllConformancesInContextRequest
35483548
class CheckRedeclarationRequest
35493549
: public SimpleRequest<
35503550
CheckRedeclarationRequest,
3551-
evaluator::SideEffect(ValueDecl *, NominalTypeDecl *),
3551+
evaluator::SideEffect(ValueDecl *),
35523552
RequestFlags::SeparatelyCached | RequestFlags::DependencySource |
35533553
RequestFlags::DependencySink> {
35543554
public:
@@ -3561,8 +3561,7 @@ class CheckRedeclarationRequest
35613561
/// \p SelfNominalType is \c VD->getDeclContext()->getSelfNominalType().
35623562
/// Passed as a parameter in here so this request doesn't tigger self nominal
35633563
/// type computation.
3564-
evaluator::SideEffect evaluate(Evaluator &evaluator, ValueDecl *VD,
3565-
NominalTypeDecl *SelfNominalType) const;
3564+
evaluator::SideEffect evaluate(Evaluator &evaluator, ValueDecl *VD) const;
35663565

35673566
public:
35683567
// Separate caching.

lib/AST/NameLookup.cpp

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

26542654
if (gpList && !member.isSpecial()) {
2655-
if (auto gp = gpList->lookUpGenericParam(member.getBaseIdentifier())) {
2656-
if (gp->isValue()) {
2657-
decls.push_back(gp);
2658-
}
2655+
auto gp = gpList->lookUpGenericParam(member.getBaseIdentifier());
2656+
2657+
if (gp && gp->isValue()) {
2658+
decls.push_back(gp);
26592659
}
26602660
}
26612661

lib/AST/TypeCheckRequests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1547,7 +1547,7 @@ void CheckRedeclarationRequest::writeDependencySink(
15471547
return;
15481548

15491549
if (currentDC->isTypeContext()) {
1550-
if (auto nominal = std::get<1>(getStorage())) {
1550+
if (auto nominal = currentDC->getSelfNominalTypeDecl()) {
15511551
tracker.addUsedMember(nominal, current->getBaseName());
15521552
}
15531553
} else {

lib/Sema/TypeCheckDeclPrimary.cpp

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

670670
/// Check whether \c current is a redeclaration.
671671
evaluator::SideEffect
672-
CheckRedeclarationRequest::evaluate(Evaluator &eval, ValueDecl *current,
673-
NominalTypeDecl *SelfNominalType) const {
672+
CheckRedeclarationRequest::evaluate(Evaluator &eval, ValueDecl *current) const {
674673
// Ignore invalid and anonymous declarations.
675674
if (current->isInvalid() || !current->hasName())
676675
return std::make_tuple<>();
@@ -1088,6 +1087,26 @@ CheckRedeclarationRequest::evaluate(Evaluator &eval, ValueDecl *current,
10881087
break;
10891088
}
10901089
}
1090+
1091+
// Look to see if this type has a value generic with the same name and that
1092+
// the current value is a property.
1093+
if (currentDC->isTypeContext() && currentDC->isGenericContext() &&
1094+
isa<VarDecl>(current)) {
1095+
auto gpList = currentDC->getAsDecl()->getAsGenericContext()->getGenericParams();
1096+
1097+
if (gpList && !current->getBaseName().isSpecial()) {
1098+
auto gp = gpList->lookUpGenericParam(current->getBaseIdentifier());
1099+
1100+
if (gp && gp->isValue()) {
1101+
ctx.Diags.diagnoseWithNotes(
1102+
current->diagnose(diag::invalid_redecl, current), [&]() {
1103+
gp->diagnose(diag::invalid_redecl_prev, gp);
1104+
});
1105+
current->setInvalid();
1106+
}
1107+
}
1108+
}
1109+
10911110
return std::make_tuple<>();
10921111
}
10931112

@@ -2301,11 +2320,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23012320
// Force some requests, which can produce diagnostics.
23022321

23032322
// Check redeclaration.
2304-
(void)evaluateOrDefault(
2305-
Ctx.evaluator,
2306-
CheckRedeclarationRequest{
2307-
VD, VD->getDeclContext()->getSelfNominalTypeDecl()},
2308-
{});
2323+
(void)evaluateOrDefault(Ctx.evaluator, CheckRedeclarationRequest{VD}, {});
23092324

23102325
// Compute access level.
23112326
(void) VD->getFormalAccess();

test/Sema/value_generics.swift

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

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

117-
struct E<A, let b: Int> {}
117+
struct E<A, let b: Int> { // expected-note {{'b' previously declared here}}
118+
// expected-note@-1 {{'b' previously declared here}}
119+
static var b: Int { // expected-error {{invalid redeclaration of 'b'}}
120+
// expected-note@-1 {{'b' declared here}}
121+
123
122+
}
123+
124+
let b: String // expected-error {{invalid redeclaration of 'b'}}
125+
// expected-note@-1 {{'b' declared here}}
126+
127+
func b() {} // expected-note {{'b' declared here}}
128+
}
118129

119130
func testE1() -> Int {
120131
E<Int, 123>.b // OK
@@ -127,3 +138,12 @@ func testE2() -> Int {
127138
func testE3<let c: Int>(_: E<Int, c>.Type = E<Int, c>.self) -> Int {
128139
E<Int, c>.b // OK
129140
}
141+
142+
func testShadowing<let a: Int>(_: A<a>) {
143+
var a: Int {
144+
123
145+
}
146+
147+
print(a) // OK
148+
print(a.self) // OK
149+
}

0 commit comments

Comments
 (0)