Skip to content

Commit 9b143bb

Browse files
GearsDatapackslpil
authored andcommitted
Fix renaming module selects in guards
1 parent 452c42b commit 9b143bb

File tree

8 files changed

+100
-22
lines changed

8 files changed

+100
-22
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,7 @@
165165
a dev dependency, while previously it would incorrectly let these
166166
dependencies to be imported.
167167
([Surya Rose](https://github.com/GearsDatapacks))
168+
169+
- Fixed a bug where renaming a constant which is referenced in another module
170+
inside a guard would generate invalid code.
171+
([Surya Rose](https://github.com/GearsDatapacks))

compiler-core/src/ast.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,7 +2047,7 @@ pub enum ClauseGuard<Type, RecordTag> {
20472047
},
20482048

20492049
FieldAccess {
2050-
location: SrcSpan,
2050+
label_location: SrcSpan,
20512051
index: Option<u64>,
20522052
label: EcoString,
20532053
type_: Type,
@@ -2093,9 +2093,13 @@ impl<A, B> ClauseGuard<A, B> {
20932093
| ClauseGuard::DivInt { location, .. }
20942094
| ClauseGuard::DivFloat { location, .. }
20952095
| ClauseGuard::RemainderInt { location, .. }
2096-
| ClauseGuard::FieldAccess { location, .. }
20972096
| ClauseGuard::LtEqFloat { location, .. }
20982097
| ClauseGuard::ModuleSelect { location, .. } => *location,
2098+
ClauseGuard::FieldAccess {
2099+
label_location,
2100+
container,
2101+
..
2102+
} => container.location().merge(label_location),
20992103
}
21002104
}
21012105

compiler-core/src/ast/visit.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -382,13 +382,13 @@ pub trait Visit<'ast> {
382382

383383
fn visit_typed_clause_guard_field_access(
384384
&mut self,
385-
location: &'ast SrcSpan,
385+
label_location: &'ast SrcSpan,
386386
index: &'ast Option<u64>,
387387
label: &'ast EcoString,
388388
type_: &'ast Arc<Type>,
389389
container: &'ast TypedClauseGuard,
390390
) {
391-
visit_typed_clause_guard_field_access(self, location, index, label, type_, container)
391+
visit_typed_clause_guard_field_access(self, label_location, index, label, type_, container)
392392
}
393393

394394
fn visit_typed_clause_guard_module_select(
@@ -1384,12 +1384,14 @@ where
13841384
tuple,
13851385
} => v.visit_typed_clause_guard_tuple_index(location, index, type_, tuple),
13861386
super::ClauseGuard::FieldAccess {
1387-
location,
1387+
label_location,
13881388
index,
13891389
label,
13901390
type_,
13911391
container,
1392-
} => v.visit_typed_clause_guard_field_access(location, index, label, type_, container),
1392+
} => {
1393+
v.visit_typed_clause_guard_field_access(label_location, index, label, type_, container)
1394+
}
13931395
super::ClauseGuard::ModuleSelect {
13941396
location,
13951397
type_,
@@ -1434,7 +1436,7 @@ pub fn visit_typed_clause_guard_tuple_index<'a, V>(
14341436

14351437
pub fn visit_typed_clause_guard_field_access<'a, V>(
14361438
v: &mut V,
1437-
_location: &'a SrcSpan,
1439+
_label_location: &'a SrcSpan,
14381440
_index: &'a Option<u64>,
14391441
_label: &'a EcoString,
14401442
_type_: &'a Arc<Type>,

compiler-core/src/language_server/tests/rename.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,3 +1526,27 @@ pub fn main() {
15261526
find_position_of("Ok")
15271527
);
15281528
}
1529+
1530+
#[test]
1531+
fn rename_module_access_in_clause_guard() {
1532+
assert_rename!(
1533+
(
1534+
"wibble",
1535+
"
1536+
import app
1537+
1538+
pub fn main() {
1539+
case app.something {
1540+
thing if thing == app.something -> True
1541+
_ -> False
1542+
}
1543+
}
1544+
"
1545+
),
1546+
"
1547+
pub const something = 10
1548+
",
1549+
"new_name",
1550+
find_position_of("something")
1551+
);
1552+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
source: compiler-core/src/language_server/tests/rename.rs
3+
expression: "\npub const something = 10\n"
4+
---
5+
----- BEFORE RENAME
6+
-- wibble.gleam
7+
8+
import app
9+
10+
pub fn main() {
11+
case app.something {
12+
thing if thing == app.something -> True
13+
_ -> False
14+
}
15+
}
16+
17+
18+
-- app.gleam
19+
20+
pub const something = 10
21+
↑▔▔▔▔▔▔▔▔
22+
23+
24+
----- AFTER RENAME
25+
-- wibble.gleam
26+
27+
import app
28+
29+
pub fn main() {
30+
case app.new_name {
31+
thing if thing == app.new_name -> True
32+
_ -> False
33+
}
34+
}
35+
36+
37+
-- app.gleam
38+
39+
pub const new_name = 10

compiler-core/src/parse.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,13 +1782,13 @@ where
17821782
}
17831783
}
17841784

1785-
Some((_, Token::Name { name: label }, int_e)) => {
1785+
Some((name_start, Token::Name { name: label }, name_end)) => {
17861786
self.parse_function_call_in_clause_guard(start)?;
17871787

17881788
unit = ClauseGuard::FieldAccess {
1789-
location: SrcSpan {
1790-
start: dot_s,
1791-
end: int_e,
1789+
label_location: SrcSpan {
1790+
start: name_start,
1791+
end: name_end,
17921792
},
17931793
index: None,
17941794
label,

compiler-core/src/type_/expression.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2370,20 +2370,22 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
23702370
}
23712371

23722372
ClauseGuard::FieldAccess {
2373-
location,
2373+
label_location,
23742374
label,
23752375
container,
23762376
index: _,
23772377
type_: (),
23782378
} => match self.infer_clause_guard(*container.clone()) {
2379-
Ok(container) => self.infer_guard_record_access(container, label, location),
2379+
Ok(container) => self.infer_guard_record_access(container, label, label_location),
23802380

23812381
Err(err) => match *container {
23822382
ClauseGuard::Var { name, location, .. } => {
2383-
self.infer_guard_module_access(name, label, location, err)
2383+
self.infer_guard_module_access(name, label, location, label_location, err)
23842384
}
23852385

2386-
_ => Err(Error::RecordAccessUnknownType { location }),
2386+
_ => Err(Error::RecordAccessUnknownType {
2387+
location: label_location,
2388+
}),
23872389
},
23882390
},
23892391

@@ -2820,7 +2822,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
28202822
container,
28212823
label,
28222824
index: Some(index),
2823-
location,
2825+
label_location: location,
28242826
type_,
28252827
})
28262828
}
@@ -2829,11 +2831,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
28292831
&mut self,
28302832
name: EcoString,
28312833
label: EcoString,
2832-
location: SrcSpan,
2834+
module_location: SrcSpan,
2835+
label_location: SrcSpan,
28332836
record_access_error: Error,
28342837
) -> Result<TypedClauseGuard, Error> {
28352838
let module_access = self
2836-
.infer_module_access(&name, label, &location, location)
2839+
.infer_module_access(&name, label, &module_location, label_location)
28372840
.and_then(|ma| match ma {
28382841
TypedExpr::ModuleSelect {
28392842
location,
@@ -2849,7 +2852,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
28492852
module_name.clone(),
28502853
label.clone(),
28512854
&label,
2852-
location,
2855+
label_location,
28532856
ReferenceKind::Qualified,
28542857
);
28552858

@@ -2866,7 +2869,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
28662869
_ => Err(Error::RecordAccessUnknownType { location }),
28672870
},
28682871

2869-
_ => Err(Error::RecordAccessUnknownType { location }),
2872+
_ => Err(Error::RecordAccessUnknownType {
2873+
location: module_location,
2874+
}),
28702875
});
28712876

28722877
// If the name is in the environment, use the original error from

compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__guards__string_variable_access.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ pub fn a(a: String) {
1414

1515
----- ERROR
1616
error: Unknown record field
17-
┌─ /src/one/two.gleam:4:11
17+
┌─ /src/one/two.gleam:4:12
1818
1919
4_ if a.b -> 1
20-
^^ This field does not exist
20+
^ This field does not exist
2121

2222
The value being accessed has this type:
2323

0 commit comments

Comments
 (0)