1
- use std:: collections:: HashMap ;
1
+ use std:: collections:: { HashMap , HashSet } ;
2
2
3
3
use ecow:: EcoString ;
4
4
use lsp_types:: Location ;
@@ -342,13 +342,13 @@ fn find_references_in_module(
342
342
}
343
343
}
344
344
345
- #[ derive( Debug , Clone , Copy ) ]
345
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
346
346
pub struct VariableReference {
347
347
pub location : SrcSpan ,
348
348
pub kind : VariableReferenceKind ,
349
349
}
350
350
351
- #[ derive( Debug , Clone , Copy ) ]
351
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
352
352
pub enum VariableReferenceKind {
353
353
Variable ,
354
354
LabelShorthand ,
@@ -358,9 +358,9 @@ pub fn find_variable_references(
358
358
module : & TypedModule ,
359
359
definition_location : SrcSpan ,
360
360
name : EcoString ,
361
- ) -> Vec < VariableReference > {
361
+ ) -> HashSet < VariableReference > {
362
362
let mut finder = FindVariableReferences {
363
- references : Vec :: new ( ) ,
363
+ references : HashSet :: new ( ) ,
364
364
definition_location,
365
365
alternative_variable : AlternativeVariable :: Ignore ,
366
366
name,
@@ -376,7 +376,11 @@ enum AlternativeVariable {
376
376
}
377
377
378
378
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 > ,
380
384
definition_location : SrcSpan ,
381
385
alternative_variable : AlternativeVariable ,
382
386
name : EcoString ,
@@ -400,16 +404,10 @@ impl<'ast> Visit<'ast> for FindVariableReferences {
400
404
location : definition_location,
401
405
..
402
406
} 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
+ } ) ;
413
411
}
414
412
_ => { }
415
413
}
@@ -423,10 +421,10 @@ impl<'ast> Visit<'ast> for FindVariableReferences {
423
421
definition_location : & ' ast SrcSpan ,
424
422
) {
425
423
if * definition_location == self . definition_location {
426
- self . references . push ( VariableReference {
424
+ _ = self . references . insert ( VariableReference {
427
425
location : * location,
428
426
kind : VariableReferenceKind :: Variable ,
429
- } )
427
+ } ) ;
430
428
}
431
429
}
432
430
@@ -474,7 +472,7 @@ impl<'ast> Visit<'ast> for FindVariableReferences {
474
472
AlternativeVariable :: Track
475
473
if * name == self . name && * location != self . definition_location =>
476
474
{
477
- self . references . push ( VariableReference {
475
+ _ = self . references . insert ( VariableReference {
478
476
location : * location,
479
477
kind : VariableReferenceKind :: Variable ,
480
478
} ) ;
@@ -499,10 +497,10 @@ impl<'ast> Visit<'ast> for FindVariableReferences {
499
497
location : definition_location,
500
498
..
501
499
} if * definition_location == self . definition_location => {
502
- self . references . push ( VariableReference {
500
+ _ = self . references . insert ( VariableReference {
503
501
location : * location,
504
502
kind : VariableReferenceKind :: Variable ,
505
- } )
503
+ } ) ;
506
504
}
507
505
_ => { }
508
506
}
@@ -522,7 +520,7 @@ impl<'ast> Visit<'ast> for FindVariableReferences {
522
520
} if arg. uses_label_shorthand ( )
523
521
&& * definition_location == self . definition_location =>
524
522
{
525
- self . references . push ( VariableReference {
523
+ _ = self . references . insert ( VariableReference {
526
524
location : * location,
527
525
kind : VariableReferenceKind :: LabelShorthand ,
528
526
} ) ;
0 commit comments