Rust der crate中SetOfVec的Encode blanket实现未被编译器识别
问题描述
使用RustCrypto项目的der crate对嵌套数据结构执行DER编码时,代码中定义了元素类型为SetOfVec的Vec结构。按照crate文档说明,der::Encode trait已经为SetOfVec提供了默认实现,但编译时出现类型不匹配错误,无法识别该trait实现。
复现环境配置
首先在Cargo.toml中添加依赖:
[dependencies] der = { version = "0.6", features = ["alloc", "oid"]}
复现代码
main.rs代码如下:
use der::{DecodeValue, Encode, Header, Reader, Sequence}; use der::asn1::{ObjectIdentifier, SetOfVec}; struct NestedType(Vec<SetOfVec<ObjectIdentifier>>); impl<'a> DecodeValue<'a> for NestedType { fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> { Ok(reader.decode()?) } } impl<'a> Sequence<'a> for NestedType { fn fields<F, T>(&self, field_encoder: F) -> der::Result<T> where F: FnOnce(&[&dyn Encode]) -> der::Result<T>, { // 该段代码可正常编译 let encoder1 = SetOfVec::<ObjectIdentifier>::new(); let encoder2 = SetOfVec::<ObjectIdentifier>::new(); field_encoder(&[&encoder1, &encoder2])?; // 该段代码编译失败 let mut refs: Vec<&SetOfVec<ObjectIdentifier>> = Vec::new(); for rdn in self.0.iter() { refs.push(rdn); } field_encoder(refs.as_slice()) } } fn main() {}
编译错误输出
error[E0308]: mismatched types --> src\main.rs:33:23 | 33 | field_encoder(refs.as_slice()) | ^^^^^^^^^^^^^^^ expected trait object `dyn Encode`, found struct `SetOfVec` | = note: expected reference `&[&dyn Encode]` found reference `&[&SetOfVec<der::asn1::ObjectIdentifier>]`
问题根本原因
这个错误和SetOfVec是否实现Encode trait无关,本质是Rust的trait对象隐式转换规则限制:
- 固定长度的数组字面量(比如例子中
&[&encoder1, &encoder2])在编译期可确定所有元素类型,编译器会在构造数组时自动将每个具体类型的引用转换为带trait虚表的宽指针,直接得到&[&dyn Encode]类型,因此可以正常编译。 - 动态构造的
Vec<&SetOfVec<ObjectIdentifier>>,内存中存储的是仅指向具体类型实例的瘦指针,没有携带Encodetrait的虚表信息。调用as_slice()得到的&[&SetOfVec<ObjectIdentifier>]切片,元素内存布局和&[&dyn Encode]要求的宽指针布局完全不同。Rust不会隐式遍历整个切片做逐元素的宽化转换——这类转换存在运行时开销,必须由开发者显式触发。
修复方案
构造Vec时直接指定元素类型为&dyn Encode,让编译器在push元素时就完成trait对象转换:
let mut refs: Vec<&dyn Encode> = Vec::new(); for rdn in self.0.iter() { refs.push(rdn); } field_encoder(refs.as_slice())
修改后Vec中存储的就是带虚表的宽指针,最终as_slice()得到的切片类型完全匹配参数要求,即可正常编译。
内容的提问来源于stack exchange,提问作者kletterstein
相关产品推荐
相关产品推荐

