This queue is for tickets about the Future-AsyncAwait CPAN distribution.

Report information
The Basics
Id:
134790
Status:
resolved
Priority:
Low/Low

People
Owner:
Nobody in particular
Requestors:
leonerd-cpan [...] leonerd.org.uk
Cc:
AdminCc:

BugTracker
Severity:
(no value)
Broken in:
0.49
Fixed in:
(no value)



Subject: list return within try within async sub loses non-initial items
To: bug-Future-AsyncAwait@rt.cpan.org
Date: Thu, 18 Mar 2021 12:37:30 -0400
From: leonerd-cpan@leonerd.org.uk
#!/usr/bin/perl use strict; use warnings; use Test::More; use Future::AsyncAwait; use Syntax::Keyword::Try; async sub X { return ( [1,2], [3,4] ); } async sub Y { try { return await X(); } catch ($e) { die $e; } } my ($onetwo, $threefour) = await Y(); is_deeply( $onetwo, [1,2], 'first result' ); is_deeply( $threefour, [3,4], 'second result' ); done_testing; __END__ ok 1 - first result not ok 2 - second result # Failed test 'second result' # at return-list-in-try.pl line 26. # Structures begin differing at: # $got = undef # $expected = ARRAY(0x55bd70a74b10) 1..2 # Looks like you failed 1 test of 2. By commenting out the try/catch parts and having Y call X() directly, it behaves as expected and tests pass. $ perlmodversion Syntax::Keyword::Try 0.21 $ perlmodversion Future::AsyncAwait 0.49 -- Paul Evans
Initial analysis is most strange. At first I thought the problem was that `async sub` provides scalar context to its body, but nope - adding a test of `wantarray` demonstrates it's a list. OK, so next thought is what does `pp_returnintry` see for context? Turns out it sees G_ARRAY context, yet there's only one item pushed to the stack there. It could be that the `return EXPR` has been compiled into scalar context, but yet if that was the case the comma would become scalar-comma and the result would be [3,4], not [1,2]. Most most puzzling -- Paul Evans
OK, some actual progress. Much tracing of code reveals that the value goes missing in Future:/AsyncAwait.xs's call to 1961 future_get_to_stack(f, GIMME_V); as part of the await "READY" path. It passes a GIMME_V value of G_SCALAR, meaning that the `->get` method will only fetch a single value as the result. This means there's only one value on the stack at the time. I can force the issue by putting G_ARRAY in there and then the test case in this issue passes. I'm not yet sure if I feel this is the correct approach though. More thought required. -- Paul Evans
With Syntax-Keyword-Try version 0.22, this is now fixed. -- Paul Evans


This service runs on Request Tracker, is sponsored by The Perl Foundation, and maintained by Best Practical Solutions.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.