Skip to content

dart2wasm: Failed null check at ClosureRepresentation.fieldIndexForSignature on a statically typed constructor tearoff expression #56372

@plammens

Description

@plammens

I get a compilation error when compiling to wasm with flutter build web --wasm --release (that I don't get with other compilation targets.) (I use a flutter command but the error happens in the dart2wasm library, so I'm posting the issue here.)

The error is:

Target dart2wasm failed: ProcessException: Process exited abnormally with exit code 64:
*NOTE*: Compilation to WasmGC is experimental.
The support may change, or be removed, with no advance notice.

Exception in ConstantExpression at [...]:70:21

Unhandled exception:
Null check operator used on a null value

Stack trace:

Details

#0      ClosureRepresentation.fieldIndexForSignature (package:dart2wasm/closures.dart:112)
#1      ConstantCreator.visitInstantiationConstant.<anonymous closure>.fillVtableEntry (package:dart2wasm/constants.dart:725)
#2      ConstantCreator.visitInstantiationConstant.<anonymous closure>.makeVtable (package:dart2wasm/constants.dart:749)
#3      ConstantCreator.visitInstantiationConstant.<anonymous closure> (package:dart2wasm/constants.dart:765)
#4      ConstantCreator.createConstant (package:dart2wasm/constants.dart:285)
#5      ConstantCreator.visitInstantiationConstant (package:dart2wasm/constants.dart:698)
#6      InstantiationConstant.accept (package:kernel/ast.dart:14209)
#7      ConstantCreator.ensureConstant (package:dart2wasm/constants.dart:252)
#8      ConstantInstantiator.defaultConstant (package:dart2wasm/constants.dart:137)
#9      ConstantVisitorDefaultMixin.visitStaticTearOffConstant (package:kernel/visitor.dart:944)
#10     InstantiationConstant.accept (package:kernel/ast.dart:14209)
#11     ConstantInstantiator.instantiate (package:dart2wasm/constants.dart:121)
#12     Constants.instantiateConstant (package:dart2wasm/constants.dart:103)
#13     CodeGenerator.visitConstantExpression (package:dart2wasm/code_generator.dart:2841)
#14     ConstantExpression.accept1 (package:kernel/ast.dart:8707)
#15     CodeGenerator.wrap (package:dart2wasm/code_generator.dart:852)
#16     CodeGenerator.visitRecordLiteral (package:dart2wasm/code_generator.dart:3086)
#17     RecordLiteral.accept1 (package:kernel/ast.dart:8490)
#18     CodeGenerator.wrap (package:dart2wasm/code_generator.dart:852)
#19     CodeGenerator.visitLet (package:dart2wasm/code_generator.dart:1669)
#20     Let.accept1 (package:kernel/ast.dart:8775)
#21     CodeGenerator.wrap (package:dart2wasm/code_generator.dart:852)
#22     CodeGenerator.visitLet (package:dart2wasm/code_generator.dart:1669)
#23     Let.accept1 (package:kernel/ast.dart:8775)
#24     CodeGenerator.wrap (package:dart2wasm/code_generator.dart:852)
#25     CodeGenerator.visitMapLiteral.<anonymous closure> (package:dart2wasm/code_generator.dart:2956)
#26     Translator.makeArray (package:dart2wasm/translator.dart:1025)
#27     CodeGenerator.makeArray (package:dart2wasm/code_generator.dart:2921)
#28     CodeGenerator.visitMapLiteral (package:dart2wasm/code_generator.dart:2949)
#29     MapLiteral.accept1 (package:kernel/ast.dart:8341)
#30     CodeGenerator.wrap (package:dart2wasm/code_generator.dart:852)
#31     CodeGenerator.visitVariableDeclaration (package:dart2wasm/code_generator.dart:1020)
#32     VariableDeclaration.accept (package:kernel/ast.dart:10791)
#33     CodeGenerator.visitStatement (package:dart2wasm/code_generator.dart:863)
#34     CodeGenerator.visitBlock (package:dart2wasm/code_generator.dart:983)
#35     Block.accept (package:kernel/ast.dart:9247)
#36     CodeGenerator.visitStatement (package:dart2wasm/code_generator.dart:863)
#37     CodeGenerator.generateBody (package:dart2wasm/code_generator.dart:557)
#38     CodeGenerator.generate (package:dart2wasm/code_generator.dart:236)
#39     Translator.translate (package:dart2wasm/translator.dart:374)
#40     compileToModule (package:dart2wasm/compile.dart:188)
<asynchronous suspension>
#41     generateWasm (package:dart2wasm/generate_wasm.dart:24)
<asynchronous suspension>
#42     main (file:///C:/b/s/w/ir/x/w/sdk/pkg/dart2wasm/bin/dart2wasm.dart:10)
<asynchronous suspension>

I've tried to write a minimal reproducible example from scratch, but I haven't succeeded, so I'll show my actual code.

The culprit of this exception, as pointed out by the error, seems to be this tearoff expression:

final Map<Type, _TypeConfig> typesConfig = {
      // [...]
      Habit: (
        enabled: isSubtype<Habit, C>(),
        typeInfo: CommitmentTypeInfo(
          name: "Habit",
          icon: Habit.icon_,
          orderKey: DiscreteHabit.commitmentTypeInfo.orderKey,
          fromMapFactory: (map) => throw UnimplementedError(),
        ),
        editScreen: EditHabit.blank   // ERROR: this is the constant expression that causes the error
      ),
     // [...]
    };

I have the following typedefs:

typedef _EditPageBuilder<C extends Commitment> = Widget Function({
  CompositeCommitment<C>? parentCommitment,
  Function(C)? onEdited,
});

typedef _TypeConfig<C extends Commitment> = ({
  bool enabled,
  CommitmentTypeInfo typeInfo,
  _EditPageBuilder<C> editScreen,
});

The problem disappears when I set:

typedef _EditPageBuilder<C extends Commitment> = dynamic;

Related code (definition of EditHabit.blank):

Details
class EditHabit<H extends Habit> extends EditCommitment<H> {
  // [...]

  EditHabit.blank({
    super.key,
    super.parentCommitment,
    super.onEdited,
  }) : super.blank(
          commitmentTypeInfo: DiscreteHabit.commitmentTypeInfo,
          titleHintText: titleHint,
        );

  // [...]
}

abstract class EditCommitment<C extends Commitment> extends Edit<C> {
  // [...]

  /// For creating a new commitment.
  const EditCommitment.blank({
    super.key,
    required CommitmentTypeInfo commitmentTypeInfo,
    required super.titleHintText,
    this.parentCommitment,
    super.onEdited,
  })  : _commitmentTypeInfo = commitmentTypeInfo,
        super.blank();

  // Should be CompositeCommitment<C> but Dart forces the type parameter to be
  // covariant, which is not desirable here.
  final CompositeCommitment? parentCommitment;

  // [...]
}

abstract class Edit<O extends CommitmentStoreObjectSnapshot>
    extends ConsumerStatefulWidget {
  // [...]

  const Edit.blank({
    super.key,
    required this.titleHintText,
    this.onEdited,
  }) : object = null;

  /// Called after the edit/creation has been successfully executed.
  final Function(O)? onEdited;

  // [...]
}

Surprisingly, I have other elements in the map above for which this error does not occur, in particular for EditTask.blank:

Details
class EditTask extends EditCommitment<Task> {
  // [...]

  const EditTask.blank({
    super.parentCommitment,
    super.key,
    super.onEdited,
  }) : super.blank(
          commitmentTypeInfo: Task.commitmentTypeInfo,
          titleHintText: titleHint,
        );

  // [...]
}

I thought the difference might be in the const, but I haven't managed to make a minimal reproducible example. Maybe someone experienced with dart2wasm will be able to do so.


  • Dart version and tooling diagnostic info (dart info)
Details
#### General info

- Dart 3.4.4 (stable) (Wed Jun 12 15:54:31 2024 +0000) on "windows_x64"
- on windows / "Windows 10 Home" 10.0 (Build 22631)
- locale is en-GB

#### Project info

- sdk constraint: '^3.4.0'
- dependencies: built_collection, cloud_firestore, collection, cupertino_icons, easy_debounce, equatable, firebase_auth, firebase_core, firebase_ui_auth, firebase_ui_oauth_google, flut
ter, flutter_fancy_tree_view, flutter_local_notifications, flutter_localizations, flutter_riverpod, flutter_speed_dial, flutter_timezone, google_sign_in, intersperse, intl, meta, modal_bottom_sheet, package_info_plus, quiver, rrule_generator, skeletonizer, sliver_tools, stream_transform, timezone, url_launcher
- dev_dependencies: custom_lint, flutter_launcher_icons, flutter_lints, flutter_test, riverpod_lint, test
- elided dependencies: 2

#### Process info

| Memory | CPU | Elapsed time | Command line |
| -----: | --: | -----------: | ------------ |
| 274 MB |  -- |              | dart.exe     |
|  30 MB |  -- |              | dart.exe     |
|   3 MB |  -- |              | dart.exe     |
| 476 MB |  -- |              | dart.exe     |
| 485 MB |  -- |              | dart.exe     |
|  94 MB |  -- |              | dart.exe     |
| 100 MB |  -- |              | dart.exe     |

  • Whether you are using Windows, macOS, or Linux (if applicable)
    Windows

  • Whether you are using Chrome, Safari, Firefox, Edge (if applicable)
    Chrome

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-dart2wasmIssues for the dart2wasm compiler.type-bugIncorrect behavior (everything from a crash to more subtle misbehavior)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions