Skip to content
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

Unname some unused variables #1190

Merged
merged 6 commits into from Jun 7, 2022
Merged

Unname some unused variables #1190

merged 6 commits into from Jun 7, 2022

Conversation

Kha
Copy link
Member

@Kha Kha commented Jun 4, 2022

The following quick script takes as stdin a Lean build log and replaces reportedly unused variables with _ in the following two cases where formatting isn't too much of an issue:

  • single-letter variables
  • something that looks like a top-level pattern variable, in which case we pad with an appropriate number of spaces after the , (if any)
def main : IO Unit := do
  let stdin ← IO.getStdin
  while !(← stdin.isEof) do
    match (← (← IO.getStdin).getLine).trim.splitOn with
    | [loc, "warning:", "unused", "variable", var] =>
      let [file, lineNo, col, ""] := loc.splitOn ":" | throw <| IO.userError loc
      let lineNo := lineNo.toNat! - 1
      let col := col.toNat!
      let var := var.extract ⟨1⟩ (var.prev var.endPos)  -- remove ``
      let lines := (← IO.FS.readFile file).splitOn "\n" |>.toArray
      let line := lines[lineNo]
      if (line.contains '|' && !line.contains '(') || var.length == 1 then  -- then
        IO.println loc
        IO.println line
        let mut line := line.take col ++ "_" ++ "".pushn ' ' (var.length - "_".length) ++ line.drop (col + var.length)
        -- adjust trailing comma
        if var.length > 1 && (line.mkIterator.nextn (col + var.length) |>.curr) == ',' then
          line := line.mkIterator.nextn (col + 1) |>.setCurr ',' |>.nextn (var.length - 1) |>.setCurr ' ' |>.toString
        IO.println line
        let lines := lines.set! lineNo line
        IO.FS.writeFile file (String.join <| lines.toList.intersperse "\n")
    | _ => continue

It looks like the linter sometimes reports the same variable multiple times, which confuses the script, so I filtered the input through sort -u first. Then I post-processed the result using sed -i 's![_ : ![!g' to fix instance implicits. And then I did some more manual cleanups as in the commits below.

@@ -27,11 +27,11 @@ class CoeTail (α : Sort u) (β : Sort v) where
class CoeHTCT (α : Sort u) (β : Sort v) where
coe : α → β

class CoeDep (α : Sort u) (_ : α) (β : Sort v) where
class CoeDep (α : Sort u) (a : α) (β : Sort v) where
Copy link
Member Author

Choose a reason for hiding this comment

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

@larsk21 I wonder if we should exclude class signatures by default

Copy link
Contributor

Choose a reason for hiding this comment

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

After seeing this use case, yes, probably. But the same issue occurs with structure and inductive signatures as well, doesn't it?

Copy link
Contributor

Choose a reason for hiding this comment

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

see #1191

Copy link
Member Author

Choose a reason for hiding this comment

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

But the same issue occurs with structure and inductive signatures as well, doesn't it?

That's a good question. It could be argued that it is likelier for classes where parameters that are exclusively for directing typeclass resolution sounds quite reasonable, whereas "faux-typed" structures such as the single KeyedDeclsAttribute.Def from this PR seem more edge case (and often may as well be defs, in which case we can't exclude them anyway).

let _ := if e.isAppOfArity ``id 2 then e.appArg! else e
return some (← reduceProjs (← instantiateMVars e.appArg!) expandedStructNames)
let r := if e.isAppOfArity ``id 2 then e.appArg! else e
return some (← reduceProjs (← instantiateMVars r.appArg!) expandedStructNames)
Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Apparently not, the change breaks run/diamond{3,4}.lean

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for catching this. I pushed a fix for this.

      let r := if e.isAppOfArity ``id 2 then e.appArg! else e
      return some (← reduceProjs (← instantiateMVars r) expandedStructNames)

@@ -1147,7 +1147,7 @@ private def unfoldBothDefEq (fn : Name) (t s : Expr) : MetaM LBool := do

private def sameHeadSymbol (t s : Expr) : Bool :=
match t.getAppFn, s.getAppFn with
| Expr.const c₁ _ _, Expr.const c₂ _ _ => true
| Expr.const _ _ _, Expr.const _ _ _ => true
Copy link
Member Author

Choose a reason for hiding this comment

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

@leodemoura correct?

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for catching this. I pushed a fix for it.

src/Init/Tactics.lean Outdated Show resolved Hide resolved
src/Lean/Meta/Tactic/Simp/Main.lean Outdated Show resolved Hide resolved
src/Lean/Message.lean Outdated Show resolved Hide resolved
src/Lean/Data/JsonRpc.lean Outdated Show resolved Hide resolved
src/Lean/Compiler/IR/PushProj.lean Outdated Show resolved Hide resolved

theorem eq_false_of_decide {p : Prop} {s : Decidable p} (h : decide p = false) : p = False :=
theorem eq_false_of_decide {p : Prop} {_ : Decidable p} (h : decide p = false) : p = False :=
Copy link
Member

@gebner gebner Jun 4, 2022

Choose a reason for hiding this comment

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

I really dislike that this disables the (s := ...) syntax to specify implicit arguments (for no good reason). (Not that s is a great name, inst or something would certainly be better.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Ugh, I dislike the counter-intuitive implicit-as-inst-implicit pattern in general. Not sure what would be a good general solution here.

Copy link
Member

Choose a reason for hiding this comment

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

implicit-as-inst-implicit pattern

Do you mean {_ : Decidable p} instead of [Decidable p]? (Not sure I understood you correctly. I would have named it the way around: inst-implicit-as-implicit pattern.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I was thinking of it the other way around - an implicit parameter that becomes an inst-implicit argument in an application

Copy link
Member Author

Choose a reason for hiding this comment

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

I just noticed that the {_ : style is prevalent in e.g. Std.Data.PersistentHashMap, so this really is a pre-existing style issue that should be discussed at a larger scope.

Copy link
Member Author

Choose a reason for hiding this comment

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

Just a quick idea, but a "nicer" way could be to allow selecting parameters by type as in eq_false_of_decide (‹Decidable p› := ...). One slight downside would be a larger parser overlap.

@Kha
Copy link
Member Author

Kha commented Jun 4, 2022

@gebner Thanks, I definitely didn't look at every line in detail!

@@ -2,9 +2,9 @@
a : α
as bs : List α
h : bs = a :: as
⊢ List.length (?a :: as) = List.length bs
⊢ List.length (?head :: as) = List.length bs
Copy link
Member Author

Choose a reason for hiding this comment

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

An unexpected consequence from renaming a pattern variable, but I can't say I've every done such a refold myself so far.

leodemoura added a commit that referenced this pull request Jun 6, 2022
leodemoura added a commit that referenced this pull request Jun 6, 2022
@leodemoura leodemoura merged commit 130cc8b into leanprover:master Jun 7, 2022
@Kha Kha deleted the unnamed branch June 8, 2022 09:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants