Skip to content

Conversation

@thorimur
Copy link
Contributor

@thorimur thorimur commented Nov 21, 2025

This PR ensures that withSetOptionIn does not modify the infotrees or error on malformed option values, and thus avoids panics in linters that traverse the infotrees with visitM.

withSetOptionIn is only intended to be used in linters, and thus should provide the linter action with the infotrees produced during elaboration without modification. However, withSetOptionIn had not only been modifying the infotrees by elaborating the option, but had been producing context-free info nodes in doing so. These caused uses of visitM and related functions to panic in typical linters.

Likewise, withSetOptionIn also should not cause the linter to error if somehow it consumes a malformed option value, but instead should fail silently.

We give an optional flag (addInfo := true) to Elab.elabSetOption which controls whether info is added to the infotrees.

This was brought up on Zulip here, and discussed briefly in office hours.

@thorimur
Copy link
Contributor Author

changelog-language

@github-actions github-actions bot added the changelog-language Language features and metaprograms label Nov 21, 2025
@thorimur
Copy link
Contributor Author

awaiting-review

@github-actions github-actions bot added awaiting-review Waiting for someone to review the PR toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN labels Nov 21, 2025
@leanprover-bot
Copy link
Collaborator

Reference manual CI status:

  • ❗ Reference manual CI can not be attempted yet, as the nightly-testing-2025-11-21 tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto nightly-with-manual, reference manual CI should run now. You can force reference manual CI using the force-manual-ci label. (2025-11-21 23:05:12)

leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request Nov 21, 2025
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Nov 21, 2025
leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request Nov 21, 2025
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Nov 21, 2025
@leanprover-community-bot
Copy link
Collaborator

leanprover-community-bot commented Nov 21, 2025

Mathlib CI status (docs):

Copy link
Member

@Kha Kha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we also noticed that existing core linters worked around this, could you adjust them as well (and check that their behavior is covered by a test)?

Given a command elaborator `cmd`, returns a new command elaborator that
first evaluates any local `set_option ... in ...` clauses and then invokes `cmd` on what remains.
This is expected to be used in linters, after elaboration is complete. It is not appropriate for
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move it to Linter.Basic then?

Copy link
Contributor Author

@thorimur thorimur Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'm having difficulty doing so without introducing a build cycle.

withSetOptionIn uses definitions in Lean.Elab.Command, but Lean.Elab.Command depends on Lean.Elab.Binders, which depends on Lean.Linter.Basic (only) in order to log a deprecation for let_fun in elabLetFunDecl. (Haven't checked if that's the only dependency Lean.Linter.BasicLean.Elab.Command.)

Should we leave withSetOptionIn in Lean.Elab.Command for now, or can we shuffle things around somehow?

(I've reverted my failing attempts to move it for now.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, Linter.Util then?

Copy link
Contributor Author

@thorimur thorimur Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought about this a bit:

  1. I feel that ideally Lean.Linter.Basic should give you everything you need to define a typical linter. withSetOptionIn ought to be part of that, as it's only an unusual linter which avoids it.
  2. Moreover, Lean.Elab.Command should also be part of that, as it has addLinter, which you will always want. So it would be nice if Lean.Linter.Basic could actually publicly import Lean.Elab.Command.

Assuming let_fun is the only issue (I'm testing this at #11497), what do you say to either (a) removing let_fun (seems it was deprecated 5 months ago, June 29; not sure if that's long enough) or (b) moving it somewhere else? (The option logic for logLintIf seems inextricable from Linter.Basic, so inlining that code isn't easy. We could of course issue a "worse" deprecation warning that just checks the option directly; I'm not sure if anyone is likely to be relying on linter sets/linter.all to turn off that warning...)

It might make sense to do this in another couple of PRs, of course. :)

EDIT: It seems more things prior to Lean.Elab.Command log deprecation warnings than let_fun. :( It would be nice to have one module that people import to write a linter, though...Lean.Linter seems to also include actual linters, and I imagine would therefore not be most people's first choice; Util connotes optional utilities, not the basic infrastructure. Either way it does seem that the contents of Lean.Linter.Basic have to precede Lean.Elab.Command, though.

Copy link
Contributor Author

@thorimur thorimur Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about:

  • moving the contents of Lean.Linter.Basic to a new file, e.g. Lean.Linter.Log (or Lean.Linter.Option, Lean.Linter.Init, or something else)
  • putting withSetOptionIn in the now-empty Lean.Linter.Basic, and publicly importing Lean.Elab.Command there.

Or, of course, we can just make Lean.Linter.Util the file to import when writing linters. I'm willing to make either of these changes, ultimately; I just have a preference for providing all the basic linter necessities in Lean.Linter.Basic (which includes Lean.Elab.Command and addLinter) if possible instead. :)

leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request Nov 25, 2025
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Nov 25, 2025
@leanprover-bot leanprover-bot added the P-medium We may work on this issue if we find the time label Dec 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review Waiting for someone to review the PR builds-mathlib CI has verified that Mathlib builds against this PR changelog-language Language features and metaprograms P-medium We may work on this issue if we find the time toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants