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.27k stars 1.58k forks source link

Placing a positional argument after a named argument causes assertion failure in compiler #50632

Open stereotype441 opened 1 year ago

stereotype441 commented 1 year ago

I'm not sure how to reproduce this with a small test case, but I have reliable repro steps (see below).

Have a look at the difference between patchsets 1 and 2 in the following CL: https://dart-review.googlesource.com/c/sdk/+/273829/1..2

The only difference is that in patchset 1, without realizing it, I took advantage of the fact that named and positional arguments may be specified in arbitrary order; in patchset 2, I didn't. There are no other differences, and patchset 1 failed trybots.

Here is the relevant line of code, from patchset 1:

          token =
              parsePattern(next, precedence: tokenLevel + 1, patternContext);

And here is the compiler stacktrace it leads to:

  Crash when compiling file:///b/s/w/ir/cache/builder/sdk/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart at character offset 332862:
  'package:front_end/src/fasta/kernel/internal_ast.dart': Failed assertion: line 3344 pos 10: 'expression is! ThisExpression': is not true.

  dart:core-patch/errors_patch.dart 51:61                                         _AssertionError._doThrowNew
  dart:core-patch/errors_patch.dart 40:5                                          _AssertionError._throwNew
  package:front_end/src/fasta/kernel/internal_ast.dart 3344:10                    createVariable
  package:front_end/src/fasta/type_inference/inference_results.dart 165:40        SuccessfulInferenceResult.applyResult
  package:front_end/src/fasta/type_inference/inference_visitor_base.dart 2655:26  InferenceVisitorBase._inferInstanceMethodInvocation
  package:front_end/src/fasta/type_inference/inference_visitor_base.dart 3111:20  InferenceVisitorBase.inferMethodInvocation
  package:front_end/src/fasta/type_inference/inference_visitor.dart 4171:12       InferenceVisitorImpl.visitMethodInvocation

(the full stacktrace can be found at https://logs.chromium.org/logs/dart/buildbucket/cr-buildbucket/8795577674055193633/+/u/test_results/new_test_failures__logs_)

The code at line 165 of package:front_end/src/fasta/type_inference/inference_visitor_base.dart 2655 is trying to hoist the receiver of a method call (presumably the receiver is the implicit this in the call to parsePattern). It calls createVariable as part of the hoisting, which asserts because it is expecting the receiver not to be a this expression.

The assertion failure doesn't occur during compilation of the parser; it only occurs in the unit test pkg/frontend_server/test/frontend_server_test. I'm guessing this is because during the build process, the compiler we are using to compile the compiler has assertions disabled.

Repro steps

I was able to reproduce this failure locally on my Linux box by checking out patchset 1 using:

git fetch https://dart.googlesource.com/sdk refs/changes/29/273829/1 && git checkout FETCH_HEAD

Then building the SDK, then running:

out/ReleaseX64/dart-sdk/bin/dart --enable_asserts -Dtest_runner.configuration=unittest-asserts-release-linux --ignore-unrecognized-flags pkg/frontend_server/test/frontend_server_test.dart
stereotype441 commented 1 year ago

CC @johnniwinther @chloestefantsova