Почему я получаю «переполнение, оценивающее требование` Sized` "при использовании read_exact из tokio_io с Rc <TcpStream>? - PullRequest
0 голосов
/ 05 мая 2018

Уже опубликовано довольно много похожих ошибок:

Мой случай гораздо проще и выглядит невинно:

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 тоже должно работать, я просто не понимаю, почему у нас эта ошибка.

1 Ответ

0 голосов
/ 12 мая 2018

Разница между &*conn и conn.borrow() заключается в том, что тип может иметь несколько значений заимствования .

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 s.

Когда вы пишете

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 .

Хорошей новостью является то, что система черт обновляется для использования стандартных методов логического вывода (таких как Prolog), которые позволяют правильно выводить программу OP.

Однако, до того, как будет реализован новый движок черт, если вы должны использовать 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 []
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...