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

Rust Syn/Quote宏生成JSON Schema时Where子句及泛型调用问题

解决Rust属性宏myschema处理带Where子句泛型函数的问题

错误1:no rules expected the token :

这个错误是因为宏解析逻辑没正确处理带Where子句的泛型函数签名。Syn解析时遇到Where子句里的类型约束冒号(比如T: std::ops::Mul<Output = T>)时,找不到匹配的解析规则——大概率是之前只解析了函数签名的部分字段,没完整捕获包含where子句的generics结构。

解决方法:用Syn的ItemFn完整解析输入函数,它会自动处理泛型参数和Where子句。

错误2:生成的辅助函数无泛型参数

生成的schema_multiply没继承原函数的泛型参数和Where子句,导致调用时传入<i32>出现参数不匹配。这是因为生成代码时没把原函数的泛型信息传递到辅助函数定义里。

完整修复代码示例

use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, ItemFn};

#[proc_macro_attribute]
pub fn myschema(_attr: TokenStream, input: TokenStream) -> TokenStream {
    // 完整解析输入函数,包含泛型、Where子句等所有信息
    let func: ItemFn = parse_macro_input!(input);
    
    let name = &func.sig.ident;
    let schema_name = format_ident!("schema_{}", name);
    let return_type = &func.sig.output;
    // 捕获原函数的泛型参数和Where子句
    let generics = &func.generics;

    let expanded = quote! {
        // 保留原函数定义
        #func

        #[allow(non_snake_case)]
        // 将泛型参数和Where子句直接复制到辅助函数定义中
        pub fn #schema_name #generics() -> schemars::schema::RootSchema {
            // 生成Schema时带上泛型参数,确保类型解析正确
            schemars::schema_for!(#return_type #generics)
        }
    };

    expanded.into()
}

验证修复效果

对于带Where子句的泛型函数:

#[myschema]
fn multiply<T>(a: T, b: T) -> T where T: std::ops::Mul<Output = T> + schemars::JsonSchema {
    a * b
}

现在生成的schema_multiply会带有完整的泛型参数和Where子句,调用schema_multiply::<i32>()时不会再出现参数不匹配的错误,同时宏解析也能正确处理Where子句中的冒号。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:12:44