Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

fix crash in ls

author
Giacomo Cavalieri
committer
Louis Pilfold
date (Jul 25, 2026, 12:59 PM +0100) commit 02730a87 parent 97b74f82 change-id vkxxxxsn
+54 -45
+8
CHANGELOG.md
··· 30 30 were ignored. 31 31 ([Francesco Cappetti](https://github.com/frakappa)) 32 32 33 + - Fixed a bug where the language server would crash on code that contains syntax 34 + errors. 35 + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 36 + 37 + - Fixed a bug where bit array segments would not be compiled properly, using an 38 + invalid Erlang segment option. 39 + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 40 + 33 41 ## v1.18.0-rc1 - 2026-07-21 34 42 35 43 ### Compiler
+46 -45
language-server/src/code_action.rs
··· 12992 12992 12993 12993 pub fn code_actions(self) -> Vec<CodeAction> { 12994 12994 let line = self.params.range.start.line; 12995 - let num_slashes = self 12996 - .count_leading_slashes(line) 12997 - .expect("Line number should be valid"); 12995 + let Some(num_slashes) = self.count_leading_slashes(line) else { 12996 + return vec![]; 12997 + }; 12998 12998 12999 12999 if !(2..=4).contains(&num_slashes) { 13000 13000 return vec![]; ··· 13012 13012 } 13013 13013 13014 13014 let comment = match num_slashes { 13015 - 2 if self.is_module_comment(start_line, end_line) => "////", 13015 + 2 if self.can_be_module_comment(start_line, end_line) => "////", 13016 13016 2 if self.can_have_doc_comment(end_line) => "///", 13017 13017 3 | 4 => "//", 13018 13018 _ => return vec![], ··· 13020 13020 13021 13021 let mut edits = TextEdits::new(self.lines); 13022 13022 for line in start_line..=end_line { 13023 - let start = next_nonwhitespace( 13024 - &self.module.code, 13025 - self.line_start(line).expect("Line number should be valid"), 13026 - ); 13023 + let Some(line_start) = self.line_start(line) else { 13024 + return vec![]; 13025 + }; 13026 + let start = next_nonwhitespace(&self.module.code, line_start); 13027 13027 edits.replace(SrcSpan::new(start, start + num_slashes), comment.to_owned()); 13028 13028 } 13029 13029 ··· 13058 13058 } 13059 13059 13060 13060 /// Find the last line in the range that is part of the same comment. 13061 - fn find_comment_edge(&self, range: impl Iterator<Item = u32>, num_slashes: u32) -> Option<u32> { 13062 - range 13063 - .take_while(|&i| { 13064 - self.count_leading_slashes(i) 13061 + fn find_comment_edge(&self, lines: impl Iterator<Item = u32>, num_slashes: u32) -> Option<u32> { 13062 + lines 13063 + .take_while(|&line| { 13064 + self.count_leading_slashes(line) 13065 13065 .is_some_and(|n| n == num_slashes) 13066 13066 }) 13067 13067 .last() 13068 13068 } 13069 13069 13070 - fn is_module_comment(&self, start_line: u32, end_line: u32) -> bool { 13071 - previous_nonwhitespace( 13072 - &self.module.code, 13073 - self.line_start(start_line) 13074 - .expect("Line number should be valid"), 13075 - ) == 0 13070 + fn can_be_module_comment(&self, start_line: u32, end_line: u32) -> bool { 13071 + let Some(line_start) = self.line_start(start_line) else { 13072 + return false; 13073 + }; 13074 + previous_nonwhitespace(&self.module.code, line_start) == 0 13076 13075 && self 13077 13076 .line_start(end_line + 1) 13078 13077 .is_none_or(|position| self.module.extra.empty_lines.contains(&position)) ··· 13080 13079 13081 13080 /// Check if the comment is before a node that can have a doc comment, e.g. a function. 13082 13081 fn can_have_doc_comment(&self, end_line: u32) -> bool { 13083 - self.line_start(end_line + 1).is_some_and(|position| { 13084 - let next_node = next_nonwhitespace(&self.module.code, position); 13085 - let definitions = &self.module.ast.definitions; 13086 - definitions 13087 - .functions 13082 + let Some(position) = self.line_start(end_line + 1) else { 13083 + return false; 13084 + }; 13085 + 13086 + let next_node = next_nonwhitespace(&self.module.code, position); 13087 + let definitions = &self.module.ast.definitions; 13088 + definitions 13089 + .functions 13090 + .iter() 13091 + .any(|function| function.location.contains(next_node)) 13092 + || definitions 13093 + .constants 13088 13094 .iter() 13089 - .any(|function| function.location.contains(next_node)) 13090 - || definitions 13091 - .constants 13092 - .iter() 13093 - .any(|constant| constant.location.contains(next_node)) 13094 - || definitions 13095 - .type_aliases 13096 - .iter() 13097 - .any(|type_alias| type_alias.location.contains(next_node)) 13098 - || definitions.custom_types.iter().any(|custom_type| { 13099 - custom_type.location.contains(next_node) 13100 - || custom_type.constructors.iter().any(|constructor| { 13101 - constructor.location.contains(next_node) 13102 - || constructor.arguments.iter().any(|argument| { 13103 - argument 13104 - .label 13105 - .as_ref() 13106 - .is_some_and(|label| label.0.contains(next_node)) 13107 - }) 13108 - }) 13109 - }) 13110 - }) 13095 + .any(|constant| constant.location.contains(next_node)) 13096 + || definitions 13097 + .type_aliases 13098 + .iter() 13099 + .any(|type_alias| type_alias.location.contains(next_node)) 13100 + || definitions.custom_types.iter().any(|custom_type| { 13101 + custom_type.location.contains(next_node) 13102 + || custom_type.constructors.iter().any(|constructor| { 13103 + constructor.location.contains(next_node) 13104 + || constructor.arguments.iter().any(|argument| { 13105 + argument 13106 + .label 13107 + .as_ref() 13108 + .is_some_and(|label| label.0.contains(next_node)) 13109 + }) 13110 + }) 13111 + }) 13111 13112 } 13112 13113 } 13113 13114