Skip to content

Dart2JS collection compiler error #48762

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

Closed
danielszopa-wk opened this issue Apr 7, 2022 · 26 comments
Closed

Dart2JS collection compiler error #48762

danielszopa-wk opened this issue Apr 7, 2022 · 26 comments
Labels
area-web-js Issues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop. web-dart2js

Comments

@danielszopa-wk
Copy link

danielszopa-wk commented Apr 7, 2022

Sadly, I don't have a small case to reproduce this & the codebase is private, but I can summarize the change that resulted in this error.

This started occurring after removing the _dtoList.removeWhere line of code below, but I found that it would continue to happen even if this _replaceDto function & its callsites were removed.

class DtoCache {
  List<Dto> _dtoList = [];

  // ...

  // Gets called as part of a code path that is listening to a stream event.
  void _replaceDto(Dto dto) {
    // If either of these lines, or the function itself are removed, I get the compiler error below.
   _dtoList.removeWhere((d) => dto.id == d.id);
   _cacheDto(dto);
  }
}

Edit: I realize it's probably useful if I include that our pubspec.lock is using collection: 1.16.0.


Name & Version of OS:

  • macOS 10.15.7
  • We also have CI running a container based on the official dart-docker image that fails with the same error. On our side we're using FROM dart:2.13.4.

Dart SDK Build Number:

  • 2.13.4

Command run: pub global run webdev build --output build -- --delete-conflicting-outputs

Error:

[SEVERE] build_web_compilers:entrypoint on web/main.dart: ExitCode:255
StdOut:
org-dartlang-app:///packages/collection/src/algorithms.dart@2303+1:
Internal Error: Runtime type information not available for type_variable_local(j:type_variable(lowerBound.E)) in (SyntheticLocal(result), local(lowerBound#sortedList), local(lowerBound#value), local(lowerBound#compare)) for j:method(lowerBound).
The compiler is broken.

When compiling the above element, the compiler crashed. It is not
possible to tell if this is caused by a problem in your program or
not. Regardless, the compiler should not crash.

The Dart team would greatly appreciate if you would take a moment to
report this problem at http://dartbug.com/new.

Please include the following information:

* the name and version of your operating system,

* the Dart SDK build number (2.13.4), and

* the entire message you see here (including the full stack trace
  below as well as the source location above).


StdErr:
Unhandled exception:
Assertion failure: Runtime type information not available for type_variable_local(j:type_variable(lowerBound.E)) in (SyntheticLocal(result), local(lowerBound#sortedList), local(lowerBound#value), local(lowerBound#compare)) for j:method(lowerBound).
#0      failedAt (package:compiler/src/diagnostics/invariant.dart:49:3)
#1      LocalsHandler.readLocal (package:compiler/src/ssa/locals_handler.dart:354:11)
#2      TypeBuilder._buildEnvironmentForType (package:compiler/src/ssa/type_builder.dart:289:12)
#3      TypeBuilder.analyzeTypeArgumentNewRti (package:compiler/src/ssa/type_builder.dart:207:9)
#4      TypeBuilder.analyzeTypeArgument (package:compiler/src/ssa/type_builder.dart:191:12)
#5      KernelSsaGraphBuilder.visitInstantiation (package:compiler/src/ssa/builder_kernel.dart:5212:24)
#6      Instantiation.accept (package:kernel/ast.dart:6291:44)
#7      KernelSsaGraphBuilder._visitPositionalArguments (package:compiler/src/ssa/builder_kernel.dart:3616:16)
#8      KernelSsaGraphBuilder._visitArgumentsForStaticTarget (package:compiler/src/ssa/builder_kernel.dart:3736:33)
#9      KernelSsaGraphBuilder.visitStaticInvocation (package:compiler/src/ssa/builder_kernel.dart:3820:11)
#10     StaticInvocation.accept (package:kernel/ast.dart:6120:44)
#11     KernelSsaGraphBuilder.visitReturnStatement (package:compiler/src/ssa/builder_kernel.dart:1797:23)
#12     ReturnStatement.accept (package:kernel/ast.dart:9497:43)
#13     KernelSsaGraphBuilder.visitBlock (package:compiler/src/ssa/builder_kernel.dart:1731:17)
#14     Block.accept (package:kernel/ast.dart:8518:43)
#15     KernelSsaGraphBuilder._visitInlinedFunction (package:compiler/src/ssa/builder_kernel.dart:6325:30)
#16     KernelSsaGraphBuilder._doInline (package:compiler/src/ssa/builder_kernel.dart:6303:5)
#17     KernelSsaGraphBuilder._tryInlineMethod.doInlining.<anonymous closure> (package:compiler/src/ssa/builder_kernel.dart:5984:11)
#18     KernelSsaGraphBuilder._inlinedFrom.<anonymous closure> (package:compiler/src/ssa/builder_kernel.dart:926:21)
#19     CompilerDiagnosticReporter.withCurrentElement (package:compiler/src/compiler.dart:819:15)
#20     KernelSsaGraphBuilder._inlinedFrom (package:compiler/src/ssa/builder_kernel.dart:924:14)
#21     KernelSsaGraphBuilder._tryInlineMethod.doInlining (package:compiler/src/ssa/builder_kernel.dart:5979:7)
#22     KernelSsaGraphBuilder._tryInlineMethod (package:compiler/src/ssa/builder_kernel.dart:5991:17)
#23     KernelSsaGraphBuilder._pushStaticInvocation (package:compiler/src/ssa/builder_kernel.dart:4939:9)
#24     KernelSsaGraphBuilder.visitStaticInvocation (package:compiler/src/ssa/builder_kernel.dart:3841:5)
#25     StaticInvocation.accept (package:kernel/ast.dart:6120:44)
#26     KernelSsaGraphBuilder.visitVariableDeclaration (package:compiler/src/ssa/builder_kernel.dart:3562:24)
#27     VariableDeclaration.accept (package:kernel/ast.dart:10058:43)
#28     KernelSsaGraphBuilder.visitBlock (package:compiler/src/ssa/builder_kernel.dart:1731:17)
#29     Block.accept (package:kernel/ast.dart:8518:43)
#30     KernelSsaGraphBuilder._visitInlinedFunction (package:compiler/src/ssa/builder_kernel.dart:6325:30)
#31     KernelSsaGraphBuilder._doInline (package:compiler/src/ssa/builder_kernel.dart:6303:5)
#32     KernelSsaGraphBuilder._tryInlineMethod.doInlining.<anonymous closure> (package:compiler/src/ssa/builder_kernel.dart:5984:11)
#33     KernelSsaGraphBuilder._inlinedFrom.<anonymous closure> (package:compiler/src/ssa/builder_kernel.dart:926:21)
#34     CompilerDiagnosticReporter.withCurrentElement (package:compiler/src/compiler.dart:819:15)
#35     KernelSsaGraphBuilder._inlinedFrom (package:compiler/src/ssa/builder_kernel.dart:924:14)
#36     KernelSsaGraphBuilder._tryInlineMethod.doInlining (package:compiler/src/ssa/builder_kernel.dart:5979:7)
#37     KernelSsaGraphBuilder._tryInlineMethod (package:compiler/src/ssa/builder_kernel.dart:5991:17)
#38     KernelSsaGraphBuilder._pushDynamicInvocation (package:compiler/src/ssa/builder_kernel.dart:5020:11)
#39     KernelSsaGraphBuilder._handleMethodInvocation (package:compiler/src/ssa/builder_kernel.dart:5245:5)
#40     KernelSsaGraphBuilder.visitInstanceInvocation (package:compiler/src/ssa/builder_kernel.dart:5259:5)
#41     InstanceInvocation.accept (package:kernel/ast.dart:5178:44)
#42     KernelSsaGraphBuilder.visitExpressionStatement (package:compiler/src/ssa/builder_kernel.dart:1765:18)
#43     ExpressionStatement.accept (package:kernel/ast.dart:8462:43)
#44     KernelSsaGraphBuilder.visitBlock (package:compiler/src/ssa/builder_kernel.dart:1731:17)
#45     Block.accept (package:kernel/ast.dart:8518:43)
#46     KernelSsaGraphBuilder._visitInlinedFunction (package:compiler/src/ssa/builder_kernel.dart:6325:30)
#47     KernelSsaGraphBuilder._doInline (package:compiler/src/ssa/builder_kernel.dart:6303:5)
#48     KernelSsaGraphBuilder._tryInlineMethod.doInlining.<anonymous closure> (package:compiler/src/ssa/builder_kernel.dart:5984:11)
#49     KernelSsaGraphBuilder._inlinedFrom.<anonymous closure> (package:compiler/src/ssa/builder_kernel.dart:926:21)
#50     CompilerDiagnosticReporter.withCurrentElement (package:compiler/src/compiler.dart:819:15)
#51     KernelSsaGraphBuilder._inlinedFrom (package:compiler/src/ssa/builder_kernel.dart:924:14)
#52     KernelSsaGraphBuilder._tryInlineMethod.doInlining (package:compiler/src/ssa/builder_kernel.dart:5979:7)
#53     KernelSsaGraphBuilder._tryInlineMethod (package:compiler/src/ssa/builder_kernel.dart:5991:17)
#54     KernelSsaGraphBuilder._pushDynamicInvocation (package:compiler/src/ssa/builder_kernel.dart:5020:11)
#55     KernelSsaGraphBuilder._handleMethodInvocation (package:compiler/src/ssa/builder_kernel.dart:5245:5)
#56     KernelSsaGraphBuilder.visitInstanceInvocation (package:compiler/src/ssa/builder_kernel.dart:5259:5)
#57     InstanceInvocation.accept (package:kernel/ast.dart:5178:44)
#58     KernelSsaGraphBuilder.visitExpressionStatement (package:compiler/src/ssa/builder_kernel.dart:1765:18)
#59     ExpressionStatement.accept (package:kernel/ast.dart:8462:43)
#60     KernelSsaGraphBuilder.visitBlock (package:compiler/src/ssa/builder_kernel.dart:1731:17)
#61     Block.accept (package:kernel/ast.dart:8518:43)
#62     KernelSsaGraphBuilder._buildForInIterator.buildBody (package:compiler/src/ssa/builder_kernel.dart:2088:17)
#63     LoopHandler.handleLoop (package:compiler/src/ssa/loop_handler.dart:85:9)
#64     KernelSsaGraphBuilder._buildForInIterator (package:compiler/src/ssa/builder_kernel.dart:2091:18)
#65     KernelSsaGraphBuilder.visitForInStatement (package:compiler/src/ssa/builder_kernel.dart:1882:7)
#66     ForInStatement.accept (package:kernel/ast.dart:9058:43)
#67     KernelSsaGraphBuilder.visitBlock (package:compiler/src/ssa/builder_kernel.dart:1731:17)
#68     Block.accept (package:kernel/ast.dart:8518:43)
#69     KernelSsaGraphBuilder._buildGeneratorBody (package:compiler/src/ssa/builder_kernel.dart:1359:23)
#70     KernelSsaGraphBuilder.build.<anonymous closure> (package:compiler/src/ssa/builder_kernel.dart:516:11)
#71     CompilerDiagnosticReporter.withCurrentElement (package:compiler/src/compiler.dart:819:15)
#72     KernelSsaGraphBuilder.build (package:compiler/src/ssa/builder_kernel.dart:429:21)
#73     KernelSsaBuilder.build.<anonymous closure> (package:compiler/src/js_model/js_strategy.dart:502:22)
#74     CompilerTask.measure (package:compiler/src/common/tasks.dart:66:51)
#75     KernelSsaBuilder.build (package:compiler/src/js_model/js_strategy.dart:485:18)
#76     SsaBuilderTask.build (package:compiler/src/ssa/ssa.dart:346:21)
#77     SsaFunctionCompiler.compile (package:compiler/src/ssa/ssa.dart:80:29)
#78     OnDemandCodegenResults.getCodegenResults (package:compiler/src/common/codegen.dart:454:30)
#79     JsBackendStrategy.generateCode (package:compiler/src/js_model/js_strategy.dart:318:43)
#80     KernelCodegenWorkItem.run (package:compiler/src/js_model/js_strategy.dart:452:29)
#81     Compiler.emptyQueue.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:530:70)
#82     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#83     Compiler.emptyQueue.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:530:32)
#84     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#85     Compiler.emptyQueue.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:528:28)
#86     CompilerDiagnosticReporter.withCurrentElement (package:compiler/src/compiler.dart:819:15)
#87     Compiler.emptyQueue.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:526:18)
#88     CodegenEnqueuer._forEach (package:compiler/src/js_backend/enqueuer.dart:269:12)
#89     CodegenEnqueuer.forEach (package:compiler/src/js_backend/enqueuer.dart:285:5)
#90     Compiler.emptyQueue.<anonymous closure> (package:compiler/src/compiler.dart:522:16)
#91     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#92     Compiler.emptyQueue (package:compiler/src/compiler.dart:521:14)
#93     Compiler.processQueue.<anonymous closure> (package:compiler/src/compiler.dart:547:7)
#94     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#95     Compiler.processQueue (package:compiler/src/compiler.dart:540:14)
#96     Compiler.runCodegenEnqueuer (package:compiler/src/compiler.dart:428:5)
#97     Compiler.generateJavaScriptCode (package:compiler/src/compiler.dart:331:9)
#98     Compiler.compileFromKernel.<anonymous closure> (package:compiler/src/compiler.dart:503:7)
#99     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#100    Compiler.compileFromKernel (package:compiler/src/compiler.dart:469:14)
#101    Compiler.runInternal (package:compiler/src/compiler.dart:304:13)
<asynchronous suspension>
@devoncarew devoncarew added the area-web-js Issues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop. label Apr 7, 2022
@sigmundch
Copy link
Member

Thanks for the bug report @danielszopa-wk

We've seen this kind of error in the past, and the cause was either a bug in our rti optimization (an optimization that removes type variables if it can determine that the type variable is not used for anything meaningful) or a bug in how data from this optimization was consumed.

There are a few things that would help us isolate this issue:

  • To confirm this is related to such optimizations, can you try adding --disable-rti-optimization as a dart2js flag? When that's provided I'd expect this crash will no longer occur, is that correct?
  • The issue may already be fixed, could you help us verify that this is not the case? We have fixed both kinds of bugs in the last year, and you may be hitting one of those fixed bugs. Is it possible for you to try a one-off compilation with the latest dev or beta version of dart2js? (we have had fixes very recently that are not in 2.16.2, but are available in 2.17.0-182.2.beta or 2.17.0-266.0.dev).
  • If the issue is still there in the latest dart2js, it would help to get more context about the function causing the crash and how it's used. It appears that the crash happens when compiling lowerBound form package:collect. Could describe or show how that function is used elsewhere in your app? Is it torn off and stored somewhere and later called indirectly? Other odd patterns you can notice? This may help us isolate the issue further.

Thanks!

FYI @fishythefish

@fishythefish
Copy link
Member

Testing with a newer version of dart2js would be great, but AFAIK all the fixes I landed for similar issues were in 2.10 or earlier, so this may be something new. It's hard to diagnose without a repro because many of the RTI optimizations are affected by the state of the whole program - things like which types all of the closures have, whether certain type tests occur anywhere in the code, etc.

@danielszopa-wk
Copy link
Author

To confirm this is related to such optimizations, can you try adding --disable-rti-optimization as a dart2js flag? When that's provided I'd expect this crash will no longer occur, is that correct?

I can confirm this is correct. I do not hit the error when using that flag.

Is it possible for you to try a one-off compilation with the latest dev or beta version of dart2js?

Since our codebase hasn't fully migrated to support null safety and apparently there are some breaking changes affecting analyzer and build_runner preventing us from using more recent versions of the SDK. @alanknight-wk would be able to elaborate better than I if you'd like more of an explanation.

It appears that the crash happens when compiling lowerBound form package:collect. Could describe or show how that function is used elsewhere in your app?

Ah I didn't even know that function existed. It appears we use lowerBound in two locations. The first is for the implementation of _cacheDto() which I omitted earlier:

    var n = lowerBound(_dtoList, dto, compare: _compareDtos);
    _dtoList.insert(n, dto);

The second callsite is essentially the same, just for a different object type.

From testing, it appears the two callsites are both being considered by the compiler as removing both appears to result in a successful build, but leaving one results in a failure.

I tried removing the callsites and attempted to reproduce this on a smaller scale but had no luck.

I noticed that lowerBound internally calls lowerBoundBy so I experimented and imported lowerBoundBy with import 'package:collection/src/algorithms.dart' as algo (don't do this in actual production code) and I was able to get a successful build by replacing both the lowerBound calls with:

    final n = algo.lowerBoundBy<Dto, Dto>(_dtoList, (value) => value, _compareDtos, dto);

Additionally, I think it's worth calling out that we're passing the --no-minify & -O3 flags to dart2js.

@sigmundch
Copy link
Member

Thanks for the updates!

@fishythefish for reference this is the definition of lowerBound:

int lowerBound<E>(List<E> sortedList, E value, {int Function(E, E)? compare}) {
  compare ??= defaultCompare;
  return lowerBoundBy<E, E>(sortedList, identity, compare, value);
}

Nothing stands out to me at the moment unforutnately.

@danielszopa-wk
Copy link
Author

Alright one more update. I poked at this some more and I found that if I updated lowerBound locally to use (value) => value instead of identity, the error went away.

int lowerBound<E>(List<E> sortedList, E value, {int Function(E, E)? compare}) {
  compare ??= defaultCompare;
  return lowerBoundBy<E, E>(sortedList, (value) => value, compare, value);
}

@fishythefish
Copy link
Member

@sigmundch: Yup, I was playing around with some small programs using lowerBound earlier and didn't see an obvious issue.

@danielszopa-wk: I wouldn't expect --no-minify to affect the result. I also don't expect -O3 to affect anything since --disable-rti-optimization is only set at -O0, but please let us know if you discover other optimization levels affecting the build.

My initial hunch is that this is related to closures, as was the case with similar issues in the past. removeWhere is passed the closure (d) => dto.id == d.id, but it would be great if you're able to also provide the implementation of _compareDtos. You also mentioned that lowerBound is called on a different type. Is the type essentially the same as Dto, or does it have e.g. a type argument? Is the comparison function for that type similar to _compareDtos?

@danielszopa-wk
Copy link
Author

danielszopa-wk commented Apr 18, 2022

I wouldn't expect --no-minify to affect the result. I also don't expect -O3 to affect anything since --disable-rti-optimization is only set at -O0, but please let us know if you discover other optimization levels affecting the build.

I actually found that -O0, -01, & -O2 all passed the build.

--no-minify didn't appear to have any impact.

it would be great if you're able to also provide the implementation of _compareDtos

Here's the two implementations:

  static int _compareDto1s(Dto1 left, Dto1 right) {
    var result = right.stringVar1.compareTo(left.stringVar1);
    if (result == 0) {
      result = left.stringVar2.compareTo(right.stringVar2);
    }
    return result;

  static int _compareDto2s(Dto2 left, Dto2 right) {
    return left.stringVar.compareTo(right.stringVar);
  }

I did think it was slightly odd that we were declaring these as static but I found that removing the static declaration didn't cause the build to pass.

You also mentioned that lowerBound is called on a different type. Is the type essentially the same as Dto, or does it have e.g. a type argument? Is the comparison function for that type similar to _compareDtos?

Neither calls specify the type argument on lowerBound (ex: lowerBound<Dto1>(...)) I tried adding them and the build still failed.

Edit: Something that's probably worth noting here is that Dto1 & Dto2 do have a common ancestor of implementing thrift's TBase reference.

@fishythefish
Copy link
Member

Thanks for the additional information! I'll try playing around with this some more to see if I can distill a repro.

Neither calls specify the type argument...

Sorry, what I meant was: are the two (implicit) type arguments similar types, or do they have some distinguishing features (e.g. one is generic) or major differences in how they're used?

@danielszopa-wk
Copy link
Author

Sorry, what I meant was: are the two (implicit) type arguments similar types, or do they have some distinguishing features (e.g. one is generic) or major differences in how they're used?

Yeah the two callsites are similar, no use of generics, they look like this:

  // Call site 1
  // _dtoList1 is a List<Dto1>
  // dto1 is a Dto1 object, no parent type like TBase is referenced / used.
  var n = lowerBound(_dto1List, dto1, compare: _compareDto1s); // See _compareDto1s in previous comment

  // Call site 2
  // _dtoList2 is a List<Dto2>
  // dto2 is a Dto2 object, no parent type like TBase is referenced / used.
  var n = lowerBound(_dto2List, dto2, compare: _compareDto2s) // See _compareDto2s in previous comment

@fishythefish
Copy link
Member

fishythefish commented Apr 20, 2022

So the fact that the breakage starts at -O3 is interesting - --omit-implicit-checks is the only flag we enable going from -O2 to -O3. This could make sense - an implicit typecheck elsewhere in the program may have been causing us to collect the missing type variable information; when those checks get omitted, the compiler crashes.

Unfortunately, I haven't yet been able to repro the crash itself, so I'm not sure what triggers the lookup of the missing type information.

@fishythefish
Copy link
Member

@danielszopa-wk The locals which are in scope when the crash occurs look like we're setting up state for inlining. Does the problem persist if you pass --disable-inlining?

@danielszopa-wk
Copy link
Author

@fishythefish I can confirm the build passes if I add the --disable-inlining flag.

@fishythefish
Copy link
Member

@danielszopa-wk Okay, great, that helps. I'll keep trying to get a repro and I may have some follow-up questions, but just a heads up that this will likely be a slow, intermittent process without direct access to an existing failure.

@greglittlefield-wf
Copy link
Contributor

We just hit another instance of this issue, where quickSort from package:collection (source) was failing to compile:

org-dartlang-app:///packages/collection/src/algorithms.dart@14383+1:
Internal Error: Runtime type information not available for type_variable_local(j:type_variable(quickSort.E)) in (SyntheticLocal(result), local(quickSort#elements), local(quickSort#compare), local(quickSort#start), local(quickSort#end)) for j:method(quickSort).
…
The full error:
org-dartlang-app:///packages/collection/src/algorithms.dart@14383+1:
Internal Error: Runtime type information not available for type_variable_local(j:type_variable(quickSort.E)) in (SyntheticLocal(result), local(quickSort#elements), local(quickSort#compare), local(quickSort#start), local(quickSort#end)) for j:method(quickSort).
The compiler is broken.

When compiling the above element, the compiler crashed. It is not
possible to tell if this is caused by a problem in your program or
not. Regardless, the compiler should not crash.

The Dart team would greatly appreciate if you would take a moment to
report this problem at http://dartbug.com/new.

Please include the following information:

* the name and version of your operating system,

* the Dart SDK build number (2.13.4), and

* the entire message you see here (including the full stack trace
  below as well as the source location above).


StdErr:
Unhandled exception:
Assertion failure: Runtime type information not available for type_variable_local(j:type_variable(quickSort.E)) in (SyntheticLocal(result), local(quickSort#elements), local(quickSort#compare), local(quickSort#start), local(quickSort#end)) for j:method(quickSort).
#0      failedAt (package:compiler/src/diagnostics/invariant.dart:49:3)
#1      LocalsHandler.readLocal (package:compiler/src/ssa/locals_handler.dart:354:11)
#2      TypeBuilder._buildEnvironmentForType (package:compiler/src/ssa/type_builder.dart:289:12)
#3      TypeBuilder.analyzeTypeArgumentNewRti (package:compiler/src/ssa/type_builder.dart:207:9)
#4      TypeBuilder.analyzeTypeArgument (package:compiler/src/ssa/type_builder.dart:191:12)
#5      KernelSsaGraphBuilder.visitInstantiation (package:compiler/src/ssa/builder_kernel.dart:5212:24)
#6      Instantiation.accept (package:kernel/ast.dart:6291:44)
#7      KernelSsaGraphBuilder._visitPositionalArguments (package:compiler/src/ssa/builder_kernel.dart:3616:16)
#8      KernelSsaGraphBuilder._visitArgumentsForStaticTarget (package:compiler/src/ssa/builder_kernel.dart:3736:33)
#9      KernelSsaGraphBuilder.visitStaticInvocation (package:compiler/src/ssa/builder_kernel.dart:3820:11)
#10     StaticInvocation.accept (package:kernel/ast.dart:6120:44)
#11     KernelSsaGraphBuilder.visitExpressionStatement (package:compiler/src/ssa/builder_kernel.dart:1765:18)
#12     ExpressionStatement.accept (package:kernel/ast.dart:8462:43)
#13     KernelSsaGraphBuilder.visitBlock (package:compiler/src/ssa/builder_kernel.dart:1731:17)
#14     Block.accept (package:kernel/ast.dart:8518:43)
#15     KernelSsaGraphBuilder._visitInlinedFunction (package:compiler/src/ssa/builder_kernel.dart:6325:30)
#16     KernelSsaGraphBuilder._doInline (package:compiler/src/ssa/builder_kernel.dart:6303:5)
#17     KernelSsaGraphBuilder._tryInlineMethod.doInlining.<anonymous closure> (package:compiler/src/ssa/builder_kernel.dart:5984:11)
#18     KernelSsaGraphBuilder._inlinedFrom.<anonymous closure> (package:compiler/src/ssa/builder_kernel.dart:926:21)
#19     CompilerDiagnosticReporter.withCurrentElement (package:compiler/src/compiler.dart:819:15)
#20     KernelSsaGraphBuilder._inlinedFrom (package:compiler/src/ssa/builder_kernel.dart:924:14)
#21     KernelSsaGraphBuilder._tryInlineMethod.doInlining (package:compiler/src/ssa/builder_kernel.dart:5979:7)
#22     KernelSsaGraphBuilder._tryInlineMethod (package:compiler/src/ssa/builder_kernel.dart:5991:17)
#23     KernelSsaGraphBuilder._pushStaticInvocation (package:compiler/src/ssa/builder_kernel.dart:4939:9)
#24     KernelSsaGraphBuilder.visitStaticInvocation (package:compiler/src/ssa/builder_kernel.dart:3841:5)
#25     StaticInvocation.accept (package:kernel/ast.dart:6120:44)
#26     KernelSsaGraphBuilder.visitExpressionStatement (package:compiler/src/ssa/builder_kernel.dart:1765:18)
#27     ExpressionStatement.accept (package:kernel/ast.dart:8462:43)
#28     KernelSsaGraphBuilder.visitBlock (package:compiler/src/ssa/builder_kernel.dart:1731:17)
#29     Block.accept (package:kernel/ast.dart:8518:43)
#30     KernelSsaGraphBuilder._buildFunctionNode (package:compiler/src/ssa/builder_kernel.dart:1260:23)
#31     KernelSsaGraphBuilder.build.<anonymous closure> (package:compiler/src/ssa/builder_kernel.dart:444:15)
#32     CompilerDiagnosticReporter.withCurrentElement (package:compiler/src/compiler.dart:819:15)
#33     KernelSsaGraphBuilder.build (package:compiler/src/ssa/builder_kernel.dart:429:21)
#34     KernelSsaBuilder.build.<anonymous closure> (package:compiler/src/js_model/js_strategy.dart:502:22)
#35     CompilerTask.measure (package:compiler/src/common/tasks.dart:66:51)
#36     KernelSsaBuilder.build (package:compiler/src/js_model/js_strategy.dart:485:18)
#37     SsaBuilderTask.build (package:compiler/src/ssa/ssa.dart:346:21)
#38     SsaFunctionCompiler.compile (package:compiler/src/ssa/ssa.dart:80:29)
#39     OnDemandCodegenResults.getCodegenResults (package:compiler/src/common/codegen.dart:454:30)
#40     JsBackendStrategy.generateCode (package:compiler/src/js_model/js_strategy.dart:318:43)
#41     KernelCodegenWorkItem.run (package:compiler/src/js_model/js_strategy.dart:452:29)
#42     Compiler.emptyQueue.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:530:70)
#43     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#44     Compiler.emptyQueue.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:530:32)
#45     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#46     Compiler.emptyQueue.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:528:28)
#47     CompilerDiagnosticReporter.withCurrentElement (package:compiler/src/compiler.dart:819:15)
#48     Compiler.emptyQueue.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:526:18)
#49     CodegenEnqueuer._forEach (package:compiler/src/js_backend/enqueuer.dart:269:12)
#50     CodegenEnqueuer.forEach (package:compiler/src/js_backend/enqueuer.dart:285:5)
#51     Compiler.emptyQueue.<anonymous closure> (package:compiler/src/compiler.dart:522:16)
#52     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#53     Compiler.emptyQueue (package:compiler/src/compiler.dart:521:14)
#54     Compiler.processQueue.<anonymous closure> (package:compiler/src/compiler.dart:547:7)
#55     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#56     Compiler.processQueue (package:compiler/src/compiler.dart:540:14)
#57     Compiler.runCodegenEnqueuer (package:compiler/src/compiler.dart:428:5)
#58     Compiler.generateJavaScriptCode (package:compiler/src/compiler.dart:331:9)
#59     Compiler.compileFromKernel.<anonymous closure> (package:compiler/src/compiler.dart:503:7)
#60     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#61     Compiler.compileFromKernel (package:compiler/src/compiler.dart:469:14)
#62     Compiler.runInternal (package:compiler/src/compiler.dart:304:13)
<asynchronous suspension>

There only seemed to be one codepath to quickSort in the package being compiled, and that was via usages of .slice, which returns a ListSlice, whose sort implementation uses quickSort. Removing those usages of .slice in this package worked around the issue: https://github.com/Workiva/json_schema/pull/145/files

This specific instance only started happening when we removed code in an unrelated package (which is unfortunately private). I tried reproducing the issue in a smaller test case with the version of that package before the code was removed, but didn't have any luck.

@fishythefish
Copy link
Member

Thanks, @greglittlefield-wf, that's helpful! Notably, both lowerBound and quickSort take a compare function with similar types (involving E), and they both delegate to other functions like lowerBoundBy/quickSortBy. Closures have been involved in similar issues in the past, so I'm curious if any of the code deleted from the unrelated package also indirectly invoked quickSort or if it involved closures with a similar type to the compare function.

@greglittlefield-wf
Copy link
Contributor

@fishythefish It seems like that's still the only usage of quickSort 😕.

I tried looking for other usages of sort or compare functions and couldn't really find anything, but the deleted code apparently referenced quite a bit of code from other packages transitively, so it's possible I missed something in there.

I also diffed the dart2js output between a build with dependencies that failed unless --disable-inlining was provided, and a build that reverted those code deletions and thus didn't fail (but was also built with --disable-inlining).

I couldn't find any different calls to sort or referencing a compare function, but I did notice that ListSlice.sort and quickSort were compiled a little differently:

Screen Shot 2022-05-27 at 2 17 08 PM

Screen Shot 2022-05-27 at 2 17 35 PM

(note that deletion lines represent the build that exhibits this bug, and addition lines the build that does not exhibit this bug)

@fishythefish
Copy link
Member

Thanks, @greglittlefield-wf! Between that info and what @danielszopa-wk provided, I think I might have a rough idea of what's going wrong. What's the best way to provide you with a fix to test?

@greglittlefield-wf
Copy link
Contributor

@fishythefish You're welcome! Thank you for looking into it!

Oh, awesome!! If there's a branch with a fix, we should be able to compile the Dart SDK locally and give it a whirl.

@fishythefish
Copy link
Member

Would just a change on Gerrit work? (I think @robbecker-wf might know how to patch this in.)

https://dart-review.googlesource.com/c/sdk/+/247609

If this doesn't fix the issue, we may have to do a bit of back-and-forth print debugging.

@greglittlefield-wf
Copy link
Contributor

That sounds perfect—we'll give that a try!

@greglittlefield-wf
Copy link
Contributor

We ended up not being able to compile that test case in the latest Dart SDK, but @alanknight-wk was able to apply the patch locally to Dart 2.13.4's builder_kernel.dart, and that appears to have fixed the issue!! 🎉

@fishythefish
Copy link
Member

Wow, that's great to hear! As a software engineer, I'm already stunned when any of my code actually works, and this was a shot in the almost-dark. :P

Ironically, an actual repro remains the most elusive part of this fix, but I'll try to land this ASAP once I get one.

@greglittlefield-wf
Copy link
Contributor

That feeling when shot in the almost-dark solutions actually work is the best 😁.

Awesome, thank you! Please let us know if we can help provide more clues around how to repro the issue.

@fishythefish
Copy link
Member

@danielszopa-wk @greglittlefield-wf I'm starting to suspect that there's another latent bug related to instantiations which is making this tricky to reproduce. Could you uncomment the following code and share what it prints for a successful build and for a failing build? Ideally, this is with a minimal change to the code, like replacing identity with (x) => x in Daniel's example.

/*print(typeVariableTests.dump());
print('------------------------------------------------------------------');
print('classesNeedingTypeArguments:');
classesNeedingTypeArguments.forEach((e) => print(' $e'));
print('------------------------------------------------------------------');
print('methodsNeedingSignature:');
methodsNeedingSignature.forEach((e) => print(' $e'));
print('------------------------------------------------------------------');
print('methodsNeedingTypeArguments:');
methodsNeedingTypeArguments.forEach((e) => print(' $e'));
print('------------------------------------------------------------------');
print('localFunctionsNeedingSignature:');
localFunctionsNeedingSignature.forEach((e) => print(' $e'));
print('------------------------------------------------------------------');
print('localFunctionsNeedingTypeArguments:');
localFunctionsNeedingTypeArguments.forEach((e) => print(' $e'));
print('------------------------------------------------------------------');
print('selectorsNeedingTypeArguments:');
selectorsNeedingTypeArguments.forEach((e) => print(' $e'));
print('instantiationsNeedingTypeArguments: '
'$instantiationsNeedingTypeArguments');*/

Depending on the size of the application, this might dump a lot of info - hopefully it isn't too sensitive.

@alanknight-wk
Copy link

Hmm. It is indeed a lot of data, about 1.1MB in each case. I'll have to ask about the sensitivity. However, the difference between the two is extremely slight. The passing version is created by adding the line

_contextList.removeWhere((dto) => dto.id == context.id);
in the method

void _replaceContext(ContextDTO context) {

In the passing version, there is an extra line for that method

k:local_function(_replaceContext.<anonymous>)

and in the failing version at the end there is

instantiationsNeedingTypeArguments: {1}
org-dartlang-app:///packages/collection/src/algorithms.dart@2303+1:
Internal Error: ...

where in the passing version it still lists

instantiationsNeedingTypeArguments: {1}

but then succeeds.

@fishythefish
Copy link
Member

fishythefish commented Jun 15, 2022

Thanks for looking into it, @alanknight-wk. I'm going to mark this issue closed for now since it sounds like the CL fixes the issue and we don't have a repro to investigate further. There have been some minor changes to the way we handle generic instantiations since 2.13.4, so that might make it difficult to isolate a repro as well. Please feel free to reopen or file a new issue if you run into this again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-web-js Issues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop. web-dart2js
Projects
None yet
Development

No branches or pull requests

6 participants