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

Configure Feed

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

Collapse ifs with chained lets

author
Eli Treuherz
committer
Louis Pilfold
date (Aug 8, 2025, 10:58 AM +0100) commit f297bfc1 parent 17f7e0cc change-id wstllkox
+355 -375
+5 -5
compiler-cli/src/dependencies.rs
··· 1037 1037 let mut packages_to_unlock: Vec<EcoString> = packages_to_unlock.to_vec(); 1038 1038 1039 1039 while let Some(package_name) = packages_to_unlock.pop() { 1040 - if locked.remove(&package_name).is_some() { 1041 - if let Some(package) = manifest.packages.iter().find(|p| p.name == package_name) { 1042 - let deps_to_unlock = find_deps_to_unlock(package, locked, manifest); 1043 - packages_to_unlock.extend(deps_to_unlock); 1044 - } 1040 + if locked.remove(&package_name).is_some() 1041 + && let Some(package) = manifest.packages.iter().find(|p| p.name == package_name) 1042 + { 1043 + let deps_to_unlock = find_deps_to_unlock(package, locked, manifest); 1044 + packages_to_unlock.extend(deps_to_unlock); 1045 1045 } 1046 1046 } 1047 1047 } else {
+7 -11
compiler-cli/src/publish.rs
··· 342 342 // Otherwise we need to check that the annotated version range is 343 343 // correct and includes the minimum required version. 344 344 Some(gleam_version) => { 345 - if let Some(lowest_allowed_version) = gleam_version.lowest_version() { 346 - if lowest_allowed_version < minimum_required_version { 347 - return Err(Error::CannotPublishWrongVersion { 348 - minimum_required_version: SmallVersion::from_hexpm( 349 - minimum_required_version, 350 - ), 351 - wrongfully_allowed_version: SmallVersion::from_hexpm( 352 - lowest_allowed_version, 353 - ), 354 - }); 355 - } 345 + if let Some(lowest_allowed_version) = gleam_version.lowest_version() 346 + && lowest_allowed_version < minimum_required_version 347 + { 348 + return Err(Error::CannotPublishWrongVersion { 349 + minimum_required_version: SmallVersion::from_hexpm(minimum_required_version), 350 + wrongfully_allowed_version: SmallVersion::from_hexpm(lowest_allowed_version), 351 + }); 356 352 } 357 353 } 358 354 }
+6 -6
compiler-cli/src/run.rs
··· 56 56 no_print_progress: bool, 57 57 ) -> Result<Command, Error> { 58 58 // Validate the module path 59 - if let Some(mod_path) = &module { 60 - if !is_gleam_module(mod_path) { 61 - return Err(Error::InvalidModuleName { 62 - module: mod_path.to_owned(), 63 - }); 64 - } 59 + if let Some(mod_path) = &module 60 + && !is_gleam_module(mod_path) 61 + { 62 + return Err(Error::InvalidModuleName { 63 + module: mod_path.to_owned(), 64 + }); 65 65 }; 66 66 67 67 let telemetry: &'static dyn Telemetry = if no_print_progress {
+19 -19
compiler-core/src/analyse.rs
··· 643 643 } => self.track_feature_usage(FeatureKind::InternalAnnotation, location), 644 644 } 645 645 646 - if let Some((module, _, location)) = &external_javascript { 647 - if module.contains('@') { 648 - self.track_feature_usage(FeatureKind::AtInJavascriptModules, *location) 649 - } 646 + if let Some((module, _, location)) = &external_javascript 647 + && module.contains('@') 648 + { 649 + self.track_feature_usage(FeatureKind::AtInJavascriptModules, *location) 650 650 } 651 651 652 652 // Assert that the inferred type matches the type of any recursive call ··· 1558 1558 1559 1559 // Then if the required version is not in the specified version for the 1560 1560 // range we emit a warning highlighting the usage of the feature. 1561 - if let Some(gleam_version) = &self.package_config.gleam_version { 1562 - if let Some(lowest_allowed_version) = gleam_version.lowest_version() { 1563 - // There is a version in the specified range that is lower than 1564 - // the one required by this feature! This means that the 1565 - // specified range is wrong and would allow someone to run a 1566 - // compiler that is too old to know of this feature. 1567 - if minimum_required_version > lowest_allowed_version { 1568 - self.problems 1569 - .warning(Warning::FeatureRequiresHigherGleamVersion { 1570 - location, 1571 - feature_kind, 1572 - minimum_required_version: minimum_required_version.clone(), 1573 - wrongfully_allowed_version: lowest_allowed_version, 1574 - }) 1575 - } 1561 + if let Some(gleam_version) = &self.package_config.gleam_version 1562 + && let Some(lowest_allowed_version) = gleam_version.lowest_version() 1563 + { 1564 + // There is a version in the specified range that is lower than 1565 + // the one required by this feature! This means that the 1566 + // specified range is wrong and would allow someone to run a 1567 + // compiler that is too old to know of this feature. 1568 + if minimum_required_version > lowest_allowed_version { 1569 + self.problems 1570 + .warning(Warning::FeatureRequiresHigherGleamVersion { 1571 + location, 1572 + feature_kind, 1573 + minimum_required_version: minimum_required_version.clone(), 1574 + wrongfully_allowed_version: lowest_allowed_version, 1575 + }) 1576 1576 } 1577 1577 } 1578 1578
+12 -12
compiler-core/src/ast.rs
··· 962 962 963 963 Definition::ModuleConstant(constant) => { 964 964 // Check if location is within the annotation. 965 - if let Some(annotation) = &constant.annotation { 966 - if let Some(l) = annotation.find_node(byte_index, constant.type_.clone()) { 967 - return Some(l); 968 - } 965 + if let Some(annotation) = &constant.annotation 966 + && let Some(l) = annotation.find_node(byte_index, constant.type_.clone()) 967 + { 968 + return Some(l); 969 969 } 970 970 971 971 if let Some(located) = constant.value.find_node(byte_index) { ··· 3635 3635 3636 3636 impl TypedAssignment { 3637 3637 pub fn find_node(&self, byte_index: u32) -> Option<Located<'_>> { 3638 - if let Some(annotation) = &self.annotation { 3639 - if let Some(l) = annotation.find_node(byte_index, self.pattern.type_()) { 3640 - return Some(l); 3641 - } 3638 + if let Some(annotation) = &self.annotation 3639 + && let Some(l) = annotation.find_node(byte_index, self.pattern.type_()) 3640 + { 3641 + return Some(l); 3642 3642 } 3643 3643 self.pattern 3644 3644 .find_node(byte_index) ··· 3665 3665 if let Some(found) = self.value.find_node(byte_index) { 3666 3666 return Some(found); 3667 3667 } 3668 - if let Some(message) = &self.message { 3669 - if let Some(found) = message.find_node(byte_index) { 3670 - return Some(found); 3671 - } 3668 + if let Some(message) = &self.message 3669 + && let Some(found) = message.find_node(byte_index) 3670 + { 3671 + return Some(found); 3672 3672 } 3673 3673 None 3674 3674 }
+8 -8
compiler-core/src/ast/typed.rs
··· 339 339 } 340 340 } 341 341 342 - if let Some(tail) = tail { 343 - if let Some(node) = tail.find_node(byte_index) { 344 - return Some(node); 345 - } 342 + if let Some(tail) = tail 343 + && let Some(node) = tail.find_node(byte_index) 344 + { 345 + return Some(node); 346 346 } 347 347 self.self_if_contains_location(byte_index) 348 348 } ··· 484 484 } 485 485 } 486 486 487 - if let Some(tail) = tail { 488 - if let Some(node) = tail.find_statement(byte_index) { 489 - return Some(node); 490 - } 487 + if let Some(tail) = tail 488 + && let Some(node) = tail.find_statement(byte_index) 489 + { 490 + return Some(node); 491 491 } 492 492 None 493 493 }
+9 -11
compiler-core/src/bit_array.rs
··· 208 208 } 209 209 210 210 // All but the last segment in a pattern must have an exact size 211 - if must_have_size { 212 - if let SegmentOptionCategories { 211 + if must_have_size 212 + && let SegmentOptionCategories { 213 213 type_: Some(opt @ (Bytes { .. } | Bits { .. })), 214 214 size: None, 215 215 .. 216 216 } = categories 217 - { 218 - return err(ErrorType::SegmentMustHaveSize, opt.location()); 219 - } 217 + { 218 + return err(ErrorType::SegmentMustHaveSize, opt.location()); 220 219 } 221 220 222 221 // Endianness is only valid for int, utf16, utf16_codepoint, utf32, ··· 312 311 size: Some(size), 313 312 .. 314 313 } = categories 314 + && let Some(abox) = size.value() 315 315 { 316 - if let Some(abox) = size.value() { 317 - match abox.as_int_literal() { 318 - None => (), 319 - Some(value) if value == 16.into() || value == 32.into() || value == 64.into() => (), 320 - _ => return err(ErrorType::FloatWithSize, size.location()), 321 - } 316 + match abox.as_int_literal() { 317 + None => (), 318 + Some(value) if value == 16.into() || value == 32.into() || value == 64.into() => (), 319 + _ => return err(ErrorType::FloatWithSize, size.location()), 322 320 } 323 321 } 324 322
+13 -14
compiler-core/src/erlang.rs
··· 1034 1034 } 1035 1035 1036 1036 fn block<'a>(statements: &'a Vec1<TypedStatement>, env: &mut Env<'a>) -> Document<'a> { 1037 - if statements.len() == 1 { 1038 - if let Statement::Expression(expression) = statements.first() { 1039 - if !needs_begin_end_wrapping(expression) { 1040 - return docvec!['(', expr(expression, env), ')']; 1041 - } 1042 - } 1037 + if statements.len() == 1 1038 + && let Statement::Expression(expression) = statements.first() 1039 + && !needs_begin_end_wrapping(expression) 1040 + { 1041 + return docvec!['(', expr(expression, env), ')']; 1043 1042 } 1044 1043 1045 1044 let vars = env.current_scope_vars.clone(); ··· 3165 3164 let mut overridden_publicity = im::HashSet::new(); 3166 3165 3167 3166 for definition in module.definitions.iter() { 3168 - if let Definition::ModuleConstant(constant) = definition { 3169 - if constant.publicity.is_importable() { 3170 - find_referenced_private_functions(&constant.value, &mut overridden_publicity) 3171 - } 3167 + if let Definition::ModuleConstant(constant) = definition 3168 + && constant.publicity.is_importable() 3169 + { 3170 + find_referenced_private_functions(&constant.value, &mut overridden_publicity) 3172 3171 } 3173 3172 } 3174 3173 overridden_publicity ··· 3189 3188 TypedConstant::Var { 3190 3189 name, constructor, .. 3191 3190 } => { 3192 - if let Some(ValueConstructor { type_, .. }) = constructor.as_deref() { 3193 - if let Type::Fn { .. } = **type_ { 3194 - let _ = already_found.insert(name.clone()); 3195 - } 3191 + if let Some(ValueConstructor { type_, .. }) = constructor.as_deref() 3192 + && let Type::Fn { .. } = **type_ 3193 + { 3194 + let _ = already_found.insert(name.clone()); 3196 3195 } 3197 3196 } 3198 3197
+12 -11
compiler-core/src/error.rs
··· 688 688 ); 689 689 } 690 690 691 - if (i > 1) && (j > 1) { 692 - if let (Some(&a_val), Some(&b_val_prev), Some(&a_val_prev), Some(&b_val)) = ( 691 + if (i > 1) 692 + && (j > 1) 693 + && let (Some(&a_val), Some(&b_val_prev), Some(&a_val_prev), Some(&b_val)) = ( 693 694 a.get(a_idx), 694 695 b.get(b_idx - 1), 695 696 a.get(a_idx - 1), 696 697 b.get(b_idx), 697 - ) { 698 - if (a_val == b_val_prev) && (a_val_prev == b_val) { 699 - // transposition 700 - if let Some(curr) = current.get_mut(j) { 701 - if let Some(&prev_prev_val) = prev_prev.get(j - 2) { 702 - *curr = std::cmp::min(*curr, prev_prev_val + 1); 703 - } 704 - } 705 - } 698 + ) 699 + && (a_val == b_val_prev) 700 + && (a_val_prev == b_val) 701 + { 702 + // transposition 703 + if let Some(curr) = current.get_mut(j) 704 + && let Some(&prev_prev_val) = prev_prev.get(j - 2) 705 + { 706 + *curr = std::cmp::min(*curr, prev_prev_val + 1); 706 707 } 707 708 } 708 709 }
+4 -4
compiler-core/src/format.rs
··· 2198 2198 let item_location = item.location(); 2199 2199 // A list has multiple items on the same line if two consecutive 2200 2200 // ones do not span multiple lines. 2201 - if let Some(previous) = previous { 2202 - if !self.spans_multiple_lines(previous.end, item_location.start) { 2203 - return true; 2204 - } 2201 + if let Some(previous) = previous 2202 + && !self.spans_multiple_lines(previous.end, item_location.start) 2203 + { 2204 + return true; 2205 2205 } 2206 2206 previous = Some(item_location); 2207 2207 }
+12 -10
compiler-core/src/javascript/expression.rs
··· 1754 1754 // If there's no arguments and the type is a function that takes 1755 1755 // arguments then this is the constructor being referenced, not the 1756 1756 // function being called. 1757 - if let Some(arity) = type_.fn_arity() { 1758 - if arguments.is_empty() && arity != 0 { 1759 - let arity = arity as u16; 1760 - return record_constructor(type_.clone(), None, name, arity, self.tracker); 1761 - } 1757 + if let Some(arity) = type_.fn_arity() 1758 + && arguments.is_empty() 1759 + && arity != 0 1760 + { 1761 + let arity = arity as u16; 1762 + return record_constructor(type_.clone(), None, name, arity, self.tracker); 1762 1763 } 1763 1764 1764 1765 let field_values = arguments ··· 2135 2136 // If there's no arguments and the type is a function that takes 2136 2137 // arguments then this is the constructor being referenced, not the 2137 2138 // function being called. 2138 - if let Some(arity) = type_.fn_arity() { 2139 - if arguments.is_empty() && arity != 0 { 2140 - let arity = arity as u16; 2141 - return record_constructor(type_.clone(), None, name, arity, self.tracker); 2142 - } 2139 + if let Some(arity) = type_.fn_arity() 2140 + && arguments.is_empty() 2141 + && arity != 0 2142 + { 2143 + let arity = arity as u16; 2144 + return record_constructor(type_.clone(), None, name, arity, self.tracker); 2143 2145 } 2144 2146 2145 2147 let field_values = arguments
+95 -104
compiler-core/src/language_server/code_action.rs
··· 1442 1442 arguments: &'ast Vec<ast::TypeAst>, 1443 1443 ) { 1444 1444 let range = src_span_to_lsp_range(*location, self.line_numbers); 1445 - if overlaps(self.params.range, range) { 1446 - if let Some((module_alias, _)) = module { 1447 - if let Some(import) = self.module.find_node(location.end).and_then(|node| { 1448 - if let Located::Annotation { type_, .. } = node { 1449 - if let Some((module, _)) = type_.named_type_name() { 1450 - return self.get_module_import(&module, name, ast::Layer::Type); 1451 - } 1452 - } 1453 - None 1454 - }) { 1455 - self.qualified_constructor = Some(QualifiedConstructor { 1456 - import, 1457 - used_name: module_alias.clone(), 1458 - constructor: name.clone(), 1459 - layer: ast::Layer::Type, 1460 - }); 1445 + if overlaps(self.params.range, range) 1446 + && let Some((module_alias, _)) = module 1447 + && let Some(import) = self.module.find_node(location.end).and_then(|node| { 1448 + if let Located::Annotation { type_, .. } = node 1449 + && let Some((module, _)) = type_.named_type_name() 1450 + { 1451 + return self.get_module_import(&module, name, ast::Layer::Type); 1461 1452 } 1462 - } 1453 + None 1454 + }) 1455 + { 1456 + self.qualified_constructor = Some(QualifiedConstructor { 1457 + import, 1458 + used_name: module_alias.clone(), 1459 + constructor: name.clone(), 1460 + layer: ast::Layer::Type, 1461 + }); 1463 1462 } 1464 1463 ast::visit::visit_type_ast_constructor( 1465 1464 self, ··· 1487 1486 // ↑ 1488 1487 // This allows us to offer a code action when hovering over the module name. 1489 1488 let range = src_span_to_lsp_range(*location, self.line_numbers); 1490 - if overlaps(self.params.range, range) { 1491 - if let ModuleValueConstructor::Record { 1489 + if overlaps(self.params.range, range) 1490 + && let ModuleValueConstructor::Record { 1492 1491 name: constructor_name, 1493 1492 .. 1494 1493 } = constructor 1495 - { 1496 - if let Some(import) = 1497 - self.get_module_import(module_name, constructor_name, ast::Layer::Value) 1498 - { 1499 - self.qualified_constructor = Some(QualifiedConstructor { 1500 - import, 1501 - used_name: module_alias.clone(), 1502 - constructor: constructor_name.clone(), 1503 - layer: ast::Layer::Value, 1504 - }); 1505 - } 1506 - } 1494 + && let Some(import) = 1495 + self.get_module_import(module_name, constructor_name, ast::Layer::Value) 1496 + { 1497 + self.qualified_constructor = Some(QualifiedConstructor { 1498 + import, 1499 + used_name: module_alias.clone(), 1500 + constructor: constructor_name.clone(), 1501 + layer: ast::Layer::Value, 1502 + }); 1507 1503 } 1508 1504 ast::visit::visit_typed_expr_module_select( 1509 1505 self, ··· 1529 1525 type_: &'ast Arc<Type>, 1530 1526 ) { 1531 1527 let range = src_span_to_lsp_range(*location, self.line_numbers); 1532 - if overlaps(self.params.range, range) { 1533 - if let Some((module_alias, _)) = module { 1534 - if let analyse::Inferred::Known(constructor) = constructor { 1535 - if let Some(import) = 1536 - self.get_module_import(&constructor.module, name, ast::Layer::Value) 1537 - { 1538 - self.qualified_constructor = Some(QualifiedConstructor { 1539 - import, 1540 - used_name: module_alias.clone(), 1541 - constructor: name.clone(), 1542 - layer: ast::Layer::Value, 1543 - }); 1544 - } 1545 - } 1546 - } 1528 + if overlaps(self.params.range, range) 1529 + && let Some((module_alias, _)) = module 1530 + && let analyse::Inferred::Known(constructor) = constructor 1531 + && let Some(import) = 1532 + self.get_module_import(&constructor.module, name, ast::Layer::Value) 1533 + { 1534 + self.qualified_constructor = Some(QualifiedConstructor { 1535 + import, 1536 + used_name: module_alias.clone(), 1537 + constructor: name.clone(), 1538 + layer: ast::Layer::Value, 1539 + }); 1547 1540 } 1548 1541 ast::visit::visit_typed_pattern_constructor( 1549 1542 self, ··· 1754 1747 spread: &'ast Option<SrcSpan>, 1755 1748 type_: &'ast Arc<Type>, 1756 1749 ) { 1757 - if let Some((module_alias, _)) = module { 1758 - if let analyse::Inferred::Known(_) = constructor { 1759 - let QualifiedConstructor { 1760 - used_name, 1761 - constructor, 1762 - layer, 1763 - .. 1764 - } = &self.qualified_constructor; 1750 + if let Some((module_alias, _)) = module 1751 + && let analyse::Inferred::Known(_) = constructor 1752 + { 1753 + let QualifiedConstructor { 1754 + used_name, 1755 + constructor, 1756 + layer, 1757 + .. 1758 + } = &self.qualified_constructor; 1765 1759 1766 - if layer.is_value() && used_name == module_alias && name == constructor { 1767 - self.remove_module_qualifier(*location); 1768 - } 1760 + if layer.is_value() && used_name == module_alias && name == constructor { 1761 + self.remove_module_qualifier(*location); 1769 1762 } 1770 1763 } 1771 1764 ast::visit::visit_typed_pattern_constructor( ··· 1957 1950 name: &'ast EcoString, 1958 1951 ) { 1959 1952 let range = src_span_to_lsp_range(*location, self.line_numbers); 1960 - if overlaps(self.params.range, range) { 1961 - if let Some(module_name) = match &constructor.variant { 1953 + if overlaps(self.params.range, range) 1954 + && let Some(module_name) = match &constructor.variant { 1962 1955 type_::ValueConstructorVariant::ModuleConstant { module, .. } 1963 1956 | type_::ValueConstructorVariant::ModuleFn { module, .. } 1964 1957 | type_::ValueConstructorVariant::Record { module, .. } => Some(module), 1965 1958 1966 1959 type_::ValueConstructorVariant::LocalVariable { .. } 1967 1960 | type_::ValueConstructorVariant::LocalConstant { .. } => None, 1968 - } { 1969 - self.get_module_import_from_value_constructor(module_name, name); 1970 1961 } 1962 + { 1963 + self.get_module_import_from_value_constructor(module_name, name); 1971 1964 } 1972 1965 ast::visit::visit_typed_expr_var(self, location, constructor, name); 1973 1966 } ··· 1988 1981 self.params.range, 1989 1982 src_span_to_lsp_range(*location, self.line_numbers), 1990 1983 ) 1984 + && let analyse::Inferred::Known(constructor) = constructor 1991 1985 { 1992 - if let analyse::Inferred::Known(constructor) = constructor { 1993 - self.get_module_import_from_value_constructor(&constructor.module, name); 1994 - } 1986 + self.get_module_import_from_value_constructor(&constructor.module, name); 1995 1987 } 1996 1988 1997 1989 ast::visit::visit_typed_pattern_constructor( ··· 2595 2587 // The cursor has to be inside the last statement of the function to 2596 2588 // offer the code action. 2597 2589 let last_statement_range = self.edits.src_span_to_lsp_range(fun.body.last().location()); 2598 - if within(self.params.range, last_statement_range) { 2599 - if let Some(call_data) = turn_statement_into_use(fun.body.last()) { 2600 - self.selected_call = Some(call_data); 2601 - } 2590 + if within(self.params.range, last_statement_range) 2591 + && let Some(call_data) = turn_statement_into_use(fun.body.last()) 2592 + { 2593 + self.selected_call = Some(call_data); 2602 2594 } 2603 2595 2604 2596 ast::visit::visit_typed_function(self, fun) ··· 2616 2608 // The cursor has to be inside the last statement of the body to 2617 2609 // offer the code action. 2618 2610 let last_statement_range = self.edits.src_span_to_lsp_range(body.last().location()); 2619 - if within(self.params.range, last_statement_range) { 2620 - if let Some(call_data) = turn_statement_into_use(body.last()) { 2621 - self.selected_call = Some(call_data); 2622 - } 2611 + if within(self.params.range, last_statement_range) 2612 + && let Some(call_data) = turn_statement_into_use(body.last()) 2613 + { 2614 + self.selected_call = Some(call_data); 2623 2615 } 2624 2616 2625 2617 ast::visit::visit_typed_expr_fn( ··· 3614 3606 return_annotation: &'ast Option<ast::TypeAst>, 3615 3607 ) { 3616 3608 let fn_range = self.edits.src_span_to_lsp_range(*location); 3617 - if within(self.params.range, fn_range) && kind.is_capture() { 3618 - if let [argument] = arguments { 3619 - self.function_capture_data = Some(FunctionCaptureData { 3620 - function_span: *location, 3621 - hole_span: argument.location, 3622 - hole_type: argument.type_.clone(), 3623 - reserved_names: VariablesNames::from_statements(body), 3624 - }); 3625 - } 3609 + if within(self.params.range, fn_range) 3610 + && kind.is_capture() 3611 + && let [argument] = arguments 3612 + { 3613 + self.function_capture_data = Some(FunctionCaptureData { 3614 + function_span: *location, 3615 + hole_span: argument.location, 3616 + hole_type: argument.type_.clone(), 3617 + reserved_names: VariablesNames::from_statements(body), 3618 + }); 3626 3619 } 3627 3620 3628 3621 ast::visit::visit_typed_expr_fn( ··· 6612 6605 spread: Some(spread_location), 6613 6606 .. 6614 6607 } = pattern 6615 - { 6616 - if let Some(PatternUnusedArguments { 6608 + && let Some(PatternUnusedArguments { 6617 6609 positional, 6618 6610 labelled, 6619 6611 }) = pattern.unused_arguments() 6620 - { 6621 - // If there's any unused argument that's being ignored we want to 6622 - // suggest the code action. 6623 - let first_labelled_argument_start = arguments 6624 - .iter() 6625 - .find(|arg| !arg.is_implicit() && arg.label.is_some()) 6626 - .map(|arg| arg.location.start); 6612 + { 6613 + // If there's any unused argument that's being ignored we want to 6614 + // suggest the code action. 6615 + let first_labelled_argument_start = arguments 6616 + .iter() 6617 + .find(|arg| !arg.is_implicit() && arg.label.is_some()) 6618 + .map(|arg| arg.location.start); 6627 6619 6628 - let last_argument_end = arguments 6629 - .iter() 6630 - .filter(|arg| !arg.is_implicit()) 6631 - .next_back() 6632 - .map(|arg| arg.location.end); 6620 + let last_argument_end = arguments 6621 + .iter() 6622 + .filter(|arg| !arg.is_implicit()) 6623 + .next_back() 6624 + .map(|arg| arg.location.end); 6633 6625 6634 - self.data = Some(FillUnusedFieldsData { 6635 - positional, 6636 - labelled, 6637 - first_labelled_argument_start, 6638 - last_argument_end, 6639 - spread_location: *spread_location, 6640 - }); 6641 - }; 6642 - } 6626 + self.data = Some(FillUnusedFieldsData { 6627 + positional, 6628 + labelled, 6629 + first_labelled_argument_start, 6630 + last_argument_end, 6631 + spread_location: *spread_location, 6632 + }); 6633 + }; 6643 6634 6644 6635 ast::visit::visit_typed_pattern(self, pattern); 6645 6636 }
+16 -16
compiler-core/src/language_server/completer.rs
··· 455 455 if let Some(module) = import.used_name() { 456 456 // If the user has already started a module select then don't show irrelevant modules. 457 457 // e.x. when the user has typed mymodule.| we should only show items from mymodule. 458 - if let Some(input_mod_name) = &module_select { 459 - if &module != input_mod_name { 460 - continue; 461 - } 458 + if let Some(input_mod_name) = &module_select 459 + && &module != input_mod_name 460 + { 461 + continue; 462 462 } 463 463 completions.push(type_completion( 464 464 Some(&module), ··· 515 515 516 516 // If the user has already started a module select then don't show irrelevant modules. 517 517 // e.x. when the user has typed mymodule.| we should only show items from mymodule. 518 - if let Some(input_mod_name) = &module_select { 519 - if qualifier != input_mod_name { 520 - continue; 521 - } 518 + if let Some(input_mod_name) = &module_select 519 + && qualifier != input_mod_name 520 + { 521 + continue; 522 522 } 523 523 524 524 // Qualified types ··· 650 650 if let Some(module) = import.used_name() { 651 651 // If the user has already started a module select then don't show irrelevant modules. 652 652 // e.x. when the user has typed mymodule.| we should only show items from mymodule. 653 - if let Some(input_mod_name) = &module_select { 654 - if &module != input_mod_name { 655 - continue; 656 - } 653 + if let Some(input_mod_name) = &module_select 654 + && &module != input_mod_name 655 + { 656 + continue; 657 657 } 658 658 completions.push(value_completion( 659 659 Some(&module), ··· 709 709 710 710 // If the user has already started a module select then don't show irrelevant modules. 711 711 // e.x. when the user has typed mymodule.| we should only show items from mymodule. 712 - if let Some(input_mod_name) = &module_select { 713 - if qualifier != input_mod_name { 714 - continue; 715 - } 712 + if let Some(input_mod_name) = &module_select 713 + && qualifier != input_mod_name 714 + { 715 + continue; 716 716 } 717 717 718 718 // Qualified values
+9 -10
compiler-core/src/parse.rs
··· 470 470 ) -> Result<(), ParseError> { 471 471 // Produce better error message for `[x] = [1]` outside 472 472 // of `let` statement. 473 - if !is_let_binding { 474 - if let UntypedExpr::List { .. } = unit { 475 - if let Some((start, Token::Equal, end)) = self.tok0 { 476 - return parse_error(ParseErrorType::NoLetBinding, SrcSpan { start, end }); 477 - } 478 - } 473 + if !is_let_binding 474 + && let UntypedExpr::List { .. } = unit 475 + && let Some((start, Token::Equal, end)) = self.tok0 476 + { 477 + return parse_error(ParseErrorType::NoLetBinding, SrcSpan { start, end }); 479 478 } 480 479 Ok(()) 481 480 } ··· 1187 1186 1188 1187 fn parse_statement_errors(&mut self) -> Result<(), ParseError> { 1189 1188 // Better error: name definitions must start with `let` 1190 - if let Some((_, Token::Name { .. }, _)) = self.tok0.as_ref() { 1191 - if let Some((start, Token::Equal | Token::Colon, end)) = self.tok1 { 1192 - return parse_error(ParseErrorType::NoLetBinding, SrcSpan { start, end }); 1193 - } 1189 + if let Some((_, Token::Name { .. }, _)) = self.tok0.as_ref() 1190 + && let Some((start, Token::Equal | Token::Colon, end)) = self.tok1 1191 + { 1192 + return parse_error(ParseErrorType::NoLetBinding, SrcSpan { start, end }); 1194 1193 } 1195 1194 Ok(()) 1196 1195 }
+4 -4
compiler-core/src/type_.rs
··· 630 630 } 631 631 632 632 pub fn collapse_links(t: Arc<Type>) -> Arc<Type> { 633 - if let Type::Var { type_ } = t.deref() { 634 - if let TypeVar::Link { type_ } = type_.borrow().deref() { 635 - return collapse_links(type_.clone()); 636 - } 633 + if let Type::Var { type_ } = t.deref() 634 + && let TypeVar::Link { type_ } = type_.borrow().deref() 635 + { 636 + return collapse_links(type_.clone()); 637 637 } 638 638 t 639 639 }
+9 -9
compiler-core/src/type_/environment.rs
··· 877 877 } 878 878 879 879 // Collapse right hand side type links. Left hand side will be collapsed in the next block. 880 - if let Type::Var { type_ } = t2.deref() { 881 - if let TypeVar::Link { type_ } = type_.borrow().deref() { 882 - return unify(t1, type_.clone()); 883 - } 880 + if let Type::Var { type_ } = t2.deref() 881 + && let TypeVar::Link { type_ } = type_.borrow().deref() 882 + { 883 + return unify(t1, type_.clone()); 884 884 } 885 885 886 886 if let Type::Var { type_ } = t1.deref() { ··· 899 899 } 900 900 901 901 TypeVar::Generic { id } => { 902 - if let Type::Var { type_ } = t2.deref() { 903 - if type_.borrow().is_unbound() { 904 - *type_.borrow_mut() = TypeVar::Generic { id: *id }; 905 - return Ok(()); 906 - } 902 + if let Type::Var { type_ } = t2.deref() 903 + && type_.borrow().is_unbound() 904 + { 905 + *type_.borrow_mut() = TypeVar::Generic { id: *id }; 906 + return Ok(()); 907 907 } 908 908 Action::CouldNotUnify 909 909 }
+70 -71
compiler-core/src/type_/expression.rs
··· 903 903 .error(convert_unify_error(error, value.location())); 904 904 } 905 905 906 - if let TypedExpr::Int { value: ref v, .. } = value { 907 - if v.starts_with('-') { 908 - self.problems 909 - .warning(Warning::UnnecessaryDoubleIntNegation { location }); 910 - } 906 + if let TypedExpr::Int { value: ref v, .. } = value 907 + && v.starts_with('-') 908 + { 909 + self.problems 910 + .warning(Warning::UnnecessaryDoubleIntNegation { location }); 911 911 } 912 912 913 913 if let TypedExpr::NegateInt { .. } = value { ··· 1259 1259 (Ok(record_access), _) => { 1260 1260 // If this is actually record access and not module access, and we didn't register 1261 1261 // the reference earlier, we register it now. 1262 - if let TypedExpr::RecordAccess { record, .. } = &record_access { 1263 - if let TypedExpr::Var { 1262 + if let TypedExpr::RecordAccess { record, .. } = &record_access 1263 + && let TypedExpr::Var { 1264 1264 location, 1265 1265 constructor, 1266 1266 name, 1267 1267 } = record.as_ref() 1268 - { 1269 - self.register_value_constructor_reference( 1270 - name, 1271 - &constructor.variant, 1272 - *location, 1273 - ReferenceKind::Unqualified, 1274 - ) 1275 - } 1268 + { 1269 + self.register_value_constructor_reference( 1270 + name, 1271 + &constructor.variant, 1272 + *location, 1273 + ReferenceKind::Unqualified, 1274 + ) 1276 1275 } 1277 1276 record_access 1278 1277 } ··· 4135 4134 // argument that is implicitly passed by the compiler. 4136 4135 // This way we can provide better argument hints for incomplete use 4137 4136 // expressions. 4138 - if let CallKind::Use { .. } = kind { 4139 - if let Some(last) = arguments.pop() { 4140 - for _ in 0..missing_arguments { 4141 - arguments.push(CallArg { 4142 - label: None, 4143 - location, 4144 - value: UntypedExpr::Placeholder { 4145 - // We intentionally give this an empty span since it 4146 - // is an implicit argument being passed by the compiler 4147 - // that doesn't appear in the source code. 4148 - location: SrcSpan { 4149 - start: last.location().start, 4150 - end: last.location().start, 4151 - }, 4137 + if let CallKind::Use { .. } = kind 4138 + && let Some(last) = arguments.pop() 4139 + { 4140 + for _ in 0..missing_arguments { 4141 + arguments.push(CallArg { 4142 + label: None, 4143 + location, 4144 + value: UntypedExpr::Placeholder { 4145 + // We intentionally give this an empty span since it 4146 + // is an implicit argument being passed by the compiler 4147 + // that doesn't appear in the source code. 4148 + location: SrcSpan { 4149 + start: last.location().start, 4150 + end: last.location().start, 4152 4151 }, 4153 - implicit: Some(ImplicitCallArgOrigin::IncorrectArityUse), 4154 - }); 4155 - } 4156 - arguments.push(last); 4152 + }, 4153 + implicit: Some(ImplicitCallArgOrigin::IncorrectArityUse), 4154 + }); 4157 4155 } 4156 + arguments.push(last); 4158 4157 }; 4159 4158 4160 4159 // Ensure that the given args have the correct types ··· 4383 4382 let mut body = body_typer.infer_statements(body); 4384 4383 4385 4384 // Check that any return type is accurate. 4386 - if let Some(return_type) = return_type { 4387 - if let Err(error) = unify(return_type, body.last().type_()) { 4388 - let error = error 4389 - .return_annotation_mismatch() 4390 - .into_error(body.last().type_defining_location()); 4391 - body_typer.problems.error(error); 4385 + if let Some(return_type) = return_type 4386 + && let Err(error) = unify(return_type, body.last().type_()) 4387 + { 4388 + let error = error 4389 + .return_annotation_mismatch() 4390 + .into_error(body.last().type_defining_location()); 4391 + body_typer.problems.error(error); 4392 4392 4393 - // If the return type doesn't match with the annotation we 4394 - // add a new expression to the end of the function to match 4395 - // the annotated type and allow type inference to keep 4396 - // going. 4397 - body.push(Statement::Expression(TypedExpr::Invalid { 4398 - // This is deliberately an empty span since this 4399 - // placeholder expression is implicitly inserted by the 4400 - // compiler and doesn't actually appear in the source 4401 - // code. 4402 - location: SrcSpan { 4403 - start: body.last().location().end, 4404 - end: body.last().location().end, 4405 - }, 4406 - type_: body_typer.new_unbound_var(), 4407 - })) 4408 - }; 4409 - } 4393 + // If the return type doesn't match with the annotation we 4394 + // add a new expression to the end of the function to match 4395 + // the annotated type and allow type inference to keep 4396 + // going. 4397 + body.push(Statement::Expression(TypedExpr::Invalid { 4398 + // This is deliberately an empty span since this 4399 + // placeholder expression is implicitly inserted by the 4400 + // compiler and doesn't actually appear in the source 4401 + // code. 4402 + location: SrcSpan { 4403 + start: body.last().location().end, 4404 + end: body.last().location().end, 4405 + }, 4406 + type_: body_typer.new_unbound_var(), 4407 + })) 4408 + }; 4410 4409 4411 4410 Ok((arguments, body)) 4412 4411 }) ··· 4499 4498 4500 4499 // Then if the required version is not in the specified version for the 4501 4500 // range we emit a warning highlighting the usage of the feature. 4502 - if let Some(gleam_version) = &self.environment.gleam_version { 4503 - if let Some(lowest_allowed_version) = gleam_version.lowest_version() { 4504 - // There is a version in the specified range that is lower than 4505 - // the one required by this feature! This means that the 4506 - // specified range is wrong and would allow someone to run a 4507 - // compiler that is too old to know of this feature. 4508 - if minimum_required_version > lowest_allowed_version { 4509 - self.problems 4510 - .warning(Warning::FeatureRequiresHigherGleamVersion { 4511 - location, 4512 - feature_kind, 4513 - minimum_required_version: minimum_required_version.clone(), 4514 - wrongfully_allowed_version: lowest_allowed_version, 4515 - }) 4516 - } 4501 + if let Some(gleam_version) = &self.environment.gleam_version 4502 + && let Some(lowest_allowed_version) = gleam_version.lowest_version() 4503 + { 4504 + // There is a version in the specified range that is lower than 4505 + // the one required by this feature! This means that the 4506 + // specified range is wrong and would allow someone to run a 4507 + // compiler that is too old to know of this feature. 4508 + if minimum_required_version > lowest_allowed_version { 4509 + self.problems 4510 + .warning(Warning::FeatureRequiresHigherGleamVersion { 4511 + location, 4512 + feature_kind, 4513 + minimum_required_version: minimum_required_version.clone(), 4514 + wrongfully_allowed_version: lowest_allowed_version, 4515 + }) 4517 4516 } 4518 4517 } 4519 4518
+30 -31
compiler-core/src/type_/pattern.rs
··· 1001 1001 } 1002 1002 } 1003 1003 1004 - if let Some(spread_location) = spread { 1005 - if let ValueConstructorVariant::Record { arity, .. } = 1004 + if let Some(spread_location) = spread 1005 + && let ValueConstructorVariant::Record { arity, .. } = 1006 1006 &constructor.variant 1007 - { 1008 - while pattern_arguments.len() < usize::from(*arity) { 1009 - pattern_arguments.push(CallArg { 1010 - value: Pattern::Discard { 1011 - name: "_".into(), 1012 - location: spread_location, 1013 - type_: (), 1014 - }, 1007 + { 1008 + while pattern_arguments.len() < usize::from(*arity) { 1009 + pattern_arguments.push(CallArg { 1010 + value: Pattern::Discard { 1011 + name: "_".into(), 1015 1012 location: spread_location, 1016 - label: None, 1017 - implicit: Some(ImplicitCallArgOrigin::PatternFieldSpread), 1018 - }); 1019 - } 1020 - }; 1021 - } 1013 + type_: (), 1014 + }, 1015 + location: spread_location, 1016 + label: None, 1017 + implicit: Some(ImplicitCallArgOrigin::PatternFieldSpread), 1018 + }); 1019 + } 1020 + }; 1022 1021 } 1023 1022 } 1024 1023 ··· 1316 1315 1317 1316 // Then if the required version is not in the specified version for the 1318 1317 // range we emit a warning highlighting the usage of the feature. 1319 - if let Some(gleam_version) = &self.environment.gleam_version { 1320 - if let Some(lowest_allowed_version) = gleam_version.lowest_version() { 1321 - // There is a version in the specified range that is lower than 1322 - // the one required by this feature! This means that the 1323 - // specified range is wrong and would allow someone to run a 1324 - // compiler that is too old to know of this feature. 1325 - if minimum_required_version > lowest_allowed_version { 1326 - self.problems 1327 - .warning(Warning::FeatureRequiresHigherGleamVersion { 1328 - location, 1329 - feature_kind, 1330 - minimum_required_version: minimum_required_version.clone(), 1331 - wrongfully_allowed_version: lowest_allowed_version, 1332 - }) 1333 - } 1318 + if let Some(gleam_version) = &self.environment.gleam_version 1319 + && let Some(lowest_allowed_version) = gleam_version.lowest_version() 1320 + { 1321 + // There is a version in the specified range that is lower than 1322 + // the one required by this feature! This means that the 1323 + // specified range is wrong and would allow someone to run a 1324 + // compiler that is too old to know of this feature. 1325 + if minimum_required_version > lowest_allowed_version { 1326 + self.problems 1327 + .warning(Warning::FeatureRequiresHigherGleamVersion { 1328 + location, 1329 + feature_kind, 1330 + minimum_required_version: minimum_required_version.clone(), 1331 + wrongfully_allowed_version: lowest_allowed_version, 1332 + }) 1334 1333 } 1335 1334 } 1336 1335
+15 -19
compiler-core/src/type_/pipe.rs
··· 417 417 } 418 418 419 419 fn warn_if_call_first_argument_is_hole(&mut self, call: &UntypedExpr) { 420 - if let UntypedExpr::Fn { kind, body, .. } = &call { 421 - if kind.is_capture() { 422 - if let Statement::Expression(UntypedExpr::Call { arguments, .. }) = body.first() { 423 - match arguments.as_slice() { 424 - // If the first argument is labelled, we don't warn the user 425 - // as they might be intentionally adding it to provide more 426 - // information about exactly which argument is being piped into. 427 - [first] | [first, ..] 428 - if first.is_capture_hole() && first.label.is_none() => 429 - { 430 - self.expr_typer.problems.warning( 431 - Warning::RedundantPipeFunctionCapture { 432 - location: first.location, 433 - }, 434 - ) 435 - } 436 - _ => (), 437 - } 438 - } 420 + if let UntypedExpr::Fn { kind, body, .. } = &call 421 + && kind.is_capture() 422 + && let Statement::Expression(UntypedExpr::Call { arguments, .. }) = body.first() 423 + { 424 + match arguments.as_slice() { 425 + // If the first argument is labelled, we don't warn the user 426 + // as they might be intentionally adding it to provide more 427 + // information about exactly which argument is being piped into. 428 + [first] | [first, ..] if first.is_capture_hole() && first.label.is_none() => self 429 + .expr_typer 430 + .problems 431 + .warning(Warning::RedundantPipeFunctionCapture { 432 + location: first.location, 433 + }), 434 + _ => (), 439 435 } 440 436 } 441 437 }