You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中mockall::automock与Send+Sync+Any冲突问题求解

解决Mockall中Trait同时满足Send+Sync、Any转型与Mock的编译问题

问题重现

原代码实现了一个继承Send + Sync的Trait,包含返回&dyn Any的方法,普通结构体实现该Trait可正常编译,但添加#[automock]宏后编译失败:

use std::any::Any;
use mockall::automock;

#[automock] // 添加该宏后触发编译报错
pub trait MyTrait: Send + Sync {
    fn get_next(&self) -> &dyn Any;
}

pub struct MyStruct {}

impl MyTrait for MyStruct {
    fn get_next(&self) -> &dyn Any {
        self
    }
}

编译报错信息

25 | pub trait MyTrait: Send + Sync {
   |           ^^^^^^^ `(dyn std::any::Any + 'static)` cannot be shared between threads safely
   |
   = help: the trait `Sync` is not implemented for `(dyn std::any::Any + 'static)`, which is required by `MockMyTrait: Sync`
   = note: required for `Unique<(dyn std::any::Any + 'static)>` to implement `Sync`

问题原因

dyn Any本身不自动实现Sync(或Send),而Mockall生成的MockMyTrait需要满足原Trait的Send + Sync约束。原Trait方法返回&dyn Any,意味着Mock的返回值仅被视为普通dyn Any,无法保证线程安全,因此编译器判定MockMyTrait不满足Sync约束。

解决方案

方案1:为返回的dyn Any添加Send + Sync约束(推荐)

修改Trait中方法的返回类型,明确要求返回的dyn Any同时满足Send + Sync,Mockall生成的代码会自动符合线程安全要求:

use std::any::Any;
use mockall::automock;

#[automock]
pub trait MyTrait: Send + Sync {
    // 为dyn Any追加Send + Sync约束
    fn get_next(&self) -> &(dyn Any + Send + Sync);
}

pub struct MyStruct {}

impl MyTrait for MyStruct {
    fn get_next(&self) -> &(dyn Any + Send + Sync) {
        self // 空结构体自动实现Send + Sync,类型转型合法
    }
}

方案2:手动为Mock结构体实现Send + Sync(不推荐,需unsafe)

若无法修改原Trait定义,可通过unsafe代码手动为生成的MockMyTrait实现Send + Sync,但必须确保所有Mock返回的dyn Any实例都确实满足Send + Sync,否则会引入线程安全隐患:

// 在MockMyTrait生成后添加以下unsafe实现
unsafe impl Send for MockMyTrait {}
unsafe impl Sync for MockMyTrait {}

内容的提问来源于stack exchange,提问作者Treagzhao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 23:18:19