~/bend-docscommunity

src/rules/correctness/chars.bend checks

raw source on the hub · import 0x582b4b0fdf3dafdeecc8c3bfddc5e4db/src/rules/correctness/chars.bend as Chars

rule chars: a match with more than eight character-literal arms (case '.':). Char is Chr{code: U32}, so such an arm is a U32 literal inside a constructor pattern, and bend's C backend pays for each one out of all proportion to its size -- about 90 MB, and the cost compounds through every def downstream of the one holding them (eighteen arms cost 1.57 GB and 8.3 s here, 0.10 GB and 0.7 s once rewritten). It is the literals, not the arms: a match over eighteen constructors costs nothing measurable.

Compare Char.to_u32(c) instead. Bind the fallback above the comparisons so it is a value, not a call, or bolt's own eager rule fires on it; and give the def the reusable quantity (+c: Char), since the code point and the fallback both consume it. Where the arms carry linear values, leave the match alone: a cascade would break linearity and do every branch's work.

Only a case's first match column is read, and only an arm whose pattern opens with a character literal counts: case 'x': does, case Con{'x', t}: and a literal in a later column of match a b: do not.

7 imports
import Base
import ../../src.bend as Src
import ../../finding.bend as F
import ../../syntax/lex.bend as Lex
import ../../syntax/tree.bend as Tree
import ../../lazy/lazy.bend as Lazy
import ../tokens.bend as T

Definitions

def literal source · line 28 · raw

@kids:0x582b4b0fdf3dafdeecc8c3bfddc5e4db/src/syntax/tree.Node -> U32

one when a case pattern opens with a character literal, else zero

def tally source · line 36 · raw

@body:0x582b4b0fdf3dafdeecc8c3bfddc5e4db/src/syntax/tree.Node -> @+nn:U32 -> U32

the character-literal arms among a match's statements

def report source · line 47 · raw

@+nn:U32 -> @+path:String -> @+ll:U32 -> @+cc:U32 -> List<&2, 0x582b4b0fdf3dafdeecc8c3bfddc5e4db/src/finding.Finding>

a finding when the match holds more character literals than is cheap

def on_stmt source · line 54 · raw

@+kids:0x582b4b0fdf3dafdeecc8c3bfddc5e4db/src/syntax/tree.Node -> @+body:0x582b4b0fdf3dafdeecc8c3bfddc5e4db/src/syntax/tree.Node -> @+path:String -> List<&2, 0x582b4b0fdf3dafdeecc8c3bfddc5e4db/src/finding.Finding>

a statement: a match is tallied

def walk source · line 60 · raw

@nn:0x582b4b0fdf3dafdeecc8c3bfddc5e4db/src/syntax/tree.Node -> @+path:String -> List<&2, 0x582b4b0fdf3dafdeecc8c3bfddc5e4db/src/finding.Finding>

every statement, at any depth

def check source · line 70 · raw

@ss:0x582b4b0fdf3dafdeecc8c3bfddc5e4db/src/src.Src -> List<&2, 0x582b4b0fdf3dafdeecc8c3bfddc5e4db/src/finding.Finding>

the rule