Skip to content

Commit 8e88e80

Browse files
authored
chore: deprecate := variants of inductive and structure (#5542)
Deprecates `inductive ... :=`, `structure ... :=`, and `class ... :=` in favor of the `... where` variant. Currently this syntax produces a warning, controlled by the `linter.deprecated` option. Breaking change: modifies `Lean.Linter.logLintIf` to use `Lean.Linter.getLinterValue` to determine if a linter value is set. This means that the `linter.all` option now is taken into account when the linter option is not set. Part of #5236
1 parent 96e996e commit 8e88e80

File tree

5 files changed

+53
-7
lines changed

5 files changed

+53
-7
lines changed

Diff for: src/Lean/Elab/Declaration.lean

+6-2
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ def elabAxiom (modifiers : Modifiers) (stx : Syntax) : CommandElabM Unit := do
136136
Term.applyAttributesAt declName modifiers.attrs AttributeApplicationTime.afterCompilation
137137

138138
/-
139-
leading_parser "inductive " >> declId >> optDeclSig >> optional ":=" >> many ctor
140-
leading_parser atomic (group ("class " >> "inductive ")) >> declId >> optDeclSig >> optional ":=" >> many ctor >> optDeriving
139+
leading_parser "inductive " >> declId >> optDeclSig >> optional ("where" <|> ":=") >> many ctor
140+
leading_parser atomic (group ("class " >> "inductive ")) >> declId >> optDeclSig >> optional ("where" <|> ":=") >> many ctor >> optDeriving
141141
-/
142142
private def inductiveSyntaxToView (modifiers : Modifiers) (decl : Syntax) : CommandElabM InductiveView := do
143143
checkValidInductiveModifier modifiers
@@ -167,6 +167,10 @@ private def inductiveSyntaxToView (modifiers : Modifiers) (decl : Syntax) : Comm
167167
let computedFields ← (decl[5].getOptional?.map (·[1].getArgs) |>.getD #[]).mapM fun cf => withRef cf do
168168
return { ref := cf, modifiers := cf[0], fieldId := cf[1].getId, type := ⟨cf[3]⟩, matchAlts := ⟨cf[4]⟩ }
169169
let classes ← liftCoreM <| getOptDerivingClasses decl[6]
170+
if decl[3][0].isToken ":=" then
171+
-- https://github.com/leanprover/lean4/issues/5236
172+
withRef decl[0] <| Linter.logLintIf Linter.linter.deprecated decl[3]
173+
"'inductive ... :=' has been deprecated in favor of 'inductive ... where'."
170174
return {
171175
ref := decl
172176
shortDeclName := name

Diff for: src/Lean/Elab/Structure.lean

+8-2
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,12 @@ def structSimpleBinder := leading_parser atomic (declModifiers true >> ident)
137137
def structFields := leading_parser many (structExplicitBinder <|> structImplicitBinder <|> structInstBinder)
138138
```
139139
-/
140-
private def expandFields (structStx : Syntax) (structModifiers : Modifiers) (structDeclName : Name) : TermElabM (Array StructFieldView) :=
140+
private def expandFields (structStx : Syntax) (structModifiers : Modifiers) (structDeclName : Name) : TermElabM (Array StructFieldView) := do
141+
if structStx[5][0].isToken ":=" then
142+
-- https://github.com/leanprover/lean4/issues/5236
143+
let cmd := if structStx[0].getKind == ``Parser.Command.classTk then "class" else "structure"
144+
withRef structStx[0] <| Linter.logLintIf Linter.linter.deprecated structStx[5][0]
145+
s!"{cmd} ... :=' has been deprecated in favor of '{cmd} ... where'."
141146
let fieldBinders := if structStx[5].isNone then #[] else structStx[5][2][0].getArgs
142147
fieldBinders.foldlM (init := #[]) fun (views : Array StructFieldView) fieldBinder => withRef fieldBinder do
143148
let mut fieldBinder := fieldBinder
@@ -879,7 +884,8 @@ private def elabStructureView (view : StructView) : TermElabM Unit := do
879884
addDefaults lctx defaultAuxDecls
880885

881886
/-
882-
leading_parser (structureTk <|> classTk) >> declId >> many Term.bracketedBinder >> optional «extends» >> Term.optType >> " := " >> optional structCtor >> structFields >> optDeriving
887+
leading_parser (structureTk <|> classTk) >> declId >> many Term.bracketedBinder >> optional «extends» >> Term.optType >>
888+
optional (("where" <|> ":=") >> optional structCtor >> structFields) >> optDeriving
883889
884890
where
885891
def «extends» := leading_parser " extends " >> sepBy1 termParser ", "

Diff for: src/Lean/Linter/Basic.lean

+8-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,14 @@ def logLint [Monad m] [MonadLog m] [AddMessageContext m] [MonadOptions m]
2323
let disable := m!"note: this linter can be disabled with `set_option {linterOption.name} false`"
2424
logWarningAt stx (.tagged linterOption.name m!"{msg}\n{disable}")
2525

26-
/-- If `linterOption` is true, print a linter warning message at the position determined by `stx`.
26+
/--
27+
If `linterOption` is enabled, print a linter warning message at the position determined by `stx`.
28+
29+
Whether a linter option is enabled or not is determined by the following sequence:
30+
1. If it is set, then the value determines whether or not it is enabled.
31+
2. Otherwise, if `linter.all` is set, then its value determines whether or not the option is enabled.
32+
3. Otherwise, the default value determines whether or not it is enabled.
2733
-/
2834
def logLintIf [Monad m] [MonadLog m] [AddMessageContext m] [MonadOptions m]
2935
(linterOption : Lean.Option Bool) (stx : Syntax) (msg : MessageData) : m Unit := do
30-
if linterOption.get (← getOptions) then logLint linterOption stx msg
36+
if getLinterValue linterOption (← getOptions) then logLint linterOption stx msg

Diff for: tests/lean/linterMissingDocs.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ structure Foo where
5353
{mk4 mk5 : Nat}
5454
[mk6 mk7 : Nat]
5555

56-
class Bar (α : Prop) := mk ::
56+
class Bar (α : Prop) where mk ::
5757
(foo bar := 1)
5858

5959
class Bar2 (α : Prop) where

Diff for: tests/lean/run/5236.lean

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/-!
2+
# Deprecate `:=` for `inductive` and `structure`
3+
-/
4+
5+
set_option linter.deprecated true
6+
7+
/--
8+
warning: 'inductive ... :=' has been deprecated in favor of 'inductive ... where'.
9+
note: this linter can be disabled with `set_option linter.deprecated false`
10+
-/
11+
#guard_msgs in
12+
inductive DogSound' :=
13+
| woof
14+
| grr
15+
16+
/--
17+
warning: structure ... :=' has been deprecated in favor of 'structure ... where'.
18+
note: this linter can be disabled with `set_option linter.deprecated false`
19+
-/
20+
#guard_msgs in
21+
structure S :=
22+
(n : Nat)
23+
24+
/--
25+
warning: class ... :=' has been deprecated in favor of 'class ... where'.
26+
note: this linter can be disabled with `set_option linter.deprecated false`
27+
-/
28+
#guard_msgs in
29+
class C :=
30+
(n : Nat)

0 commit comments

Comments
 (0)