Skip to content

Commit

Permalink
chore: remove unused deriving handler argument syntax
Browse files Browse the repository at this point in the history
As far as I can tell, the ability to pass a structure instance to a
deriving handler is not actually used in practice.

Do we want to remove this, or do we want to use and document it?
  • Loading branch information
david-christiansen committed Sep 5, 2024
1 parent a926d0c commit 18c2d27
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 20 deletions.
30 changes: 12 additions & 18 deletions src/Lean/Elab/Deriving/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ def processDefDeriving (className : Name) (declName : Name) : TermElabM Bool :=

end Term

def DerivingHandler := (typeNames : Array Name) → (args? : Option (TSyntax ``Parser.Term.structInst)) → CommandElabM Bool
def DerivingHandlerNoArgs := (typeNames : Array Name) → CommandElabM Bool
def DerivingHandler := (typeNames : Array Name) → CommandElabM Bool

builtin_initialize derivingHandlersRef : IO.Ref (NameMap (List DerivingHandler)) ← IO.mkRef {}

Expand All @@ -71,25 +70,21 @@ as well as the syntax of a `with` argument, if present.
For example, `deriving instance Foo with fooArgs for Bar, Baz` invokes
``fooHandler #[`Bar, `Baz] `(fooArgs)``. -/
def registerDerivingHandlerWithArgs (className : Name) (handler : DerivingHandler) : IO Unit := do
def registerDerivingHandler (className : Name) (handler : DerivingHandler) : IO Unit := do
unless (← initializing) do
throw (IO.userError "failed to register deriving handler, it can only be registered during initialization")
derivingHandlersRef.modify fun m => match m.find? className with
| some handlers => m.insert className (handler :: handlers)
| none => m.insert className [handler]

/-- Like `registerBuiltinDerivingHandlerWithArgs` but ignoring any `with` argument. -/
def registerDerivingHandler (className : Name) (handler : DerivingHandlerNoArgs) : IO Unit := do
registerDerivingHandlerWithArgs className fun typeNames _ => handler typeNames

def defaultHandler (className : Name) (typeNames : Array Name) : CommandElabM Unit := do
throwError "default handlers have not been implemented yet, class: '{className}' types: {typeNames}"

def applyDerivingHandlers (className : Name) (typeNames : Array Name) (args? : Option (TSyntax ``Parser.Term.structInst)) : CommandElabM Unit := do
def applyDerivingHandlers (className : Name) (typeNames : Array Name) : CommandElabM Unit := do
match (← derivingHandlersRef.get).find? className with
| some handlers =>
for handler in handlers do
if (← handler typeNames args?) then
if (← handler typeNames) then
return ()
defaultHandler className typeNames
| none => defaultHandler className typeNames
Expand All @@ -99,37 +94,36 @@ private def tryApplyDefHandler (className : Name) (declName : Name) : CommandEla
Term.processDefDeriving className declName

@[builtin_command_elab «deriving»] def elabDeriving : CommandElab
| `(deriving instance $[$classes $[with $argss?]?],* for $[$declNames],*) => do
| `(deriving instance $[$classes],* for $[$declNames],*) => do
let declNames ← liftCoreM <| declNames.mapM realizeGlobalConstNoOverloadWithInfo
for cls in classes, args? in argss? do
for cls in classes do
try
let className ← liftCoreM <| realizeGlobalConstNoOverloadWithInfo cls
withRef cls do
if declNames.size == 1 && args?.isNone then
if declNames.size == 1 then
if (← tryApplyDefHandler className declNames[0]!) then
return ()
applyDerivingHandlers className declNames args?
applyDerivingHandlers className declNames
catch ex =>
logException ex
| _ => throwUnsupportedSyntax

structure DerivingClassView where
ref : Syntax
className : Name
args? : Option (TSyntax ``Parser.Term.structInst)

def getOptDerivingClasses (optDeriving : Syntax) : CoreM (Array DerivingClassView) := do
match optDeriving with
| `(Parser.Command.optDeriving| deriving $[$classes $[with $argss?]?],*) =>
| `(Parser.Command.optDeriving| deriving $[$classes],*) =>
let mut ret := #[]
for cls in classes, args? in argss? do
for cls in classes do
let className ← realizeGlobalConstNoOverloadWithInfo cls
ret := ret.push { ref := cls, className := className, args? }
ret := ret.push { ref := cls, className := className }
return ret
| _ => return #[]

def DerivingClassView.applyHandlers (view : DerivingClassView) (declNames : Array Name) : CommandElabM Unit :=
withRef view.ref do applyDerivingHandlers view.className declNames view.args?
withRef view.ref do applyDerivingHandlers view.className declNames

builtin_initialize
registerTraceClass `Elab.Deriving
Expand Down
2 changes: 1 addition & 1 deletion src/Lean/Parser/Command.lean
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def «example» := leading_parser
def ctor := leading_parser
atomic (optional docComment >> "\n| ") >>
ppGroup (declModifiers true >> rawIdent >> optDeclSig)
def derivingClasses := sepBy1 (group (ident >> optional (" with " >> ppIndent Term.structInst))) ", "
def derivingClasses := sepBy1 ident ", "
def optDeriving := leading_parser
optional (ppLine >> atomic ("deriving " >> notSymbol "instance") >> derivingClasses)
def computedField := leading_parser
Expand Down
2 changes: 1 addition & 1 deletion stage0/src/stdlib_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ options get_default_options() {
// switch to `true` for ABI-breaking changes affecting meta code
opts = opts.update({"interpreter", "prefer_native"}, false);
// switch to `true` for changing built-in parsers used in quotations
opts = opts.update({"internal", "parseQuotWithCurrentStage"}, false);
opts = opts.update({"internal", "parseQuotWithCurrentStage"}, true);
// toggling `parseQuotWithCurrentStage` may also require toggling the following option if macros/syntax
// with custom precheck hooks were affected
opts = opts.update({"quotPrecheck"}, true);
Expand Down

0 comments on commit 18c2d27

Please sign in to comment.