dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.22k stars 1.58k forks source link

Stack overflow from package:analyzer LeastUpperBoundHelper.getLeastUpperBound #54572

Open modulovalue opened 10 months ago

modulovalue commented 10 months ago

Consider the code example from https://github.com/dart-lang/sdk/issues/53254 and paste it into DartPad:

void foo<T extends List<S>, S extends List<T>>(T x, S y) {
  var a = (x == y) ? x : y;
}

Notice the confusing error message:

Screenshot 2024-01-09 at 13 31 20

I expected the error message to be descriptive and not confusing.

devoncarew commented 9 months ago

It looks like we're getting an error from the analysis server's analysis.getError call (not a crash, but an error result):

RequestError(method: analysis.getErrors, code: GET_ERRORS_INVALID_FILE, message: Error during `analysis.getErrors`: invalid file)
devoncarew commented 9 months ago

@scheglov - I see very strange behavior when editing this snippet in a local editor. Initially I see no analysis issues. If I remove some parts of the local variable assignment I see some. Further edits can cause the issues to update or not in unpredictable ways. It doesn't look like the analysis server is crashing but there's definitely some analysis oddities.

Switching the ternary from x : y to x : x yields predictable analysis:

void foo<T extends List<S>, S extends List<T>>(T x, S y) {
  var a = (x == y) ? x : x;
}

The value of the local variable 'a' isn't used.

scheglov commented 9 months ago

There is an exception inside the analyzer.

  Stack Overflow
  #0      _AssertionError._evaluateAssertion (dart:core-patch/errors_patch.dart:56:3)
  dart-lang/dart-pad#1      _HashBase._indexSizeToHashMask (dart:collection-patch/compact_hash.dart)
  dart-lang/dart-pad#2      _LinkedHashSetMixin._init (dart:collection-patch/compact_hash.dart:828:28)
  dart-lang/dart-pad#3      _LinkedHashSetMixin._rehash (dart:collection-patch/compact_hash.dart:811:7)
  dart-lang/dart-pad#4      _LinkedHashSetMixin._add (dart:collection-patch/compact_hash.dart:873:7)
  dart-lang/dart-pad#5      _LinkedHashSetMixin.add (dart:collection-patch/compact_hash.dart:847:12)
  dart-lang/dart-pad#6      SetBase.addAll (dart:collection/set.dart:58:33)
  dart-lang/dart-pad#7      _CompactLinkedIdentityHashSet.addAll (dart:collection-patch/compact_hash.dart:1092:11)
  dart-lang/dart-pad#8      TypeSystemImpl.greatestClosure (package:analyzer/src/dart/element/type_system.dart:623:22)
  dart-lang/dart-pad#9      LeastUpperBoundHelper.getLeastUpperBound (package:analyzer/src/dart/element/least_upper_bound.dart:565:33)
  dart-lang/dart-pad#10     TypeSystemImpl.leastUpperBound (package:analyzer/src/dart/element/type_system.dart:1572:35)
  dart-lang/dart-pad#11     InterfaceLeastUpperBoundHelper.compute (package:analyzer/src/dart/element/least_upper_bound.dart:76:31)
  dart-lang/dart-pad#12     LeastUpperBoundHelper.getLeastUpperBound (package:analyzer/src/dart/element/least_upper_bound.dart:647:19)
  dart-lang/dart-pad#13     LeastUpperBoundHelper.getLeastUpperBound (package:analyzer/src/dart/element/least_upper_bound.dart:584:14)
  dart-lang/dart-pad#14     LeastUpperBoundHelper.getLeastUpperBound (package:analyzer/src/dart/element/least_upper_bound.dart:566:14)
  dart-lang/dart-pad#15     TypeSystemImpl.leastUpperBound (package:analyzer/src/dart/element/type_system.dart:1572:35)
  dart-lang/dart-pad#16     InterfaceLeastUpperBoundHelper.compute (package:analyzer/src/dart/element/least_upper_bound.dart:76:31)
  dart-lang/dart-pad#17     LeastUpperBoundHelper.getLeastUpperBound (package:analyzer/src/dart/element/least_upper_bound.dart:647:19)
  dart-lang/dart-pad#18     LeastUpperBoundHelper.getLeastUpperBound (package:analyzer/src/dart/element/least_upper_bound.dart:584:14)
  dart-lang/dart-pad#19     LeastUpperBoundHelper.getLeastUpperBound (package:analyzer/src/dart/element/least_upper_bound.dart:566:14)
  dart-lang/dart-pad#20     TypeSystemImpl.leastUpperBound (package:analyzer/src/dart/element/type_system.dart:1572:35)
  dart-lang/dart-pad#21     InterfaceLeastUpperBoundHelper.compute (package:analyzer/src/dart/element/least_upper_bound.dart:76:31)
  dart-lang/dart-pad#22     LeastUpperBoundHelper.getLeastUpperBound (package:analyzer/src/dart/element/least_upper_bound.dart:647:19)
  dart-lang/dart-pad#23     LeastUpperBoundHelper.getLeastUpperBound (package:analyzer/src/dart/element/least_upper_bound.dart:584:14)
  dart-lang/dart-pad#24     LeastUpperBoundHelper.getLeastUpperBound (package:analyzer/src/dart/element/least_upper_bound.dart:566:14)
  dart-lang/dart-pad#25     TypeSystemImpl.leastUpperBound (package:analyzer/src/dart/element/type_system.dart:1572:35)
devoncarew commented 9 months ago

Thanks for the investigation! I'll bump this issue over to the sdk repo.

modulovalue commented 9 months ago

Note that this is a known issue, see https://github.com/dart-lang/sdk/issues/53254#issuecomment-1683624544 by @eernst for details.

~I have suggested one possible solution here: https://github.com/dart-lang/sdk/issues/53254#issuecomment-1683845625. It is not meant to resolve the issue, but to detect it and to fail early before the stack overflow occurs.~ This issue appears to have been fixed on stable, but it crashes the compiler again on beta. (https://github.com/dart-lang/sdk/issues/53254#issuecomment-1886981305)

modulovalue commented 9 months ago

I'll bump this issue over to the sdk repo.

@devoncarew This issue wasn't necessarily meant to resolve the underlying issue that causes the analysis to fail, but to point out that DartPad is outputting what appears to be raw unprocessed output from the analyzer.

That is, I expected to see an error message like the following:

Screenshot 2024-01-11 at 00 16 10