test-weak-partial
路径:
components/crate_interface/test_crates/test-weak-partial类型:二进制 crate(独立测试工作区成员,publish = false) 分层:组件层 /crate_interface多 crate 测试矩阵 / 最终链接验证端 Rust 要求:nightly(依赖#![feature(linkage)]) 文 档依据:components/crate_interface/test_crates/test-weak-partial/Cargo.toml、components/crate_interface/test_crates/test-weak-partial/src/main.rs、components/crate_interface/test_crates/Cargo.toml、components/crate_interface/test_crates/run_tests.sh、components/crate_interface/README.md、components/crate_interface/tests/test_weak_default.rs、components/crate_interface/Cargo.toml、Cargo.toml
test-weak-partial 是 crate_interface weak_default 测试矩阵中负责“默认回退路径”的最终链接/验证端。它只链接 define-weak-traits 和 impl-weak-partial,并且刻意不把 impl-weak-traits 带入最终二进制,从而观察当实现侧只补齐必需方法时,弱符号默认实现是否会在真实程序里接管剩余方法。它不是“功能不完整的运行时组件”,而是专门为链接期默认回退语义准备的终端测试资产。
架构设计
1.1 在测试矩阵中的真实定位
test-weak-partial 与 test-weak 共同组成 weak_default 的最终验证矩阵,但两者承担的职责相反:
test-weak:观察“有覆盖时,强符号如何优先”test-weak-partial:观察“无覆盖时,弱符号如何接管”
它同样位于独立测试工作区中,而不是仓库正式产品路径的一部分:
- 仓库顶层
Cargo.toml将components/crate_interface/test_crates排除在主工作区之外 components/crate_interface/Cargo.toml也排除了test_cratescomponents/crate_interface/test_crates/Cargo.toml统一设置为publish = false
这表明它的价值不在于对外提供功能,而在于给 crate_interface 的默认回退语义提供最终证据。
1.2 隔离性就是它的架构核心
test-weak-partial 最重要的设计不是“做了什么”,而是“刻意不链接什么”:
- 只引入
PartialOnlyImpl与SelfRefPartialImpl - 不引入
impl-weak-traits中那些会产生强覆盖的实现类型
如果完整实现 crate 也被带进最终二进制,那么本来应该回退到默认实现的方法就可能被强符号抢走,整个测试将失去意义。换句话说,test-weak-partial 的核心架构特征就是“隔离回退路径”。
1.3 链接锚点设计
src/main.rs 用匿名常量块通过 std::any::type_name::<...>() 显式引用了:
PartialOnlyImplSelfRefPartialImpl
这些引用不是为了实例化对象,而是为了稳定地把“部分实现”带进最终链接单元,并把观测对象限定在这组实现上。
1.4 覆盖场景矩阵
main() 依次运行 5 个测试函数,专门观测默认回退路径:
| 测试函数 | 覆盖对象 | 关注点 |
|---|---|---|
test_required_methods() | WeakDefaultIf | 必需方法是否仍命中部分实现导出的强符号 |
test_weak_default_methods() | WeakDefaultIf | default_value、default_add、default_greeting 是否回退到弱默认 |
test_weak_default_multiple_calls() | WeakDefaultIf | 默认回退在重复调用下是否稳定 |
test_mixed_required_and_default() | WeakDefaultIf | 同一接口中必需方法与默认方法能否并存 |
test_self_ref_partial() | SelfRefIf | 默认实现内部 Self:: 直接调用与函数引用是否都回到默认路径 |
这里最关键的观察维度不是“方法能不能运行”,而是“没有覆写时,最终到底会落到哪里”。
1.5 与其它测试的关系
components/crate_interface/tests/test_weak_default.rs 提供了 weak_default 的最小功能确认,但它不负责完整描述跨 crate 的最终链接行为。test-weak-partial 则补上真正贴近使用场景的第三段验证:
- 定义侧在一个 crate 中生成弱符号默认实现
- 实现侧在另一个 crate 中故意只实现必需方法
- 最终二进制在第三个 crate 中确认默认回退确实生效
这也是 README 中“定义、实现、调用可拆到不同 crate”的模型在默认回退场景下的真正落地证明。
核心功能
功能概览
- 在真实二进制中验证弱符号默认实现的回退路径
- 验证“部分实现 + 默认实现”可以在同一接口上稳定协作
- 验证默认实现中的
Self::直接调用与函数引用在无覆盖时仍能正确工作 - 作为
impl-weak-partial的最终观测点,为默认回退语义提供端到端证据
2.2 真实调用链
2.3 为什么它必须单独存在
默认回退这件事只有在“覆盖型实现完全缺席”的最终链接单元里才可验证。因此 test-weak-partial 不是 test-weak 的精简版,也不是冗余副本,而是 weak_default 测试矩阵不可替代的一半。
依赖关系
直接依赖
| 依赖 | 作用 |
|---|---|
crate_interface | 提供 call_interface! 调用入口 |
define-weak-traits | 提供带弱默认实现的接口定义 |
impl-weak-partial | 提供只实现必需方法的部分实现样本 |
3.2 在测试矩阵中的上下游
- 上游定义侧:
define-weak-traits - 上游实现侧:
impl-weak-partial - 互补验证端:
test-weak - 参照测试:
components/crate_interface/tests/test_weak_default.rs
test-weak-partial 同样没有产品代码下游,它的消费方是测试流程本身。