File: Mathlib/Tactic/Linter/UnusedTactic.lean

full_name: Mathlib.Linter.linter.unusedTactic
code: /-- The unused tactic linter makes sure that every tactic call actually changes *something*. -/
register_option linter.unusedTactic : Bool := {
  defValue := true
  descr := "enable the unused tactic linter"
}
goal: Lean.Option Bool

full_name: Mathlib.Linter.initFn._@.Mathlib.Tactic.Linter.UnusedTactic._hyg.8
code: /-- The unused tactic linter makes sure that every tactic call actually changes *something*. -/
register_option linter.unusedTactic : Bool := {
  defValue := true
  descr := "enable the unused tactic linter"
}
goal: IO (Lean.Option Bool)

full_name: Mathlib.Linter.UnusedTactic.M
code: /-- The monad for collecting the ranges of the syntaxes that do not modify any goal. -/
abbrev M 
goal: Type

full_name: Mathlib.Linter.UnusedTactic.allowedRef
code: /-- `Parser`s allowed to not change the tactic state.
This can be increased dynamically, using `#allow_unused_tactic`.
-/
initialize allowedRef : IO.Ref (HashSet SyntaxNodeKind) ←
  IO.mkRef <| HashSet.empty
    |>.insert `Mathlib.Tactic.Says.says
    |>.insert `Batteries.Tactic.«tacticOn_goal-_=>_»
    -- attempt to speed up, by ignoring more tactics
    |>.insert `by
    |>.insert `null
    |>.insert `«]»
    |>.insert ``Lean.Parser.Term.byTactic
    |>.insert ``Lean.Parser.Tactic.tacticSeq
    |>.insert ``Lean.Parser.Tactic.tacticSeq1Indented
    |>.insert ``Lean.Parser.Tactic.tacticTry_
    -- the following `SyntaxNodeKind`s play a role in silencing `test`s
    |>.insert ``Lean.Parser.Tactic.guardHyp
    |>.insert ``Lean.Parser.Tactic.guardTarget
    |>.insert ``Lean.Parser.Tactic.failIfSuccess
    |>.insert `Mathlib.Tactic.successIfFailWithMsg
    |>.insert `Mathlib.Tactic.failIfNoProgress
    |>.insert `Mathlib.Tactic.ExtractGoal.extractGoal
    |>.insert `Mathlib.Tactic.Propose.propose'
    |>.insert `Lean.Parser.Tactic.traceState
    |>.insert `Mathlib.Tactic.tacticMatch_target_
    |>.insert `change?
    |>.insert `«tactic#adaptation_note_»
goal: IO.Ref (Lean.HashSet Lean.SyntaxNodeKind)

full_name: Mathlib.Linter.UnusedTactic.initFn._@.Mathlib.Tactic.Linter.UnusedTactic._hyg.59
code: /-- `Parser`s allowed to not change the tactic state.
This can be increased dynamically, using `#allow_unused_tactic`.
-/
initialize allowedRef : IO.Ref (HashSet SyntaxNodeKind) ←
  IO.mkRef <| HashSet.empty
    |>.insert `Mathlib.Tactic.Says.says
    |>.insert `Batteries.Tactic.«tacticOn_goal-_=>_»
    -- attempt to speed up, by ignoring more tactics
    |>.insert `by
    |>.insert `null
    |>.insert `«]»
    |>.insert ``Lean.Parser.Term.byTactic
    |>.insert ``Lean.Parser.Tactic.tacticSeq
    |>.insert ``Lean.Parser.Tactic.tacticSeq1Indented
    |>.insert ``Lean.Parser.Tactic.tacticTry_
    -- the following `SyntaxNodeKind`s play a role in silencing `test`s
    |>.insert ``Lean.Parser.Tactic.guardHyp
    |>.insert ``Lean.Parser.Tactic.guardTarget
    |>.insert ``Lean.Parser.Tactic.failIfSuccess
    |>.insert `Mathlib.Tactic.successIfFailWithMsg
    |>.insert `Mathlib.Tactic.failIfNoProgress
    |>.insert `Mathlib.Tactic.ExtractGoal.extractGoal
    |>.insert `Mathlib.Tactic.Propose.propose'
    |>.insert `Lean.Parser.Tactic.traceState
    |>.insert `Mathlib.Tactic.tacticMatch_target_
    |>.insert `change?
    |>.insert `«tactic#adaptation_note_»
goal: IO (IO.Ref (Lean.HashSet Lean.SyntaxNodeKind))

full_name: Mathlib.Linter.UnusedTactic.«_aux_Mathlib_Tactic_Linter_UnusedTactic___elabRules_Mathlib_Linter_UnusedTactic_command#allow_unused_tactic__1»
code: /-- `#allow_unused_tactic` takes an input a space-separated list of identifiers.
These identifiers are then allowed by the unused tactic linter:
even if these tactics do not modify goals, there will be no warning emitted.
Note: for this to work, these identifiers should be the `SyntaxNodeKind` of each tactic.

For instance, you can allow the `done` and `skip` tactics using
```lean
#allow_unused_tactic Lean.Parser.Tactic.done Lean.Parser.Tactic.skip
```
Notice that you should use the `SyntaxNodeKind` of the tactic.
-/
elab "#allow_unused_tactic " ids:ident* : command => do
  let ids := ← Command.liftCoreM do ids.mapM realizeGlobalConstNoOverload
  allowedRef.modify (·.insertMany ids)
goal: Lean.Elab.Command.CommandElab

full_name: Mathlib.Linter.UnusedTactic.«command#allow_unused_tactic_»
code: /-- `#allow_unused_tactic` takes an input a space-separated list of identifiers.
These identifiers are then allowed by the unused tactic linter:
even if these tactics do not modify goals, there will be no warning emitted.
Note: for this to work, these identifiers should be the `SyntaxNodeKind` of each tactic.

For instance, you can allow the `done` and `skip` tactics using
```lean
#allow_unused_tactic Lean.Parser.Tactic.done Lean.Parser.Tactic.skip
```
Notice that you should use the `SyntaxNodeKind` of the tactic.
-/
elab "#allow_unused_tactic " ids:ident* : command => do
  let ids := ← Command.liftCoreM do ids.mapM realizeGlobalConstNoOverload
  allowedRef.modify (·.insertMany ids)
goal: Lean.ParserDescr

full_name: Mathlib.Linter.UnusedTactic.initFn._@.Mathlib.Tactic.Linter.UnusedTactic._hyg.269
code: /--
A list of blacklisted syntax kinds, which are expected to have subterms that contain
unevaluated tactics.
-/
initialize ignoreTacticKindsRef : IO.Ref NameHashSet ←
  IO.mkRef <| HashSet.empty
    |>.insert `Mathlib.Tactic.Says.says
    |>.insert ``Parser.Term.binderTactic
    |>.insert ``Lean.Parser.Term.dynamicQuot
    |>.insert ``Lean.Parser.Tactic.quotSeq
    |>.insert ``Lean.Parser.Tactic.tacticStop_
    |>.insert ``Lean.Parser.Command.notation
    |>.insert ``Lean.Parser.Command.mixfix
    |>.insert ``Lean.Parser.Tactic.discharger
    |>.insert ``Lean.Parser.Tactic.Conv.conv
    |>.insert `Batteries.Tactic.seq_focus
    |>.insert `Mathlib.Tactic.Hint.registerHintStx
    |>.insert `Mathlib.Tactic.LinearCombination.linearCombination
    -- the following `SyntaxNodeKind`s play a role in silencing `test`s
    |>.insert ``Lean.Parser.Tactic.failIfSuccess
    |>.insert `Mathlib.Tactic.successIfFailWithMsg
    |>.insert `Mathlib.Tactic.failIfNoProgress
goal: IO (IO.Ref Lean.NameHashSet)

full_name: Mathlib.Linter.UnusedTactic.ignoreTacticKindsRef
code: /--
A list of blacklisted syntax kinds, which are expected to have subterms that contain
unevaluated tactics.
-/
initialize ignoreTacticKindsRef : IO.Ref NameHashSet ←
  IO.mkRef <| HashSet.empty
    |>.insert `Mathlib.Tactic.Says.says
    |>.insert ``Parser.Term.binderTactic
    |>.insert ``Lean.Parser.Term.dynamicQuot
    |>.insert ``Lean.Parser.Tactic.quotSeq
    |>.insert ``Lean.Parser.Tactic.tacticStop_
    |>.insert ``Lean.Parser.Command.notation
    |>.insert ``Lean.Parser.Command.mixfix
    |>.insert ``Lean.Parser.Tactic.discharger
    |>.insert ``Lean.Parser.Tactic.Conv.conv
    |>.insert `Batteries.Tactic.seq_focus
    |>.insert `Mathlib.Tactic.Hint.registerHintStx
    |>.insert `Mathlib.Tactic.LinearCombination.linearCombination
    -- the following `SyntaxNodeKind`s play a role in silencing `test`s
    |>.insert ``Lean.Parser.Tactic.failIfSuccess
    |>.insert `Mathlib.Tactic.successIfFailWithMsg
    |>.insert `Mathlib.Tactic.failIfNoProgress
goal: IO.Ref Lean.NameHashSet

full_name: Mathlib.Linter.UnusedTactic.isIgnoreTacticKind
code: /-- Is this a syntax kind that contains intentionally unused tactic subterms? -/
def isIgnoreTacticKind (ignoreTacticKinds : NameHashSet) (k : SyntaxNodeKind) : Bool 
goal: Bool

full_name: Mathlib.Linter.UnusedTactic.addIgnoreTacticKind
code: /--
Adds a new syntax kind whose children will be ignored by the `unusedTactic` linter.
This should be called from an `initialize` block.
-/
def addIgnoreTacticKind (kind : SyntaxNodeKind) : IO Unit 
goal: IO Unit

full_name: Mathlib.Linter.UnusedTactic.getTactics
code: /-- Accumulates the set of tactic syntaxes that should be evaluated at least once. -/
@[specialize] partial def getTactics (stx : Syntax) : M Unit 
goal: Mathlib.Linter.UnusedTactic.M Unit

full_name: Mathlib.Linter.UnusedTactic.getNames
code: /-- `getNames mctx` extracts the names of all the local declarations implied by the
`MetavarContext` `mctx`. -/
def getNames (mctx : MetavarContext) : List Name 
goal: List Lean.Name

full_name: Mathlib.Linter.UnusedTactic.getLinterHash
code: /-- Gets the value of the `linter.unusedTactic` option. -/
def getLinterHash (o : Options) : Bool 
goal: Bool

full_name: Mathlib.Linter.UnusedTactic.unusedTacticLinter
code: /-- The main entry point to the unused tactic linter. -/
def unusedTacticLinter : Linter 
goal: Lean.Linter

full_name: Mathlib.Linter.UnusedTactic.initFn._@.Mathlib.Tactic.Linter.UnusedTactic._hyg.1605
code: initialize addLinter unusedTacticLinter
goal: IO Unit