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

Configure Feed

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

Add deprecation warning for piping into calls which return functions

author
Gears
committer
Louis Pilfold
date (Jul 1, 2026, 2:43 PM +0100) commit 30af7642 parent ac3ba212 change-id psormwov
+113 -3
+4
CHANGELOG.md
··· 35 35 JavaScript target, allowing for faster comparison in most cases. 36 36 ([Surya Rose](https://github.com/GearsDatapacks)) 37 37 38 + - The use of pipes to turn the Gleam code `a |> b(c)` into `b(c)(a)` has been 39 + deprecated. 40 + ([Surya Rose](https://github.com/GearsDatapacks)) 41 + 38 42 ### Build tool 39 43 40 44 - The build tool now generates Hexdocs URLs using the new format of
+6 -1
compiler-core/src/type_/error.rs
··· 1190 1190 location: SrcSpan, 1191 1191 size: BigInt, 1192 1192 }, 1193 + 1194 + PipeIntoCallWhichReturnsFunction { 1195 + location: SrcSpan, 1196 + }, 1193 1197 } 1194 1198 1195 1199 #[derive(Debug, Eq, PartialEq, Clone, serde::Serialize, serde::Deserialize)] ··· 1461 1465 } 1462 1466 | Warning::RedundantComparison { location, .. } 1463 1467 | Warning::JavaScriptBitArrayUnsafeInt { location, .. } 1464 - | Warning::UnusedRecursiveArgument { location, .. } => *location, 1468 + | Warning::UnusedRecursiveArgument { location, .. } 1469 + | Warning::PipeIntoCallWhichReturnsFunction { location } => *location, 1465 1470 } 1466 1471 } 1467 1472
+6
compiler-core/src/type_/pipe.rs
··· 144 144 // Without lifting purity tracking into the type system, 145 145 // we have no idea whether it's pure or not! 146 146 self.expr_typer.purity = self.expr_typer.purity.merge(Purity::Unknown); 147 + 148 + // This syntax is deprecated. 149 + self.expr_typer 150 + .problems 151 + .warning(Warning::PipeIntoCallWhichReturnsFunction { location }); 152 + 147 153 ( 148 154 PipelineAssignmentKind::FunctionCall, 149 155 self.infer_apply_to_call_pipe(fun, arguments, location),
+28
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__warnings__piping_into_call_which_returns_function.snap
··· 1 + --- 2 + source: compiler-core/src/type_/tests/warnings.rs 3 + expression: "\npub fn main() {\n 1 |> wibble(2)\n}\n\nfn wibble(a) {\n fn(b) { #(a, b) }\n}\n" 4 + --- 5 + ----- SOURCE CODE 6 + 7 + pub fn main() { 8 + 1 |> wibble(2) 9 + } 10 + 11 + fn wibble(a) { 12 + fn(b) { #(a, b) } 13 + } 14 + 15 + 16 + ----- WARNING 17 + warning: Deprecated pipe use 18 + ┌─ /src/warning/wrn.gleam:3:8 19 + 20 + 3 │ 1 |> wibble(2) 21 + │ ^^^^^^^^^ This should have an extra set of parentheses 22 + 23 + This use of pipelines is deprecated, as it creates ambiguity in pipe 24 + syntax. Currently `a |> b(c)` can desugar to either `b(a, c)` or `b(a)(c)` 25 + depending on the type of `b`. The latter syntax is deprecated, and should 26 + not be used. 27 + 28 + Hint: Add an extra set of parentheses after the call, like `a |> b(c)()`
+31 -1
compiler-core/src/type_/tests/warnings.rs
··· 3949 3949 } 3950 3950 3951 3951 fn impure(x) { 3952 - x |> make_panic() 3952 + x |> make_panic()() 3953 3953 } 3954 3954 3955 3955 pub fn main() { ··· 5081 5081 " 5082 5082 ); 5083 5083 } 5084 + 5085 + #[test] 5086 + fn piping_into_call_which_returns_function() { 5087 + assert_warning!( 5088 + " 5089 + pub fn main() { 5090 + 1 |> wibble(2) 5091 + } 5092 + 5093 + fn wibble(a) { 5094 + fn(b) { #(a, b) } 5095 + } 5096 + " 5097 + ); 5098 + } 5099 + 5100 + #[test] 5101 + fn no_warning_when_extra_brackets_are_added_to_call_returning_function() { 5102 + assert_no_warnings!( 5103 + " 5104 + pub fn main() { 5105 + 1 |> wibble(2)() 5106 + } 5107 + 5108 + fn wibble(a) { 5109 + fn(b) { #(a, b) } 5110 + } 5111 + " 5112 + ); 5113 + }
+23
compiler-core/src/warning.rs
··· 1490 1490 extra_labels: vec![], 1491 1491 }), 1492 1492 }, 1493 + 1494 + type_::Warning::PipeIntoCallWhichReturnsFunction { location } => Diagnostic { 1495 + title: "Deprecated pipe use".into(), 1496 + text: wrap( 1497 + "This use of pipelines is deprecated, as it creates \ 1498 + ambiguity in pipe syntax. Currently `a |> b(c)` can desugar to either `b(a, c)` or \ 1499 + `b(a)(c)` depending on the type of `b`. The latter syntax is deprecated, and should \ 1500 + not be used.", 1501 + ), 1502 + hint: Some( 1503 + "Add an extra set of parentheses after the call, like `a |> b(c)()`".into(), 1504 + ), 1505 + level: diagnostic::Level::Warning, 1506 + location: Some(Location { 1507 + label: diagnostic::Label { 1508 + text: Some("This should have an extra set of parentheses".into()), 1509 + span: *location, 1510 + }, 1511 + path: path.clone(), 1512 + src: src.clone(), 1513 + extra_labels: vec![], 1514 + }), 1515 + }, 1493 1516 }, 1494 1517 1495 1518 Warning::EmptyModule { path: _, name } => Diagnostic {
+13
docs/v2.md
··· 47 47 48 48 - [x] Emits warning when used. 49 49 - [x] Formatter rewrites it to desired syntax. 50 + 51 + ## Piping into a call that returns a function 52 + 53 + In Gleam v1, the syntax `a |> b(c)` is ambiguous; it can either mean `b(a, c)` 54 + or `b(a)(c)`. This makes code harder to reason about as it means that you cannot 55 + determine the meaning of pipe expressions without knowing the type of the called 56 + function. 57 + 58 + In Gleam v2, we want to remove the second option, so `a |> b(c)` always desugars 59 + to `b(a, c)`, regardless of the types. 60 + 61 + - [x] Emits warning when used. 62 + - [ ] Code action to rewrite to desired syntax
+2 -1
language-server/src/code_action.rs
··· 9413 9413 | type_::Warning::TopLevelDefinitionShadowsImport { .. } 9414 9414 | type_::Warning::RedundantComparison { .. } 9415 9415 | type_::Warning::UnusedRecursiveArgument { .. } 9416 - | type_::Warning::JavaScriptBitArrayUnsafeInt { .. } => None, 9416 + | type_::Warning::JavaScriptBitArrayUnsafeInt { .. } 9417 + | type_::Warning::PipeIntoCallWhichReturnsFunction { .. } => None, 9417 9418 }) 9418 9419 .sorted_by_key(|import| import.location()) 9419 9420 .collect_vec();