I have a app in production using the latest stable version of Flutter:
``
Flutter (Channel stable, v1.12.13+hotfix.8, on Microsoft Windows [versão 10.0.18362.657],
locale pt-BR)
This is definetly killing me for hours and I have no idea what is going on. But iin short terms:
- I am passing a variable as parameter to a function and inside that function, it has a total different value (and type!)
This is the code :
I pass a variable `localId` to the function `finishOrCancelRecover`. In the moment I call that function, my variable is an integer of value `13983`. But inside the function it becames an `double` of value `-19.9848765`. WTF?
This is the declaration of the `localId` variable (as you can see, it is immutable!):

```dart
return lastKnownLocation
.timeout(5.seconds)
.catchError((it) => null)
.then((location) async =>
DenoxRequests.finishOrCancelRecover(
localId, //THIS VARIABLE HERE HAS A VALUE OF 13983
false,
location != null
? UserLocation(
latitude: location.latitude,
longitude: location.longitude,
deviceId: await deviceId,
)
: null))
lastKnownLocation is a call for: Future<Position> get lastKnownLocation async =>
Geolocator().getLastKnownPosition(desiredAccuracy: LocationAccuracy.high);
I've set the debugger and I got this to proove that there is something wrong:


The result of printing the localId.runtimeType confirms that this is a double now:

As you can see on the photo above, the int variable localId has a double value and the value of 19.9848765 is exactly the latitude returned by the Geolocator package. How can it be possible?
Is this a bug on the language or I am crazy here?
I PARTIALLY fixed the code by moving the inner await deviceId to above the request call. It fixes the value but the type changes to double:
Before:

Actual:

Perharps the inner pointers are getting crazy about those nested await calls?
Does this happen in Flutter release/profile mode only or does it consistently happen in Flutter debug mode?
Based on the answer we would need to ask you to provide a bit more information.
@shinayser It would seem to be a bug in our compiler. Could you provide us with a small reproduction example that triggers this? That would be very helpful.
WOW! After some hours trying to reproduce the project on pure Dart CLI app, I gave up and created a flutter project to reproduce it.
I've added as much as code I could to reproduce my real world production app, so you folks will find a lot of boilerplate code.
Thanks for the reproduction @shinayser! Things go wrong at the async transformation level - we don't correctly allocate async temporaries.
Pure Dart reduction:
foo(int x) async {
return bar(x - 1, x != null ? [x + 1, x + 2, await null] : null);
}
bar(int a, List b) {
if (a != (b[0] - 2)) {
throw 'failure: a=$a, b=$b';
}
}
void main() async {
await foo(0);
}
$ out/ReleaseX64/dart test.dart
Unhandled exception:
failure: a=1, b=[1, 2, null]
#0 bar (file:///usr/local/google/home/vegorov/src/dart/sdk/test.dart:7:5)
#1 foo (file:///usr/local/google/home/vegorov/src/dart/sdk/test.dart:2:10)
<asynchronous suspension>
#2 main (file:///usr/local/google/home/vegorov/src/dart/sdk/test.dart:12:9)
#3 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
#4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
Looking at Kernel reveals that we did not properly assign async temporary.
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
{
:async_temporary_1 = x.{core::num::-}(1); // Should be :async_temporary_2 I think.
if(!x.{core::num::==}(null)) {
:async_temporary_1 = x.{core::num::+}(1);
:async_temporary_0 = x.{core::num::+}(2);
[yield] let dynamic #t1 = asy::_awaitHelper(null, :async_op_then, :async_op_error, :async_op) in null;
:async_temporary_0 = <dynamic>[:async_temporary_1, :async_temporary_0, _in::unsafeCast<core::Null?>(:result)];
}
else {
:async_temporary_0 = null;
}
:return_value = test::bar(:async_temporary_1, :async_temporary_0);
break #L1;
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
return;
}
on dynamic catch(dynamic :exception, dynamic :stack_trace) {
:async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
}
@cskau-g Clement could you take a look at this issue? It's in the async transformation.
Alright, this issue should have been fixed at HEAD now.
Note however that it will still take a little bit for the fix to make it into a release.
Most helpful comment
Thanks for the reproduction @shinayser! Things go wrong at the async transformation level - we don't correctly allocate async temporaries.
Pure Dart reduction:
Looking at Kernel reveals that we did not properly assign async temporary.
@cskau-g Clement could you take a look at this issue? It's in the async transformation.