Closed
Description
First reported at rust-lang/futures-rs#97
xx.rs:
use futures::*;
pub fn yy() -> BoxFuture<u32, ::std::io::Error> {
done(Ok(1)).boxed()
}
main.rs:
extern crate futures;
mod xx;
use futures::Future;
fn main() {
let f = xx::yy();
println!("wait: {:?}", f.wait());
}
This code works.
If use futures::Future
is commented out in main.rs
, compiler complains:
src/main.rs:10:30: 10:34 error: the trait bound `futures::Future<Error=std::io::Error, Item=u32> + Send: std::marker::Sized` is not satisfied [E0277]
src/main.rs:10 println!("wait: {:?}", f.wait());
^~~~
<std macros>:2:27: 2:58 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
src/main.rs:10:5: 10:38 note: in this expansion of println! (defined in <std macros>)
src/main.rs:10:30: 10:34 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:10:30: 10:34 note: `futures::Future<Error=std::io::Error, Item=u32> + Send` does not have a constant size known at compile-time
error: aborting due to previous error
error: Could not compile `futures-rs-td`.
I'm not sure if is it a bug, or just a usability problem, is it in futures-rs or in rust language, but it is hard to understand error message.
rustc 1.11.0 (9b21dcd 2016-08-15), futures-rs from master
cc @stepancheg
cc @jonathandturner
cc @nikomatsakis
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
luser commentedon Nov 2, 2016
This is seriously confusing. I just spend 30 minutes trying to figure it out before googling and finding this.
nikomatsakis commentedon Nov 3, 2016
I believe what is happening is this:
<Box<Future> as Future>::wait(&f)
(presumingwait()
is an&self
method)<Future as Future>::wait(&*f)
Self
type isFuture
, and I imagine thatwait()
is defined withwhere Self: Sized
Given the popularity of this pattern (e.g., iterators work the same way), it's probably worth trying to tailor an error message for this case if we can.
nikomatsakis commentedon Nov 3, 2016
I imagine something like this:
where Self: Sized
messageThe trick is...what do we say in this scenario? Advising to import the trait may not be a good fix, though we could look for trait impls on
Box<Trait>
and/or&Trait
etc and only give the message in that case.luser commentedon Nov 3, 2016
Giving the existing "import the trait" error would at least be an improvement.
Mark-Simulacrum commentedon May 15, 2017
Marking as a diagnostics issue. cc @rust-lang/compiler, perhaps we could prioritize this? It's possible that even small wins ("import the trait") here would be very good. Even just almost always doing this might be a lot better if given with the right wording.
nikomatsakis commentedon May 26, 2017
OK, so, the challenge here is that method resolution succeeds. I am a bit torn. Perhaps the easiest (and maybe even best) way to solve this is to modify method resolution itself to check for this particular case. That is, when method resolution succeeds, if this is a trait method, we could quickly scan the where-clauses for the method, looking specifically for
Self: Sized
. If we find it, we can remove it from the list and issue a customized error. I think this is how I would go about it.I'm out of time this morning for writing detailed mentoring instructions, but let me give a few pointers. I'm happy to elaborate further in the future. The method searching code is found in this module. It works in two phases: the first phase, probing, finds which method applies. That doesn't have to change here, I think.
The second phase, confirmation, does a bit of further work. Here is the implementation of the
confirm_method()
function. As part of its work, it invokesadd_obligations()
, which is what records the where clauses (later on, we will check that they are satisfied).So basically my proposal is to interject there and detect this particular case and issue a custom error.
nikomatsakis commentedon Jun 8, 2017
triage: P-medium
1 remaining item
trishume commentedon Jul 31, 2017
@raphlinus and I ran into this bug this morning when using
and_then
on aBoxFuture
without importing the trait. It took us 10+ minutes working together and replicating a skeleton of our code in play.rust-lang.org and looking for differences before we figured it out.I think @nikomatsakis's solution would have worked well for us. If it detects you trying to call a trait method with a
Self: Sized
bound it could jump up a deref-level and use the same logic that failed method resolution normally uses to suggest traits applicable toBox<Future>
you might want to import, which would find thatfutures::Future
has anand_then
method.Add a more precise error message
Auto merge of #43600 - scalexm:issue-35976, r=nikomatsakis