Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Stage 4: Semantic Analysis (lfe_lint.erl)

Purpose: Validate code for semantic correctness without executing it.

Module: lfe_lint.erl (2,532 LOC - largest module) - Location: src/lfe_lint.erl

Lint state:

-record(lfe_lint, {
    module = [],              % Module name
    mline = 0,               % Module definition line
    exports = orddict:new(), % Exported function-line
    imports = orddict:new(), % Imported function-{module,func}
    aliases = orddict:new(), % Module-alias
    onload = [],             % Onload function
    funcs = orddict:new(),   % Defined function-line
    types = [],              % Known types
    texps = orddict:new(),   % Exported types
    specs = [],              % Known func specs
    records = orddict:new(), % Record definitions
    struct = undefined,      % Struct definition
    env = [],                % Top-level environment
    func = [],               % Current function
    file = "no file",        % File name
    opts = [],               % Compiler options
    errors = [],             % Errors
    warnings = []            % Warnings
}).

What gets checked (comprehensive list from src/lfe_lint.erl:200-500):

1. Module Definition:

  • Bad attributes
  • Bad metadata
  • Redefining imports/exports
  • Multiple module definitions

2. Functions:

  • Undefined functions (called but not defined)
  • Redefining functions
  • Redefining core forms/BIFs
  • Importing then defining same function (conflict)
  • Head arity mismatches (clauses with different arities)
  • Bad function definitions

3. Variables:

  • Unbound symbols (used but not bound)
  • Multiple variable definitions in patterns (same var bound twice)
  • Unused variables (bound but never used) - warning only

4. Patterns:

  • Illegal patterns (non-pattern forms in pattern position)
  • Bad pattern aliases (= operator misuse)
  • Invalid record patterns
  • Invalid binary patterns

5. Guards:

  • Illegal guard expressions (only BIFs allowed)
  • Bad guard forms
  • Non-boolean guard results

6. Records/Structs:

  • Undefined records/structs (used but not defined)
  • Undefined fields (accessing non-existent fields)
  • Bad definitions (malformed define-record/define-struct)
  • Redefining records/structs

7. Types/Specs:

  • Undefined types (type references to non-existent types)
  • Redefining types
  • Bad type definitions (syntax errors)
  • Singleton type variables (defined but used only once) - warning only
  • Spec arity mismatch (spec doesn't match function arity)

8. Operators:

  • Illegal operator calls (operators used incorrectly)

9. Literals:

  • Illegal literal values
  • Illegal map keys (non-constant keys)
  • Illegal bit segments (invalid bitstring specifications)

Example error detection:

;; Unbound variable
(defun foo (x)
  (+ x y))  % ERROR: unbound symbol y

;; Undefined function
(defun bar ()
  (baz 42))  % ERROR: undefined function baz/1

;; Arity mismatch
(defun multi
  ([x] x)
  ([x y] (+ x y))
  ([x] (* x 2)))  % ERROR: clause arity mismatch

;; Pattern error
(defun bad ([x x] x))  % ERROR: variable x bound multiple times