Skip to content

[Wildcard Variables][spec] Allow super._? #3792

Closed
@kallentu

Description

@kallentu

Let's talk about what we want to do with super._ in this issue.

Previous Discussion

I just checked, and the icky thing I disagree with is disallowing super._.

We should allow it.
If it breaks the current desugaring specification of super parameters, then define super._ as introducing a fresh name instead of no name.

Originally posted by @lrhn in #55661

I added the rule that super._ is an error because the desugaring will turn it into code that doesn't work (or code that does something completely different! - if _ in super(..., _, ...) will now denote a static or top-level declaration).

We could try to enable super._ by introducing an implicit renaming step that makes it possible for the superinitializer to denote this parameter. However, I think that would be an anomaly, and it is yet another exception to remember while coding.

So I'd prefer that we keep super._ as an error. Developers may then do the rename themselves. First case, it's in the same library:

// Current code. Breaks because `super._` will be an error.



class A {

  final int _;

  A(this._);

}



class B extends A {

  B(super._);

}
// Migrated code. No problem, no rename lints, no code outside this library can know.



class A {

  final int __;

  A(this.__);

}



class B extends A {

  B(super.__);

}

Other approaches can be used as well, of course. For example, the initializing formal in A could be turned into a normal parameter with some other name (say, __), such that the name of the instance variable wouldn't have to change, and we'd have A(int __) : _ = __;.

In the other case, where A and B are declared in two distinct libraries, we might introduce a lint message which would then need to be ignored:

class OtherB extends A {

  OtherB(super._);

}
class OtherB extends A {

  // ignore: matching_super_parameters

  OtherB(super.__);

}

In general, we will continue to allow developers to use _ as the name of some declarations. But I do not think we should bend over backwards to make it convenient to do so, at the expense of the consistency and comprehensibility of these parts of the language.

Originally posted by @eernstg in #55661

I think we should allow super._ because I don't expect users to expect an exception, so it not working is a surprising exception to them.

If the author doesn't use the name of a positional super.x parameter, it's reasonable to assume that changing it to super._ is fine. After all, they can change it to super.y or super._arglebargle without any problem.

The reasoning that the specification uses the name is meaningless to the user. Can't it just not do that? Yes, yes it can. It's an accident of specification that the name is used, not anything inherent to the feature. It used to be a safe assumption that the name given to the parameter would still be in scope and refer to the same value at the point of the super constructor invocation, so the specification chose to specify the meaning as a desugaring to an invocation that references the parameter variable. That's no longer safe if we allow super._, but that shouldn't break the wildcard feature by disallowing a meaningful use, it just means that the specification of super parameters shouldn't make that assumption any more, and should be rewritten to work anyway.

We can make it work. How we do that is up to us, it shouldn't matter to the user that we wrote a specification for super parameters that wasn't forward compatible. That's our problem, and we should solve it, and allow super._.

Originally posted by @lrhn in #55661

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions