@@ -28,7 +28,6 @@ use ecow::{EcoString, eco_format};
2828use im:: HashMap ;
2929use itertools:: Itertools ;
3030use lsp_types:: { CodeAction , CodeActionKind , CodeActionParams , Position , Range , TextEdit , Url } ;
31- use regex:: Regex ;
3231use vec1:: { Vec1 , vec1} ;
3332
3433use super :: {
@@ -4801,8 +4800,7 @@ impl<'a, IO> PatternMatchOnValue<'a, IO> {
48014800 } ;
48024801
48034802 let variable_start = ( variable_location. start - clause_location. start ) as usize ;
4804- let variable_end =
4805- variable_start + ( variable_location. end - variable_location. start ) as usize ;
4803+ let variable_end = variable_start + variable_location. len ( ) ;
48064804
48074805 let clause_code = code_at ( self . module , clause_location) ;
48084806 let patterns = patterns
@@ -8273,34 +8271,43 @@ impl<'a> CollapseNestedCase<'a> {
82738271 name : BoundVariableName :: Regular { .. } | BoundVariableName :: ListTail { .. } ,
82748272 ..
82758273 } => {
8276- // If the variable is a regular variable we'll have to replace
8277- // it entirely with the new pattern taking its place.
8274+ let trimmed_contents = new_content. trim ( ) ;
8275+
8276+ let pattern_is_literal_list =
8277+ trimmed_contents. starts_with ( "[" ) && trimmed_contents. ends_with ( "]" ) ;
8278+ let pattern_is_discard = trimmed_contents == "_" ;
8279+
8280+ let span_to_replace = match (
8281+ & matched_variable. name ,
8282+ // We verify whether the pattern is compatible with the list prefix `..`.
8283+ // For example, `..var` is valid syntax, but `..[]` and `.._` are not.
8284+ pattern_is_literal_list || pattern_is_discard,
8285+ ) {
8286+ // We normally replace the selected variable with the pattern.
8287+ ( BoundVariableName :: Regular { .. } , _) => matched_variable_span,
8288+
8289+ // If the selected pattern is not a list, we also replace it normally.
8290+ ( BoundVariableName :: ListTail { .. } , false ) => matched_variable_span,
8291+ // If the pattern is a list to also remove the list tail prefix.
8292+ ( BoundVariableName :: ListTail { tail_location, .. } , true ) => {
8293+ // When it's a list literal, we remove the surrounding brackets.
8294+ let len = trimmed_contents. len ( ) ;
8295+ if let Some ( slice) = new_content. trim ( ) . get ( 1 ..( len - 1 ) ) {
8296+ new_content = slice. to_string ( )
8297+ } ;
82788298
8279- let variable_span_to_use = if let BoundVariableName :: ListTail {
8280- tail_prefix_location : prefix_and_variable_span,
8281- ..
8282- } = matched_variable. name
8283- {
8284- // We need to un-nest the list when replacing the tail
8285- let surrounding_brackets = Regex :: new ( r"(^\[|\]$)" ) . expect ( "a valid regex" ) ;
8286- new_content = surrounding_brackets
8287- . replace_all ( new_content. trim ( ) , "" )
8288- . to_string ( ) ;
8289-
8290- // We need to also remove the prefix when replacing the variable
8291- // at the tail of the list
8292- prefix_and_variable_span
8293- } else {
8294- matched_variable_span
8299+ * tail_location
8300+ }
8301+
8302+ ( BoundVariableName :: ShorthandLabel { .. } , _) => unreachable ! ( ) ,
82958303 } ;
82968304
8297- let variable_start_in_pattern =
8298- ( variable_span_to_use. start - matched_pattern_span. start ) as usize ;
8299- let variable_length =
8300- ( variable_span_to_use. end - variable_span_to_use. start ) as usize ;
8305+ let start_of_pattern =
8306+ ( span_to_replace. start - matched_pattern_span. start ) as usize ;
8307+ let pattern_length = span_to_replace. len ( ) ;
83018308
8302- let variable_end_in_pattern = variable_start_in_pattern + variable_length ;
8303- let replaced_range = variable_start_in_pattern..variable_end_in_pattern ;
8309+ let end_of_pattern = start_of_pattern + pattern_length ;
8310+ let replaced_range = start_of_pattern..end_of_pattern ;
83048311
83058312 new_pattern. replace_range ( replaced_range, & new_content) ;
83068313 }
0 commit comments