Skip to content

Is it intentional that class instance members can have the same name as a named constructor? #4231

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

Open
nshahan opened this issue Jan 16, 2025 · 1 comment
Labels
question Further information is requested

Comments

@nshahan
Copy link

nshahan commented Jan 16, 2025

This code produces a static error:

class C {
  int sameName = 10;
  static String sameName = "hello world";
}

main() {
  var c = C();
  print(c.sameName);
  print(C.sameName);
}
example.dart:3:17: Error: 'sameName' is already declared in this scope.
  static String sameName = "hello world";
                ^^^^^^^^
example.dart:2:7: Context: Previous declaration of 'sameName'.
  int sameName = 10;
      ^^^^^^^^
example.dart:9:11: Error: Can't use 'sameName' because it is declared more than once.
  print(C.sameName);
          ^^^^^^^^

While this code produces no errors:

class C {
  int sameName = 10;
  C.sameName() {}
}

main() {
  var c = C.sameName();
  print(c.sameName);
}

Is this expected? I see that the namespace supports it but the inconsistency is a little confusing. I came across at least one place in the SDK where this pattern exists. https://github.com/dart-lang/sdk/blob/99247f155789107b48e58667ff3a601b95364ec2/sdk/lib/developer/extension.dart#L13-L31

Overall it appears to work fine but I did hit an API in the CFE that crashes in the presence of this pattern and I'm curious if that is a bug in the CFE code. dart-lang/sdk#59910

@nshahan nshahan added the question Further information is requested label Jan 16, 2025
@lrhn
Copy link
Member

lrhn commented Jan 16, 2025

Maybe.
I don't think anyone remembers the original intent.

The rule that two members can't have the same name comes from the general rule of not allowing two declarations with the same name in the same scope, and the name of the constructor is C.sameName whereas the instance member's name is sameName, so they are not the same.

A constructor and a static member cannot have the same base name because then C.sameName is ambiguous, so that rule had to be added on top of the "same name in same scope" rule. No extra rule for instance members was ever added.

It's known that the language allows the pattern.
I've occasionally used that it's allowed.
Things like Box.value(this.value).
If the CFE chokes on it, that's a bug.

(I also think we should allow static and instance members with the same name.
You can already stimulate it using extension members, just slightly more fragile. If we ever get static extensions, it'll be even better, because an extension static member is almost indistinguishable from a static member, where the instance extension member isn't virtual.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants