Library-private final fields get different instances depending on how the library was imported

I tried to find relevant issues via search but it didn’t yield anything similar.

This may be me learning, but I find following behavior really confusing.

For instance, this Dart file:

// lib/src/a.dart
final _a = new A();

class A {}

void doWithA(String from) {
  print('Hash code of A from $from: ${_a.hashCode}');

Up until now I assumed that _a would always be the same instance, but it turns out not entirely true and there can actually be multiple instances of _a depending on how import / export statements are organized in a project.

It is a bit verbose to describe in this issue so I created example project here:

Executing dart lib/main.dart there prints something like this for me:

Hash code of A from main: 931022103
Hash code of A from B: 85304837

Combination of export and import statements in that project is probably far from perfect and normally should be cleaned up. However it seems dangerous to even allow such scenarios.

Author: Fantashit

1 thought on “Library-private final fields get different instances depending on how the library was imported

  1. The current model comes from a time when we expected Dart to run in the browser and import all libraries remotely by URL. It makes much less sense when imports are always files, and all import are file: URIs (or package: URIs resolving to file: URIs).

    Changing the language specification is probably doable. We just say that the identity of package: URI-imported libraries is based on the underlying non-package: URI. It’s more complexity, but it’s definitely both specifiable and implementable (the dart:mirrors library needs to know about it if you look up libraries by URI, and might need to resolve package URIs at runtime, but otherwise it should all be front-end).

    We could go even further and allow file: URI imports to base their identity on whether they reference the same file (which would also avoid the Windows-is-case-insensitive issues), and leave it up to tooling to figure out what that actually means. (Follow symbolic links? Recognize the same hard-linked file in different directories? Not just content based!)

    In almost most cases, everything will be fine and simple, but we should at least be aware of edge cases.

Comments are closed.