Skip to content

Commit 1107538

Browse files
committed
fix(LS): make visiters ignore type variables from other definitions
1 parent 895e93e commit 1107538

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
@@ -10644,16 +10644,30 @@ pub fn add_one(thing: Int) {
1064410644
);
1064510645
}
1064610646

10647-
// FIXME: make test working
10648-
// #[test]
10649-
// fn annotate_all_top_level_definitions_with_two_generic_functions() {
10650-
// assert_code_action!(
10651-
// ANNOTATE_TOP_LEVEL_DEFINITIONS,
10652-
// r#"
10653-
// fn wibble(one) { todo }
10654-
10655-
// fn wobble(other) { todo }
10656-
// "#,
10657-
// find_position_of("wobble").to_selection()
10658-
// );
10659-
// }
10647+
#[test]
10648+
fn annotate_all_top_level_definitions_with_two_generic_functions() {
10649+
assert_code_action!(
10650+
ANNOTATE_TOP_LEVEL_DEFINITIONS,
10651+
r#"
10652+
fn wibble(one) { todo }
10653+
10654+
fn wobble(other) { todo }
10655+
"#,
10656+
find_position_of("wobble").to_selection()
10657+
);
10658+
}
10659+
10660+
#[test]
10661+
fn annotate_all_top_level_definitions_with_constant_and_generic_functions() {
10662+
assert_code_action!(
10663+
ANNOTATE_TOP_LEVEL_DEFINITIONS,
10664+
r#"
10665+
const answer = 42
10666+
10667+
fn wibble(one) { todo }
10668+
10669+
fn wobble(other) { todo }
10670+
"#,
10671+
find_position_of("wobble").to_selection()
10672+
);
10673+
}
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)