尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Carbon 语言名称查找设计解析:作用域、未限定名称解析、名称污染与遮蔽规则
Carbon 语言名称查找设计解析作用域、未限定名称解析、名称污染与遮蔽规则【免费下载链接】carbon-langCarbon Languages main repository: documents, design, implementation, and related tools. (NOTE: Carbon Language is experimental; see README)项目地址: https://gitcode.com/GitHub_Trending/ca/carbon-lang导读本文聚焦 Carbon Language实验性编程语言的名称查找name lookup设计系统讲解名称如何被引入作用域、未限定名称unqualified name的解析路径、声明性作用域中名称污染poisoning机制以及Core包与 prelude 对常见标准类型名称的支撑。文章以 docs/design/name_lookup.md 为骨架结合 toolchain/check/name_lookup.cpp 等源码实现与 toolchain/check/testdata 下的测试用例帮助读者理解 Carbon 如何在不引入上下文敏感歧义的前提下为编译器、IDE 和开发者提供可预测的名称解析语义。概述名称始终属于某个作用域在 Carbon 中名称总是被引入到某个作用域scope中作用域决定了该名称可以被引用的范围。许多作用域本身是有名字的类型是有名字的名称作用域可以直接用namespace声明。关于包package、库library、命名空间namespace的组织方式可参考 代码与名称组织文档。名称查找正是这一组织体系在编译器语义层面的落地点它决定了写下一个名字时这个名字到底解析到哪个实体。值得注意的是Carbon 明确不提供 C 的using namespace或通配符导入式的名称合并机制也不支持在namespace声明块内放置大段代码——因为这些机制会让名称来源变得模糊、增加上下文敏感性。这一设计取向记录在 低上下文敏感性原则 中也是理解下文名称查找规则的一把钥匙。未限定名称查找Unqualified name lookup未限定名称查找是名称解析的核心路径它从当前作用域开始逐层向外搜索包围作用域enclosing scopes直到文件顶层作用域为止。参与查找的名称来源分为三类。1. 本地声明的名称声明必须出现在引用之前当前作用域或任何包围作用域中本地声明的名称都会参与查找但有一个硬性约束声明必须位于引用之前。也就是说Carbon 不采用先使用、后声明的顺序自由语义文件中的名称引用只能解析到它之前已经引入的名称。这一规则的一个推论体现在限定声明out-of-line declaration/definition中。当一个声明或定义带有作用域限定符如fn Foo.Bar(...)时限定符所指定的作用域Foo与Foo.Bar会作为该声明的签名与函数体中未限定名称查找的包围作用域。这一规则同时适用于命名空间、类和接口。在测试 toolchain/check/testdata/namespace/unqualified_lookup.carbon 中可以看到典型的应用namespace OuterN; namespace OuterN.InnerN; fn A(); fn OuterN.B(); fn OuterN.InnerN.C(); fn CallA() { A(); // 在顶层文件作用域找到 A } fn OuterN.CallAB() { A(); // 通过文件作用域找到 A B(); // 通过限定符 OuterN 找到 B } fn OuterN.InnerN.CallABC() { A(); // 通过文件作用域找到 A B(); // 通过限定符 OuterN 找到 B C(); // 通过限定符 OuterN.InnerN 找到 C }从该测试的 SemIR 输出可以看到编译器为每个函数体内的name_ref记录了其解析目标如name_ref A, file.%A.decl证明查找结果在语义检查阶段就被确定下来。2. 导入的名称包内导入与 impl 文件对 API 的隐式导入来自当前包、通过导入变得可见的名称同样参与未限定查找典型形式是import library ...;其中有一个容易被忽略的隐式机制实现文件impl file会隐式导入其所属库的 API 文件。因此impl文件中即使不写import library语句也能直接引用 API 文件中声明的名称。这一点在 代码与名称组织文档 中有明确描述实现文件隐式导入库的 API但不能互相导入。3. prelude标准库基础能力的隐式注入第三类来源是隐式prelude——对标准库基础内容的一组导入与别名。Carbon 会在每个文件中隐式注入 prelude使核心类型与接口无需显式导入即可使用详见下文常见标准类型的名称查找一节。关键约束包名不会注入文件作用域一个容易踩坑的设计是包的名字不会被注入到其所属文件的作用域中。也就是说在package Geometry;声明的文件中你不能直接写Geometry.Circle来引用同包实体的限定名同包内的导入语句也不带包名前缀例如import library Shapes;而非import Geometry library Shapes;。来自其他包的符号则必须通过导入引入并经由该包的命名空间访问例如Math.Trigonometry.Sin(...)。这条规则保证了一个文件读到某个名字时它的来源是有限的、可预测的。声明性作用域中的名称污染poisoning声明性作用域declarative scopes包括命名空间、类和接口。在这些作用域内存在一个非常独特的机制——名称污染poisoning如果在某个声明性作用域中对一个名称执行未限定查找且查找失败则该名称在该作用域中被视为被污染poisoned。之后若再有人试图在该作用域中声明这个名称就是错误因为这会改变此前查找结果的含义。污染的跨文件传播规则是在同一个库内污染会从 API 文件持续到实现文件。也就是说API 文件中某作用域内一次失败的查找会让实现文件中的同名声明同样报错。在 toolchain/check/name_lookup.h 中LookupNameInExactScope的注释明确描述了这一实现语义如果is_being_declared为 false这是普通名称查找若未找到该名称则将其污染poisoned后续查找会把它当作未声明处理否则这是对被声明名称的查找名称不会被污染但如果它已被查找过则返回污染状态。与之对应的诊断接口包括DiagnosePoisonedName与DiagnoseDuplicateName分别产生NameUseBeforeDeclname used before it was declared与NameDeclDuplicateduplicate name being declared in the same scope错误。测试文件 toolchain/check/testdata/namespace/name_poisoning.carbon 给出了完整的正面与负面用例。以fail_use_poison.carbon为例namespace N1; // 使用 package.N1并使 N2.N1 被污染。 namespace N2; alias N2.N3 N1; // 错误成员名 N1 在 N2 中未找到 [MemberNameNotFoundInInstScope] alias N2.N4 N2.N1;而fail_declare_after_poison.carbon展示了污染后声明的错误形态namespace N2; // 错误名称 N1 在使用之前被声明 [NameUseBeforeDecl] alias N2.N3 N1; // note: 在此处声明 [NameUseBeforeDeclNote] namespace N2.N1;fail_poison_multiple_scopes.carbon则展示了污染的多层传播一次失败的查找会同时污染沿途所有声明性作用域中的同名名称例如N2.N1、N2.N3.N1、N2.N3.N4.N1全部被污染。同类测试也存在于类作用域见 toolchain/check/testdata/class/name_poisoning.carbon涵盖类嵌套、数据成员、extend base等场景。值得注意的是测试中还标注了两个已知的 TODO#4622impl文件中在 API 文件已污染的名称上再声明当前尚不会报错见 toolchain/check/testdata/class/name_poisoning.carbon 中poison.impl.carbon用例——这属于当前实现与设计目标之间的已知差距阅读测试数据时需要注意区分。顺序性作用域中的禁止重声明与声明性作用域相对的是顺序性作用域sequential scopes典型代表是函数体。在顺序性作用域中不允许重声明实体——同一个名字在函数体内只能引入一次。这一约束避免了函数体内名称含义随位置漂移带来的阅读与维护成本。常见标准类型的名称查找Core 包与 preludeCarbon 的标准库位于Core包中而Core包的一个子集被称为prelude它会被隐式导入到每个文件中因此Core这个包名在任何文件中始终可用。prelude 的实际构成可以在源码中直接确认core/prelude.carbon 声明了package Core library prelude; export import library prelude/copy; export import library prelude/default; export import library prelude/destroy; export import library prelude/iterate; export import library prelude/operators; export import library prelude/range; export import library prelude/types;也就是说prelude 通过export import聚合了拷贝、默认构造、销毁、迭代、运算符、区间与类型等基础库。基于 preludeCarbon 实现了两类看起来像内建语法的机制关键字与类型字面量bool、i32等是 prelude 中实体的别名。例如在 toolchain/check/name_lookup.cpp 中LookupNameInCore与GetCorePackage提供了对Core包内名称如通过CoreIdentifier枚举指定的内建标识符的结构化查找如果Core包缺失则会报出 packageCorenot found 错误测试用例见 toolchain/check/testdata/packages/missing_prelude.carbon。语言语法糖部分语法如运算符与for循环被定义为 prelude 中接口的实现。这意味着a b、for (x in range)这类写法的语义最终都会落到 prelude 中定义/约束的接口上而不是编译器内部特设的魔法。对编译器实现者而言Core包的查找路径是先判断当前包的名称作用域是否为Core包本身否则在包作用域中精确查找Core名称LookupNameInExactScopeSemIR::NameId::Core再逐级沿限定符深入。相关入口见 toolchain/check/name_lookup.cpp 的LookupNameInCore实现。未决问题名称遮蔽Shadowing名称查找设计中最主要的未决问题之一是名称遮蔽规则。相关讨论集中在提案 p003763-matching-redeclarations.md 的 Use package-wide name poisoning 一节其中提出了一条正在考虑中的规则始终在所有包围作用域中查找如果未限定名称在多个包围作用域中被找到则诊断为歧义。也就是说候选方案之一是禁止内层作用域的名称遮蔽外层同名名称——内层声明不隐藏外层声明一旦出现多个匹配就报错。这与 低上下文敏感性原则中的名称遮蔽讨论 保持一致该原则主张限制名称在不同作用域间的复用方式避免名字的含义在作用域之间意外变化也避免读者找到一处匹配声明后还要继续搜索是否存在隐藏它的另一个声明。该提案同时权衡了不同遮蔽规则对包级名称污染package-wide name poisoning的影响若采用更严格的遮蔽规则内层不遮蔽外层则包级污染的影响面很大一个库中函数内的局部变量名将不能作为任何库中任何包围命名空间的公开名称使用若采用更宽松的规则包级污染则更容易被接受值得重新评估无论采用哪种规则对私有名称private names都可能需要特殊处理一个库中导致名称被污染的使用不应与另一个库中的私有声明冲突因为两者无法相互作用。需要注意的是这些仍是未决设计方向当前仓库的编译器实现尚未敲定最终的遮蔽规则——从实现角度看toolchain/check/name_lookup.cpp 的LookupUnqualifiedName中保留着// TODO: Check for shadowed lookup results.的注释说明遮蔽查找结果的检查仍是待办事项。实现要点速览关注点源码/测试位置说明未限定查找入口toolchain/check/name_lookup.cppLookupUnqualifiedName先查词法作用域链再遍历非词法作用域命名空间、类等精确作用域查找与污染toolchain/check/name_lookup.cppLookupNameInExactScopeLookupOrPoison实现未找到即污染限定名查找含 extend 作用域toolchain/check/name_lookup.cppLookupQualifiedName沿当前作用域及其 extended scopes 逐层搜索重复命中报歧义Core包查找toolchain/check/name_lookup.cppLookupNameInCore/GetCorePackage污染语义测试命名空间toolchain/check/testdata/namespace/name_poisoning.carbon覆盖声明后污染、使用污染名、多层污染、导入场景污染语义测试类toolchain/check/testdata/class/name_poisoning.carbon覆盖嵌套类、数据成员、extend base等场景未限定查找测试toolchain/check/testdata/namespace/unqualified_lookup.carbon验证限定声明中限定词作用域参与未限定查找prelude 构成core/prelude.carbonexport import聚合 7 个 prelude 子库需要说明Carbon Language 目前仍处于实验阶段上述名称查找规则、污染机制与遮蔽讨论会随提案演进而变化本文描述以当前仓库中的设计文档与实现代码为准。【免费下载链接】carbon-langCarbon Languages main repository: documents, design, implementation, and related tools. (NOTE: Carbon Language is experimental; see README)项目地址: https://gitcode.com/GitHub_Trending/ca/carbon-lang创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

11 个数学可视化与计算工具如何选?awesome-math 免费资源完整指南

11 个数学可视化与计算工具如何选?awesome-math 免费资源完整指南

11 个数学可视化与计算工具如何选?awesome-math 免费资源完整指南 【免费下载链接】awesome-math A curated list of awesome mathematics resources 项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-math 学数学最怕"符号堆出来的抽象"…

📅 2026/9/10 6:54:31
CVAT标注平台快速上手:如何用3条命令启动自己的计算机视觉标注服务

CVAT标注平台快速上手:如何用3条命令启动自己的计算机视觉标注服务

CVAT标注平台快速上手:如何用3条命令启动自己的计算机视觉标注服务 【免费下载链接】cvat Computer Vision Annotation Tool (CVAT) is a leading platform for building high-quality visual datasets for vision AI. It offers open-source, cloud, and enterpris…

📅 2026/9/10 6:54:31
CANN/GE LLM数据分发缓存配置

CANN/GE LLM数据分发缓存配置

TransferWithCacheKeyConfig 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch…

📅 2026/9/10 6:54:30
MORE NEWS

更多资讯

📰

随身WiFi避坑指南:原理、场景、硬件参数与套餐全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Arduino ESP32 安装完整指南:从进度条卡死到第一次点亮 Blink 一次走通

Arduino ESP32 安装完整指南:从进度条卡死到第一次点亮 Blink 一次走通 【免费下载链接】arduino-esp32 Arduino core for the ESP32 family of SoCs 项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32 运行 Arduino ESP32 安装时&#xff0c…

📰

ComputeShader实战指南:GPU粒子更新、线程模型与Buffer绑定避坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

微信小程序原创音乐管理系统:全栈开发与论文实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Vitest 完整指南:让 Vite 驱动的前端测试快 10 倍

Vitest 完整指南:让 Vite 驱动的前端测试快 10 倍 【免费下载链接】vitest Next generation testing framework powered by Vite. 项目地址: https://gitcode.com/GitHub_Trending/vi/vitest 你有没有这种经历:本地改一行代码,测试框架…

📰

YOLOv5s口罩检测毕设闭环系统:从训练到Docker部署

简介:本资源是一套完整的YOLOv5口罩佩戴检测实战项目,面向计算机、人工智能及相关专业本科生毕业设计、课程设计与深度学习初学者,解决公共场所人员口罩佩戴状态自动识别这一典型目标检测应用场景。压缩包共149个文件,含40个Pytho…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬