@@ -30,7 +30,7 @@ namespace Structure
3030
3131/-! Recall that the `structure command syntax is
3232```
33- leading_parser (structureTk <|> classTk) >> declId >> many Term.bracketedBinder >> Term.optType >> optional «extends» >> optional (" := " >> optional structCtor >> structFields)
33+ leading_parser (structureTk <|> classTk) >> declId >> optDeclSig >> optional «extends» >> optional (" := " >> optional structCtor >> structFields)
3434```
3535-/
3636
@@ -206,10 +206,10 @@ private def expandCtor (structStx : Syntax) (structModifiers : Modifiers) (struc
206206 let ref := structStx[1 ].mkSynthetic
207207 addDeclarationRangesFromSyntax declName ref
208208 pure { ref, declId := ref, modifiers := default, declName }
209- if structStx[5 ].isNone then
209+ if structStx[4 ].isNone then
210210 useDefault
211211 else
212- let optCtor := structStx[5 ][1 ]
212+ let optCtor := structStx[4 ][1 ]
213213 if optCtor.isNone then
214214 useDefault
215215 else
@@ -278,12 +278,12 @@ def structFields := leading_parser many (structExplicitBinder <|> struct
278278```
279279-/
280280private def expandFields (structStx : Syntax) (structModifiers : Modifiers) (structDeclName : Name) : TermElabM (Array StructFieldView) := do
281- if structStx[5 ][0 ].isToken ":=" then
281+ if structStx[4 ][0 ].isToken ":=" then
282282 -- https://github.com/leanprover/lean4/issues/5236
283283 let cmd := if structStx[0 ].getKind == ``Parser.Command.classTk then "class" else "structure"
284- withRef structStx[0 ] <| Linter.logLintIf Linter.linter.deprecated structStx[5 ][0 ]
284+ withRef structStx[0 ] <| Linter.logLintIf Linter.linter.deprecated structStx[4 ][0 ]
285285 s! "{ cmd} ... :=' has been deprecated in favor of '{ cmd} ... where'."
286- let fieldBinders := if structStx[5 ].isNone then #[] else structStx[5 ][2 ][0 ].getArgs
286+ let fieldBinders := if structStx[4 ].isNone then #[] else structStx[4 ][2 ][0 ].getArgs
287287 fieldBinders.foldlM (init := #[]) fun (views : Array StructFieldView) fieldBinder => withRef fieldBinder do
288288 let mut fieldBinder := fieldBinder
289289 if fieldBinder.getKind == ``Parser.Command.structSimpleBinder then
@@ -342,43 +342,45 @@ private def expandFields (structStx : Syntax) (structModifiers : Modifiers) (str
342342 }
343343
344344/-
345- leading_parser (structureTk <|> classTk) >> declId >> many Term.bracketedBinder >> Term.optType >> optional «extends» >>
345+ leading_parser (structureTk <|> classTk) >> declId >> optDeclSig >> optional «extends» >>
346346 optional (("where" <|> ":=") >> optional structCtor >> structFields) >> optDeriving
347347
348348where
349349def structParent := leading_parser optional (atomic (ident >> " : ")) >> termParser
350- def «extends» := leading_parser " extends " >> sepBy1 structParent ", "
351- def typeSpec := leading_parser " : " >> termParser
352- def optType : Parser := optional typeSpec
350+ def «extends» := leading_parser " extends " >> sepBy1 structParent ", " >> optType
353351
354352def structFields := leading_parser many (structExplicitBinder <|> structImplicitBinder <|> structInstBinder)
355353def structCtor := leading_parser try (declModifiers >> ident >> " :: ")
356354-/
357355def structureSyntaxToView (modifiers : Modifiers) (stx : Syntax) : TermElabM StructView := do
356+ let stx := -- for bootstrap compatibility, remove this after stage0 update
357+ if stx.getNumArgs == 7
358+ then stx.setArgs #[stx[0 ], stx[1 ], .node .none ``Parser.Command.optDeclSig #[stx[2 ], stx[3 ]], stx[4 ], stx[5 ], stx[6 ]]
359+ else stx
358360 checkValidInductiveModifier modifiers
359361 let isClass := stx[0 ].getKind == ``Parser.Command.classTk
360362 let modifiers := if isClass then modifiers.addAttr { name := `class } else modifiers
361363 let declId := stx[1 ]
362364 let ⟨name, declName, levelNames⟩ ← Term.expandDeclId (← getCurrNamespace) (← Term.getLevelNames) declId modifiers
363365 addDeclarationRangesForBuiltin declName modifiers.stx stx
364- let binders := stx[2 ]
365- let (optType, exts) ←
366+ let (binders, type?) := expandOptDeclSig stx[2 ]
367+ let exts := stx[3 ]
368+ let type? ←
366369 -- Compatibility mode for `structure S extends P : Type` syntax
367- if stx[ 3 ] .isNone && !stx[ 4 ] .isNone && !stx[ 4 ] [0 ][2 ].isNone then
368- logWarningAt stx[ 4 ] [0 ][2 ][0 ] "\
370+ if type? .isNone && !exts .isNone && !exts [0 ][2 ].isNone then
371+ logWarningAt exts [0 ][2 ][0 ] "\
369372 The syntax is now 'structure S : Type extends P' rather than 'structure S extends P : Type'.\n\n \
370373 The purpose of this change is to accommodate 'structure S extends toP : P' syntax for naming parent projections."
371- pure (stx[ 4 ][ 0 ][2 ], stx[ 4 ])
374+ pure (some exts[ 0 ][2 ][ 0 ][ 1 ])
372375 else
373- if !stx[ 4 ] .isNone && !stx[ 4 ] [0 ][2 ].isNone then
374- logErrorAt stx[ 4 ] [0 ][2 ][0 ] "\
376+ if !exts .isNone && !exts [0 ][2 ].isNone then
377+ logErrorAt exts [0 ][2 ][0 ] "\
375378 Unexpected additional resulting type. \
376379 The syntax is now 'structure S : Type extends P' rather than 'structure S extends P : Type'.\n\n \
377380 The purpose of this change is to accommodate 'structure S extends toP : P' syntax for naming parent projections."
378- pure (stx[3 ], stx[4 ])
379- let parents ← expandParents exts
380- let derivingClasses ← getOptDerivingClasses stx[6 ]
381- let type? := if optType.isNone then none else some optType[0 ][1 ]
381+ pure type?
382+ let parents ← expandParents exts
383+ let derivingClasses ← getOptDerivingClasses stx[5 ]
382384 let ctor ← expandCtor stx modifiers declName
383385 let fields ← expandFields stx modifiers declName
384386 fields.forM fun field => do
0 commit comments