Skip to content

Commit abc26b4

Browse files
ankddevlpil
authored andcommitted
fix(LS): make visiters ignore type variables from other definitions
1 parent ac6cc7e commit abc26b4

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
@@ -1367,7 +1367,6 @@ pub struct AnnotateTopLevelDefinitions<'a> {
13671367
module: &'a Module,
13681368
params: &'a CodeActionParams,
13691369
edits: TextEdits<'a>,
1370-
printer: Printer<'a>,
13711370
is_hovering_definition: bool,
13721371
}
13731372

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

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

14191410
if overlaps(code_action_range, self.params.range) {
@@ -1427,18 +1418,19 @@ impl<'ast> ast::visit::Visit<'ast> for AnnotateTopLevelDefinitions<'_> {
14271418

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

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

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

@@ -1464,15 +1456,15 @@ impl<'ast> ast::visit::Visit<'ast> for AnnotateTopLevelDefinitions<'_> {
14641456

14651457
self.edits.insert(
14661458
argument.location.end,
1467-
format!(": {}", self.printer.print_type(&argument.type_)),
1459+
format!(": {}", printer.print_type(&argument.type_)),
14681460
);
14691461
}
14701462

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

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

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11273,16 +11273,30 @@ pub fn add_one(thing: Int) {
1127311273
);
1127411274
}
1127511275

11276-
// FIXME: make test working
11277-
// #[test]
11278-
// fn annotate_all_top_level_definitions_with_two_generic_functions() {
11279-
// assert_code_action!(
11280-
// ANNOTATE_TOP_LEVEL_DEFINITIONS,
11281-
// r#"
11282-
// fn wibble(one) { todo }
11283-
11284-
// fn wobble(other) { todo }
11285-
// "#,
11286-
// find_position_of("wobble").to_selection()
11287-
// );
11288-
// }
11276+
#[test]
11277+
fn annotate_all_top_level_definitions_with_two_generic_functions() {
11278+
assert_code_action!(
11279+
ANNOTATE_TOP_LEVEL_DEFINITIONS,
11280+
r#"
11281+
fn wibble(one) { todo }
11282+
11283+
fn wobble(other) { todo }
11284+
"#,
11285+
find_position_of("wobble").to_selection()
11286+
);
11287+
}
11288+
11289+
#[test]
11290+
fn annotate_all_top_level_definitions_with_constant_and_generic_functions() {
11291+
assert_code_action!(
11292+
ANNOTATE_TOP_LEVEL_DEFINITIONS,
11293+
r#"
11294+
const answer = 42
11295+
11296+
fn wibble(one) { todo }
11297+
11298+
fn wobble(other) { todo }
11299+
"#,
11300+
find_position_of("wobble").to_selection()
11301+
);
11302+
}
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 }
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)