diff --git a/crates/core/tests/method_contracts.rs b/crates/core/tests/method_contracts.rs index d355421..679f2b5 100644 --- a/crates/core/tests/method_contracts.rs +++ b/crates/core/tests/method_contracts.rs @@ -10,10 +10,15 @@ use std::collections::BTreeMap; /// 测试辅助,生成先写 globals.ran=42 再返回 result 的源码方法,附显式 owner/参数/返回注解。 fn source( vm: &mut Vm, + // 借用全局字典,源码函数持环境边;副作用 ran 与动态注解名称都从这里观察。 globals: ObjectRef, + // 写入源码签名的方法所属类名,按接收者继承链解析该声明身份。 owner: &str, + // 含显式 self 的参数注解文本,也决定位置参数及局部槽数量。 parameters: &[&str], + // 返回注解文本,实际类型在注册/调用契约检查时解析。 returns: &str, + // 写 ran 后返回的常量;对象身份由托管代码常量边持有,不因 Value 移动自动 retain。 result: Value, ) -> ObjectRef { // 手工指令保证源码体可观测,参数/局部槽按注解数量保持一致。 @@ -50,6 +55,7 @@ fn source( function } /// 测试辅助,以给定基类构造只声明 check 方法、无自有字段的源码类。 +/// base/function 均借用,成功返回新类拥有根并建立内部边;失败不消耗调用方持有的根。 fn class( vm: &mut Vm, name: &str, @@ -300,7 +306,7 @@ fn global_rebinding_is_rechecked_before_the_source_body_and_recovers() { "Actual", Value::Object(result), ); - // 先创建当前合法后代,再对父方法提出可能使它失效的更新。 + // 先创建当前合法后代;下面只重绑定其 Actual 注解名,不修改父方法或子方法载荷。 let child = class(&mut vm, "Child", base, child_fn).unwrap(); // 显式 self 为 Child 实例,调用时据其继承链解析各方法 own-class 注解。 let receiver = vm.new_object().unwrap(); @@ -487,7 +493,7 @@ fn unknown_forward_names_defer_until_call_without_entering_the_body() { ); // 定义阶段允许未知名称的派生创建,实例调用时会重新核对。 let child = class(&mut vm, "Child", base, child_fn).unwrap(); - // 实例提供实际接收者身份,绑定效果分析可据此查 helper,未绑定函数则未知。 + // 显式 self 使用 Child 实例,让调用预检按其继承链解析 Base/Child,再检查仍未知的 Later。 let receiver = vm.new_object().unwrap(); vm.attach_type(receiver, child).unwrap(); assert!(matches!( @@ -577,7 +583,7 @@ fn verified_source_read_only_effects_constrain_native_overrides() { // 后代继承已证明只读的方法,候选原生覆盖不能扩大已知效果。 let child = vm.new_type("Child", base, TypeConstructor::Record).unwrap(); assert_eq!(vm.call_effect(source).unwrap(), Some(CallEffect::ReadOnly)); - // 实例提供实际接收者身份,绑定效果分析可据此查 helper,未绑定函数则未知。 + // 以 Child 实例创建绑定方法,核对绑定形式仍可证明只读;此处未绑定源码本身也已由白名单证明。 let receiver = vm.new_object().unwrap(); vm.attach_type(receiver, child).unwrap(); // 绑定对象拥有函数和实际接收者边,分析可用 receiver 区分实例方法/字段。 @@ -594,7 +600,7 @@ fn verified_source_read_only_effects_constrain_native_overrides() { CallEffect::ReadOnly, CallEffect::Delegated, ] { - // 函数持有其代码/全局边,效果查询从当前载荷及环境读取快照。 + // 候选为原生包装器,仅签名引用类型形成 trace 边;效果查询读取其声明,不存在源码代码/全局字段。 let function = vm .allocate(ContextNativeFunction::new( "check", diff --git a/crates/core/tests/native_context.rs b/crates/core/tests/native_context.rs index 8f74b97..06be2d5 100644 --- a/crates/core/tests/native_context.rs +++ b/crates/core/tests/native_context.rs @@ -62,7 +62,7 @@ fn scoped_allocations_return_one_root_and_clean_up_errors() { /// 返回目标借用身份,由包装载荷 captures 保活,NativeContext 为 Invoke 输出取得拥有根。 struct Delegate(ObjectRef); impl NativeCallable for Delegate { - /// VM 在 NativeContext 内调用此测试分派器,临时分配与输入由上下文保活,返回/委托后移交输出根。 + /// VM 分派时原样委托给 captures 保活的目标;参数 clone 仍借用,NativeContext 随后为 Invoke 输出逐项取根。 fn invoke(&self, _cx: &mut NativeContext<'_>, args: &[Value]) -> Result { Ok(NativeResult::Invoke { function: self.0, @@ -157,7 +157,7 @@ fn native_delegation_shares_budget_and_cleans_owned_arguments() { assert_eq!(vm.ref_count(target).unwrap(), 2); // VM 调用已完成根移交,返回对象应只有一份调用者根。 let value = vm.call(delegate, &[]).unwrap(); - // 归还成功结果,之后只剩函数载荷,临时对象应已自动清理。 + // 归还 Allocate 返回的独立结果根;delegate、target、arg 的测试根仍在下面分别释放。 vm.release_value(value).unwrap(); vm.release(delegate).unwrap(); vm.release(target).unwrap(); @@ -237,6 +237,7 @@ fn notification_overflow_requires_rescan_instead_of_losing_changes_silently() { } #[derive(Debug)] +/// 只读场景的复制器:读输入字段并构造新结果,可选故意改旧输入以验证写屏障及错误退出。 struct ReadResult { /// 输入借用身份,包装载荷 captures 负责保活。 source: ObjectRef, @@ -381,6 +382,7 @@ fn annotation_reads_remain_dependencies_without_becoming_program_content_reads() } #[derive(Debug)] +/// 完整签名场景共用分派器,以计数器区分预检/回调/返回检查,支持委托、新分配或回传实参。 struct TypedNative { /// 构造时快照的完整签名,包装载荷负责 trace 类型定义。 signature: endor_core::CallSignature, @@ -479,7 +481,7 @@ fn delegated_source_results_obey_every_native_contract_without_extra_frames() { let code = vm.new_code(code).unwrap(); // 源码环境有分配根,函数持有它的内部边。 let globals = vm.new_dict().unwrap(); - // 源码函数返回文本或 Nil,作为后续返回契约一致/不一致的终点。 + // 此源码函数固定返回文本;inner 的 String 返回约束可通过,outer 的 Number 约束必须失败。 let source = vm .new_function("source", code, globals, vec![], vec![]) .unwrap(); @@ -705,10 +707,11 @@ fn legacy_native_signatures_check_optional_variadic_types_and_metadata() { } #[derive(Debug)] +/// 移除自身载荷的回归分派器,迫使签名类型在原持边消失后仍由执行检查根保活。 struct EraseThenDelegate { /// 构造时快照的完整签名,包装载荷负责 trace 类型定义。 signature: endor_core::CallSignature, - /// 被委托源码函数,由包装载荷 captures 保活至回调中输出保护接管。 + /// 被委托源码函数最初有 captures 边;载荷自替换后该边消失,本测试另保留 source 根保护目标。 target: ObjectRef, } impl NativeCallable for EraseThenDelegate { @@ -719,6 +722,7 @@ impl NativeCallable for EraseThenDelegate { /// 测试原生分派入口,回调内借用参数/目标,NativeContext 校验并移交 Return 或 Invoke 输出根。 fn invoke(&self, cx: &mut NativeContext<'_>, _: &[Value]) -> Result { // 将当前函数换为普通 Record,移除签名及捕获边,迫使返回约束靠执行器自己的根存活。 + // self.target 的存活此时依赖测试未归还的 source 根,Arc 中的 ObjectRef 不构成托管边。 cx.replace_payload(cx.callee(), endor_core::Record)?; Ok(NativeResult::Invoke { function: self.target, @@ -758,7 +762,7 @@ fn delegated_return_type_survives_removal_of_the_original_signature_edges() { let code = vm.new_code(code).unwrap(); // 源码环境有分配根,函数持有它的内部边。 let globals = vm.new_dict().unwrap(); - // 源码函数返回文本或 Nil,作为后续返回契约一致/不一致的终点。 + // 此源码函数固定返回 Nil,故意不满足包装器的 Transient | Number 返回联合。 let source = vm .new_function("source", code, globals, vec![], vec![]) .unwrap(); @@ -916,7 +920,7 @@ fn native_union_and_nullable_contracts_accept_each_branch_and_reject_invalid_met } #[test] -/// Delegated 包装器能进入只读域,但实际目标仍在同域核对效果,目标换为纯函数后可通过。 +/// Delegated 包装器能进入只读域,但实际目标仍在同域核对效果,目标改为 ReadOnly 声明后可通过。 fn delegated_effects_keep_the_original_read_only_scope_and_check_the_actual_target() { use endor_core::{AnnotationType as T, CallEffect, CallSignature}; use std::sync::{ diff --git a/crates/core/tests/types.rs b/crates/core/tests/types.rs index 03ce664..265bdea 100644 --- a/crates/core/tests/types.rs +++ b/crates/core/tests/types.rs @@ -242,7 +242,7 @@ fn late_trait_registration_and_ancestor_updates_validate_existing_descendants() vm.object_store().lookup_method(base, "render").unwrap(), Some(good) ); - // 第三堆查询已有类型/能力应报 ForeignHandle,不是简单 false。 + // 另建独立 VM 查询原堆类型/能力应报 ForeignHandle,不是简单 false。 let foreign = Vm::new().unwrap(); assert_eq!( foreign.implements_trait(base, capability), @@ -357,7 +357,7 @@ fn failed_nominal_return_releases_value_and_captured_type_roots() { Value::Object(expected), ) .unwrap(); - // 测试用已验证指令,返回常量 Nil;数量由参数布局决定。 + // 零参数代码返回 Other 实例常量,故意违背下面声明的 Expected 返回类型。 let code = EndorCode::from_instructions( &[ Instruction::new(Opcode::LoadConst, 0), @@ -438,7 +438,7 @@ fn native_arity_checks_precede_effects_and_traits_require_published_signatures() // 副作用标志载体被 CountedNative 的显式 captures 边保活。 let state = vm.new_object().unwrap(); vm.set_attr(state, "called", Value::Bool(false)).unwrap(); - // 原生载荷也按 is_function 分类附着类型,数量协议仍独立。 + // 本场景未配置 Function 名义类型;包装器发布的数量区间独立用于预检及能力匹配。 let native = vm .allocate(ContextNativeFunction::new( "counted", @@ -477,7 +477,7 @@ fn native_arity_checks_precede_effects_and_traits_require_published_signatures() let Value::Object(instance) = vm.call(class, &[]).unwrap() else { panic!("instance") }; - // 绑定结果持有函数与 receiver,且本身应自动取得 Function 类型。 + // 绑定结果持有 native 和 instance;这里只核对扣除 self 后的数量区间,不要求 Function 名义类型。 let Value::Object(bound) = vm.bind_attr(instance, "run").unwrap() else { panic!("bound") };