Skip to content

Commit 6eab52f

Browse files
committed
fix(LS): make visiters ignore type variables from other definitions
1 parent 3cfe7b5 commit 6eab52f

4 files changed

+76
-32
lines changed

compiler-core/src/language_server/code_action.rs

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,7 +1366,6 @@ pub struct AnnotateTopLevelDefinitions<'a> {
13661366
module: &'a Module,
13671367
params: &'a CodeActionParams,
13681368
edits: TextEdits<'a>,
1369-
printer: Printer<'a>,
13701369
is_hovering_definition: bool,
13711370
}
13721371

@@ -1380,9 +1379,6 @@ impl<'a> AnnotateTopLevelDefinitions<'a> {
13801379
module,
13811380
params,
13821381
edits: TextEdits::new(line_numbers),
1383-
// We need to use the same printer for all the edits because otherwise
1384-
// we could get duplicate type variable names.
1385-
printer: Printer::new_without_type_variables(&module.ast.names),
13861382
is_hovering_definition: false,
13871383
}
13881384
}
@@ -1408,11 +1404,6 @@ impl<'a> AnnotateTopLevelDefinitions<'a> {
14081404

14091405
impl<'ast> ast::visit::Visit<'ast> for AnnotateTopLevelDefinitions<'_> {
14101406
fn visit_typed_module_constant(&mut self, constant: &'ast TypedModuleConstant) {
1411-
// Since type variable names are local to definitions, any type variables
1412-
// in other parts of the module shouldn't affect what we print for the
1413-
// annotations of this constant.
1414-
self.printer.clear_type_variables();
1415-
14161407
let code_action_range = self.edits.src_span_to_lsp_range(constant.location);
14171408

14181409
if overlaps(code_action_range, self.params.range) {
@@ -1426,18 +1417,19 @@ impl<'ast> ast::visit::Visit<'ast> for AnnotateTopLevelDefinitions<'_> {
14261417

14271418
self.edits.insert(
14281419
constant.name_location.end,
1429-
format!(": {}", self.printer.print_type(&constant.type_)),
1420+
format!(
1421+
": {}",
1422+
// Create new printer to ignore type variables from other definitions
1423+
Printer::new_without_type_variables(&self.module.ast.names)
1424+
.print_type(&constant.type_)
1425+
),
14301426
);
14311427
}
14321428

14331429
fn visit_typed_function(&mut self, fun: &'ast ast::TypedFunction) {
1434-
// Since type variable names are local to definitions, any type variables
1435-
// in other parts of the module shouldn't affect what we print for the
1436-
// annotations of this functions. The only variables which cannot clash
1437-
// are ones defined in the signature of this function, which we register
1438-
// when we visit the parameters of this function inside `collect_type_variables`.
1439-
self.printer.clear_type_variables();
1440-
collect_type_variables(&mut self.printer, fun);
1430+
// Create new printer to ignore type variables from other definitions
1431+
let mut printer = Printer::new_without_type_variables(&self.module.ast.names);
1432+
collect_type_variables(&mut printer, fun);
14411433

14421434
ast::visit::visit_typed_function(self, fun);
14431435

@@ -1463,15 +1455,15 @@ impl<'ast> ast::visit::Visit<'ast> for AnnotateTopLevelDefinitions<'_> {
14631455

14641456
self.edits.insert(
14651457
argument.location.end,
1466-
format!(": {}", self.printer.print_type(&argument.type_)),
1458+
format!(": {}", printer.print_type(&argument.type_)),
14671459
);
14681460
}
14691461

14701462
// Annotate the return type if it isn't already annotated
14711463
if fun.return_annotation.is_none() {
14721464
self.edits.insert(
14731465
fun.location.end,
1474-
format!(" -> {}", self.printer.print_type(&fun.return_type)),
1466+
format!(" -> {}", printer.print_type(&fun.return_type)),
14751467
);
14761468
}
14771469
}

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

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10744,16 +10744,30 @@ pub fn add_one(thing: Int) {
1074410744
);
1074510745
}
1074610746

10747-
// FIXME: make test working
10748-
// #[test]
10749-
// fn annotate_all_top_level_definitions_with_two_generic_functions() {
10750-
// assert_code_action!(
10751-
// ANNOTATE_TOP_LEVEL_DEFINITIONS,
10752-
// r#"
10753-
// fn wibble(one) { todo }
10754-
10755-
// fn wobble(other) { todo }
10756-
// "#,
10757-
// find_position_of("wobble").to_selection()
10758-
// );
10759-
// }
10747+
#[test]
10748+
fn annotate_all_top_level_definitions_with_two_generic_functions() {
10749+
assert_code_action!(
10750+
ANNOTATE_TOP_LEVEL_DEFINITIONS,
10751+
r#"
10752+
fn wibble(one) { todo }
10753+
10754+
fn wobble(other) { todo }
10755+
"#,
10756+
find_position_of("wobble").to_selection()
10757+
);
10758+
}
10759+
10760+
#[test]
10761+
fn annotate_all_top_level_definitions_with_constant_and_generic_functions() {
10762+
assert_code_action!(
10763+
ANNOTATE_TOP_LEVEL_DEFINITIONS,
10764+
r#"
10765+
const answer = 42
10766+
10767+
fn wibble(one) { todo }
10768+
10769+
fn wobble(other) { todo }
10770+
"#,
10771+
find_position_of("wobble").to_selection()
10772+
);
10773+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
source: compiler-core/src/language_server/tests/action.rs
3+
expression: "\nconst answer = 42\n\nfn wibble(one) { todo }\n\nfn wobble(other) { todo }\n"
4+
---
5+
----- BEFORE ACTION
6+
7+
const answer = 42
8+
9+
fn wibble(one) { todo }
10+
11+
fn wobble(other) { todo }
12+
13+
14+
15+
----- AFTER ACTION
16+
17+
const answer: Int = 42
18+
19+
fn wibble(one: a) -> b { todo }
20+
21+
fn wobble(other: a) -> b { todo }
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
source: compiler-core/src/language_server/tests/action.rs
3+
expression: "\nfn wibble(one) { todo }\n\nfn wobble(other) { todo }\n"
4+
---
5+
----- BEFORE ACTION
6+
7+
fn wibble(one) { todo }
8+
9+
fn wobble(other) { todo }
10+
11+
12+
13+
----- AFTER ACTION
14+
15+
fn wibble(one: a) -> b { todo }
16+
17+
fn wobble(other: a) -> b { todo }

0 commit comments

Comments
 (0)