diff --git a/src/Lean/Elab/Match.lean b/src/Lean/Elab/Match.lean index 75423a6085..feea07b271 100644 --- a/src/Lean/Elab/Match.lean +++ b/src/Lean/Elab/Match.lean @@ -709,9 +709,7 @@ where for indexFVarId in indicesFVar do if mctx.localDeclDependsOn localDecl indexFVarId then toAdd := toAdd.push fvarId - let lctx ← getLCtx - let indicesFVar := (indicesFVar ++ toAdd).qsort fun fvarId₁ fvarId₂ => - (lctx.get! fvarId₁).index < (lctx.get! fvarId₂).index + let indicesFVar ← sortFVarIds (indicesFVar ++ toAdd) return indicesFVar.map mkFVar ++ indicesNonFVar updateMatchType (indices : Array Expr) (matchType : Expr) : TermElabM Expr := do diff --git a/src/Lean/Elab/Tactic/BuiltinTactic.lean b/src/Lean/Elab/Tactic/BuiltinTactic.lean index 8cce19e4b6..7b2a3803a4 100644 --- a/src/Lean/Elab/Tactic/BuiltinTactic.lean +++ b/src/Lean/Elab/Tactic/BuiltinTactic.lean @@ -172,23 +172,12 @@ where replaceMainGoal [mvarId] | _ => throwUnsupportedSyntax -/- Sort free variables using an order `x < y` iff `x` was defined after `y` -/ -private def sortFVarIds (fvarIds : Array FVarId) : TacticM (Array FVarId) := - withMainContext do - let lctx ← getLCtx - return fvarIds.qsort fun fvarId₁ fvarId₂ => - match lctx.find? fvarId₁, lctx.find? fvarId₂ with - | some d₁, some d₂ => d₁.index > d₂.index - | some _, none => false - | none, some _ => true - | none, none => Name.quickLt fvarId₁.name fvarId₂.name - @[builtinTactic Lean.Parser.Tactic.clear] def evalClear : Tactic := fun stx => match stx with | `(tactic| clear $hs*) => do let fvarIds ← getFVarIds hs - let fvarIds ← sortFVarIds fvarIds - for fvarId in fvarIds do + let fvarIds ← withMainContext <| sortFVarIds fvarIds + for fvarId in fvarIds.reverse do withMainContext do let mvarId ← clear (← getMainGoal) fvarId replaceMainGoal [mvarId] diff --git a/src/Lean/Elab/Tactic/Induction.lean b/src/Lean/Elab/Tactic/Induction.lean index e8e431d50f..cc11747c9e 100644 --- a/src/Lean/Elab/Tactic/Induction.lean +++ b/src/Lean/Elab/Tactic/Induction.lean @@ -291,7 +291,7 @@ private def generalizeVars (mvarId : MVarId) (stx : Syntax) (targets : Array Exp if s.contains userFVarId then throwError "unnecessary 'generalizing' argument, variable '{mkFVar userFVarId}' is generalized automatically" s := s.insert userFVarId - let fvarIds ← sortFVars s + let fvarIds ← sortFVarIds s.toArray let (fvarIds, mvarId') ← Meta.revert mvarId fvarIds return (fvarIds.size, mvarId') diff --git a/src/Lean/Meta/Basic.lean b/src/Lean/Meta/Basic.lean index 32ac2c4698..c41eed377f 100644 --- a/src/Lean/Meta/Basic.lean +++ b/src/Lean/Meta/Basic.lean @@ -1125,6 +1125,18 @@ def mapErrorImp (x : MetaM α) (f : MessageData → MessageData) : MetaM α := d @[inline] def mapError [MonadControlT MetaM m] [Monad m] (x : m α) (f : MessageData → MessageData) : m α := controlAt MetaM fun runInBase => mapErrorImp (runInBase x) f +/-- + Sort free variables using an order `x < y` iff `x` was defined before `y`. + If a free variable is not in the local context, we use their id. -/ +def sortFVarIds (fvarIds : Array FVarId) : MetaM (Array FVarId) := do + let lctx ← getLCtx + return fvarIds.qsort fun fvarId₁ fvarId₂ => + match lctx.find? fvarId₁, lctx.find? fvarId₂ with + | some d₁, some d₂ => d₁.index < d₂.index + | some _, none => false + | none, some _ => true + | none, none => Name.quickLt fvarId₁.name fvarId₂.name + end Methods end Meta diff --git a/src/Lean/Meta/GeneralizeVars.lean b/src/Lean/Meta/GeneralizeVars.lean index 22091d3ce2..4ee1322c6c 100644 --- a/src/Lean/Meta/GeneralizeVars.lean +++ b/src/Lean/Meta/GeneralizeVars.lean @@ -65,14 +65,9 @@ def getFVarSetToGeneralize (targets : Array Expr) (forbidden : FVarIdSet) : Meta s := s.insert localDecl.fvarId return r -def sortFVars (fvars : FVarIdSet) : MetaM (Array FVarId) := do - let fvarIds := fvars.fold (init := #[]) fun s fvarId => s.push fvarId - let lctx ← getLCtx - return fvarIds.qsort fun x y => (lctx.get! x).index < (lctx.get! y).index - def getFVarsToGeneralize (targets : Array Expr) (forbidden : FVarIdSet := {}) : MetaM (Array FVarId) := do let forbidden ← mkGeneralizationForbiddenSet targets forbidden let s ← getFVarSetToGeneralize targets forbidden - sortFVars s + sortFVarIds s.toArray end Lean.Meta