Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smaller await #1159

Merged
merged 5 commits into from
Aug 2, 2018
Merged

Smaller await #1159

merged 5 commits into from
Aug 2, 2018

Conversation

cramertj
Copy link
Member

@cramertj cramertj commented Aug 2, 2018

async bodies are huge right now, largely due to rust-lang/rust#52924, but this change makes them quite a bit smaller. I've added tests so that we know when the sizes go up or down in response to changes-- these will be somewhat volatile in response to MIR changes, especially any work on rust-lang/rust#52924, but I think it's good for us to watch and be aware of any changes with respect to the size of the generated structures.

let mut all_done = true;
$(
if $crate::poll!($fut.reborrow()).is_pending() {
if $crate::future::Future::poll($fut.reborrow(), cx).is_pending() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's safe to use the method call syntax because we know that it's a MaybeDone future.

Copy link
Contributor

@seanmonstar seanmonstar Aug 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With macros, since they're expanded in a user's crate, you never know what other traits might be in scope that happen to have a conflicting method name. It's much safer to fully qualify the method call, and costs nothing :)

Copy link
Contributor

@MajorBreakfast MajorBreakfast Aug 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm aware of that. It's fine here because this type is under our control because we define it.

We already do the same with .reborrow() here and with non-macro code everywhere else

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MajorBreakfast the problem is the user could introduce a new trait that has a poll method and implement that for MaybeDone. That’s highly unlikely, but the only way to guarantee no method resolution errors is to always use expanded function calls.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. And it's okay for reborrow because it's an inherent method and those have precedence (I just checked that because I was curious)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, as others said we can't assume that the Future trait is in-scope or that other methods called poll haven't been provided via other traits. .reborrow() is fine because it's an inherent method.

// `.ok().unwrap()` rather than `.unwrap()` so that we don't introduce
// an `E: Debug` bound.
$fut.reborrow().take_output().unwrap().ok().unwrap(),
)*)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent indentation

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// an `E: Debug` bound.
$fut.reborrow().take_output().unwrap().ok().unwrap(),
)*))
res
Copy link
Contributor

@MajorBreakfast MajorBreakfast Aug 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's basically:

let res = await!(/* ... */);
res

You could give back the value from the expression above directly

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's intentionally done this way in order to provide the : Result<_, _> annotation .

@@ -5,7 +5,7 @@

use core::marker::Unpin;
use core::mem::PinMut;
use futures_core::future::Future;
pub use futures_core::future::Future;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be doc hidden.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And maybe a comment // Reexported for use in macros

Copy link
Contributor

@MajorBreakfast MajorBreakfast Aug 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or even better: Add a futures_core_reexport (doc hidden)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't go overboard with reexports. We should try to only use reexports in our facade and in futures_core.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

&mut $name));
if let $crate::core_reexport::task::Poll::Ready(x) = poll_res {
break __PrivResult::$name(x);
match $crate::future::Future::poll(
Copy link
Contributor

@MajorBreakfast MajorBreakfast Aug 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$crate::core_reexport::future::Future would also work. It's IMO no different than for Poll where you already do it this way

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

{
$crate::core_reexport::task::Poll::Ready(x) =>
return $crate::core_reexport::task::Poll::Ready(__PrivResult::$name(x)),
$crate::core_reexport::task::Poll::Pending => {},
Copy link
Contributor

@MajorBreakfast MajorBreakfast Aug 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this branch is empty, you could use if let $crate::...::Poll::Ready(x) = poll {} instead

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I intentionally changed it because I think it's easier to read as a match since all of the paths included are so long.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd have introduced a poll variable. But match is also fine

@cramertj cramertj merged commit 393f733 into rust-lang:master Aug 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants