Skip to content

Commit 801c531

Browse files
GearsDatapackslpil
authored andcommitted
Replace Vec with HashSet
1 parent 5a422e4 commit 801c531

File tree

2 files changed

+28
-26
lines changed

2 files changed

+28
-26
lines changed

compiler-core/src/language_server/code_action.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5947,10 +5947,14 @@ impl<'a> InlineVariable<'a> {
59475947
}
59485948

59495949
fn maybe_inline(&mut self, location: SrcSpan, name: EcoString) {
5950-
let reference = match find_variable_references(&self.module.ast, location, name).as_slice()
5951-
{
5952-
[only_reference] => *only_reference,
5953-
_ => return,
5950+
let references = find_variable_references(&self.module.ast, location, name);
5951+
let reference = if references.len() == 1 {
5952+
references
5953+
.into_iter()
5954+
.next()
5955+
.expect("References has length 1")
5956+
} else {
5957+
return;
59545958
};
59555959

59565960
let Some(ast::Statement::Assignment(assignment)) =

compiler-core/src/language_server/reference.rs

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::HashMap;
1+
use std::collections::{HashMap, HashSet};
22

33
use ecow::EcoString;
44
use lsp_types::Location;
@@ -342,13 +342,13 @@ fn find_references_in_module(
342342
}
343343
}
344344

345-
#[derive(Debug, Clone, Copy)]
345+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
346346
pub struct VariableReference {
347347
pub location: SrcSpan,
348348
pub kind: VariableReferenceKind,
349349
}
350350

351-
#[derive(Debug, Clone, Copy)]
351+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
352352
pub enum VariableReferenceKind {
353353
Variable,
354354
LabelShorthand,
@@ -358,9 +358,9 @@ pub fn find_variable_references(
358358
module: &TypedModule,
359359
definition_location: SrcSpan,
360360
name: EcoString,
361-
) -> Vec<VariableReference> {
361+
) -> HashSet<VariableReference> {
362362
let mut finder = FindVariableReferences {
363-
references: Vec::new(),
363+
references: HashSet::new(),
364364
definition_location,
365365
alternative_variable: AlternativeVariable::Ignore,
366366
name,
@@ -376,7 +376,11 @@ enum AlternativeVariable {
376376
}
377377

378378
struct FindVariableReferences {
379-
references: Vec<VariableReference>,
379+
// Due to the structure of some AST nodes (for example, record updates),
380+
// when we traverse the AST it is possible to accidentally duplicate references.
381+
// To avoid this, we use a `HashSet` instead of a `Vec` here.
382+
// See: https://github.com/gleam-lang/gleam/issues/4859 and the linked PR.
383+
references: HashSet<VariableReference>,
380384
definition_location: SrcSpan,
381385
alternative_variable: AlternativeVariable,
382386
name: EcoString,
@@ -400,16 +404,10 @@ impl<'ast> Visit<'ast> for FindVariableReferences {
400404
location: definition_location,
401405
..
402406
} if definition_location == self.definition_location => {
403-
if !self
404-
.references
405-
.iter()
406-
.any(|reference| reference.location == *location)
407-
{
408-
self.references.push(VariableReference {
409-
location: *location,
410-
kind: VariableReferenceKind::Variable,
411-
})
412-
}
407+
_ = self.references.insert(VariableReference {
408+
location: *location,
409+
kind: VariableReferenceKind::Variable,
410+
});
413411
}
414412
_ => {}
415413
}
@@ -423,10 +421,10 @@ impl<'ast> Visit<'ast> for FindVariableReferences {
423421
definition_location: &'ast SrcSpan,
424422
) {
425423
if *definition_location == self.definition_location {
426-
self.references.push(VariableReference {
424+
_ = self.references.insert(VariableReference {
427425
location: *location,
428426
kind: VariableReferenceKind::Variable,
429-
})
427+
});
430428
}
431429
}
432430

@@ -474,7 +472,7 @@ impl<'ast> Visit<'ast> for FindVariableReferences {
474472
AlternativeVariable::Track
475473
if *name == self.name && *location != self.definition_location =>
476474
{
477-
self.references.push(VariableReference {
475+
_ = self.references.insert(VariableReference {
478476
location: *location,
479477
kind: VariableReferenceKind::Variable,
480478
});
@@ -499,10 +497,10 @@ impl<'ast> Visit<'ast> for FindVariableReferences {
499497
location: definition_location,
500498
..
501499
} if *definition_location == self.definition_location => {
502-
self.references.push(VariableReference {
500+
_ = self.references.insert(VariableReference {
503501
location: *location,
504502
kind: VariableReferenceKind::Variable,
505-
})
503+
});
506504
}
507505
_ => {}
508506
}
@@ -522,7 +520,7 @@ impl<'ast> Visit<'ast> for FindVariableReferences {
522520
} if arg.uses_label_shorthand()
523521
&& *definition_location == self.definition_location =>
524522
{
525-
self.references.push(VariableReference {
523+
_ = self.references.insert(VariableReference {
526524
location: *location,
527525
kind: VariableReferenceKind::LabelShorthand,
528526
});

0 commit comments

Comments
 (0)