Skip to content
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

[dart2js] Compiler crash 'classNode' was called on null #47691

Closed
edhom opened this issue Nov 13, 2021 · 4 comments
Closed

[dart2js] Compiler crash 'classNode' was called on null #47691

edhom opened this issue Nov 13, 2021 · 4 comments
Assignees
Labels
area-web Use area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop. dart2js-crash type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) web-dart2js

Comments

@edhom
Copy link

edhom commented Nov 13, 2021

The following method causes a compiler crash when building without null safety. (The getter 'classNode' was called on null)

Future<void> addElements() async {
    final elements = await _loadElements();
    for (final element in elements) {
        print(element);
    }
}

Iterating over i instead will resolve it.

Future<void> addElements() async {
    final elements = await _loadElements();
    for (var i = 0; i < elements.length; i++) {
        print(elements[i]);
    }
}

Building without sound null safety
OS: macOS Big Sur 11.4 (20F71)
Dart SDK: 2.14.4

Target dart2js failed: Exception: lib/presentation/view_models/map_screen_view_model.dart:22:16:
Internal Error: The compiler crashed when compiling this element.
  Future<void> addElements() async {
               ^
The compiler is broken.

The compiler crashed: NoSuchMethodError: The getter 'classNode' was called on null.
Receiver: null
Tried calling: classNode
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:63:5)
#1      StaticTypeVisitor.visitForInStatement (package:compiler/src/ir/static_type.dart:1577:33)
#2      ForInStatement.accept (package:kernel/ast.dart:9029:43)
#3      StaticTypeBase.visitNode (package:compiler/src/ir/static_type_base.dart:80:18)
#4      StaticTypeVisitor.visitBlock (package:compiler/src/ir/static_type.dart:1313:22)
#5      Block.accept (package:kernel/ast.dart:8489:43)
#6      StaticTypeBase.visitNode (package:compiler/src/ir/static_type_base.dart:80:18)
#7      StaticTypeVisitor.visitProcedure (package:compiler/src/ir/static_type.dart:1737:5)
#8      Procedure.accept (package:kernel/ast.dart:2831:40)
#9      KernelToElementMapImpl.computeWorldImpact (package:compiler/src/kernel/element_map_impl.dart:1440:12)
#10     KernelWorkItem.run.<anonymous closure>.<anonymous closure> (package:compiler/src/kernel/kernel_strategy.dart:395:47)
#11     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#12     KernelWorkItem.run.<anonymous closure> (package:compiler/src/kernel/kernel_strategy.dart:394:28)
#13     CompilerTask.measure (package:compiler/src/common/tasks.dart:66:51)
#14     KernelWorkItem.run (package:compiler/src/kernel/kernel_strategy.dart:369:26)
#15     Compiler.emptyQueue.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:526:70)
#16     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#17     Compiler.emptyQueue.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:526:32)
#18     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#19     Compiler.emptyQueue.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:524:28)
#20     CompilerDiagnosticReporter.withCurrentElement (package:compiler/src/compiler.dart:815:15)
#21     Compiler.emptyQueue.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:522:18)
#22     ResolutionEnqueuer._forEach (package:compiler/src/enqueue.dart:450:12)
#23     ResolutionEnqueuer.forEach (package:compiler/src/enqueue.dart:466:5)
#24     Compiler.emptyQueue.<anonymous closure> (package:compiler/src/compiler.dart:518:16)
#25     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#26     Compiler.emptyQueue (package:compiler/src/compiler.dart:517:14)
#27     Compiler.processQueue.<anonymous closure> (package:compiler/src/compiler.dart:543:7)
#28     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#29     Compiler.processQueue (package:compiler/src/compiler.dart:536:14)
#30     Compiler.computeClosedWorld (package:compiler/src/compiler.dart:382:5)
#31     Compiler.compileFromKernel.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:467:17)
#32     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#33     Compiler.compileFromKernel.<anonymous closure> (package:compiler/src/compiler.dart:466:44)
#34     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#35     Compiler.compileFromKernel (package:compiler/src/compiler.dart:465:14)
#36     Compiler.runInternal (package:compiler/src/compiler.dart:300:13)
<asynchronous suspension>
@lrhn lrhn added area-web Use area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) web-dart2js labels Nov 15, 2021
@fishythefish
Copy link
Member

How is _loadElements() defined? Is there a minimal repro?

@edhom
Copy link
Author

edhom commented Nov 16, 2021

@fishythefish I tried to break it down as much as possible. The compiler only crashes when the method is injected via riverpod (using stable version 1.0.0 here). Again, iterating over i instead of for in will prevent the compiler from crashing.

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final loadElementsProvider = Provider((ref) {
  return LoadElements();
});

class LoadElements {
  Future<List> call() => Future.value([]);
}

final viewModelProvider = Provider((ref) {
  return ViewModel(ref.read(loadElementsProvider))..init();
});

class ViewModel {
  ViewModel(this._loadElements);

  final LoadElements _loadElements;

  void init() async {
    final elements = await _loadElements();
    for (final element in elements) {
      print(element);
    }
  }
}

void main() {
  runApp(const ProviderScope(child: Example()));
}

class Example extends ConsumerWidget {
  const Example({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final model = ref.watch(viewModelProvider);
    return const SizedBox();
  }
}
Stack trace
The compiler crashed: NoSuchMethodError: The getter 'classNode' was called on null.
Receiver: null
Tried calling: classNode
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:63:5)
#1      StaticTypeVisitor.visitForInStatement (package:compiler/src/ir/static_type.dart:1577:33)
#2      ForInStatement.accept (package:kernel/ast.dart:9029:43)
#3      StaticTypeBase.visitNode (package:compiler/src/ir/static_type_base.dart:80:18)
#4      StaticTypeVisitor.visitBlock (package:compiler/src/ir/static_type.dart:1313:22)
#5      Block.accept (package:kernel/ast.dart:8489:43)
#6      StaticTypeBase.visitNode (package:compiler/src/ir/static_type_base.dart:80:18)
#7      StaticTypeVisitor.visitProcedure (package:compiler/src/ir/static_type.dart:1737:5)
#8      Procedure.accept (package:kernel/ast.dart:2831:40)
#9      KernelToElementMapImpl.computeWorldImpact (package:compiler/src/kernel/element_map_impl.dart:1440:12)
#10     KernelWorkItem.run.<anonymous closure>.<anonymous closure> (package:compiler/src/kernel/kernel_strategy.dart:395:47)
#11     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#12     KernelWorkItem.run.<anonymous closure> (package:compiler/src/kernel/kernel_strategy.dart:394:28)
#13     CompilerTask.measure (package:compiler/src/common/tasks.dart:66:51)
#14     KernelWorkItem.run (package:compiler/src/kernel/kernel_strategy.dart:369:26)
#15     Compiler.emptyQueue.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:526:70)
#16     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#17     Compiler.emptyQueue.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:526:32)
#18     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#19     Compiler.emptyQueue.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:524:28)
#20     CompilerDiagnosticReporter.withCurrentElement (package:compiler/src/compiler.dart:815:15)
#21     Compiler.emptyQueue.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:522:18)
#22     ResolutionEnqueuer._forEach (package:compiler/src/enqueue.dart:450:12)
#23     ResolutionEnqueuer.forEach (package:compiler/src/enqueue.dart:466:5)
#24     Compiler.emptyQueue.<anonymous closure> (package:compiler/src/compiler.dart:518:16)
#25     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#26     Compiler.emptyQueue (package:compiler/src/compiler.dart:517:14)
#27     Compiler.processQueue.<anonymous closure> (package:compiler/src/compiler.dart:543:7)
#28     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#29     Compiler.processQueue (package:compiler/src/compiler.dart:536:14)
#30     Compiler.computeClosedWorld (package:compiler/src/compiler.dart:382:5)
#31     Compiler.compileFromKernel.<anonymous closure>.<anonymous closure> (package:compiler/src/compiler.dart:467:17)
#32     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#33     Compiler.compileFromKernel.<anonymous closure> (package:compiler/src/compiler.dart:466:44)
#34     CompilerTask.measureSubtask (package:compiler/src/common/tasks.dart:181:35)
#35     Compiler.compileFromKernel (package:compiler/src/compiler.dart:465:14)
#36     Compiler.runInternal (package:compiler/src/compiler.dart:300:13)
<asynchronous suspension>

@fishythefish
Copy link
Member

Here's a repro without dependencies:

class LoadElements {
  Future<List> call() => Future.value([]);
}

class ViewModel {
  ViewModel(this._loadElements);

  final LoadElements _loadElements;

  void init() async {
    final elements = await _loadElements();
    for (final element in elements) {
      print(element);
    }
  }
}

void main() {
  ViewModel(LoadElements()).init();
}

Attempting to compile with or without null-safety should produce the crash. I'll try to investigate further.

@fishythefish fishythefish self-assigned this Nov 18, 2021
@fishythefish
Copy link
Member

Looks like the core issue is that visitForInStatement in StaticTypeVisitor doesn't handle the possibility that iterableType may be ir.DynamicType. It takes some effort to actually trigger this since a for-in loop over a dynamic iterable doesn't necessarily trigger this visitor.

copybara-service bot pushed a commit that referenced this issue Nov 18, 2021
Bug: #47691
Change-Id: I14a0b5f027b6a5ed74dd22b63e3c103b380823eb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220780
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-web Use area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop. dart2js-crash type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) web-dart2js
Projects
None yet
Development

No branches or pull requests

4 participants