From e5da8055e0f84d281e3efb8e192e6de8b82a1514 Mon Sep 17 00:00:00 2001 From: Codex Bot Date: Sun, 15 Nov 2026 17:40:20 +0800 Subject: [PATCH] docs(objects): explain capability conformance and annotation resolution --- crates/objects/src/types.rs | 127 +++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 2 deletions(-) diff --git a/crates/objects/src/types.rs b/crates/objects/src/types.rs index be52c28..cbd58e0 100644 --- a/crates/objects/src/types.rs +++ b/crates/objects/src/types.rs @@ -975,16 +975,22 @@ impl ObjectStore { }) } + /// 类型附着、字段/方法更新和能力查询共用:沿父链收集去重的借用能力身份。 fn inherited_traits(&self, definition: ObjectRef) -> Result, VmError> { + // 去重能力身份,不建立堆外拥有注册表或延长能力寿命。 let mut found = std::collections::BTreeSet::new(); + // 从类型自身开始,继承能力和本层能力一起核对。 let mut current = Some(definition); + // 沿固定基类链逐层读取,不按名称猜测类型。 while let Some(definition) = current { + // 验证类型载荷后才读取其基类或能力列表。 let definition = self.payload::(definition, "Type")?; found.extend(definition.traits.iter().copied()); current = definition.base; } Ok(found.into_iter().collect()) } + /// 能力验证单项方法存在及数量,完整签名存在时再调用 contracts 的替换检查。 fn validate_requirement( &self, capability: ObjectRef, @@ -993,6 +999,7 @@ impl ObjectStore { definition: ObjectRef, defer_unknown: bool, ) -> Result<(), VmError> { + // 构造带能力名/方法名的错误,调用方不需要解析诊断文本定位失败。 let invalid = |reason| VmError::TraitViolation { capability: self .payload::(capability, "Trait") @@ -1002,15 +1009,19 @@ impl ObjectStore { method: requirement.name.clone(), reason, }; + // 能力要求的方法必须实际存在,不能以缺少元数据替代。 let function = function.ok_or_else(|| invalid("required method is missing"))?; + // 查询函数可见数量约束;缺失原生数量元数据不能证明满足能力。 let arity = self .call_arity(function)? .ok_or_else(|| invalid("required member has no positional signature"))?; + // 能力最小数量不含 self,校验时加一个显式接收者。 if !arity.accepts(requirement.parameters + 1) { return Err(invalid( "positional parameter count does not match (including self)", )); } + // 完整签名存在时还要验证参数/返回/效果,不只检查数量。 if let Some(expected) = self .payload::(capability, "Trait")? .signatures @@ -1027,14 +1038,18 @@ impl ObjectStore { } Ok(()) } + /// 能力声明/查询检查全部要求,递归定义通过 with_trait_check 防止无限重入。 fn validate_trait( &self, definition: ObjectRef, capability: ObjectRef, defer_unknown: bool, ) -> Result<(), VmError> { + // 递归检查对按定义/能力区分,回调结束后 RAII 清理标记。 self.with_trait_check(definition, capability, || { + // 能力载荷先验证,再借用名称/完整签名/最小要求。 let contract = self.payload::(capability, "Trait")?; + // 遍历能力全部要求,任一失败阻止声明/更新。 for requirement in &contract.requirements { self.validate_requirement( capability, @@ -1047,7 +1062,9 @@ impl ObjectStore { Ok(()) }) } + /// 源码类创建后检查所有继承能力,允许暂缓尚未解析的源码注解。 fn validate_inherited_traits(&self, definition: ObjectRef) -> Result<(), VmError> { + // 全部继承能力都参与,不以首个成功项短路。 for capability in self.inherited_traits(definition)? { self.validate_trait(definition, capability, true)?; } @@ -1055,9 +1072,12 @@ impl ObjectStore { } // Enumerate borrowed heap handles only while validating a definition update; // no global type registry or owning descendant index is introduced. + /// 方法/能力更新前扫描存活类型,返回包含 base 自身的全部子类型借用身份。 fn descendant_types(&self, base: ObjectRef) -> Result, VmError> { self.payload::(base, "Type")?; + // 去重能力身份,不建立堆外拥有注册表或延长能力寿命。 let mut found = vec![]; + // 扫描当前存活对象;只选类型载荷及其名义子类型。 for reference in self.heap.live_references() { if self .object(reference)? @@ -1071,34 +1091,46 @@ impl ObjectStore { } Ok(found) } + /// define_method 提交前只检查真实会受该父方法变化影响的后代能力要求。 fn validate_method_update( &self, changed: ObjectRef, name: &str, function: ObjectRef, ) -> Result<(), VmError> { + // 父定义变更必须考虑现有后代,不能只核对当前类型。 for descendant in self.descendant_types(changed)? { + // 从后代向父层寻找当前方法的实际来源。 let mut current = Some(descendant); + // 记录是否在遇到更近覆盖前到达 changed。 let mut affected = false; + // 沿固定基类链逐层读取,不按名称猜测类型。 while let Some(definition) = current { + // 查找会使用此次变更的方法,该后代属于影响范围。 if definition == changed { affected = true; break; } + // 验证类型载荷后才读取其基类或能力列表。 let definition = self.payload::(definition, "Type")?; + // 更近后代已覆盖同名方法,父层更新不会改变该后代查找结果。 if definition.methods.contains_key(name) { break; } current = definition.base; } + // 未受查找影响的后代跳过能力重验。 if !affected { continue; } + // 全部继承能力都参与,不以首个成功项短路。 for capability in self.inherited_traits(descendant)? { + // 遍历能力全部要求,任一失败阻止声明/更新。 for requirement in &self .payload::(capability, "Trait")? .requirements { + // 只校验当前被替换方法对应要求,其他方法表项没有变化。 if requirement.name == name { self.validate_requirement( capability, @@ -1113,23 +1145,27 @@ impl ObjectStore { } Ok(()) } + /// 宿主/VM 显式声明能力;先验证后代和已有实例,再提交定义强边。 pub fn implement_trait( &mut self, definition: ObjectRef, capability: ObjectRef, ) -> Result<(), VmError> { self.payload::(capability, "Trait")?; + // 父定义变更必须考虑现有后代,不能只核对当前类型。 for descendant in self.descendant_types(definition)? { self.validate_trait(descendant, capability, false)?; } - // Existing objects must satisfy the same storage invariant as new writes. - // Borrowed heap enumeration adds no owning instance registry. + // 已有实例也必须满足新写入的存储约束;堆枚举只借用,不延长实例寿命。 + // 类型化能力才需要扫描实例存储,最小数量能力没有遮蔽签名要求。 if !self .payload::(capability, "Trait")? .signatures .is_empty() { + // 枚举已有实例检查同一存储不变量,不建立持有实例的注册表。 for object in self.heap.live_references() { + // 按有效类型判断是否属于被声明类型及后代,兼容类型转发门面。 if let Some(actual) = self.type_of(object)? && self.is_subtype(actual, definition)? { @@ -1137,20 +1173,25 @@ impl ObjectStore { } } } + // 复制定义准备提交;此前检查失败不改变真实能力列表。 let mut updated = self.payload::(definition, "Type")?.clone(); + // 重复声明是无操作,首次声明才更新载荷边与版本。 if !updated.traits.contains(&capability) { updated.traits.push(capability); self.heap.replace_payload(definition, updated)?; } Ok(()) } + /// 名义能力查询要求显式声明/继承,命中后重验当前方法,不以结构相似猜测。 pub fn implements_trait( &self, definition: ObjectRef, capability: ObjectRef, ) -> Result { self.payload::(capability, "Trait")?; + // 显式声明或继承才算支持能力,方法形状相同也不会自动成为声明。 let declared = self.inherited_traits(definition)?.contains(&capability); + // 命中声明后重验当前方法/实例,避免把历史声明当作永久有效证明。 if declared { self.validate_trait(definition, capability, false)?; } @@ -1158,12 +1199,15 @@ impl ObjectStore { } /// Typed capability methods belong to the method table. Instance fields /// cannot replace them independently of dispatch through that table. + /// Store 属性读写及元数据查找防止字段遮蔽类型化能力方法,带按线程递归守卫。 pub(crate) fn check_typed_method_write( &self, object: ObjectRef, name: &str, ) -> Result<(), VmError> { + // 递归属性检查按线程隔离。 let thread = std::thread::current().id(); + // 同线程同对象检查重入时返回,避免 type_target 读取自身属性导致无限递归。 if !self .active_attribute_checks .lock() @@ -1174,14 +1218,19 @@ impl ObjectStore { { return Ok(()); } + // 成功登记后建立守卫,错误和正常返回都清理本次对象检查标记。 let _guard = AttributeCheckGuard { store: self, thread, object, }; + // 仅有有效名义类型时才有继承能力可检查。 if let Some(definition) = self.type_of(object)? { + // 全部继承能力都参与,不以首个成功项短路。 for capability in self.inherited_traits(definition)? { + // 能力载荷先验证,再借用名称/完整签名/最小要求。 let contract = self.payload::(capability, "Trait")?; + // 实例字段不得取代能力方法表分派,拒绝同名属性遮蔽。 if contract.signatures.contains_key(name) { return Err(VmError::TraitViolation { capability: contract.name.clone(), @@ -1194,26 +1243,34 @@ impl ObjectStore { Ok(()) } + /// 类型附着/能力声明/宿主分派前核对实际属性存储及固有属性不遮蔽能力方法。 fn check_capability_storage( &self, object: ObjectRef, capability: ObjectRef, ) -> Result<(), VmError> { + // 能力载荷先验证,再借用名称/完整签名/最小要求。 let contract = self.payload::(capability, "Trait")?; + // 没有完整签名时无此处的类型化方法存储不变量。 if contract.signatures.is_empty() { return Ok(()); } + // 沿属性转发链确定实际存储终点,attribute_path 成功时链必非空。 let storage = *self .attribute_path(object)? .last() .expect("nonempty attribute path"); + // 检查每个类型化方法名的固有元数据及存储属性冲突。 for name in contract.signatures.keys() { + // 查询原对象固有属性身份,而不是只查看转发终点。 let payload = self.object(object)?.payload(); + // Type 的 name/base/类方法与 Trait 的 name 都是固有属性,可能与能力方法冲突。 let intrinsic = if payload.as_any().is::() { name == "name" || name == "base" || self.lookup_method(object, name)?.is_some() } else { payload.as_any().is::() && name == "name" }; + // 固有属性无法经普通存储删除,声明该冲突能力必须失败。 if intrinsic { return Err(VmError::TraitViolation { capability: contract.name.clone(), @@ -1221,6 +1278,7 @@ impl ObjectStore { reason: "intrinsic attribute shadows a typed capability method", }); } + // 字段命中即冲突;不存在或不允许属性可继续,其他错误传播。 match self.heap.get_attr(storage, name) { Ok(_) => { return Err(VmError::TraitViolation { @@ -1240,9 +1298,13 @@ impl ObjectStore { /// Method names whose instance storage participates in typed capability /// validity. Hosts can subscribe to these attribute keys when caching. + /// 宿主缓存查询当前类型化能力涉及的属性键,返回去重名称,不建立订阅。 pub fn typed_method_names(&self, object: ObjectRef) -> Result, VmError> { + // 按名称去重,多个能力共用方法名只返回一次。 let mut names = std::collections::BTreeSet::new(); + // 仅有有效名义类型时才有继承能力可检查。 if let Some(definition) = self.type_of(object)? { + // 全部继承能力都参与,不以首个成功项短路。 for capability in self.inherited_traits(definition)? { names.extend( self.payload::(capability, "Trait")? @@ -1257,8 +1319,11 @@ impl ObjectStore { /// Validate instance storage before host dispatch that bypasses attribute /// lookup. Raw storage access is trusted but cannot certify conformance. + /// 绕过普通属性查找的宿主分派必须显式重验实例存储,原始载荷读取不能证明符合能力。 pub fn check_typed_instance_storage(&self, object: ObjectRef) -> Result<(), VmError> { + // 仅有有效名义类型时才有继承能力可检查。 if let Some(definition) = self.type_of(object)? { + // 全部继承能力都参与,不以首个成功项短路。 for capability in self.inherited_traits(definition)? { self.check_capability_storage(object, capability)?; } @@ -1266,11 +1331,15 @@ impl ObjectStore { Ok(()) } + /// 值级能力查询:先验证有效类型显式声明,再检查实例实际存储,旧无类型对象为 false。 pub fn supports(&self, object: ObjectRef, capability: ObjectRef) -> Result { self.payload::(capability, "Trait")?; + // 无有效类型返回 false,有类型还需显式能力声明及实例存储检查。 match self.type_of(object)? { Some(definition) => { + // 显式声明或继承才算支持能力,方法形状相同也不会自动成为声明。 let declared = self.implements_trait(definition, capability)?; + // 命中声明后重验当前方法/实例,避免把历史声明当作永久有效证明。 if declared { self.check_capability_storage(object, capability)?; } @@ -1285,19 +1354,31 @@ impl ObjectStore { /// while validating the return, so rebinding globals cannot release it mid-call. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum AnnotationType { + /// 内建 Object 注解,接受所有有效值,不等于特定 Object 名义定义。 Any, + /// 只接受 Value::Nil。 Unit, + /// 接受直接 Number 或堆数值载荷。 Number, + /// 接受直接 Text 或堆字符串载荷。 String, + /// 只接受直接 Bool。 Bool, + /// 按载荷 is_function 判定,不接受所有可调用 Type。 Function, + /// 要求 Type 载荷。 Type, + /// 要求 Trait 载荷。 Trait, + /// 借用名义类型定义,按实例继承关系匹配。 Nominal(ObjectRef), + /// 借用显式能力定义,按 supports 完整检查。 Capability(ObjectRef), } impl AnnotationType { + /// 帧/签名 trace 和保护逻辑取得注解携带的借用定义引用,直接类别没有引用。 pub fn reference(self) -> Option { + // 只有 Nominal/Capability 携带定义强边来源,其余注解是直接类别。 match self { Self::Nominal(reference) | Self::Capability(reference) => Some(reference), _ => None, @@ -1305,7 +1386,9 @@ impl AnnotationType { } } impl ObjectStore { + /// 源码字段/函数解析内建注解名,优先于环境同名绑定;Text 与 String 同义。 fn primitive_annotation(name: &str) -> Option { + // 内建注解直接映射固定类别,不访问语言全局空间。 match name { "Object" => Some(AnnotationType::Any), "Unit" => Some(AnnotationType::Unit), @@ -1319,6 +1402,7 @@ impl ObjectStore { } } + /// Store 字段写入/删除按对象有效类型查字段真实声明层,返回借用定义及字段。 pub(crate) fn declared_field( &self, object: ObjectRef, @@ -1327,17 +1411,22 @@ impl ObjectStore { self.declared_field_in_type(self.type_of(object)?, name) } + /// 字段验证沿继承链只搜索每层自有后缀,使继承字段使用原声明环境。 fn declared_field_in_type( &self, mut current: Option, name: &str, ) -> Result, VmError> { + // 沿固定基类链逐层读取,不按名称猜测类型。 while let Some(definition) = current { + // 先验证定义/函数载荷,再访问字段表或声明环境。 let data = self.payload::(definition, "Type")?; + // 父字段占当前布局前缀,当前层只搜索其后的自有声明。 let inherited = match data.base { Some(base) => self.payload::(base, "Type")?.fields.len(), None => 0, }; + // 命中字段时返回当前声明 owner,让后续注解解析使用正确环境。 if let Some(field) = data.fields[inherited..] .iter() .find(|field| field.name == name) @@ -1349,12 +1438,14 @@ impl ObjectStore { Ok(None) } + /// Store 开启字段检查时校验已声明字段,未声明动态属性不在此限制。 pub(crate) fn check_field_write( &self, object: ObjectRef, name: &str, value: &Value, ) -> Result<(), VmError> { + // 动态未声明字段允许通过;已声明字段按原 owner 的约束验证。 let Some((owner, field)) = self.declared_field(object, name)? else { return Ok(()); }; @@ -1363,12 +1454,15 @@ impl ObjectStore { /// NativeTyped allocators can validate their field suffix before any effects. /// Count is always checked; annotation matching follows the opt-in setting. + /// Record/NativeTyped 构造器在副作用前校验字段后缀;数量始终检查,类型匹配由开关控制。 pub fn check_class_field_arguments( &self, definition: ObjectRef, arguments: &[Value], ) -> Result<(), VmError> { + // 先验证定义/函数载荷,再访问字段表或声明环境。 let data = self.payload::(definition, "Type")?; + // 字段构造数量始终严格相等,错误发生在逐字段类型检查之前。 if arguments.len() != data.fields.len() { return Err(VmError::ArgumentCount { name: data.name.clone(), @@ -1377,8 +1471,11 @@ impl ObjectStore { provided: arguments.len(), }); } + // 可选类型检查开关不改变字段数量规则。 if self.field_type_checks { + // 依照完整继承字段顺序匹配实参,每项还原真实声明层。 for (field, value) in data.fields.iter().zip(arguments) { + // 完整字段表与继承前缀不变量保证声明层存在。 let (owner, field) = self .declared_field_in_type(Some(definition), &field.name)? .expect("class field has a declaring type"); @@ -1388,13 +1485,16 @@ impl ObjectStore { Ok(()) } + /// 声明字段按自身 owner/内建名/声明函数环境解析类型,再执行值匹配。 fn check_field_value( &self, owner: ObjectRef, field: &ClassField, value: &Value, ) -> Result<(), VmError> { + // 验证类型载荷后才读取其基类或能力列表。 let definition = self.payload::(owner, "Type")?; + // 自类名优先、其次内建注解,再查声明函数环境,无环境则未知注解。 let expected = if field.type_name == definition.name { AnnotationType::Nominal(owner) } else if let Some(primitive) = Self::primitive_annotation(&field.type_name) { @@ -1404,6 +1504,7 @@ impl ObjectStore { } else { return Err(VmError::UnknownAnnotation(field.type_name.clone())); }; + // 类型化能力才需要扫描实例存储,最小数量能力没有遮蔽签名要求。 if !self.matches_annotation(value, expected)? { return Err(VmError::TypeMismatch { function: definition.name.clone(), @@ -1415,25 +1516,33 @@ impl ObjectStore { Ok(()) } + /// eval 参数/返回与字段契约解析源码注解,返回借用描述符,不 retain 定义。 pub fn annotation_type( &self, function: ObjectRef, name: &str, receiver: Option, ) -> Result { + // 先验证定义/函数载荷,再访问字段表或声明环境。 let data = self.payload::(function, "function")?; + // 方法 owner 解析需要代码中的源码声明元数据,函数本身只持有代码引用。 let signature = self .payload::(data.code(), "code")? .code() .source_signature(); // Bind a method's own class to the definition that actually owns it, // including inherited methods and old instances after REPL redefinition. + // 只对声明自身 owner 名称且有接收者的场景沿真实类型链查找。 if signature.and_then(|s| s.method_owner.as_deref()) == Some(name) && let Some(receiver) = receiver { + // 从接收者当前名义类型向父类查找实际拥有该源码方法的定义。 let mut current = self.type_of(receiver)?; + // 沿固定基类链逐层读取,不按名称猜测类型。 while let Some(definition) = current { + // 借用继承链类型,要求名称相同且方法表仍持有当前函数。 let payload = self.payload::(definition, "Type")?; + // 同时检查名称和函数身份,避免 REPL 同名重定义误绑定旧实例。 if payload.name == name && payload.methods.values().any(|method| *method == function) { @@ -1442,26 +1551,33 @@ impl ObjectStore { current = payload.base; } } + // 内建注解先于普通环境绑定,避免同名用户对象改变内建语义。 if let Some(primitive) = Self::primitive_annotation(name) { return Ok(primitive); } + // 普通注解查函数全局及内置空间;Option::or 的参数会先求值,因此内置读取不是惰性。 let value = self .dict_get_name(data.globals(), name)? .or(match data.builtins() { Some(builtins) => self.dict_get_name(builtins, name)?, None => None, }); + // 普通名称必须指向 Type 或 Trait 载荷,其他值不能充当类型注解。 if let Some(Value::Object(definition)) = value { + // 查询原对象固有属性身份,而不是只查看转发终点。 let payload = self.object(definition)?.payload(); + // 识别名义类型,描述符只借用该定义身份。 if payload.as_any().is::() { return Ok(AnnotationType::Nominal(definition)); } + // 识别显式能力定义,不以类名字符串替代能力身份。 if payload.as_any().is::() { return Ok(AnnotationType::Capability(definition)); } } Err(VmError::UnknownAnnotation(name.into())) } + /// 调用/字段检查把类型验证读取标记为 validation,普通程序读取仍可另行记录。 pub fn matches_annotation( &self, value: &Value, @@ -1471,14 +1587,17 @@ impl ObjectStore { .with_validation_reads(|| self.matches_annotation_value(value, expected)) } + /// 匹配已解析注解;对象先校验存活,直接类别可同时支持直接值和相应堆载荷。 fn matches_annotation_value( &self, value: &Value, expected: AnnotationType, ) -> Result { + // Any 也不能接受失效句柄,先验证对象存活再匹配类别。 if let Value::Object(object) = value { self.object(*object)?; } + // 直接类别与名义/能力匹配分开;Type/Function 类别不等于任意可调用对象。 Ok(match expected { AnnotationType::Any => true, AnnotationType::Unit => matches!(value, Value::Nil), @@ -1510,7 +1629,9 @@ impl ObjectStore { }, }) } + /// 类型错误诊断格式化预期名称;名义/能力定义仍验证句柄和载荷。 pub fn annotation_type_name(&self, expected: AnnotationType) -> Result { + // 直接类别与名义/能力匹配分开;Type/Function 类别不等于任意可调用对象。 Ok(match expected { AnnotationType::Any => "Object".into(), AnnotationType::Unit => "Unit".into(), @@ -1530,7 +1651,9 @@ impl ObjectStore { .clone(), }) } + /// 类型错误诊断显示实际类型,优先有效名义类型,无类型才回退载荷类别。 pub fn value_type_name(&self, value: &Value) -> Result { + // 直接值显示内建类别;对象优先显示有效名义类型名。 Ok(match value { Value::Nil => "Unit".into(), Value::Bool(_) => "Bool".into(),