Skip to content

Commit 4dd6b06

Browse files
giacomocavalierilpil
authored andcommitted
fix bug where add missing type parameter would trigger on invalid types
1 parent f037af2 commit 4dd6b06

3 files changed

Lines changed: 30 additions & 10 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@
2525
offset 0 instead of the slice's actual byte offset, causing sliced bit arrays
2626
to read from the wrong position in the underlying buffer on JavaScript.
2727
([John Downey](https://github.com/jtdowney))
28+
29+
- Fixed a bug where the "Add missing type parameter" code action could be
30+
triggered on types that do not exist instead of type variables.
31+
([Giacomo Cavalieri](https://github.com/giacomocavalieri))

language-server/src/code_action.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10926,13 +10926,12 @@ impl<'a> AddMissingTypeParameter<'a> {
1092610926

1092710927
impl<'ast> ast::visit::Visit<'ast> for AddMissingTypeParameter<'ast> {
1092810928
fn visit_typed_custom_type(&mut self, custom_type: &'ast ast::TypedCustomType) {
10929-
let full_type_definition_range = self.edits.src_span_to_lsp_range(SrcSpan::new(
10930-
custom_type.location.start,
10931-
custom_type.end_position,
10932-
));
10929+
let custom_type_range = self
10930+
.edits
10931+
.src_span_to_lsp_range(custom_type.full_location());
1093310932

1093410933
// Only continue, if the action was selected anywhere within the custom type definition.
10935-
if !overlaps(self.params.range, full_type_definition_range) {
10934+
if !overlaps(self.params.range, custom_type_range) {
1093610935
return;
1093710936
}
1093810937

@@ -10943,15 +10942,19 @@ impl<'ast> ast::visit::Visit<'ast> for AddMissingTypeParameter<'ast> {
1094310942

1094410943
self.has_existing_parameters = !custom_type.typed_parameters.is_empty();
1094510944

10945+
let existing_names: HashSet<_> = custom_type
10946+
.parameters
10947+
.iter()
10948+
.map(|(_, name)| name)
10949+
.collect();
10950+
1094610951
// Collect the remaining type parameters from the variant constructors.
1094710952
for record in &custom_type.constructors {
1094810953
for argument in &record.arguments {
10949-
if let Type::Var { .. } = argument.type_.as_ref()
10950-
&& !custom_type.typed_parameters.contains(&argument.type_)
10954+
if let ast::TypeAst::Var(ast::TypeAstVar { name, .. }) = &argument.ast
10955+
&& !existing_names.contains(name)
1095110956
{
10952-
let mut name = EcoString::new();
10953-
argument.ast.print(&mut name);
10954-
let _ = self.missing_parameters.insert(name);
10957+
let _ = self.missing_parameters.insert(name.clone());
1095510958
}
1095610959
}
1095710960
}

language-server/src/tests/action.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12113,6 +12113,19 @@ type Wibble {
1211312113
);
1211412114
}
1211512115

12116+
#[test]
12117+
fn add_missing_type_parameter_does_not_add_types_that_do_not_exist() {
12118+
assert_no_code_actions!(
12119+
ADD_MISSING_TYPE_PARAMETER,
12120+
r#"
12121+
type Wibble {
12122+
Wibble(Wobble)
12123+
}
12124+
"#,
12125+
find_position_of("Wibble").nth_occurrence(2).to_selection()
12126+
);
12127+
}
12128+
1211612129
// https://github.com/gleam-lang/gleam/issues/5288
1211712130
#[test]
1211812131
fn extract_anonymous_function_without_variable_capture_1() {

0 commit comments

Comments
 (0)