rust 中的递归宏调用编译错误

问题描述 投票:0回答:1

使用此代码:

pub type StepResult = anyhow::Result<StepOperations>;

#[derive(Debug, PartialEq)]
pub struct Output {
    pub address: u32,
    pub value: u32,
}

#[derive(Debug, PartialEq)]
pub struct Operation {
    pub destination: String,
    pub source: String,
}

#[derive(Debug, PartialEq)]
pub struct StepOperations {
    pub operations: Vec<Operation>,
    pub output: Option<Output>,
}

impl StepOperations {
    pub fn new() -> StepOperations {
        return StepOperations {
            operations: vec![],
            output: None,
        }
    }
}

macro_rules! step_result {
    () => {{
        Ok(StepOperations::new())
    }};
    ( $( ($destination:expr, $source:expr) ),* ) => {
        {
            let mut temp_sr = StepOperations::new();
            $(
                temp_sr.operations.push(Operation {
                    source: String::from($source),
                    destination: String::from($destination),
                });
            )*
            Ok(temp_sr)
        }
    };
    ( $read:expr, $( ($destination:expr, $source:expr) ),* ) => {
        {
            let mut temp_sr = step_result!($( ($destination, $source) )*).unwrap();
            temp_sr.output = $read;
            Ok(temp_sr)
        }
    };
}

fn main() {
    let output = Some(Output { address: 0xdeadbeef, value: 42 });

    let step_result = step_result!(
        output,
        ("ab", "cd")
    );

    println!("{:?}", step_result);
}

我收到以下编译错误:

error[E0282]: type annotations needed
  --> src/main.rs:43:13
   |
43 |               Ok(temp_sr)
   |               ^^^^^^^^^^^ cannot infer type
...
58 |       let step_result = step_result!(
   |  _______________________-
59 | |         output,
60 | |         ("ab", "cd")
61 | |     );
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `step_result` (in Nightly builds, run with -Z macro-backtrace for more info)

我不明白为什么编译器不能在这里推断类型,这对我来说似乎很明显。我尝试在宏中添加特定类型注释,例如

StepOperations
,但这会导致显示相同的错误。

当我放弃在第三个宏中调用第二个分支时,它工作正常,但会导致代码重复。

此错误意味着什么以及如何修复它?

recursion rust compiler-errors macros
1个回答
0
投票

通过在宏的第三个分支中添加

Ok(temp_sr) as StepResult
来修复。

    ( $read:expr, $( ($destination:expr, $source:expr) ),* ) => {
        {
            let mut temp_sr = step_result!($( ($destination, $source) )*).unwrap();
            temp_sr.output = $read;
            Ok(temp_sr) as StepResult
        }
    };
© www.soinside.com 2019 - 2024. All rights reserved.