为什么我会得到“评估需求‘大小’的溢出"?将 tokio_io 的 read_exact 与 Rc<TcpStream> 一起使用时? [英] Why do I get "overflow evaluating the requirement `Sized`" when using tokio_io's read_exact with a Rc<TcpStream>?

查看:54
本文介绍了为什么我会得到“评估需求‘大小’的溢出"?将 tokio_io 的 read_exact 与 Rc<TcpStream> 一起使用时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

There are quite a few similar errors already posted:

我的情况要简单得多看起来很无辜:

My case is much more simple and looks innocent:

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`

这是怎么回事?

我知道以下工作,它比上面更简单:

I know the following works and it is simpler than the above:

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

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

I believe conn.borrow should work as well, I just don't understand why we have this error.

推荐答案

&*connconn.borrow() 的区别在于 a类型可能有多个借用实现.

The difference between &*conn and conn.borrow() is that a type may have multiple 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 trait,其中每种类型只能有一个 Deref 实现.但是,对于不同的 X,一个类型可以有多个 Borrow 实现.

The &*conn expression uses the Deref trait, where each type can only have a single Deref implementation. However, a type can have multiple Borrow<X> implementations for different Xs.

写作时

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

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

The compiler needs to solve the following obligations:

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

请注意,X1 是未知类型.编译器需要找出所有潜在的 X1 并查看是否有人可以同时满足这两个义务.义务 2 以某种方式首先被评估,最终得到这些候选者:

Note that X1 is an unknown type. The compiler will need to find out all potential X1s and see if anyone can fit into both obligations. Obligation 2 somehow got evaluated first, which ends up with these candidates:

  1. impl X2用于 &PollEvented 的 AsyncRead其中 &X2:阅读
  2. impl AsyncRead for &TcpStream
  3. impl AsyncRead for &[u8] 和可能更不重要的候选...
  1. impl<X2> AsyncRead for &PollEvented<X2> where &X2: Read
  2. impl AsyncRead for &TcpStream
  3. impl AsyncRead for &[u8] and probably more unimportant candidates...

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

Again, somehow candidate 1 is selected before candidate 2. This leads to the following new set of obligations after candidate 1 is selected:

  1. Rc:借用>
  2. &PollEvented: AsyncRead 解决了!
  3. &X2:阅读

然后导致 impl阅读 &PollEvented其中 &X3: Read 被选中,此时求解器陷入无限循环并最终放弃.

which then leads to impl<X3> Read for &PollEvented<X3> where &X3: Read being selected, and from this point the solver got stuck in an infinite loop and eventually gave up.

有关编译器如何求解这些方程的详细信息可以在 Rust 编译器指南.

Details about how the compiler solves these equations can be found in the Rust Compiler Guide.

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

The good news is that the trait system is being revamped to use standard logic inference techniques (like Prolog) which allows OP's program to be inferred correctly.

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

However, before the new trait engine is implemented, if you must use borrow you could help the compiler a little bit by telling it what X1 should be:

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

<小时>

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


In case you're interested, the following chalk program proves that the new solver can typecheck OP's example

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 []

这篇关于为什么我会得到“评估需求‘大小’的溢出"?将 tokio_io 的 read_exact 与 Rc&lt;TcpStream&gt; 一起使用时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆