This PR sets up the new integrated test/bench suite. It then migrates all benchmarks and some related tests to the new suite. There's also some documentation and some linting. For now, a lot of the old tests are left alone so this PR doesn't become even larger than it already is. Eventually, all tests should be migrated to the new suite though so there isn't a confusing mix of two systems.
169 lines
5.1 KiB
Text
169 lines
5.1 KiB
Text
/-!
|
||
Testing for linter.constructorNameAsVariable
|
||
|
||
This linter checks warns when a bound variable's name is the name of a constructor of the variable's
|
||
type, which probably indicates a namespace mistake, but can be otherwise hard to find.
|
||
|
||
The linter is designed to interact well with the suggestions provided when a non-constructor is used
|
||
where a constructor would be expected in a pattern, so that users who don't know Lean namespaces
|
||
will be guided to the right qualified names. Thus, both are tested together here.
|
||
-/
|
||
set_option linter.unusedVariables false
|
||
|
||
inductive A where
|
||
| x | y
|
||
|
||
-- Test that the linter works even in the presence of errors (making it useful for confused new
|
||
-- users)
|
||
|
||
/--
|
||
warning: Local variable 'x' resembles constructor 'A.x' - write '.x' (with a dot) or 'A.x' to use the constructor.
|
||
|
||
Note: This linter can be disabled with `set_option linter.constructorNameAsVariable false`
|
||
-/
|
||
#guard_msgs(drop error, warning) in
|
||
def f : A → Unit
|
||
| x => _
|
||
|
||
-- Show that the linter also works when there are no errors
|
||
/--
|
||
warning: Local variable 'x' resembles constructor 'A.x' - write '.x' (with a dot) or 'A.x' to use the constructor.
|
||
|
||
Note: This linter can be disabled with `set_option linter.constructorNameAsVariable false`
|
||
-/
|
||
#guard_msgs(warning) in
|
||
def g : A → Unit
|
||
| x => ()
|
||
|
||
-- Check that turning it off works
|
||
#guard_msgs in
|
||
set_option linter.constructorNameAsVariable false in
|
||
def g' : A → Unit
|
||
| x => ()
|
||
|
||
-- Avoid false positives
|
||
#guard_msgs in
|
||
def h : A → Unit
|
||
| z => ()
|
||
|
||
-- Check that it works for let-bindings
|
||
/--
|
||
warning: Local variable 'x' resembles constructor 'A.x' - write '.x' (with a dot) or 'A.x' to use the constructor.
|
||
|
||
Note: This linter can be disabled with `set_option linter.constructorNameAsVariable false`
|
||
---
|
||
warning: Local variable 'y' resembles constructor 'A.y' - write '.y' (with a dot) or 'A.y' to use the constructor.
|
||
|
||
Note: This linter can be disabled with `set_option linter.constructorNameAsVariable false`
|
||
-/
|
||
#guard_msgs in
|
||
def i (a : A × A) : Unit :=
|
||
let (x, y) := a
|
||
()
|
||
|
||
/--
|
||
warning: Local variable 'x' resembles constructor 'A.x' - write '.x' (with a dot) or 'A.x' to use the constructor.
|
||
|
||
Note: This linter can be disabled with `set_option linter.constructorNameAsVariable false`
|
||
-/
|
||
#guard_msgs in
|
||
def i' : Unit :=
|
||
let x : A := .x
|
||
()
|
||
|
||
-- Check that it works in tactic proofs
|
||
/--
|
||
warning: Local variable 'x' resembles constructor 'A.x' - write '.x' (with a dot) or 'A.x' to use the constructor.
|
||
|
||
Note: This linter can be disabled with `set_option linter.constructorNameAsVariable false`
|
||
-/
|
||
#guard_msgs in
|
||
theorem j (a : A ⊕ A) : True := by
|
||
cases a with
|
||
| inl x => trivial
|
||
| inr z => trivial
|
||
|
||
-- Top-level names do not trigger the lint
|
||
#guard_msgs in
|
||
def x : A := A.x
|
||
|
||
/-! Test the interaction with the invalid match pattern error messages -/
|
||
|
||
inductive MyProd where
|
||
| construct : Nat → Nat → MyProd
|
||
|
||
/--
|
||
error: Invalid pattern: Expected a constructor or constant marked with `[match_pattern]`
|
||
|
||
Hint: Using `MyProd.construct` would be valid:
|
||
[apply] `MyProd.construct`
|
||
-/
|
||
#guard_msgs in
|
||
def ctorSuggestion1 (pair : MyProd) : Nat :=
|
||
match pair with
|
||
| construct x y => y
|
||
|
||
-- This test is a realistic situation if a user doesn't know how Lean namespaces work
|
||
/--
|
||
error: Invalid pattern: Expected a constructor or constant marked with `[match_pattern]`
|
||
|
||
Hint: Using one of these would be valid:
|
||
[apply] `List.Sublist.cons`
|
||
[apply] `Lean.Grind.AC.Seq.cons`
|
||
[apply] `List.Lex.cons`
|
||
[apply] `List.Perm.below.cons`
|
||
[apply] `List.Lex.below.cons`
|
||
[apply] `List.Pairwise.below.cons`
|
||
[apply] `List.cons`
|
||
[apply] `List.Sublist.below.cons`
|
||
[apply] `List.Perm.cons`
|
||
[apply] `List.Pairwise.cons`
|
||
---
|
||
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`
|
||
-/
|
||
#guard_msgs in
|
||
def ctorSuggestion2 (list : List α) : Nat :=
|
||
match list with
|
||
| nil => 0
|
||
| cons x xs => 1 + ctorSuggestion2 xs
|
||
|
||
-- Adding another `cons` also adds a suggestion
|
||
inductive StringList : Type where
|
||
| nil
|
||
| cons (s : String) (ss : StringList)
|
||
|
||
/--
|
||
error: Invalid pattern: Expected a constructor or constant marked with `[match_pattern]`
|
||
|
||
Hint: Using one of these would be valid:
|
||
[apply] `List.Sublist.cons`
|
||
[apply] `Lean.Grind.AC.Seq.cons`
|
||
[apply] `List.Lex.cons`
|
||
[apply] `List.Perm.below.cons`
|
||
[apply] `List.Lex.below.cons`
|
||
[apply] `List.Pairwise.below.cons`
|
||
[apply] `List.cons`
|
||
[apply] `List.Sublist.below.cons`
|
||
[apply] `List.Perm.cons`
|
||
[apply] `List.Pairwise.cons`
|
||
[apply] `StringList.cons`
|
||
---
|
||
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`
|
||
-/
|
||
#guard_msgs in
|
||
def ctorSuggestion3 (list : List α) : Nat :=
|
||
match list with
|
||
| nil => 0
|
||
| cons x xs => 1 + ctorSuggestion2 xs
|
||
|
||
-- There isn't always a suggestion to provide
|
||
|
||
/-- error: Invalid pattern: Expected a constructor or constant marked with `[match_pattern]` -/
|
||
#guard_msgs in
|
||
def ctorNoSuggestion (x : α) :=
|
||
match x with
|
||
| notAConstructor a b c => 42
|