为什么 Option 类型的 try 块需要类型注释?

Don*_*Lee 4 rust

编译器:rustc 1.71.0-nightly (c609da59d 2023-04-18)

我每晚都尝试#![feature(try_blocks)]这样做:

#![feature(try_blocks)]
fn test_try(input: Option<i32>) {
    let output = try {
        input?
    };

    println!("{:?}", output);
}
Run Code Online (Sandbox Code Playgroud)

但编译器声称output需要类型注释。完整的错误消息在这里:

error[E0282]: type annotations needed
 --> src/main.rs:3:9
  |
3 |     let output = try {
  |         ^^^^^^
  |
help: consider giving `output` an explicit type
  |
3 |     let output: /* Type */ = try {
  |               ++++++++++++
Run Code Online (Sandbox Code Playgroud)

如果我尝试let output: Option<i32> = ...一切正常。

看起来output应该是,Option<i32>但编译器并没有推断出这一点。

仅仅是因为该功能不稳定还是我错过了什么?除 之外还有其他类型Option<i32>output

Cha*_*man 9

try_blocks由于推理问题,该特征大多不稳定。特征的设计Try(为try块和?运算符提供动力)使其非常灵活,但编译器也很难推断类型。

Option<i32>在 std 中,除了可以是该表达式的结果之外,没有任何其他内容。但是我们可以写一个,因为驱动块脱糖的try不是?其中编辑的类型,而是它产生的类型。所以它可以是任何东西,只要它支持?ing Option<i32>。例如:

#![feature(try_blocks, try_trait_v2)]

use std::convert::Infallible;
use std::ops::ControlFlow;

#[derive(Debug)]
struct MyFancyType;

impl std::ops::FromResidual<Option<Infallible>> for MyFancyType {
    fn from_residual(_residual: Option<Infallible>) -> Self {
        Self
    }
}

impl std::ops::FromResidual for MyFancyType {
    fn from_residual(_residual: Infallible) -> Self {
        Self
    }
}

impl std::ops::Try for MyFancyType {
    type Output = i32;
    type Residual = Infallible;

    fn from_output(_output: i32) -> Self {
        Self
    }

    fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
        ControlFlow::Continue(0)
    }
}

fn test_try(input: Option<i32>) {
    let output: MyFancyType = try { input? };

    println!("{:?}", output);
}
Run Code Online (Sandbox Code Playgroud)

游乐场