lean4-htt/src/Lean/Data/NameMap/Basic.lean
Sebastian Ullrich 51bba5338a
perf: make macro scope numbering less dependent on surrounding context (#10027)
This PR changes macro scope numbering from per-module to per-command,
ensuring that unrelated changes to other commands do not affect macro
scopes generated by a command, which improves `prefer_native` hit rates
on bootstrapping as well as avoids further rebuilds under the module
system.

In detail, instead of always using the current module name as a macro
scope prefix, each command now introduces a new macro scope prefix
(called "context") of the shape `<main module>._hygCtx_<uniq>` where
`uniq` is a `UInt32` derived from the command but automatically
incremented in case of conflicts (which must be local to the current
module). In the current implementation, `uniq` is the hash of the
declaration name, if any, or else the hash of the full command's syntax.
Thus, it is always independent of syntactic changes to other commands
(except in case of hash conflicts, which should only happen in practice
for syntactically identical commands) and, in the case of declarations,
also independent of syntactic changes to any private parts of the
declaration.
2025-08-22 13:16:02 +00:00

121 lines
3.8 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2018 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
-/
module
prelude
public import Std.Data.HashSet.Basic
public import Std.Data.TreeSet.Basic
public import Lean.Data.SSet
public import Lean.Data.Name
public section
namespace Lean
@[expose] def NameMap (α : Type) := Std.TreeMap Name α Name.quickCmp
@[inline] def mkNameMap (α : Type) : NameMap α := Std.TreeMap.empty
namespace NameMap
variable {α : Type}
instance [Repr α] : Repr (NameMap α) := inferInstanceAs (Repr (Std.TreeMap _ _ _))
instance (α : Type) : EmptyCollection (NameMap α) := ⟨mkNameMap α⟩
instance (α : Type) : Inhabited (NameMap α) where
default := {}
def insert (m : NameMap α) (n : Name) (a : α) := Std.TreeMap.insert m n a
def contains (m : NameMap α) (n : Name) : Bool := Std.TreeMap.contains m n
def find? (m : NameMap α) (n : Name) : Option α := Std.TreeMap.get? m n
instance : ForIn m (NameMap α) (Name × α) :=
inferInstanceAs (ForIn _ (Std.TreeMap _ _ _) ..)
/-- `filter f m` returns the `NameMap` consisting of all
"`key`/`val`"-pairs in `m` where `f key val` returns `true`. -/
def filter (f : Name → α → Bool) (m : NameMap α) : NameMap α := Std.TreeMap.filter f m
end NameMap
@[expose] def NameSet := Std.TreeSet Name Name.quickCmp
namespace NameSet
def empty : NameSet := Std.TreeSet.empty
instance : EmptyCollection NameSet := ⟨empty⟩
instance : Inhabited NameSet := ⟨empty⟩
def insert (s : NameSet) (n : Name) : NameSet := Std.TreeSet.insert s n
def contains (s : NameSet) (n : Name) : Bool := Std.TreeSet.contains s n
instance : ForIn m NameSet Name :=
inferInstanceAs (ForIn _ (Std.TreeSet _ _) ..)
/-- The union of two `NameSet`s. -/
def append (s t : NameSet) : NameSet :=
s.merge t
instance : Append NameSet where
append := NameSet.append
instance : Singleton Name NameSet where
singleton := fun n => (∅ : NameSet).insert n
instance : Union NameSet where
union := NameSet.append
instance : Inter NameSet where
inter := fun s t => s.foldl (fun r n => if t.contains n then r.insert n else r) {}
instance : SDiff NameSet where
sdiff := fun s t => t.foldl (fun s n => s.erase n) s
/-- `filter f s` returns the `NameSet` consisting of all `x` in `s` where `f x` returns `true`. -/
def filter (f : Name → Bool) (s : NameSet) : NameSet := Std.TreeSet.filter f s
def ofList (l : List Name) : NameSet := Std.TreeSet.ofList l _
def ofArray (l : Array Name) : NameSet := Std.TreeSet.ofArray l _
end NameSet
@[expose] def NameSSet := SSet Name
namespace NameSSet
abbrev empty : NameSSet := SSet.empty
instance : EmptyCollection NameSSet := ⟨empty⟩
instance : Inhabited NameSSet := ⟨empty⟩
abbrev insert (s : NameSSet) (n : Name) : NameSSet := SSet.insert s n
abbrev contains (s : NameSSet) (n : Name) : Bool := SSet.contains s n
end NameSSet
@[expose] def NameHashSet := Std.HashSet Name
namespace NameHashSet
@[inline] def empty : NameHashSet := (∅ : Std.HashSet Name)
instance : EmptyCollection NameHashSet := ⟨empty⟩
instance : Inhabited NameHashSet := ⟨{}⟩
def insert (s : NameHashSet) (n : Name) := Std.HashSet.insert s n
def contains (s : NameHashSet) (n : Name) : Bool := Std.HashSet.contains s n
/-- `filter f s` returns the `NameHashSet` consisting of all `x` in `s` where `f x` returns `true`. -/
def filter (f : Name → Bool) (s : NameHashSet) : NameHashSet := Std.HashSet.filter f s
end NameHashSet
def MacroScopesView.isPrefixOf (v₁ v₂ : MacroScopesView) : Bool :=
v₁.name.isPrefixOf v₂.name &&
v₁.scopes == v₂.scopes &&
v₁.ctx == v₂.ctx &&
v₁.imported == v₂.imported
def MacroScopesView.isSuffixOf (v₁ v₂ : MacroScopesView) : Bool :=
v₁.name.isSuffixOf v₂.name &&
v₁.scopes == v₂.scopes &&
v₁.ctx == v₂.ctx &&
v₁.imported == v₂.imported
end Lean