@@ -66,31 +66,48 @@ namespace UnusedTactic
66
66
/-- The monad for collecting the ranges of the syntaxes that do not modify any goal. -/
67
67
abbrev M := StateRefT (HashMap String.Range Syntax) IO
68
68
69
- /-- `Parser`s allowed to not change the tactic state. -/
70
- def allowed : HashSet SyntaxNodeKind := HashSet.empty
71
- |>.insert `Mathlib.Tactic.Says.says
72
- |>.insert `Batteries.Tactic.«tacticOn_goal-_=>_»
73
- -- attempt to speed up, by ignoring more tactics
74
- |>.insert `by
75
- |>.insert `null
76
- |>.insert `«]»
77
- |>.insert ``Lean.Parser.Term.byTactic
78
- |>.insert ``Lean.Parser.Tactic.tacticSeq
79
- |>.insert ``Lean.Parser.Tactic.tacticSeq1Indented
80
- |>.insert ``Lean.Parser.Tactic.tacticTry_
81
-
82
- -- the following `SyntaxNodeKind`s play a role in silencing `test`s
83
- |>.insert ``Lean.Parser.Tactic.guardHyp
84
- |>.insert ``Lean.Parser.Tactic.guardTarget
85
- |>.insert ``Lean.Parser.Tactic.failIfSuccess
86
- |>.insert `Mathlib.Tactic.successIfFailWithMsg
87
- |>.insert `Mathlib.Tactic.failIfNoProgress
88
- |>.insert `Mathlib.Tactic.ExtractGoal.extractGoal
89
- |>.insert `Mathlib.Tactic.Propose.propose'
90
- |>.insert `Lean.Parser.Tactic.traceState
91
- |>.insert `Mathlib.Tactic.tacticMatch_target_
92
- |>.insert `change?
93
- |>.insert `«tactic#adaptation_note_»
69
+ /-- `Parser`s allowed to not change the tactic state.
70
+ This can be increased dynamically, using `#allow_unused_tactic`.
71
+ -/
72
+ initialize allowedRef : IO.Ref (HashSet SyntaxNodeKind) ←
73
+ IO.mkRef <| HashSet.empty
74
+ |>.insert `Mathlib.Tactic.Says.says
75
+ |>.insert `Batteries.Tactic.«tacticOn_goal-_=>_»
76
+ -- attempt to speed up, by ignoring more tactics
77
+ |>.insert `by
78
+ |>.insert `null
79
+ |>.insert `«]»
80
+ |>.insert ``Lean.Parser.Term.byTactic
81
+ |>.insert ``Lean.Parser.Tactic.tacticSeq
82
+ |>.insert ``Lean.Parser.Tactic.tacticSeq1Indented
83
+ |>.insert ``Lean.Parser.Tactic.tacticTry_
84
+ -- the following `SyntaxNodeKind`s play a role in silencing `test`s
85
+ |>.insert ``Lean.Parser.Tactic.guardHyp
86
+ |>.insert ``Lean.Parser.Tactic.guardTarget
87
+ |>.insert ``Lean.Parser.Tactic.failIfSuccess
88
+ |>.insert `Mathlib.Tactic.successIfFailWithMsg
89
+ |>.insert `Mathlib.Tactic.failIfNoProgress
90
+ |>.insert `Mathlib.Tactic.ExtractGoal.extractGoal
91
+ |>.insert `Mathlib.Tactic.Propose.propose'
92
+ |>.insert `Lean.Parser.Tactic.traceState
93
+ |>.insert `Mathlib.Tactic.tacticMatch_target_
94
+ |>.insert `change?
95
+ |>.insert `«tactic#adaptation_note_»
96
+
97
+ /-- `#allow_unused_tactic` takes an input a space-separated list of identifiers.
98
+ These identifiers are then allowed by the unused tactic linter:
99
+ even if these tactics do not modify goals, there will be no warning emitted.
100
+ Note: for this to work, these identifiers should be the `SyntaxNodeKind` of each tactic.
101
+
102
+ For instance, you can allow the `done` and `skip` tactics using
103
+ ```lean
104
+ #allow_unused_tactic Lean.Parser.Tactic.done Lean.Parser.Tactic.skip
105
+ ```
106
+ Notice that you should use the `SyntaxNodeKind` of the tactic.
107
+ -/
108
+ elab "#allow_unused_tactic " ids:ident* : command => do
109
+ let ids := ← Command.liftCoreM do ids.mapM realizeGlobalConstNoOverload
110
+ allowedRef.modify (·.insertMany ids)
94
111
95
112
/--
96
113
A list of blacklisted syntax kinds, which are expected to have subterms that contain
@@ -161,7 +178,7 @@ partial def eraseUsedTactics : InfoTree → M Unit
161
178
let stx := i.stx
162
179
let kind := stx.getKind
163
180
if let some r := stx.getRange? true then
164
- if allowed .contains kind
181
+ if (← allowedRef.get) .contains kind
165
182
-- if the tactic is allowed to not change the goals
166
183
then modify (·.erase r)
167
184
else
0 commit comments