The language specification has a rule that prevents imports of two distinct libraries with the same name:
// lib1.dart
library clashing.nonempty.name;
// lib2.dart
library clashing.nonempty.name;
// main.dart
import "lib1.dart";
import "lib2.dart"; // Error.
main() {}
This rule was probably intended to detect cases where the use of different URIs for the same library (or even multiple textually identical copies of a library) would be considered as distinct libraries even though that was not the intention. So types would come in two incompatible copies, and programs could break at compile time or run time.
However, library directives are basically unused today, so the rule brings very little benefit.
Even worse, the rule is written in such a way that it deals with these name clashes when they occur in libraries imported to the same library, not when they occur in arbitrary locations in the transitive import graph of a given program. So the rule is almost unlikely to flag the situations that seem to be its original motivation.
In other words, this rule is useless.
We're changing the treatment of several situations (#1083): They used to be specified as warnings, but they will now be specified as errors (which is the behavior that the analyzer has had for a while already). This rule is one of them, and we could simply delete it rather than changing it from a warning to an error.
@stereotype441, @munificent, @lrhn, @natebosh, @leafpetersen, @jakemac53, WDYT?
Even worse, the rule is written in such a way that it deals with these name clashes when they occur in libraries imported to the same library, not when they occur in arbitrary locations in the transitive import graph of a given program.
That's a spec bug.
What we agreed to, when Peter wanted something that was actually modularly detectable and not just "no two libraries in the same program", was that no two different libraries transitively imported by the same library, could have the same non-empty name. You can have two libraries with the same name in the same package, as long as no Dart library depends on both (including the entry point, so that still means just one in each program, but you can name all your tests library test; without any warnings from the analyzer).
(I'm all for making it a non-error, and even no-warning, and letting the analyzer warn you if it thinks you are importing the same file in two different ways, whether that library has a name or not.)
We don't disagree on this: If we say "in the transitive imports of a given entry point" then we get the modular semantics: Every program has/is an entry point, and every library included in an execution of that program is also transitively imported from that entry point.
So if we say "no library can transitively import two distinct libraries with the same name" then we cover both modular checks and the "whole program" constraint.
But the point remains that (1) the specified and implemented behavior has a huge loophole, and (2) library directives are not common, so I'd prefer to delete the rule.
Ouch, so all the implementations have implemented the bug as well. I had thought that Peter would originally have implemented what we decided, but either he never got around to doing it, and someone later has just implemented the spec, or it has been updated later.
In any case, I think we should remove the entire rule entirely and be done with it. As written/implemented, it is just needless overhead.
Just re-tested: dart does not report this situation when the import paths to the name clash have more than one edge (but it does emit a warning when the imports are direct). The analyzer has 'No issues' with more than one edge, and an error when the imports are direct. So they do indeed implement the specified behavior.
Speaking as a user of Dart, I personally find the library name clash restriction to be 100% annoying and 0% useful. The only time I have ever wanted to have a library declaration was so that I could apply a dartdoc comment or a metadata annotation to it, and whenever that's happened I've worried about trying to come up with a unique enough library name to make sure that clients will never hit the import name clash restriction. I can't think of a single instance when the restriction has ever benefitted me. So I'm enthusiastically infavor of getting rid of it!
Speaking as a maintainer of the analyzer, removing the rule would not take much time, and every minute of it would be a delight :)
In any case, I think we should remove the entire rule entirely and be done with it. As written/implemented, it is just needless overhead.
+1.
Closing: Spec change #1083, tests https://dart-review.googlesource.com/c/sdk/+/153963; implementation issues handled via #1012.
Most helpful comment
Speaking as a user of Dart, I personally find the library name clash restriction to be 100% annoying and 0% useful. The only time I have ever wanted to have a
librarydeclaration was so that I could apply a dartdoc comment or a metadata annotation to it, and whenever that's happened I've worried about trying to come up with a unique enough library name to make sure that clients will never hit the import name clash restriction. I can't think of a single instance when the restriction has ever benefitted me. So I'm enthusiastically infavor of getting rid of it!Speaking as a maintainer of the analyzer, removing the rule would not take much time, and every minute of it would be a delight :)