I am attempting to set up a project very similar to dueboot. That is, Rust on embedded ARM. Right now, I'm only up to the point of compiling the Rust code, but I can't get it to compile.
I've basically copied the rust code exactly from that project, but I don't fully understand the lang_items feature.
#![feature(asm)]
#![feature(lang_items)]
#![feature(no_std)]
#![no_std]
use arduino::{init, delay, pinMode, digitalWrite, analogWrite, LOW, HIGH, OUTPUT};
mod arduino;
#[lang="sized"]
trait Sized {}
#[lang="copy"]
trait Copy {}
#[lang="sync"]
trait Sync {}
static PWM:u32 = 2;
static LED:u32 = 11;
#[no_mangle]
pub fn main() {
// ...
}
Attempting to compile the code as above, results in this error:
main.rs:11:1: 11:15 error: parameter `Self` is never used
main.rs:11 trait Sized {}
^~~~~~~~~~~~~~
main.rs:14:1: 14:14 error: parameter `Self` is never used
main.rs:14 trait Copy {}
^~~~~~~~~~~~~
main.rs:17:1: 17:14 error: parameter `Self` is never used
main.rs:17 trait Sync {}
^~~~~~~~~~~~~
error: aborting due to 3 previous errors
I also attempted to comment out all of the lines relating to the lang_items, including the feature line at the top. This is the resulting error message:
// more lines of the same message
error: requires `sized` lang_item
error: requires `sized` lang_item
error: requires `sized` lang_item
error: requires `sized` lang_item
error: requires `sized` lang_item
error: aborting due to 54 previous errors
I'm using rust built from master, as of yesterday.
Any suggestions?
A few days ago, Rust added the rule that all type parameters must appear in the methods of the trait (RFC 738). But since Sized (and Copy and Sync) doesn't have any methods of its own, it breaks this rule by default.
The official workaround is to mark the trait as PhantomFn, which silences the error:
#![feature(asm)]
#![feature(lang_items)]
#![feature(no_std)]
#![no_std]
use arduino::{init, delay, pinMode, digitalWrite, analogWrite, LOW, HIGH, OUTPUT};
mod arduino;
// Copied from <http://doc.rust-lang.org/core/marker/trait.PhantomFn.html>
#[lang="phantom_fn"]
trait PhantomFn<A: ?Sized, R: ?Sized = ()> {}
#[lang="sized"]
trait Sized: PhantomFn<Self> {}
#[lang="copy"]
trait Copy: PhantomFn<Self> {}
#[lang="sync"]
trait Sync: PhantomFn<Self> {}
static PWM:u32 = 2;
static LED:u32 = 11;
#[no_mangle]
pub fn main() {
// ...
}
This change should make the code compile again.
Addendum: What are lang items?
A lang item is a symbol that's marked as "special" to the compiler. Some examples are:
The heap allocator
Procedures for unwinding on panic
Types and traits that ensure type safety, like Send and Drop and PhantomData
Traits for operator overloading, like Add and Eq and Deref
You can find a list of them in lang_items.rs.
These items are critical to the semantics of the language, but are impractical to implement in the compiler itself. So we put them in the standard library instead, with special annotations that tell the compiler where they are.
Now, while you can define these items itself, it's recommended to link to core instead, which declares these lang items for you. But I'm not sure how well that would work with your setup.
Related
quite new to rust and trying to find myself around traits - I am working on a custom testing module and am trying to construct Result types where the Err is of a TestIssue enum that either implements an Error or Failure. I essentially want any Error type that implements std::error::Error to be convertible to a TestIssue::Error type, but also want to be able to handle cases like anyhow::Error where I can call into() to convert to an std::error::Error
#[derive(Debug)]
pub enum TestIssue<E: std::error::Error> {
Error(E),
Failure(String),
}
impl<E: std::error::Error + std::convert::From<anyhow::Error>> From<anyhow::Error> for TestIssue<E> {
fn from(error: anyhow::Error) -> TestIssue<E> {
TestIssue::Error(error.into())
}
}
impl<E: std::error::Error> From<E> for TestIssue<E> {
fn from(error: E) -> TestIssue<E> {
TestIssue::Error(error)
}
}
#[async_trait]
pub trait RunnableTest {
type Error: std::error::Error;
async fn run(&self) -> Result<(), TestIssue<Self::Error>>;
}
Strangely in some compiler errors I get, it says that the From implementations are conflicting even though anyhow::Error doesn't implement the std::error::Error trait from the docs.
conflicting implementations of trait `std::convert::From<anyhow::Error>` for type `TestIssue<anyhow::Error>`
This is confusing to me as I'd expect the From implementations to be unrelated to each other if the fact that anyhow::Error doesn't implement the std::error::Error trait still holds true...
impl<E: std::error::Error + std::convert::From<anyhow::Error>> From<anyhow::Error> for TestIssue<E> {
| --------------------------------------------------------------------------------------------------- first implementation here
...
18 | impl<E: std::error::Error> From<E> for TestIssue<E> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestIssue<anyhow::Error>`
Another issue I'm facing has to do with the RunnableTest::Error type - it appears if I have it impl std::error::Error it causes issues when attempting to return anyhow::Error in concrete implementations - I believe this has to do with the earlier issue of anyhow::Error only implementing into() but not the trait directly - When I try to change it to something like this:
type Error: Into<dyn std::error::Error + Sized>;
I get other issues like this:
31 | type Error: Into<dyn std::error::Error + Sized>;
| ----------------- ^^^^^ additional non-auto trait
Curious about how reasonable the current design is or if I'm missing something with respect to traits that could make this more simple. Given how new I am to the language, any other guidance or general comments would be much appreciated as well!
If you read the full error message, you'll note that it says:
note: upstream crates may add a new impl of trait std::error::Error for type anyhow::Error in future versions
This is a bit similar to the orphan rules. Right now the anyhow error doesn't implement the std::error::Error trait but it may choose to do so in the future and you have no control over that. This would then introduce subtle behavioral changes in your code.
Therefore, using generics and traits and trait implementations is a bit more restrictive right now than it might have to be. See discussion here:
How do I work around the "upstream crates may add a new impl of trait" error?
The way to work around this is to provide your trait implementations for concrete types, possibly using macros to reduce the amount of boilerplate, or to pick one interface (either the errors from std or the anyhow crate but not both) and stick with that.
Maybe work that out first and then come back with another question about the RunnableTest stuff? :)
Reproduction project (single main.rs file): https://github.com/frederikhors/iss-custom-err.
I'm trying to create a custom error for my app:
pub struct AppError {
message: String,
error: anyhow::Error, // In the future I would also avoid anyhow
}
I'm trying to use it in my code but as you can see I'm getting the below compiler errors, why?
Isn't my AppError implementing the trait std::error::Error correctly?
I would expect an auto conversion from hyper error to AppError being both error:Error traits, am I wrong?
error[E0277]: `?` couldn't convert the error to `AppError`
--> src\main.rs:20:44
|
20 | .body(Body::from(body))?;
| ^ the trait `From<hyper::http::Error>` is not implemented for `AppError`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following other types implement trait `FromResidual<R>`:
<Result<T, F> as FromResidual<Result<Infallible, E>>>
<Result<T, F> as FromResidual<Yeet<E>>>
= note: required because of the requirements on the impl of `FromResidual<Result<Infallible, hyper::http::Error>>` for `Result<(), AppError>`
error[E0277]: `?` couldn't convert the error to `AppError`
--> src\main.rs:24:19
|
24 | .await?;
| ^ the trait `From<hyper::Error>` is not implemented for `AppError`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following other types implement trait `FromResidual<R>`:
<Result<T, F> as FromResidual<Result<Infallible, E>>>
<Result<T, F> as FromResidual<Yeet<E>>>
= note: required because of the requirements on the impl of `FromResidual<Result<Infallible, hyper::Error>>` for `Result<(), AppError>`
For more information about this error, try `rustc --explain E0277`.
I would expect an auto conversion from hyper error to AppError being both error:Error traits, am I wrong?
Yes. Error is a usage trait, it's like IntoIterator: both Vec and HashMap implement it, but that doesn't mean you can convert an arbitrary Vec to a HashMap.
Let alone that Rust will do it for you: Rust generally favors intentionality, it avoids large multi-use concepts. So all error tells you is that you can display the type, and may be able to get its source. It says nothing about conversion, except for conversion to a Box<dyn Error> (because Error is object-safe).
So as the compiler error tells you, if you want Rust (and specifically ?) to perform the conversion, you need to implement the From trait.
Note: libraries like thiserror or snafu provide tooling to more easily create bespoke error types, and conversions from existing error types.
On discord a kind user helped me understand.
What I need is a generic impl:
impl<T: error::Error + Send + Sync + 'static> From<T> for AppError {
fn from(e: T) -> Self {
Self { message: e.to_string(), error: anyhow::Error::new(e) }
}
}
That's it!
I'm trying to mock a trait for testing, but ATM not able to implement a function.
I use the crate mockall.
Error msg is:
cannot infer an appropriate lifetime due to conflicting requirements
but, the lifetime must be valid for the static lifetime...
expected `&mut __get_mapping::Expectation<'_>`
found `&mut __get_mapping::Expectation<'static>`
I'm aware that the problem is, a lifetime conflict.
But the item passed to the closure already has an anonymous lifetime, even if I do not state it explicitly.
I tried to find some examples with a solution or hints....
But I could not find a solution.
Is there a way to specify that the returning item has a lifetime other than static?
I also tried specifying the lifetime of the return type of the closure, but the error was still the same.
My code so far is:
#[mockall::automock]
pub trait Analyzer {
//...
fn get_mapping<'a>(&'a self, old: &Item) -> Option<&'a Item>;
//...
}
fn test() {
let mut analyzer = MockAnalyzer::new();
analyzer.expect_get_mapping().returning(|item:&'_ Item| Some(item));
// also tried ... returning(|item:&'_ Item| -> Option<&'_ Item> {Some(item)})
// my initial code was ... returning(|item| Some(item))
//...
}
If your Item is Clone, you might get away with the following:
analyzer
.expect_get_mapping()
.returning(|item: &'_ Item| Some(Box::leak(Box::new(item.clone()))));
This does indeed leak heap memory, so if your test code executes this more than a few 10 million times, it may cause trouble.
In the code below: Rust Playground
//////////////////////////////////////
// External code from another crate //
//////////////////////////////////////
trait FooExternal {
fn foo(&self);
}
fn foo_external(f: impl FooExternal) {
f.foo();
}
/////////////////////////////////////
// My generated library code below //
/////////////////////////////////////
trait FooImpl {
fn foo_impl(&self);
}
impl<T: FooImpl> FooExternal for T {
fn foo(&self) {
println!("foo: boilerplate");
self.foo_impl();
}
}
////////////////////////
// My user code below //
////////////////////////
#[derive(Debug, Default)]
struct Foo;
// NB: the compiler will yell if FooImpl is not implemented
// try commenting out the impl below
impl FooImpl for Foo {
fn foo_impl(&self) {
println!("foo_impl");
}
}
fn main() {
println!("Hello, world!");
let f = Foo::default();
foo_external(f);
}
The external code expects user to supply a type that implements FooExternal, so foo_external can work on an instance of the type.
However, when implementing the FooExternal trait for a user defined struct Foo, there is some boilerplate code (e.g. setting up opentelemetry tracing span context for each tonic grpc handler) that is common and error prone and a little complex to require an end user to type out.
So I plan to generate (think: proc macro, but codegen is not the issue here!) the common boilerplate implementation of FooExternal, and want user to only focus on the core app logic, and not worrying about the complex and boring chore of typing the same boilerplate over and over again!
So, instead of having user to implement FooExternal for her type Foo, I want the user to implement a generated trait FooImpl, where in the generated blanket trait implementation of FooExternal::foo, the boilerplate code is emitted, and the control is forwarded to FooImpl::foo_impl.
Here's the nice thing in the user code: FooImpl becomes a requirement for the user type Foo (when using foo_external) - if the user forgets to implement FooImpl for Foo, the compiler would kindly yell at you when calling foo_external(f)!
So it seems that the trait blanket implementation effectively have FooExternal bound on FooImpl - even the compiler error message (when the impl FooImpl for Foo is commented out) says:
Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `Foo: FooImpl` is not satisfied
--> src/main.rs:49:18
|
49 | foo_external(f);
| ^ the trait `FooImpl` is not implemented for `Foo`
|
note: required because of the requirements on the impl of `FooExternal` for `Foo`
--> src/main.rs:23:18
|
23 | impl<T: FooImpl> FooExternal for T {
| ^^^^^^^^^^^ ^
note: required by a bound in `foo_external`
--> src/main.rs:11:25
|
11 | fn foo_external(f: impl FooExternal) {
| ^^^^^^^^^^^ required by this bound in `foo_external`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error
So, I'm wondering that is trait blanket implementation ever designed to be used in such a scenario (basically tie FooImpl and FooExternal together, a little like extension trait trait FooExternal: FooImpl, but not quite!), and can I rely on this behavior to define my code generation logic to generate the library code as in the code sample?
Any insights would be greatly appreciated!
According to the trait coherence rules, impl<T: FooImpl> FooExternal for T must be in the same crate as FooExternal. So, if you do not control the crate FooExternal is defined in, you cannot do this.
The rules are are designed so that adding more crates can never create a conflict between trait implementations that wasn't there already. There can only be one blanket implementation impl<T...> FooExternal for T (because if there was more than one, they might both apply to the same type T), and only the crate defining FooExternal is allowed to write that implementation.
There are quite a few similar errors already posted:
"Overflow evaluating the requirement" but that kind of recursion should not happen at all
What does "Overflow evaluating the requirement" mean and how can I fix it?
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]);
}
It gives this error:
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`
What is going on?
I know the following works and it is simpler than the above:
read_exact(&*conn, [0u8]);
I believe conn.borrow should work as well, I just don't understand why we have this error.
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!
}
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.
When you write
read_exact(conn.borrow(), [0u8]);
The compiler needs to solve the following obligations:
Rc<TcpStream>: Borrow<X1> due to use of borrow()
&X1: AsyncRead due to read_exact
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:
impl<X2> AsyncRead for &PollEvented<X2> where &X2: Read
impl AsyncRead for &TcpStream
impl AsyncRead for &[u8] and probably more unimportant candidates...
Again, somehow candidate 1 is selected before candidate 2. This leads to the following new set of obligations after candidate 1 is selected:
Rc<TcpStream>: Borrow<PollEvented<X2>>
&PollEvented<X2>: AsyncRead solved!
&X2: 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.
Details about how the compiler solves these equations can be found in the Rust Compiler Guide.
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.
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
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 []