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
[Diagnostics] Resolves: SR-5324 Improved diagnostic when instance member of outer type is referenced from nested type #11609
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great if you could also come up with a couple more similar test-cases so we could add them into the suite. |
Of course, I will work on it right away! Thank you |
lib/Sema/CSDiag.cpp
Outdated
auto memberTypeContext = member->getDeclContext()->getInnermostTypeContext(); | ||
auto currentTypeContext = CS.DC->getInnermostTypeContext(); | ||
if (memberTypeContext->getSyntacticDepth() < currentTypeContext->getSyntacticDepth()) { | ||
diagnose(loc, diag::could_not_use_instance_member_of_outer_type_on_nested_type, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather not have a new diagnostic here. Can we emit the existing diagnostic, and have the fixit fully qualify the type name instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @slavapestov!
Could you explain the reason? I'd like to understand pros and cons of doing this.
Do I understand correctly that you suggest in this case:
struct Outer {
var outer: Int
struct Inner {
var inner: Int
func sum() -> Int {
return inner + outer
}
}
}
emit error:
instance member 'outer' cannot be used on type 'Outer.Inner'
instead of current(reported in issue):
instance member 'outer' cannot be used on type 'Outer'
Also: what do you mean by fixit? I think that compiler doesn't generate fixit in this case, at least I don't see it in Xcode.
Thanks for the help!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what @slavapestov is trying to say is that we should fix the argument of the existing diagnostic diag::could_not_use_instance_member_on_type
to say 'Outer.Inner' vs. only 'Outer' right now (first argument instanceType
) instead of creating new diagnostic with the same text, because it's already reported right after special cased one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@xedin Yeah, that’s understandable but new diagnostic doesn’t have the same text. It has different one, with different number of template arguments(3 in this case). With new one there is following message: instance member 'outer' of type 'Outer' cannot be accessed on instance of nested type 'Outer.Inner
. This gives more info than instance member ‘outer’ cannot be used on type ‘Outer.Inner
(about the variable definition scope). If we want to have this exact message(like specified in JIRA ticket) we need to have a new diagnostic. If it’s not necessary I could of course change it and implement it as @slavapestov suggests. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Kacper20 There is a way to make existing one to distinguish between on type
and on nested type
, you can add on %select{type|nested type}2
and pass the flag as a third argument (please take a look at how other diagnostics use it in DiagnosticsSema.def
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @xedin. I believe the same could be done with of type ‘Outer’
, which is also additional? Don’t know how clear will it be but let’s find out :) That’s a great tip, will look at it.
lib/Sema/CSDiag.cpp
Outdated
// provide more specialized message | ||
auto memberTypeContext = member->getDeclContext()->getInnermostTypeContext(); | ||
auto currentTypeContext = CS.DC->getInnermostTypeContext(); | ||
if (memberTypeContext->getSyntacticDepth() < currentTypeContext->getSyntacticDepth()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Syntactic depth will catch this for explicit nesting, but what about extensions of nested types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! I will check it, thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've checked it (sorry for the delay). In case of extensions it doesn't even go to this path of code. In case of writing code like:
struct Outer {
var outer: Int
struct Inner {
var inner: Int
}
}
extension Outer.Inner {
func sum() -> Int {
return inner + outer
}
}
message is use of unresolved identifier 'outer'
. Nevertheless, I've changed check to use SemanticDepth
instead. Thanks!
lib/Sema/CSDiag.cpp
Outdated
diagnose(loc, diag::could_not_use_instance_member_on_type, | ||
instanceTy, memberName) | ||
.highlight(baseRange).highlight(nameLoc.getSourceRange()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Restore the formatting here
lib/Sema/CSDiag.cpp
Outdated
diagnose(loc, diag::could_not_use_instance_member_of_outer_type_on_nested_type, | ||
memberTypeContext->getDeclaredTypeOfContext(), memberName, | ||
currentTypeContext->getDeclaredTypeOfContext() | ||
).highlight(baseRange).highlight(nameLoc.getSourceRange()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: This is stdlib-style formatting, not Swift style. Please move the dangling paren to the end of the previous line and indent the member call like highlight
below.
@slavapestov I'm not sure about this, I think I lack the knowledge of how those two relate to each other. Could you please check my last comment to your review? I've asked some questions related to this PR and I believe that answers would allow me to complete this feature(if introducing new diagnostic is not a good idea). Thanks in advance! |
b5c0e34
to
68ca0e5
Compare
@swift-ci please smoke test |
Sorry for the delay! :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@swift-ci please smoke test |
@Kacper20 Looks like this improve a bunch of other tests, so you'll have to fix that and introduced couple of new crashers which need to be addressed before we merge this, do you know how to run test suite locally? |
@xedin Yes, will fix it and let you know. I have some troubles running specific tests(lit.py failing), but will do it with full test suite. |
@Kacper20 Thanks! |
…r type references instance member of outer type
Should be fixed right now. |
@swift-ci please smoke test |
@xedin I think that this failure on Linux is unrelated to my changes. |
Yeah, I had that happen yesterday too, let's try a clean Linux build. |
@swift-ci please clean smoke test Linux platform |
@Kacper20 I'm going to squash your changes before merging if you don't mind? |
@xedin Of course, thanks! |
Merged, thanks for helping out with this, @Kacper20! |
Thanks for all of the help in implementing this @xedin, @slavapestov, @CodaFi! |
The intended behavior is described in JIRA issue.
Resolves SR-5324.
It's my first touch to the Swift compiler and I'm not sure whether it's the right approach. I'm looking for your feedback :)
Could you take a look @xedin ?
Thanks!