Skip to content

Commit be8be32

Browse files
committed
[Parse] Discriminate local variables
Set local discriminator for all local `VarDecl`s. Otherwise, they cannot be discriminated with USRs. This change is needed for rename refactoring which uses USR for discrimiating variable names. https://bugs.swift.org/browse/SR-7205, rdar://problem/34701880
1 parent 7909e24 commit be8be32

11 files changed

+436
-2
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4384,8 +4384,6 @@ VarDecl *Parser::parseDeclVarGetSet(Pattern *pattern,
43844384
if (!PrimaryVar || !primaryVarIsWellFormed) {
43854385
diagnose(pattern->getLoc(), diag::getset_nontrivial_pattern);
43864386
Invalid = true;
4387-
} else {
4388-
setLocalDiscriminator(PrimaryVar);
43894387
}
43904388

43914389
TypeLoc TyLoc;
@@ -4795,6 +4793,7 @@ Parser::parseDeclVar(ParseDeclOptions Flags,
47954793
pattern->forEachVariable([&](VarDecl *VD) {
47964794
VD->setStatic(StaticLoc.isValid());
47974795
VD->getAttrs() = Attributes;
4796+
setLocalDiscriminator(VD);
47984797
Decls.push_back(VD);
47994798
});
48004799

lib/Parse/ParseStmt.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,7 @@ static void parseGuardedPattern(Parser &P, GuardedPattern &result,
972972
// represents tuples and var patterns as tupleexprs and
973973
// unresolved_pattern_expr nodes, instead of as proper pattern nodes.
974974
patternResult.get()->forEachVariable([&](VarDecl *VD) {
975+
P.setLocalDiscriminator(VD);
975976
if (VD->hasName()) P.addToScope(VD);
976977
boundDecls.push_back(VD);
977978
});
@@ -993,6 +994,8 @@ static void parseGuardedPattern(Parser &P, GuardedPattern &result,
993994
for (auto previous : boundDecls) {
994995
if (previous->hasName() && previous->getName() == VD->getName()) {
995996
found = true;
997+
// Use the same local discriminator.
998+
VD->setLocalDiscriminator(previous->getLocalDiscriminator());
996999
break;
9971000
}
9981001
}
@@ -1390,6 +1393,7 @@ Parser::parseStmtConditionElement(SmallVectorImpl<StmtConditionElement> &result,
13901393
// Add variable bindings from the pattern to our current scope and mark
13911394
// them as being having a non-pattern-binding initializer.
13921395
ThePattern.get()->forEachVariable([&](VarDecl *VD) {
1396+
setLocalDiscriminator(VD);
13931397
if (VD->hasName())
13941398
addToScope(VD);
13951399
VD->setHasNonPatternBindingInit();
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
func test1() {
2+
if true {
3+
let x = 1
4+
print(x)
5+
} else {
6+
let x = 2
7+
print(x)
8+
}
9+
}
10+
11+
func test2(arg1: Int?, arg2: (Int, String)?) {
12+
if let x = arg1 {
13+
print(x)
14+
} else if let (x, y) = arg2 {
15+
print(x, y)
16+
}
17+
}
18+
19+
func test3(arg: Int?) {
20+
switch arg {
21+
case let .some(xRenamed) where xRenamed == 0:
22+
print(xRenamed)
23+
case let .some(x) where x == 1,
24+
let .some(x) where x == 2: // FIXME: This 'x' in '.some(x)' isn't properly renamed in 'casebind_2' case.
25+
print(x)
26+
default:
27+
break
28+
}
29+
}
30+
31+
struct Err1 : Error { }
32+
func test4(arg: () throws -> Void) {
33+
do {
34+
try arg()
35+
} catch let x as Err1 {
36+
print(x)
37+
} catch let x {
38+
print(x)
39+
}
40+
}
41+
42+
43+
44+
45+
46+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
func test1() {
2+
if true {
3+
let x = 1
4+
print(x)
5+
} else {
6+
let x = 2
7+
print(x)
8+
}
9+
}
10+
11+
func test2(arg1: Int?, arg2: (Int, String)?) {
12+
if let x = arg1 {
13+
print(x)
14+
} else if let (x, y) = arg2 {
15+
print(x, y)
16+
}
17+
}
18+
19+
func test3(arg: Int?) {
20+
switch arg {
21+
case let .some(x) where x == 0:
22+
print(x)
23+
case let .some(xRenamed) where xRenamed == 1,
24+
let .some(x) where xRenamed == 2: // FIXME: This 'x' in '.some(x)' isn't properly renamed in 'casebind_2' case.
25+
print(xRenamed)
26+
default:
27+
break
28+
}
29+
}
30+
31+
struct Err1 : Error { }
32+
func test4(arg: () throws -> Void) {
33+
do {
34+
try arg()
35+
} catch let x as Err1 {
36+
print(x)
37+
} catch let x {
38+
print(x)
39+
}
40+
}
41+
42+
43+
44+
45+
46+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
func test1() {
2+
if true {
3+
let x = 1
4+
print(x)
5+
} else {
6+
let x = 2
7+
print(x)
8+
}
9+
}
10+
11+
func test2(arg1: Int?, arg2: (Int, String)?) {
12+
if let x = arg1 {
13+
print(x)
14+
} else if let (x, y) = arg2 {
15+
print(x, y)
16+
}
17+
}
18+
19+
func test3(arg: Int?) {
20+
switch arg {
21+
case let .some(x) where x == 0:
22+
print(x)
23+
case let .some(x) where x == 1,
24+
let .some(x) where x == 2: // FIXME: This 'x' in '.some(x)' isn't properly renamed in 'casebind_2' case.
25+
print(x)
26+
default:
27+
break
28+
}
29+
}
30+
31+
struct Err1 : Error { }
32+
func test4(arg: () throws -> Void) {
33+
do {
34+
try arg()
35+
} catch let x as Err1 {
36+
print(xRenamed)
37+
} catch let x {
38+
print(x)
39+
}
40+
}
41+
42+
43+
44+
45+
46+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
func test1() {
2+
if true {
3+
let x = 1
4+
print(x)
5+
} else {
6+
let x = 2
7+
print(x)
8+
}
9+
}
10+
11+
func test2(arg1: Int?, arg2: (Int, String)?) {
12+
if let x = arg1 {
13+
print(x)
14+
} else if let (x, y) = arg2 {
15+
print(x, y)
16+
}
17+
}
18+
19+
func test3(arg: Int?) {
20+
switch arg {
21+
case let .some(x) where x == 0:
22+
print(x)
23+
case let .some(x) where x == 1,
24+
let .some(x) where x == 2: // FIXME: This 'x' in '.some(x)' isn't properly renamed in 'casebind_2' case.
25+
print(x)
26+
default:
27+
break
28+
}
29+
}
30+
31+
struct Err1 : Error { }
32+
func test4(arg: () throws -> Void) {
33+
do {
34+
try arg()
35+
} catch let x as Err1 {
36+
print(x)
37+
} catch let xRenamed {
38+
print(xRenamed)
39+
}
40+
}
41+
42+
43+
44+
45+
46+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
func test1() {
2+
if true {
3+
let x = 1
4+
print(x)
5+
} else {
6+
let x = 2
7+
print(x)
8+
}
9+
}
10+
11+
func test2(arg1: Int?, arg2: (Int, String)?) {
12+
if let xRenamed = arg1 {
13+
print(xRenamed)
14+
} else if let (x, y) = arg2 {
15+
print(x, y)
16+
}
17+
}
18+
19+
func test3(arg: Int?) {
20+
switch arg {
21+
case let .some(x) where x == 0:
22+
print(x)
23+
case let .some(x) where x == 1,
24+
let .some(x) where x == 2: // FIXME: This 'x' in '.some(x)' isn't properly renamed in 'casebind_2' case.
25+
print(x)
26+
default:
27+
break
28+
}
29+
}
30+
31+
struct Err1 : Error { }
32+
func test4(arg: () throws -> Void) {
33+
do {
34+
try arg()
35+
} catch let x as Err1 {
36+
print(x)
37+
} catch let x {
38+
print(x)
39+
}
40+
}
41+
42+
43+
44+
45+
46+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
func test1() {
2+
if true {
3+
let x = 1
4+
print(x)
5+
} else {
6+
let x = 2
7+
print(x)
8+
}
9+
}
10+
11+
func test2(arg1: Int?, arg2: (Int, String)?) {
12+
if let x = arg1 {
13+
print(x)
14+
} else if let (xRenamed, y) = arg2 {
15+
print(xRenamed, y)
16+
}
17+
}
18+
19+
func test3(arg: Int?) {
20+
switch arg {
21+
case let .some(x) where x == 0:
22+
print(x)
23+
case let .some(x) where x == 1,
24+
let .some(x) where x == 2: // FIXME: This 'x' in '.some(x)' isn't properly renamed in 'casebind_2' case.
25+
print(x)
26+
default:
27+
break
28+
}
29+
}
30+
31+
struct Err1 : Error { }
32+
func test4(arg: () throws -> Void) {
33+
do {
34+
try arg()
35+
} catch let x as Err1 {
36+
print(x)
37+
} catch let x {
38+
print(x)
39+
}
40+
}
41+
42+
43+
44+
45+
46+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
func test1() {
2+
if true {
3+
let xRenamed = 1
4+
print(xRenamed)
5+
} else {
6+
let x = 2
7+
print(x)
8+
}
9+
}
10+
11+
func test2(arg1: Int?, arg2: (Int, String)?) {
12+
if let x = arg1 {
13+
print(x)
14+
} else if let (x, y) = arg2 {
15+
print(x, y)
16+
}
17+
}
18+
19+
func test3(arg: Int?) {
20+
switch arg {
21+
case let .some(x) where x == 0:
22+
print(x)
23+
case let .some(x) where x == 1,
24+
let .some(x) where x == 2: // FIXME: This 'x' in '.some(x)' isn't properly renamed in 'casebind_2' case.
25+
print(x)
26+
default:
27+
break
28+
}
29+
}
30+
31+
struct Err1 : Error { }
32+
func test4(arg: () throws -> Void) {
33+
do {
34+
try arg()
35+
} catch let x as Err1 {
36+
print(x)
37+
} catch let x {
38+
print(x)
39+
}
40+
}
41+
42+
43+
44+
45+
46+

0 commit comments

Comments
 (0)