Open eernstg opened 3 months ago
Yes. It should be an error if a named parameter or argument has a name starting with an underscore. (I've always assumed that to be what we had specified.)
I doubt this comes up much so I wouldn't make it a high priority, but shifting a runtime error to a static error is a clear improvement if it does come up.
It can only ever become a runtime error in dynamic calls, since no function type has a named parameter with a private name. (I hope. Did we remember to say that function types cannot have private named parameters? I think we did, CFE and analyzer both complain in DartPad.)
I doubt it ever happens in practice, but I also never intended to allow it to begin with. I'd be perfectly happy to steath-nerf the capability and claim it as a bug-fix.
Very good, so this issue will target actual arguments as well as function type parameters. The existing error occurs in the section about 'Function Declarations' and it makes sense to require that it's mentioned along with the syntax for the corresponding part of a function type (that is, <parameterTypeList>
and non-terminals derived from that).
I think all implementations already implement the rule for function types. They use the same error message as for function declarations, so maybe they just did it in the function type, and checks that the declaration is valid by checking that its type is valid.
It can only ever become a runtime error in dynamic calls, since no function type has a named parameter with a private name.
This isn't true. The code below currently prints 3.
class Foo {
noSuchMethod(_) => 3;
}
void main() {
dynamic x = Foo();
print(x.bar(_nonsense : 3));
}
I'd be fine with making this an error, but I suspect the added user value is zero, so I'm not sure it's really worth the bother.
That doesn't contradict that it can only give a runtime error for a dynamic invocation. It's just that it can also not give an error, which is slightly surprising, and worrisome.
The miniscule user benefit would be to give an early error if someone writes a private named argument by accident. Or if or happens in generated code.
The added tooling benefit is that backends can trust there to be no private named arguments, so we don't risk a compiler error instead of a runtime error.
Or incorrect behavior. For example, do we know if the symbol passed to noSuchMetod
is really private, or was it created using new Symbol("_nonsense")
? That would be valid if there were no private names.
(Checked, changing the line to
noSuchMethod(i) => i.memberName == #_nonsense;
and DartPad prints false
. I don't think that's specified behavior. In fact, I don't think we have specified what happens in this case at all. So we should either disallow, or actually specify the behavior, stating whether the symbol is private or not. Which likely means we need to do both specification, testing and either front-end or backend implementation whether we disallow it or officially allow it.)
That doesn't contradict that it can only give a runtime error for a dynamic invocation.
Sorry, I misunderstood you to be saying that every such dynamic call must result in a runtime error (and hence that no normally terminating program could have such code in it).
IMHO compiler should not threat formal named parameters, starting with _
as an error. Sometimes it is very beneficial to threat this like implementation detail. Privacy rules in this case should be applied (not available outside current library)
Thanks to @sgrekhov for bringing up this situation.
It is currently a compile-time error for a named parameter to have a name whose first character is
_
.However, it is not reported as a compile-time error when an actual argument is passed to such (non-existing) parameters:
Should we make it a compile-time error to use actual arguments with such names?
We may introduce the ability to declare a formal parameter whose name starts with
_
, but we do not (as far as I can see) have any intentions to allow the parameter to have such a name, it's only considered for situations where the formal parameter name will be computed as the 'corresponding public name'. (The corresponding public name isp
when the declared name is_p
, but it does not exist when the declared name is_
or__
or_1
, so we only intend to allow formal parameters with such declared names when other constraints are satisfied as well.)@dart-lang/language-team, WDYT? Should we report
f(_pseudoPrivateName: 1)
as a compile-time error, based on the reasoning that it cannot succeed in current programs, and most likely will never succeed even in future Dart code?