-
Notifications
You must be signed in to change notification settings - Fork 612
feat: linter.unusedSimpArgs #8901
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
9dab528
refactor: elab simp arguments to declarative result, apply later
nomeata 363c2f0
stash
nomeata 403b314
starArg handling
nomeata 23b1a6f
Rename
nomeata 4235402
Subltety around erasing simp entries
nomeata a55ddae
Merge branch 'nightly-with-mathlib' of https://github.com/leanprover/…
nomeata 4cf7999
Kick CI
nomeata fdc4e00
Default argument
nomeata d959e63
docstring
nomeata 4a2bb97
Add function back for compat with mathlib
nomeata 6c5d06b
Clean up SimpTheorems.lean a bit (group API by type, mild renaming)
nomeata 54871f6
Recover .erase/eraseCore behavior
nomeata e7cce2c
elabSimpArg withRef
nomeata 780d3f1
More refactoring
nomeata 76c0309
MkSimpContextResult.addStar
nomeata 7f47d19
Simplify addStar further
nomeata bcc8d86
Merge commit '3b2990b381' into joachim/simp-arg-elab
nomeata 1bae07d
Keep simp args around
nomeata fcef7b1
feat: set_option tactic.simp.warnUnused
nomeata f098740
Also local hyps
nomeata 249703b
Also ldecls
nomeata 54ced91
Try a linter and customInfoNodes
nomeata 54a5129
More tests
nomeata 5142c44
Disable for now
nomeata e81764e
Refactor
nomeata 13f7b34
Makro-Variante
nomeata c87d07f
Docstring
nomeata 409a715
Merge branch 'nightly' of https://github.com/leanprover/lean4 into jo…
nomeata 03b1806
Final pass
nomeata 4d48063
Merge branch 'joachim/simp-arg-elab' into joachim/linter-unusedSimpArgs
nomeata eee737c
Turn on again, write description
nomeata f4fa9a9
More unused simp args
nomeata b9e7bbb
Update tests
nomeata 0eaa146
Merge branch 'master' of https://github.com/leanprover/lean4 into joa…
nomeata a5ccaf4
Merge branch 'joachim/simp-arg-elab' into joachim/linter-unusedSimpArgs
nomeata 2a00009
chore: remove more unused simp args
nomeata c0ec77e
Update src/Init/Data/BitVec/Bitblast.lean
nomeata 2411f7b
Merge branch 'joachim/more-unused-simp-args' into joachim/linter-unus…
nomeata 20ace39
Merge branch 'joachim/more-unused-simp-args' of https://github.com/le…
nomeata 6a63948
Merge branch 'master' of https://github.com/leanprover/lean4 into joa…
nomeata b77a694
Check set_option
nomeata File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/- | ||
Copyright (c) 2025 Lean FRO, LLC. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Joachim Breitner | ||
-/ | ||
prelude | ||
import Lean.Elab.Command | ||
import Lean.Elab.Tactic.Simp | ||
import Lean.Linter.Util | ||
|
||
namespace Lean.Linter | ||
|
||
open Lean Elab Command | ||
open Lean.Linter (logLint) | ||
|
||
private def warnUnused (stx : Syntax) (i : Nat) : CoreM Unit := do | ||
let stx : TSyntax `tactic := ⟨stx⟩ | ||
let simpArgs := Tactic.getSimpParams stx | ||
unless i < simpArgs.size do | ||
throwError "Index {i} out of bounds for simp arguments of {stx}" | ||
let argStx := simpArgs[i]! | ||
let msg := m!"This simp argument is unused:{indentD argStx}" | ||
let mut otherArgs : Array Syntax := #[] | ||
for h : j in [:simpArgs.size] do if j != i then | ||
otherArgs := otherArgs.push simpArgs[j] | ||
let stx' := Tactic.setSimpParams stx otherArgs | ||
let suggestion : Meta.Hint.Suggestion := stx' | ||
let suggestion := { suggestion with span? := stx } | ||
let hint ← MessageData.hint "Omit it from the simp argument list." #[ suggestion ] | ||
logLint Tactic.linter.unusedSimpArgs argStx (msg ++ hint) | ||
|
||
def unusedSimpArgs : Linter where | ||
run cmdStx := do | ||
if !Tactic.linter.unusedSimpArgs.get (← getOptions) then return | ||
let some cmdStxRange := cmdStx.getRange? | return | ||
|
||
let infoTrees := (← get).infoState.trees.toArray | ||
let masksMap : IO.Ref (Std.HashMap String.Range (Syntax × Array Bool)) ← IO.mkRef {} | ||
|
||
for tree in infoTrees do | ||
tree.visitM' (postNode := fun ci info _ => do | ||
match info with | ||
| .ofCustomInfo ci => | ||
if let some {mask} := ci.value.get? Tactic.UnusedSimpArgsInfo then | ||
-- Only look at info with a range. This also happens to prevent the linter from | ||
-- reporting about unused simp arguments inside macro, which we do not want to do | ||
-- (we likely cannot see all uses of the macro, so the warning would be incomplete) | ||
let some range := info.range? | return | ||
let maskAcc ← | ||
if let some (_, maskAcc) := (← masksMap.get)[range]? then | ||
unless mask.size = maskAcc.size do | ||
throwErrorAt info.stx "Simp argument mask size mismatch}: {maskAcc.size} vs. {mask.size}" | ||
pure <| Array.zipWith (· || ·) mask maskAcc | ||
else | ||
pure mask | ||
masksMap.modify fun m => m.insert range (ci.stx, maskAcc) | ||
| _ => pure ()) | ||
|
||
-- Sort the outputs by position | ||
for (_range, tacticStx, mask) in (← masksMap.get).toArray.qsort (·.1.start < ·.1.start) do | ||
for i in [:mask.size] do | ||
unless mask[i]! do | ||
liftCoreM <| warnUnused tacticStx i | ||
|
||
builtin_initialize addLinter unusedSimpArgs |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
4452.lean:17:4-17:6: warning: `hi` has been deprecated: Don't use `hi`. | ||
4452.lean:28:4-28:7: warning: `hi'` has been deprecated: Don't use `hi'`, either. | ||
4452.lean:18:4-18:6: warning: `hi` has been deprecated: Don't use `hi`. | ||
4452.lean:29:4-29:7: warning: `hi'` has been deprecated: Don't use `hi'`, either. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,71 +1,71 @@ | ||
linterUnusedVariables.lean:16:21-16:22: warning: unused variable `x` | ||
linterUnusedVariables.lean:17:21-17:22: warning: unused variable `x` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:17:6-17:7: warning: unused variable `y` | ||
linterUnusedVariables.lean:18:6-18:7: warning: unused variable `y` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:22:8-22:9: warning: unused variable `x` | ||
linterUnusedVariables.lean:23:8-23:9: warning: unused variable `x` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:38:5-38:6: warning: unused variable `x` | ||
linterUnusedVariables.lean:39:5-39:6: warning: unused variable `x` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:43:5-43:6: warning: unused variable `x` | ||
linterUnusedVariables.lean:44:5-44:6: warning: unused variable `x` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:46:7-46:8: warning: unused variable `x` | ||
linterUnusedVariables.lean:47:7-47:8: warning: unused variable `x` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:49:8-49:9: warning: unused variable `x` | ||
linterUnusedVariables.lean:50:8-50:9: warning: unused variable `x` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:53:9-53:10: warning: unused variable `z` | ||
linterUnusedVariables.lean:54:9-54:10: warning: unused variable `z` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:55:11-55:12: warning: unused variable `z` | ||
linterUnusedVariables.lean:56:11-56:12: warning: unused variable `z` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:60:14-60:15: warning: unused variable `y` | ||
linterUnusedVariables.lean:61:14-61:15: warning: unused variable `y` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:66:20-66:21: warning: unused variable `y` | ||
linterUnusedVariables.lean:67:20-67:21: warning: unused variable `y` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:71:34-71:38: warning: unused variable `inst` | ||
linterUnusedVariables.lean:72:34-72:38: warning: unused variable `inst` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:112:25-112:26: warning: unused variable `x` | ||
linterUnusedVariables.lean:113:25-113:26: warning: unused variable `x` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:113:6-113:7: warning: unused variable `y` | ||
linterUnusedVariables.lean:114:6-114:7: warning: unused variable `y` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:119:6-119:7: warning: unused variable `a` | ||
linterUnusedVariables.lean:120:6-120:7: warning: unused variable `a` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:129:26-129:27: warning: unused variable `z` | ||
linterUnusedVariables.lean:130:26-130:27: warning: unused variable `z` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:138:9-138:10: warning: unused variable `h` | ||
linterUnusedVariables.lean:139:9-139:10: warning: unused variable `h` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:152:8-152:9: warning: unused variable `y` | ||
linterUnusedVariables.lean:153:8-153:9: warning: unused variable `y` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:155:20-155:21: warning: unused variable `β` | ||
linterUnusedVariables.lean:156:20-156:21: warning: unused variable `β` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:156:7-156:8: warning: unused variable `x` | ||
linterUnusedVariables.lean:157:7-157:8: warning: unused variable `x` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:166:6-166:7: warning: unused variable `s` | ||
linterUnusedVariables.lean:167:6-167:7: warning: unused variable `s` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:190:6-190:7: warning: unused variable `y` | ||
linterUnusedVariables.lean:191:6-191:7: warning: unused variable `y` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:200:19-200:20: warning: unused variable `x` | ||
linterUnusedVariables.lean:201:19-201:20: warning: unused variable `x` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:204:6-204:7: warning: unused variable `y` | ||
linterUnusedVariables.lean:205:6-205:7: warning: unused variable `y` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:209:6-209:7: warning: unused variable `y` | ||
linterUnusedVariables.lean:210:6-210:7: warning: unused variable `y` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:214:6-214:7: warning: unused variable `y` | ||
linterUnusedVariables.lean:215:6-215:7: warning: unused variable `y` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:225:32-225:33: warning: unused variable `b` | ||
linterUnusedVariables.lean:226:32-226:33: warning: unused variable `b` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` | ||
linterUnusedVariables.lean:243:27-243:28: error: don't know how to synthesize placeholder | ||
linterUnusedVariables.lean:244:27-244:28: error: don't know how to synthesize placeholder | ||
context: | ||
a : Nat | ||
⊢ Nat | ||
linterUnusedVariables.lean:244:0-244:7: warning: declaration uses 'sorry' | ||
linterUnusedVariables.lean:245:0-245:7: warning: declaration uses 'sorry' | ||
linterUnusedVariables.lean:246:29-247:7: error: unexpected token 'theorem'; expected '{' or tactic | ||
linterUnusedVariables.lean:246:27-246:29: error: unsolved goals | ||
linterUnusedVariables.lean:246:0-246:7: warning: declaration uses 'sorry' | ||
linterUnusedVariables.lean:247:29-248:7: error: unexpected token 'theorem'; expected '{' or tactic | ||
linterUnusedVariables.lean:247:27-247:29: error: unsolved goals | ||
a : Nat | ||
⊢ Nat | ||
linterUnusedVariables.lean:247:33-247:40: error: unsolved goals | ||
linterUnusedVariables.lean:248:33-248:40: error: unsolved goals | ||
a : Nat | ||
⊢ Nat | ||
linterUnusedVariables.lean:247:0-247:40: error: type of theorem 'async' is not a proposition | ||
linterUnusedVariables.lean:248:0-248:40: error: type of theorem 'async' is not a proposition | ||
Nat → Nat | ||
linterUnusedVariables.lean:282:41-282:43: warning: unused variable `ha` | ||
linterUnusedVariables.lean:283:41-283:43: warning: unused variable `ha` | ||
note: this linter can be disabled with `set_option linter.unusedVariables false` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.