This came up when watching new Lean users in a class situation. A number of them were confused when they omitted a namespace on a constructor name, and Lean treated the variable as a pattern that matches anything. For example, this program is accepted but may not do what the user thinks: ``` inductive Tree (α : Type) where | leaf | branch (left : Tree α) (val : α) (right : Tree α) def depth : Tree α → Nat | leaf => 0 ``` Adding a `branch` case to `depth` results in a confusing message. With this linter, Lean marks `leaf` with: ``` Local variable 'leaf' resembles constructor 'Tree.leaf' - write '.leaf' (with a dot) or 'Tree.leaf' to use the constructor. note: this linter can be disabled with `set_option linter.constructorNameAsVariable false` ``` Additionally, the error message that occurs when invalid names are applied in patterns now suggests similar names. This means that: ``` def length (list : List α) : Nat := match list with | nil => 0 | cons x xs => length xs + 1 ``` now results in the following warning on `nil`: ``` warning: Local variable 'nil' resembles constructor 'List.nil' - write '.nil' (with a dot) or 'List.nil' to use the constructor. note: this linter can be disabled with `set_option linter.constructorNameAsVariable false` ``` and error on `cons`: ``` invalid pattern, constructor or constant marked with '[match_pattern]' expected Suggestion: 'List.cons' is similar ``` The list of suggested constructors is generated before the type of the pattern is known, so it's less accurate, but it truncates the list to ten elements to avoid being overwhelming. This mostly comes up with `mk`.
19 lines
289 B
Text
19 lines
289 B
Text
set_option linter.constructorNameAsVariable false
|
|
|
|
inductive A where
|
|
| a
|
|
|
|
inductive B : A → Type where
|
|
| b : B A.a
|
|
|
|
inductive C : B a → Type where
|
|
| c : C B.b
|
|
|
|
inductive D : C b → Type where
|
|
| d : D C.c
|
|
|
|
def f (d : D c) : Bool :=
|
|
true
|
|
|
|
set_option pp.explicit true
|
|
#print f
|