Skip to content

compiler: complete the pub library boundary - #211

Merged
dslsdzc merged 1 commit into
developfrom
pub-complete
Oct 26, 2026
Merged

dslsdzc merged 1 commit into
developfrom
pub-complete

Conversation

@dslsdzc

@dslsdzc dslsdzc commented Oct 26, 2026

Copy link
Copy Markdown
Owner

概要

把 pub 从“函数级过滤”补成完整的库边界,不再依赖 g_lib_on 开关或绕过路径。

1. 可见性始终生效

  • 退役 g_lib_on / lib_prepare_from_pub / g_saw_pub:普通用户程序(没有 pub)也执行库可见性过滤。
  • 同库声明可见;跨库只认目标库的导出表(lib_export_find_kind),非 pub 静默不可见。

2. 类型 / 方法 / 全局

  • 函数 / extern / 方法:现有函数尾标签 , pub;方法表命中后用未过滤查找取真实 owner,跨库且不在导出表 → N08 Undefined method。
  • 类型:struct / enum / type 声明携带真实声明行;跨库非 pub 类型 → N01 Undefined type。公开类型可用 pub struct / pub enum(bootstrap 兼容)或尾部 , pub。
  • 全局:顶层 , pub 标签写入导出表;非 pub 全局 → N01。
  • stdlib 的公开类型(Bits32、IntMap、CliCmd、CliFlag、MemLayout)、公开方法、公开常量都已标记 pub。

3. LSP 同源

  • analysis_completion 以文档所属库(@user)为上下文,候选经过 sym_visible / func_visible 过滤。
  • 新增 test_lsp_visibility.py:import hashmap 后补全必须出现 IntMap.put/get/...,且不得出现 IntMap.findKey/findSlot/grow。

4. 库归属修正

  • src/runtime/arena_globals.cr 的三个全局移入 src/stdlib/arena.cr:它们是 arena 库的共享状态,不是 @core 与 @std 之间的公共面。
  • rt.cr / arena.cr 删除 import arena_globals;build 清单同步移除。
  • 项目目录操作数(src/compiler 无尾斜杠)正确映射到库根,corec check src/compiler 不再误判 @user。
  • 导出集每次编译重置,长驻 LSP 不会累积旧 pub 声明。

5. 文档

  • docs/developer/syntax.md / docs/maintainer/design/frontend-semantics.md 改为“顶层默认库内部,pub 跨库导出”。

判据

  • tests/selfhost/test_pub_visibility.py 扩展:
    • Bits32 / BITS32_MASK / IntMap.put 公开可用;
    • Argv4 非 pub 类型 → N01;
    • IntMap.findKey 非 pub 方法 → N08;
    • g_current_arena 非 pub 全局 → N01;
    • 用户同名的 struct Argv4 仍可用。
  • tests/selfhost/test_lsp_visibility.py:补全白名单/黑名单。
  • selfhost-tests / bootstrap-tests / check 全绿。
  • canary D1 5/5,值已按内容面变化重锁:
    • static .ccr −17B:STR 段少 arena_globals(4B 长度 + 13B 字符);
    • canary ELF −4096B:static BSS 跨页边界,少一页对齐;
    • 非 static 两条 .ccr 逐字节不变。

不做

  • 不恢复 g_lib_on 或“只在有 pub 时过滤”的旧路径。
  • 不给内部 stdlib 符号补 pub 来让旧测试通过:test_diag_gate 的 chan_test 改由 arena 全局归 stdlib 解决。

- Visibility is always enforced (g_lib_on retired): same-library
  declarations are visible, cross-library ones only through the target
  library export table.
- Types, methods and globals join functions: type symbols carry their
  declaration line, method lookup checks the raw function owner, globals
  resolve through the export table. Non-pub declarations fail closed with
  N01/N06/N08.
- pub syntax: function/global tail `, pub`; type `pub struct`/`pub enum`
  (or tail `, pub`). stdlib public types, methods and globals are tagged.
- LSP completion runs with the document library and filters through
  sym_visible/func_visible; test_lsp_visibility pins pub members and
  hides internals.
- Move arena_globals into stdlib/arena.cr: those three globals were
  runtime-shared state leaking across the @core/@std boundary.
- Export sets reset per compilation so long-lived LSP sessions do not
  accumulate stale pub declarations.
- Performance: cache the owning library per source line, keep export
  sets sorted with binary-search lookup, and store owner/pub directly in
  symbol rows. check src/compiler is back to ~20s (from ~40s with the
  naive per-symbol path scan); selfhost-tests is ~3m50s.
- Docs updated; canary relocked with attribution (static STR -17B,
  BSS page -4096B).
@dslsdzc
dslsdzc merged commit 618c178 into develop Oct 26, 2026
4 checks passed
@dslsdzc
dslsdzc deleted the pub-complete branch October 26, 2026 19:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant