-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[TypeChecker] Issue error message when accessing subscript using keyword #5537
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
Conversation
@swift-ci please test |
Build failed |
Build failed |
I'm not sure Sema is the right place to diagnose this. I think there is a way to do this in Parse and provide the fixit. Last time I took a look at this the problem I needed a backtracking scope in some awkward place or other to find the bounds of the bracketed expr, but it's been a while so maybe it will be easier this time |
Are subscripts actually fundamentally different than functions? If not, we could maybe just allow |
They are not valid member refs in the surface language so I don't think we should try to translate them to anything; they should just be banned by diagnostic like you've got here. Take a look at how I disabled |
I don't think this is the right way to go. struct S {
func `subscript`(x: Int) { }
}
let s = S()
s.subscript(x: 1) This is definitely a valid Swift code. Instead, I think what we should do is to change the "internal" identifier for |
4ad3cb5
to
97db331
Compare
Looking at the issues above, I get the feeling that the root cause is that subscripts are internally named
I'll try this path unless somebody knows for sure that this is a no-go, because subscripts are by construction required to be named |
@DougGregor and I were talking about this recently (for Oh, and the reason why you can't just use a subscript (or property) as a method is because it's unclear whether you mean the getter or the setter. I suppose you could figure that out from the argument list, but it's still |
These used to fail look-up, e.g. in 7.3:
I wonder what changed here in 8.0 that results in us now finding the member function? |
@jrose-apple Just to make sure I understand you correctly: So you propose to have a special |
Pretty much. My first thought had been to still have them carry an Identifier so that they would print right by default, but @DougGregor points out that DeclNames already control their own printing, and not doing that will help flush out bugs faster. |
This is a preparation to use special DeclNames that don't carry identifiers for subscripts, initializers, and destructors.
Once special DeclNames are used, their identity can no longer be determined by the identifier they carry and thus cannot be encoded as an opaque pointer anymore.
Use a special DeclName that doesn't have an identifier as the name of subscripts. This prevents lookup issues where a subscript decl is found when looking for a function named 'subscript'. This fixes SR-2575
Provide a real error message when trying to access a subscript using foo.subscript(key) instead of a generic one, saying that foo has no member named 'subscript'.
97db331
to
b7b886f
Compare
Sorry for the delay on this PR, I was rather busy with uni last month and the changes were bigger than I expected. In addition to this PR, PR #104 must be merged in the LLDB repo at the same time to apply the changes from ChangesI changed a lot of places in the compiler to use Thus lookup for an identifier with name "subscript" no longer returns the subscript declaration, fixing the underlying issue of SR-2575. I should note that since I changed the return value of Possible issuesI currently see three questions/issues that may need to be fixed to implement everything properly. All of these issues also apply to SerializationSerialization of modules (i.e. the thing done by I actually wanted to serialize the Since this changes the way modules are serialized, module caches may need to be emptied before compiling this PR. Representation of subscripts in SILSubscripts are AFAIK currently represented in SIL as Name mangling of subscriptsCurrently, subscripts receive a mangled name of a getter function with name |
Wow! I didn't expect you to go all the way on this. I'll look at this more later, but I don't think we want to change the behavior of |
Also, I think we do want to continue being able to treat DeclName as an opaque pointer value; we should be able to do that by jamming the "special kind" data in where an Identifier would have gone. And ObjCSelector shouldn't be net-affected at all by this change; it's never going to have one of these special kinds in it. |
Maybe a short rationale for the changes I did and why I did them:
Whenever a As to the opaque pointer value of DeclNames, I must admit that I didn't really understand what it is used for (one place used |
It's mostly an efficiency thing. A usual program has plenty of DeclNames, word-sized integers are faster to manipulate, etc etc. It also means DeclNames can themselves be put into PointerIntPairs, though I guess not if we use up all the spare bits. I realize I misinterpreted your change; I thought This is of course a huge change and so it will take me/us a while to get through reviewing it. But thank you! |
The only places this was used, though, was for the ObjC name of ObjC attributes and as an intermediate data structure in ImportName.cpp:mergeOverriddenNames. Both don't seem to be hotspots to me. OK, should I try to keep the merge conflicts at a minimum and push new commits every now and then or would you like to review the commits in one chunk? |
I'm going to review commit-by-commit anyway for a change like this, so maybe it makes sense to split it up into multiple PRs. I really do want to keep DeclName to a single pointer, though. I think it's doable. |
OK, then I'd suggest the following procedure:
|
Sounds good to me. Thanks again for working on this, Alex! |
Trying to access a subscript using
foo.subscript(key)
currently crashes the compiler. This PR creates an error message for it.I actually wanted to provide a fixit replacing
foo.subscript(key)
withfoo[key]
but that would require knowledge about whether the result offoo.subscript
will be called or not, which AFAIK is not present at the point where the member lookup was done.Resolves SR-2575.