Add typed trait requirements and enforce actual capability results

This commit is contained in:
2026-10-22 14:36:57 +08:00
parent e26e227dd0
commit 100bf637f9
16 changed files with 799 additions and 107 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
| 文档 | 内容 |
| --- | --- |
| [types.md](types.md) | 托管 Object/Type、名义继承、方法覆写方差/动态检查、声明字段/函数注解检查、构造与类型边生命周期 |
| [types.md](types.md) | 托管 Object/Type、名义继承、方法覆写/类型化Trait/动态检查、声明字段/函数注解检查、构造与类型边生命周期 |
| [objects.md](objects.md) | 对象、句柄与默认操作 |
| [native-calls.md](native-calls.md) | 原生上下文、读取分类、统一参数数量/类型/联合/效果、非递归委托返回、弱引用、托管赋值与变更批次 |
| [builtins.md](builtins.md) | Number、String、Dict、Cell、Function、异常数据 |
+2 -2
View File
@@ -76,7 +76,7 @@ take_changes 按对象与变更键合并同一批写入,返回最终版本。
`ObjectStore::call_arity(function)`/`Vm::call_arity(function)` 统一查询源码与原生函数。源码从真实形参和默认值计算区间;绑定方法沿实际函数扣除每层接收者,最大值不足时报错,最小值饱和到零。查询返回无托管引用的复制数据,不增加 GC 根。旧 positional_parameter_count 保留“源码总形参数量减绑定接收者”的兼容语义,不用于新的原生回调分派。通用 Type 构造器的参数组合由宿主决定,返回 None;NativeTyped 内部委托和宿主实际构造仍各自检查。
显式 Trait 声明、源码派生及方法表更新使用统一区间检查“规范参数数量加 self”是否被接受;缺少元数据的原生方法不能再登记为能力实现。可选参数允许实现接受规范调用数量之外的额外形式。更新仍先检查后代再修改,无隐藏类型根。类型注解兼容性、方差、参数名称及效果检查尚未接入此结构。
显式 Trait 声明、源码派生及方法表更新使用统一区间检查“规范参数数量加 self”是否被接受;缺少元数据的原生方法不能再登记为能力实现。可选参数允许实现接受规范调用数量之外的额外形式。更新仍先检查后代再修改,无隐藏类型根。旧 new_trait 保留数量规则;new_typed_trait 的参数/返回类型、方差及已知效果检查见类型主题,参数名称不构成调用契约。
Tessera 为原生方法、回调和内部视觉 continuation 发布数量元数据,事件监听要求接受零参数或一个 Event;两者都接受时优先传 Event。绑定计算和 Task 回调要求接受零参数,登记前拒绝无元数据/不兼容函数;普通旧原生调用的兼容性不等于允许其参加这些严格回调契约。
@@ -102,7 +102,7 @@ NativeResult::Invoke 仍是尾委托,不递归进入 Rust/VM。VM 为每层已
CallEffect::ReadOnly 声明只读现存对象,可分配临时结果;Mutating 与 External 在 ObjectStore 只读作用域内、进入实现前拒绝。普通执行允许这些效果。ReadOnly 声明不绕过已有写屏障,也不证明可信 Rust 不会进行隐藏 I/O;未知旧原生函数仍沿原调用/宿主检查,不能把 None 理解为纯函数。这不是静态效果推断、完整 I/O 沙箱或对阻塞原生代码的抢占。
Tessera 的 measure/arrange/paint/hitTest、Point 几何查询、Window、Block/Container/Page、Mount、Task、Event、Subscription 方法和 ObjectList.at 发布签名。Page.open 的 Window | Unit、Page.window 的 Window | Unit 返回,以及 Block.on 的 Bool | String 可选阶段有准确元数据;Mount 的父/子/同级/Page 弱查询为可空结果。Mount.bounds 现在返回带 Bounds 名义类型的现有几何记录,可直接组合到 Point.inside 或视觉方法。滚动位置/字典等通用记录仍声明 Object,不冒充新语言类型;任务 owner 的具体资源资格仍按原域检查。构造器和其他管理 API 的签名覆盖仍未全部接入。已接入的方法覆写方差与动态名称规则见类型主题。能力注册目前继续检查参数数量,不声称已经比较签名类型或效果。
Tessera 的 measure/arrange/paint/hitTest、Point 几何查询、Window、Block/Container/Page、Mount、Task、Event、Subscription 方法和 ObjectList.at 发布签名。Page.open 的 Window | Unit、Page.window 的 Window | Unit 返回,以及 Block.on 的 Bool | String 可选阶段有准确元数据;Mount 的父/子/同级/Page 弱查询为可空结果。Mount.bounds 现在返回带 Bounds 名义类型的现有几何记录,可直接组合到 Point.inside 或视觉方法。滚动位置/字典等通用记录仍声明 Object,不冒充新语言类型;任务 owner 的具体资源资格仍按原域检查。构造器和其他管理 API 的签名覆盖仍未全部接入。已接入的方法覆写方差与动态名称规则见类型主题。旧能力注册保留数量模式;类型化能力还检查类型/已知效果,并在实际返回和尾委托结果处保留能力返回约束。
回归源码 native_context.rs 覆盖参数副作用前拒绝、错误结果清理、跨原生/源码委托检查、单帧限制、名义签名边与绑定方法循环回收、只读效果拒绝、传统直接函数及重复参数和元数据错误。只编译,不本地执行。
+19 -2
View File
@@ -72,7 +72,7 @@ ObjectPayload 可选择实现 `attribute_target(store)`,把实例字段放在
implement_trait(Type, Trait)明确建立能力关系并校验必需方法。只有同名成员不算实现。implements_trait(Type, Trait)检查声明和继承;supports(instance, Trait)先查实际类型;未分类对象返回false,非法句柄或非定义参数报错。一个类型可显式实现多个能力,派生类继承关系。声明由Type的受管强边持有,查询和临时后代扫描不保活定义。
源码与原生方法通过统一 CallArity 验证是否接受规范数量加 self;无元数据的原生方法不能登记能力。数量区间包括源码默认参数与原生可选参数,详见[原生调用](native-calls.md#统一位置参数数量)。缺少方法、非可调用成员或参数数量错误以TraitViolation报告能力名、方法名和原因。本子集只验证数量接受性,不验证注解、关联类型、返回类型、效果或完整替换兼容性;没有默认实现和trait源码语法。
源码与原生方法通过统一 CallArity 验证是否接受规范数量加 self;无元数据的原生方法不能登记能力。数量区间包括源码默认参数与原生可选参数,详见[原生调用](native-calls.md#统一位置参数数量)。缺少方法、非可调用成员或参数数量错误以TraitViolation报告能力名、方法名和原因。旧 new_trait 只验证数量接受性;new_typed_trait 的类型契约见下文。关联类型、默认实现和 trait 源码语法尚未实现。
建立声明前检查已有后代;构造源码子类检查继承的所有能力。define_method更新前检查受影响后代的显式/继承契约,被后代自己的覆盖遮蔽的方法不受该祖先更新影响。失败保留原方法表和关系。内部扫描只枚举当前借用句柄,不引入全局强类型注册表。声明更新通过普通堆写屏障与trace进行,既有类型的只读作用域内变更会被拒绝。NativeContext也可使用同一implement_trait入口,仍受该屏障约束。
@@ -126,6 +126,23 @@ new_class 在发布之前校验本类覆写,失败释放候选定义。define_
未知前向注解在类建立和方法更新时暂缓,其他已知不兼容以 OverrideViolation 报类名、方法名和原因。启用 VM 类型检查时,源码和原生调用均在进入实现前检查实际接收者所属方法的当前替换契约;UnknownAnnotation 此时不能暂缓。普通函数的首参数恰好是对象,不会因此被视为方法。默认接收者也使用实际默认参数值参与复查。每次复查动态全局注解,所以 REPL 重绑定使旧覆写不兼容时,函数体执行前拒绝;恢复兼容绑定后可继续普通调用。不回滚先前已发生的其他输入副作用。
已知原生效果只允许缩小:ReadOnly 基类只能被 ReadOnly 原生覆写;Mutating 基类不允许 External 覆写;External 可接受三者。源码效果尚无静态元数据,不能声称已经证明其纯度;实际只读布局/绘制仍通过原有堆屏障与原生效果入口限制执行。未知旧基类类型签名仍是未证明的兼容边界,Trait 当前仍仅校验数量,尚未提供独立的类型/效果要求。
已知原生效果只允许缩小:ReadOnly 基类只能被 ReadOnly 原生覆写;Mutating 基类不允许 External 覆写;External 可接受三者。源码效果尚无静态元数据,不能声称已经证明其纯度;实际只读布局/绘制仍通过原有堆屏障与原生效果入口限制执行。未知旧基类类型签名仍是未证明的兼容边界,旧 new_trait 仍仅校验数量;new_typed_trait 提供独立类型与已知效果要求,见下文。
回归源码 core/tests/method_contracts.rs 覆盖合法参数扩大/返回缩小、错误参数/返回、祖先替换对已有覆写后代的原子拒绝、调用前动态重绑定拒绝和恢复、前向名称、原生联合与效果及根清理,仅编译,不在本地执行。
## 类型化 Trait
ObjectStore/Vm::new_typed_trait(name, Vec<TypedMethodRequirement>) 以每项 name 和 CallSignature 定义能力。保留旧 new_trait/MethodRequirement 的数量契约兼容性;两者都有名义身份和显式声明,不靠同名方法推断。类型化签名必须给出包含 self 的非零、有限、固定规范数量;实现仍可提供可选参数或更多调用形式。签名完整验证、重复/保留名字检查在分配前完成。EndorTraitObject::signature(name) 返回借用描述;所有名义/能力类型引用由 Trait 载荷 trace 追踪,定义不可变,没有隐藏全局强根。
显式 implement_trait 严格检查实际方法的参数逆变、返回协变、接收者和已知原生效果;失败不登记、不改变方法表/版本。所有已有后代也检查。继承的源码子类及方法更新使用同一规则,未知前向注解可暂缓,但显式登记/查询和实际调用不暂缓。旧无类型元数据的方法不能满足类型化要求。Trait 的 self 可声明 Object 或实际名义约束,实际接收者必须满足它;不会因为普通函数首参是对象而隐式声明能力。
对于实际接收者拥有类型化能力的方法,VM 在体前复查当前契约,并强制该源码方法自己的参数/返回注解,即使全局源码检查开关关闭。参数更宽的实现仍可以通过具体方法接受额外值;不会把实现收窄成 Trait 的规范参数集合,也不删除原生方便调用的省略参数形式。未携带相应能力的普通函数调用仍沿全局配置,不是对所有自由函数的静态类型系统。
除了实现自己的返回注解,所有匹配的类型化 Trait 返回约束也检查最终实际结果,覆盖源码/原生及尾委托链。执行帧/原生作用域保留这些定义的执行根,失败和预算清理均释放。方法体中修改其他类型的动态注解可能使返回对象的能力失效,不能仅依赖体前形式签名比较;最终 Capability 匹配会再次校验。错误返回不回滚已经发生的业务修改。
嵌套能力比较按线程/定义/能力保留临时验证集合,对已经在校验的同一名义能力关系按递归约束处理,避免无限递归;它不建立新声明关系。集合不持有 GC 根,RAII 在成功、错误和展开路径清理,不让失败验证成为后续成功缓存。没有长期签名缓存;动态名称每次仍从原环境解析。
源码效果仍未知,类型化 ReadOnly 要求不等于已经证明源码纯度。已知原生效果会比较,真正只读布局/绘制继续执行堆屏障;普通输入中源码副作用仍按现有运行模式处理。没有泛型/关联类型/效果推断或 Trait 源码声明语法。Tessera 的四个宿主能力使用类型化要求,其中 Presentable 允许普通展示构造副作用,不额外宣称纯函数。
core/tests/typed_traits.rs 覆盖登记失败原子性、参数扩大仍可直接调用、全局检查关闭时的显式能力实际参数/返回检查、签名类型保活/回收,以及体内动态改变返回对象能力后的最终拒绝和验证集合恢复,仅编译未本地执行。