docs(objects): explain method substitution contracts
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
//! Store 类型/能力方法的替换约束;types 子模块可读取方法表,无需向宿主公开可变内部布局。
|
||||
//! 参数要求逆变、返回要求协变;检查只观察当前定义,拟议更新通过 Patch 预演,不先修改再回滚。
|
||||
//! UnknownAnnotation 仅在显式 defer_unknown 时暂缓,调用时检查使用完整解析路径。
|
||||
//! Method substitution rules. This is a child of types so validation can inspect
|
||||
//! method tables without exporting mutable definition internals.
|
||||
use super::{AnnotationType, EndorTypeObject};
|
||||
@@ -7,18 +10,25 @@ use crate::{
|
||||
};
|
||||
|
||||
struct Contract {
|
||||
/// 可接受的位置参数区间,包括接收者。
|
||||
arity: CallArity,
|
||||
/// 固定位置参数约束。
|
||||
parameters: Vec<CallType>,
|
||||
/// 固定部分之后的统一参数约束。
|
||||
variadic: Option<CallType>,
|
||||
/// 实现返回值必须落入父契约或能力允许范围。
|
||||
returns: CallType,
|
||||
/// 已知整体效果,None 表示不能证明,不等于 ReadOnly。
|
||||
effect: Option<CallEffect>,
|
||||
}
|
||||
impl Contract {
|
||||
/// 签名替换检查按位置选固定参数,超出固定部分回退可变参数约束。
|
||||
fn parameter(&self, index: usize) -> Option<&CallType> {
|
||||
self.parameters.get(index).or(self.variadic.as_ref())
|
||||
}
|
||||
}
|
||||
impl From<CallSignature> for Contract {
|
||||
/// 原生签名转内部契约,Delegated 不是已知整次调用效果,转换为 None。
|
||||
fn from(value: CallSignature) -> Self {
|
||||
Self {
|
||||
arity: value.arity,
|
||||
@@ -35,25 +45,35 @@ impl From<CallSignature> for Contract {
|
||||
}
|
||||
#[derive(Clone, Copy)]
|
||||
struct Patch<'a> {
|
||||
/// 拟议更新所属的类型身份,借用。
|
||||
owner: ObjectRef,
|
||||
/// 拟议更新的方法名,仅精确匹配此名。
|
||||
name: &'a str,
|
||||
/// 拟议的新函数身份,不由 Patch 保留根。
|
||||
function: ObjectRef,
|
||||
}
|
||||
|
||||
struct TraitCheckGuard<'a> {
|
||||
/// 借用递归校验状态表。
|
||||
store: &'a ObjectStore,
|
||||
/// 创建守卫时的线程身份。
|
||||
thread: std::thread::ThreadId,
|
||||
/// 当前定义/能力对,Drop 时移除。
|
||||
key: (ObjectRef, ObjectRef),
|
||||
}
|
||||
impl Drop for TraitCheckGuard<'_> {
|
||||
/// 递归校验 RAII 清理,正常/报错/展开路径都移除本线程当前定义与能力对。
|
||||
fn drop(&mut self) {
|
||||
// 取得线程校验表的锁,守卫只会在成功插入 key 后创建。
|
||||
let mut checks = self
|
||||
.store
|
||||
.active_trait_checks
|
||||
.lock()
|
||||
.expect("trait checker poisoned");
|
||||
// 只删除当前递归对,不影响同线程其他活跃校验。
|
||||
let active = checks.get_mut(&self.thread).expect("active trait check");
|
||||
active.remove(&self.key);
|
||||
// 线程没有剩余递归检查时移除空项。
|
||||
if active.is_empty() {
|
||||
checks.remove(&self.thread);
|
||||
}
|
||||
@@ -64,12 +84,18 @@ impl CallType {
|
||||
/// Whether every value admitted by provided is admitted by self.
|
||||
/// Nominal inheritance and explicit capabilities participate; no structural
|
||||
/// or callable-signature inference is implied by this relation.
|
||||
/// 替换校验的值集合包含关系:provided 的每项都必须被 self 的至少一项接纳。
|
||||
pub fn accepts_type(&self, store: &ObjectStore, provided: &Self) -> Result<bool, VmError> {
|
||||
// 先验证联合全部定义边,再做包含/匹配判断,不能让无效分支藏在后面。
|
||||
self.validate(store)?;
|
||||
provided.validate(store)?;
|
||||
// provided 是待被接纳的值集合,必须逐个候选分支都被覆盖。
|
||||
for actual in provided.alternatives() {
|
||||
// 每个 provided 分支单独寻找一个可接受它的 self 分支。
|
||||
let mut accepted = false;
|
||||
// self 联合只需一个分支能接纳当前 actual,不要求所有分支都匹配。
|
||||
for expected in self.alternatives() {
|
||||
// Any 接受所有值;名义继承和显式能力参与,不推断结构相似或可调用签名。
|
||||
accepted = match (*expected, *actual) {
|
||||
(AnnotationType::Any, _) => true,
|
||||
(AnnotationType::Nominal(base), AnnotationType::Nominal(child)) => {
|
||||
@@ -81,10 +107,12 @@ impl CallType {
|
||||
) => store.implements_trait(definition, capability)?,
|
||||
(expected, actual) => expected == actual,
|
||||
};
|
||||
// 当前 actual 已找到覆盖分支即可结束内层循环。
|
||||
if accepted {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 存在一个未被接纳的 provided 分支即整体不包含。
|
||||
if !accepted {
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -94,14 +122,18 @@ impl CallType {
|
||||
}
|
||||
|
||||
impl ObjectStore {
|
||||
/// types::validate_trait 调用的递归守卫;同线程同定义/能力对重入时暂不重复展开。
|
||||
pub(super) fn with_trait_check(
|
||||
&self,
|
||||
definition: ObjectRef,
|
||||
capability: ObjectRef,
|
||||
check: impl FnOnce() -> Result<(), VmError>,
|
||||
) -> Result<(), VmError> {
|
||||
// 递归重入按线程隔离,避免把其他线程的检查误作当前递归。
|
||||
let thread = std::thread::current().id();
|
||||
// 重入身份包含类型定义与能力,不仅是单个类型。
|
||||
let key = (definition, capability);
|
||||
// 同线程同定义/能力对已经在检查时返回,避免递归契约无限展开。
|
||||
if !self
|
||||
.active_trait_checks
|
||||
.lock()
|
||||
@@ -112,6 +144,7 @@ impl ObjectStore {
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
// 锁已释放,守卫负责退出时清除 key;执行 check 时不持全局校验锁。
|
||||
let _guard = TraitCheckGuard {
|
||||
store: self,
|
||||
thread,
|
||||
@@ -119,14 +152,17 @@ impl ObjectStore {
|
||||
};
|
||||
check()
|
||||
}
|
||||
/// 替换检查读取原生签名或解析源码签名,缺失元数据返回 None,不猜测类型。
|
||||
fn method_contract(
|
||||
&self,
|
||||
function: ObjectRef,
|
||||
owner: ObjectRef,
|
||||
) -> Result<Option<Contract>, VmError> {
|
||||
// 优先使用已解析原生签名,其引用有效性由 Store 的签名入口校验。
|
||||
if let Some(native) = self.native_signature(function)? {
|
||||
return Ok(Some(native.into()));
|
||||
}
|
||||
// 既非原生完整签名又非源码函数时无法取得契约。
|
||||
let Some(data) = self
|
||||
.object(function)?
|
||||
.payload()
|
||||
@@ -135,15 +171,23 @@ impl ObjectStore {
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
// 源码类型声明在函数指向的代码对象内,不从函数名字猜测。
|
||||
let code = self.payload::<EndorCodeObject>(data.code(), "code")?.code();
|
||||
// 源码没有声明就返回 None,调用方决定缺失元数据是否允许。
|
||||
let Some(signature) = code.source_signature() else {
|
||||
return Ok(None);
|
||||
};
|
||||
// 解析源码 owner 名称时考虑继承中的真实声明,避免只查全局同名对象。
|
||||
let resolve = |name: &str| {
|
||||
// 仅源码声明的 owner 名称走特殊继承解析,其余名称回退常规注解解析。
|
||||
if signature.method_owner.as_deref() == Some(name) {
|
||||
// 从当前声明 owner 向基类查找,不扫描任意后代。
|
||||
let mut current = Some(owner);
|
||||
// 逐层读取不可变类型定义,必要时确认父层方法身份仍是当前函数。
|
||||
while let Some(definition) = current {
|
||||
// 读取类型载荷并验证句柄,后续方法表与基类访问都基于该借用。
|
||||
let data = self.payload::<EndorTypeObject>(definition, "Type")?;
|
||||
// 名称相同还需属于当前 owner 或确实在父方法表持有该函数。
|
||||
if data.name == name
|
||||
&& (definition == owner
|
||||
|| data
|
||||
@@ -158,6 +202,7 @@ impl ObjectStore {
|
||||
}
|
||||
self.annotation_type(function, name, None)
|
||||
};
|
||||
// 逐个解析全部参数注解,首个错误即传播,不返回部分契约。
|
||||
let parameters = signature
|
||||
.parameters
|
||||
.iter()
|
||||
@@ -173,12 +218,14 @@ impl ObjectStore {
|
||||
effect: self.call_effect(function)?,
|
||||
}))
|
||||
}
|
||||
/// 查类型自身方法,若 Patch 精确匹配该类型/名称则读取拟议替代函数。
|
||||
fn own_method(
|
||||
&self,
|
||||
owner: ObjectRef,
|
||||
name: &str,
|
||||
patch: Option<Patch<'_>>,
|
||||
) -> Result<Option<ObjectRef>, VmError> {
|
||||
// 只在 owner 和 name 都相同的查询位置替换视图,不修改真实方法表。
|
||||
if let Some(patch) = patch
|
||||
&& patch.owner == owner
|
||||
&& patch.name == name
|
||||
@@ -191,13 +238,16 @@ impl ObjectStore {
|
||||
.get(name)
|
||||
.copied())
|
||||
}
|
||||
/// 沿单继承链寻找最近方法及声明 owner,支持拟议 Patch 的查找视图。
|
||||
fn inherited_method(
|
||||
&self,
|
||||
mut owner: Option<ObjectRef>,
|
||||
name: &str,
|
||||
patch: Option<Patch<'_>>,
|
||||
) -> Result<Option<(ObjectRef, ObjectRef)>, VmError> {
|
||||
// 向基类遍历;不假定候选函数一定是接收者当前生效的方法。
|
||||
while let Some(definition) = owner {
|
||||
// 最靠近当前类型的声明遮蔽更远的同名父方法。
|
||||
if let Some(function) = self.own_method(definition, name, patch)? {
|
||||
return Ok(Some((definition, function)));
|
||||
}
|
||||
@@ -205,6 +255,7 @@ impl ObjectStore {
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
/// 检查当前方法替换最近父方法是否可代换;父方法无类型元数据时保持兼容。
|
||||
fn check_override(
|
||||
&self,
|
||||
owner: ObjectRef,
|
||||
@@ -213,32 +264,40 @@ impl ObjectStore {
|
||||
patch: Option<Patch<'_>>,
|
||||
defer_unknown: bool,
|
||||
) -> Result<(), VmError> {
|
||||
// 检查 owner 类型载荷,诊断使用其声明名称。
|
||||
let definition = self.payload::<EndorTypeObject>(owner, "Type")?;
|
||||
// 没有同名父方法即不是 override,无需普通替换检查。
|
||||
let Some((base_owner, base_function)) =
|
||||
self.inherited_method(definition.base, name, patch)?
|
||||
else {
|
||||
return Ok(());
|
||||
};
|
||||
// 闭包收集解析/校验结果,外层仅在允许时暂缓 UnknownAnnotation。
|
||||
let checked = (|| {
|
||||
// 父方法没有完整元数据时不新增更严格的旧接口约束。
|
||||
let Some(base) = self.method_contract(base_function, base_owner)? else {
|
||||
return Ok(());
|
||||
};
|
||||
// 按当前调用用途构造带类型/能力与方法定位的错误,不改变验证逻辑。
|
||||
let invalid = |reason| VmError::OverrideViolation {
|
||||
definition: definition.name.clone(),
|
||||
method: name.into(),
|
||||
reason,
|
||||
};
|
||||
// 父契约存在时,派生实现也必须提供完整可检查的类型元数据。
|
||||
let derived = self
|
||||
.method_contract(function, owner)?
|
||||
.ok_or_else(|| invalid("override lacks type metadata"))?;
|
||||
self.check_substitution(owner, &derived, &base, invalid)?;
|
||||
Ok(())
|
||||
})();
|
||||
// 只有 UnknownAnnotation 可在 defer_unknown 时暂缓,其他失败始终传播。
|
||||
match checked {
|
||||
Err(VmError::UnknownAnnotation(_)) if defer_unknown => Ok(()),
|
||||
result => result,
|
||||
}
|
||||
}
|
||||
/// 父方法/能力签名的公共替换算法;所有不兼容原因交给调用方构造具体错误。
|
||||
fn check_substitution(
|
||||
&self,
|
||||
owner: ObjectRef,
|
||||
@@ -246,12 +305,15 @@ impl ObjectStore {
|
||||
base: &Contract,
|
||||
invalid: impl Fn(&'static str) -> VmError,
|
||||
) -> Result<(), VmError> {
|
||||
// 实现不得要求更多必填参数,也不得缩小最多可接收参数数量。
|
||||
if derived.arity.required > base.arity.required
|
||||
|| derived.arity.maximum < base.arity.maximum
|
||||
{
|
||||
return Err(invalid("override narrows accepted argument counts"));
|
||||
}
|
||||
// 接收者按实现声明类型核对,不能只对比两份签名的第零项文本。
|
||||
let receiver = CallType::from(AnnotationType::Nominal(owner));
|
||||
// 派生签名必须接受它自己声明类型的实例作为接收者。
|
||||
if !derived
|
||||
.parameter(0)
|
||||
.ok_or_else(|| invalid("override lacks receiver"))?
|
||||
@@ -259,6 +321,7 @@ impl ObjectStore {
|
||||
{
|
||||
return Err(invalid("override receiver rejects its declaring type"));
|
||||
}
|
||||
// 父/能力签名必须接纳实现类型,返回值则必须落在父约束范围。
|
||||
if !base
|
||||
.parameter(0)
|
||||
.ok_or_else(|| invalid("required signature lacks receiver"))?
|
||||
@@ -266,48 +329,62 @@ impl ObjectStore {
|
||||
{
|
||||
return Err(invalid("required receiver rejects implementing type"));
|
||||
}
|
||||
// 检查双方固定参数覆盖到的最大位置,但不超过父方法允许上界。
|
||||
let fixed = base
|
||||
.parameters
|
||||
.len()
|
||||
.max(derived.parameters.len())
|
||||
.min(base.arity.maximum);
|
||||
// 跳过已单独核对的接收者,第一个普通参数起检查逆变。
|
||||
for index in 1..fixed {
|
||||
// 调用方按父契约可传的类型集合,实现必须全部接纳。
|
||||
let expected = base
|
||||
.parameter(index)
|
||||
.ok_or_else(|| invalid("incomplete base parameter metadata"))?;
|
||||
// 实现的实际参数/方法契约必须存在,不能通过缺失元数据绕过检查。
|
||||
let actual = derived
|
||||
.parameter(index)
|
||||
.ok_or_else(|| invalid("incomplete override parameter metadata"))?;
|
||||
// 逆变方向是 actual 接纳 expected,反过来会错误允许缩窄参数。
|
||||
if !actual.accepts_type(self, expected)? {
|
||||
return Err(invalid("override narrows a parameter type"));
|
||||
}
|
||||
}
|
||||
// 父契约还有固定段之后的位置时,用该位置的尾部约束核对其余参数。
|
||||
if base.arity.maximum > fixed {
|
||||
// 调用方按父契约可传的类型集合,实现必须全部接纳。
|
||||
let expected = base
|
||||
.parameter(fixed)
|
||||
.ok_or_else(|| invalid("incomplete base variadic metadata"))?;
|
||||
// 实现的实际参数/方法契约必须存在,不能通过缺失元数据绕过检查。
|
||||
let actual = derived
|
||||
.parameter(fixed)
|
||||
.ok_or_else(|| invalid("incomplete override variadic metadata"))?;
|
||||
// 逆变方向是 actual 接纳 expected,反过来会错误允许缩窄参数。
|
||||
if !actual.accepts_type(self, expected)? {
|
||||
return Err(invalid("override narrows a variadic parameter type"));
|
||||
}
|
||||
}
|
||||
// 父/能力签名必须接纳实现类型,返回值则必须落在父约束范围。
|
||||
if !base.returns.accepts_type(self, &derived.returns)? {
|
||||
return Err(invalid("override widens the return type"));
|
||||
}
|
||||
// 仅双方效果都已知时比较;未知效果不在此处强行推断。
|
||||
if let (Some(expected), Some(actual)) = (base.effect, derived.effect) {
|
||||
// 只读只能替换为只读;Mutating 不接受 External;External/Delegated 不再收紧。
|
||||
let compatible = match expected {
|
||||
CallEffect::ReadOnly => actual == CallEffect::ReadOnly,
|
||||
CallEffect::Mutating => actual != CallEffect::External,
|
||||
CallEffect::External | CallEffect::Delegated => true,
|
||||
};
|
||||
// 效果扩大报替换错误,不靠实际执行检测。
|
||||
if !compatible {
|
||||
return Err(invalid("override expands known effects"));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
/// types 能力验证把实现方法与声明签名比较,报 TraitViolation 而非普通覆盖错误。
|
||||
pub(super) fn validate_typed_requirement(
|
||||
&self,
|
||||
definition: ObjectRef,
|
||||
@@ -317,6 +394,7 @@ impl ObjectStore {
|
||||
expected: &CallSignature,
|
||||
defer_unknown: bool,
|
||||
) -> Result<(), VmError> {
|
||||
// 按当前调用用途构造带类型/能力与方法定位的错误,不改变验证逻辑。
|
||||
let invalid = |reason| VmError::TraitViolation {
|
||||
capability: self
|
||||
.payload::<super::EndorTraitObject>(capability, "Trait")
|
||||
@@ -326,38 +404,49 @@ impl ObjectStore {
|
||||
method: name.into(),
|
||||
reason,
|
||||
};
|
||||
// 闭包收集解析/校验结果,外层仅在允许时暂缓 UnknownAnnotation。
|
||||
let checked = (|| {
|
||||
// 实现的实际参数/方法契约必须存在,不能通过缺失元数据绕过检查。
|
||||
let actual = self
|
||||
.method_contract(function, definition)?
|
||||
.ok_or_else(|| invalid("required member lacks type metadata"))?;
|
||||
self.check_substitution(definition, &actual, &expected.clone().into(), invalid)
|
||||
})();
|
||||
// 只有 UnknownAnnotation 可在 defer_unknown 时暂缓,其他失败始终传播。
|
||||
match checked {
|
||||
Err(VmError::UnknownAnnotation(_)) if defer_unknown => Ok(()),
|
||||
result => result,
|
||||
}
|
||||
}
|
||||
/// 类型构造时按开关校验自身方法覆盖,允许暂缓尚未解析的注解。
|
||||
pub(super) fn validate_class_overrides(&self, definition: ObjectRef) -> Result<(), VmError> {
|
||||
// 类定义/更新阶段普通 override 检查受配置开关控制。
|
||||
if self.field_type_checks {
|
||||
// 逐个检查当前类型自身方法,不把继承方法当作自身声明。
|
||||
for (name, function) in &self.payload::<EndorTypeObject>(definition, "Type")?.methods {
|
||||
self.check_override(definition, name, *function, None, true)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
/// set_method 提交前,以 Patch 校验受影响后代,避免先改表再发现错误。
|
||||
pub(super) fn validate_override_update(
|
||||
&self,
|
||||
owner: ObjectRef,
|
||||
name: &str,
|
||||
function: ObjectRef,
|
||||
) -> Result<(), VmError> {
|
||||
// 类定义/更新阶段普通 override 检查受配置开关控制。
|
||||
if self.field_type_checks {
|
||||
// 拟议 owner/name/function 只作为查询视图,验证完成前不提交。
|
||||
let patch = Some(Patch {
|
||||
owner,
|
||||
name,
|
||||
function,
|
||||
});
|
||||
// 父方法变化可能破坏已有子方法的替换关系,所以检查全部后代。
|
||||
for descendant in self.descendant_types(owner)? {
|
||||
// 最靠近当前类型的声明遮蔽更远的同名父方法。
|
||||
if let Some(function) = self.own_method(descendant, name, patch)? {
|
||||
self.check_override(descendant, name, function, patch, true)?;
|
||||
}
|
||||
@@ -366,6 +455,7 @@ impl ObjectStore {
|
||||
Ok(())
|
||||
}
|
||||
/// Explicit override validation, including any typed capabilities.
|
||||
/// VM/宿主显式启用普通覆盖检查,同时校验接收者的类型化能力约束。
|
||||
pub fn check_method_override_call(
|
||||
&self,
|
||||
function: ObjectRef,
|
||||
@@ -376,25 +466,35 @@ impl ObjectStore {
|
||||
}
|
||||
/// Typed capabilities are explicit opt-ins and always checked. Ordinary
|
||||
/// override checking remains configurable by the VM's source-check flag.
|
||||
/// eval 原生调用前核对实际方法;能力约束始终检查,普通覆盖由 overrides 控制。
|
||||
pub fn check_method_contract_call(
|
||||
&self,
|
||||
function: ObjectRef,
|
||||
receiver: ObjectRef,
|
||||
overrides: bool,
|
||||
) -> Result<bool, VmError> {
|
||||
// 返回值表示是否命中类型化能力约束,不代表普通覆盖检查是否执行。
|
||||
let mut typed = false;
|
||||
// 接收者的有效类型可能经 type_target 转发;无类型时不会枚举名义方法。
|
||||
let actual = self.type_of(receiver)?;
|
||||
// 从实际类型开始向基类枚举可能声明当前函数的方法名。
|
||||
let mut owner = actual;
|
||||
// 向基类遍历;不假定候选函数一定是接收者当前生效的方法。
|
||||
while let Some(definition) = owner {
|
||||
// 读取类型载荷并验证句柄,后续方法表与基类访问都基于该借用。
|
||||
let data = self.payload::<EndorTypeObject>(definition, "Type")?;
|
||||
// 同一函数可出现在多个方法名下,各自可能承担不同能力契约。
|
||||
for (name, candidate) in &data.methods {
|
||||
// 这里只处理正在调用的函数身份,其余方法不检查。
|
||||
if *candidate != function {
|
||||
continue;
|
||||
}
|
||||
self.check_typed_instance_storage(receiver)?;
|
||||
// 普通 override 检查由调用方选择,能力约束不受该开关豁免。
|
||||
if overrides {
|
||||
self.check_override(definition, name, function, None, false)?;
|
||||
}
|
||||
// 实际方法查找仍选中该函数时按实际类型能力检查,否则按当前声明层处理。
|
||||
let effective = if self
|
||||
.lookup_method(actual.expect("method receiver has a type"), name)?
|
||||
== Some(function)
|
||||
@@ -403,7 +503,9 @@ impl ObjectStore {
|
||||
} else {
|
||||
definition
|
||||
};
|
||||
// 有效类型继承的全部能力都参与,不能只检查第一个匹配能力。
|
||||
for capability in self.inherited_traits(effective)? {
|
||||
// 只有该能力声明当前方法的完整类型签名时才有约束可检查。
|
||||
if let Some(expected) = self
|
||||
.payload::<super::EndorTraitObject>(capability, "Trait")?
|
||||
.signatures
|
||||
@@ -423,20 +525,29 @@ impl ObjectStore {
|
||||
|
||||
/// Borrowed expected results for all typed capabilities of this effective
|
||||
/// method. The evaluator retains definitions before entering the body.
|
||||
/// eval/NativeContext 收集有效方法的全部能力返回约束;返回类型句柄仍为借用。
|
||||
pub fn method_trait_returns(
|
||||
&self,
|
||||
function: ObjectRef,
|
||||
receiver: ObjectRef,
|
||||
) -> Result<Vec<(String, CallType)>, VmError> {
|
||||
// 接收者的有效类型可能经 type_target 转发;无类型时不会枚举名义方法。
|
||||
let actual = self.type_of(receiver)?;
|
||||
// 从实际类型开始向基类枚举可能声明当前函数的方法名。
|
||||
let mut owner = actual;
|
||||
// 累计所有能力返回约束,clone 不保留其中托管定义根。
|
||||
let mut returns = Vec::new();
|
||||
// 向基类遍历;不假定候选函数一定是接收者当前生效的方法。
|
||||
while let Some(definition) = owner {
|
||||
// 读取类型载荷并验证句柄,后续方法表与基类访问都基于该借用。
|
||||
let data = self.payload::<EndorTypeObject>(definition, "Type")?;
|
||||
// 同一函数可出现在多个方法名下,各自可能承担不同能力契约。
|
||||
for (name, candidate) in &data.methods {
|
||||
// 这里只处理正在调用的函数身份,其余方法不检查。
|
||||
if *candidate != function {
|
||||
continue;
|
||||
}
|
||||
// 实际方法查找仍选中该函数时按实际类型能力检查,否则按当前声明层处理。
|
||||
let effective = if self
|
||||
.lookup_method(actual.expect("method receiver has a type"), name)?
|
||||
== Some(function)
|
||||
@@ -445,8 +556,11 @@ impl ObjectStore {
|
||||
} else {
|
||||
definition
|
||||
};
|
||||
// 有效类型继承的全部能力都参与,不能只检查第一个匹配能力。
|
||||
for capability in self.inherited_traits(effective)? {
|
||||
// 读取能力签名表,名称用于返回错误的定位。
|
||||
let contract = self.payload::<super::EndorTraitObject>(capability, "Trait")?;
|
||||
// 只有该能力声明当前方法的完整类型签名时才有约束可检查。
|
||||
if let Some(expected) = contract.signatures.get(name) {
|
||||
returns.push((
|
||||
format!("{}.{}", contract.name, name),
|
||||
|
||||
Reference in New Issue
Block a user