src/rules/suspicious/unit.bend checks
raw source on the hub · import 0xd96f2ab40f5df4925c42e96d0ba857ff/src/rules/suspicious/unit.bend as MUnit
rule unit: a multiply or divide by the literal one (1, 1n, 1.0) on a
step that actually recurses. * and / inside (e : T) are T.mul and
T.div; bare, they are Nat. Either form, and a direct Nat.mul /
U32.mul / F32.mul or .div, does nothing when an operand is one
(/ only when the divisor is). Drop the operation. Any other factor or
divisor is left alone, and so is a base case or a def that does not call
itself. A base case is a case arm that does not call the def; the arms are
judged per case only, so a Bool.pick branch beside a self-call is still
the recursive step, and so is a lambda body inside it (a Lazy.stop
thunk or a List.map callback runs on the step). One finding per
operation, on the literal: Nat.mul(1n, 1n) is one. Laws and proofs do not
run (a def with no type at all fills a law: it is a proof).
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 ../calls.bend as Calls import ../../lazy/lazy.bend as Lazy
Definitions
def one_text source · line 22 · raw
@+tt:String -> Bool
is the text the literal one?
def num_kind source · line 26 · raw
@kk:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.TokKind -> Bool
is the kind a number token?
def one_tok source · line 34 · raw
@tok:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok -> Bool
a token that is the literal one
def op_kind source · line 39 · raw
@kk:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.TokKind -> Bool
is the kind an operator's?
def one_of source · line 47 · raw
@mm:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>
the maybe, when it holds the literal one
def either source · line 55 · raw
@aa:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> @bb:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>
the first maybe when it holds a token, else the second
def which source · line 64 · raw
@+op:String -> @prev:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> @+nxt:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>
the literal an operator's finding points at: for * the factor after it
when it is one, else the one before; for / the divisor when it is one
def cite source · line 70 · raw
@mm:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> @+path:String -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>
a finding on that literal
def arg_one source · line 79 · raw
@aa:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>
an argument that is exactly the literal one
def last_one source · line 87 · raw
@as:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>
the last argument, when it is the literal one
def any_one source · line 97 · raw
@as:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>
the last argument that is the literal one
def on_div_is source · line 106 · raw
@+div:Bool -> @+as:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node> -> @+path:String -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>
a divide's divisor, when the call is a divide
def on_div source · line 114 · raw
@+tt:String -> @+as:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node> -> @+path:String -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>
a divide's divisor, when the call is a divide
def on_op_is source · line 118 · raw
@+mul:Bool -> @+tt:String -> @+as:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node> -> @+path:String -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>
a multiply (either factor) or a divide (the divisor only)
def on_op source · line 126 · raw
@+tt:String -> @+as:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node> -> @+path:String -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>
a multiply (either factor) or a divide (the divisor only)
def on_hot source · line 130 · raw
@hot:Bool -> @+tt:String -> @+as:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node> -> @+path:String -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>
the call's own identity operands, when this step recurses
def on_call source · line 138 · raw
@+tt:String -> @kids:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+path:String -> @+hot:Bool -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>
the call's own identity operands, when this step recurses
def own_of source · line 142 · raw
@call:Bool -> @+tt:String -> @+kids:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+path:String -> @+hot:Bool -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>
the call's findings when the group is an application
def first_tok source · line 156 · raw
@nn:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>
the first leaf, when the chain starts with one
def after source · line 164 · raw
@tok:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>
the token a leaf leaves behind for what follows it: none past an operator
def op_hit source · line 170 · raw
@tok:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok -> @+prev:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> @+nxt:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> @+path:String -> @+hot:Bool -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>
a leaf's own finding: an operator by one, in a hot region
def callee source · line 182 · raw
@mm:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> String
the name a group is called by: the token right before it ("" for none)
def walk source · line 192 · raw
@nn:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+prev:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> @+self:String -> @+path:String -> @+hot:Bool -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>
* / / by one, and the same through calls, in a hot region. prev is the
leaf right before, none past an operator, a group or a statement; a (
group right after a leaf is a call of it
def check.go source · line 214 · raw
@ds:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/rules/calls.Def> -> @+path:String -> @acc:List<&2, List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>> -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>
def check source · line 225 · raw
@ss:0xd96f2ab40f5df4925c42e96d0ba857ff/src/src.Src -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>
the rule