rust - 为什么我使用 Rc<TcpStream> 得到 "overflow evaluating the requirement ` Sized `"when using tokio_io' s read_exact?

标签 rust

已经发布了很多类似的错误:

My case更简单,看起来无辜:

extern crate tokio_core;
extern crate tokio_io;

use std::{borrow::Borrow, rc::Rc};
use tokio_core::net::TcpStream;
use tokio_io::io::read_exact;

fn read_one(conn: Rc<TcpStream>) {
    read_exact(conn.borrow(), [0u8]);
}

它给出了这个错误:

error[E0275]: overflow evaluating the requirement `_: std::marker::Sized`
 --> src/main.rs:9:5
  |
9 |     read_exact(conn.borrow(), [0u8]);
  |     ^^^^^^^^^^
  |
  = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
  = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_core::reactor::poll_evented2::PollEvented<_>`
  = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<_>>`
  = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<_>>>`
[... snip ...]
  = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
  = note: required because of the requirements on the impl of `tokio_io::AsyncRead` for `&tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<tokio_core::reactor::poll_evented2::PollEvented<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
  = note: required by `tokio_io::io::read_exact`

这是怎么回事?

我知道下面的作品,它比上面的更简单:

read_exact(&*conn, [0u8]);

我相信 conn.borrow 应该也能正常工作,我只是不明白为什么我们会出现这个错误。

最佳答案

&*conn之间的区别和 conn.borrow()一个类型可能有多个 Borrow impls

use std::borrow::Borrow;

fn main() {
    let input = vec![1, 2, 3];

    let _slice:   &[u8]    = input.borrow(); // ok
    let _vec_ref: &Vec<u8> = input.borrow(); // also ok 

    let _slice:   &[u8]    = &*input; // ok
//  let _vec_ref: &Vec<u8> = &*input; // error!
}

&*conn表达式使用 Deref 特征,其中每种类型只能有一个 Deref执行。但是,一个类型可以有多个 Borrow<X>不同的实现 X秒。

当你写作时

read_exact(conn.borrow(), [0u8]);

编译器需要解决以下义务:

  1. Rc<TcpStream>: Borrow<X1>由于使用 borrow()
  2. &X1: AsyncRead由于 read_exact

请注意 X1是未知类型。编译器需要找出所有潜在的 X1看看是否有人可以同时履行这两项义务。义务 2 以某种方式首先被评估,最终有这些候选人:

  1. impl<X2> AsyncRead for &PollEvented<X2> where &X2: Read
  2. impl AsyncRead for &TcpStream
  3. impl AsyncRead for &[u8]可能还有更不重要的候选人……

同样,候选人 1 在候选人 2 之前以某种方式被选中。这导致在候选人 1 被选中后出现以下新的义务集:

  1. Rc<TcpStream>: Borrow<PollEvented<X2>>
  2. &PollEvented<X2>: AsyncRead 解决了!
  3. &X2: Read

然后导致 impl<X3> Read for &PollEvented<X3> where &X3: Read被选中,从这一点开始,求解器陷入无限循环并最终放弃。

有关编译器如何求解这些方程的详细信息,请参阅 Rust Compiler Guide .

好消息是特征系统正在revamped使用允许正确推断 OP 程序的标准逻辑推理技术(如 Prolog)。

但是,在新的trait引擎实现之前,如果必须使用borrow你可以通过告诉编译器什么来帮助编译器 X1应该是:

read_exact::<&TcpStream, _>(conn.borrow(), [u8]);
//           ^~~~~~~~~~ forces &X1 = &TcpStream

如果您有兴趣,以下 chalk程序证明新求解器可以对 OP 的示例进行类型检查

trait Borrow<T> {}
trait AsyncRead {}
trait Read {}

struct Ref<T> {} // meaning &T

struct Rc<T> {}
impl<T> Borrow<T> for Rc<T> {}

struct TcpStream {}
impl Read for TcpStream {}
impl AsyncRead for TcpStream {}
impl Read for Ref<TcpStream> {}
impl AsyncRead for Ref<TcpStream> {}

struct PollEvented<E> {}
impl<E> AsyncRead for Ref<PollEvented<E>> where Ref<E>: Read {}
impl<E> Read for Ref<PollEvented<E>> where Ref<E>: Read {}

// Verify:
// 
// ?- exists<X> { Ref<X>: AsyncRead, Rc<TcpStream>: Borrow<X> }
// Unique; substitution [?0 := TcpStream], lifetime constraints []

关于rust - 为什么我使用 Rc<TcpStream> 得到 "overflow evaluating the requirement ` Sized `"when using tokio_io' s read_exact?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50189976/

相关文章:

struct - 你能把 struct impl block 放在不同的文件中吗?

rust - 代码中隐藏的逻辑错误?

rust - 如何在 Rust 可执行文件中嵌入资源?

generics - 创建从任何类型到任何其他类型的闭包向量

performance - 如何提高 Rust 中逐元素乘法的性能?

multithreading - 为什么我的 Rust 线​​程没有并行运行?

c# - 如何释放 C# 中从 Rust 返回的字符串的内存?

rust - 为什么 Rust 的 if-else AST 对 then 和 else 使用不同的类型?

rust - 实现树形数据结构

rust - 在编译时使用 serde_json 反序列化文件