-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Index] Walk implicit DeclRefExpr with an explicit ValueDecl. #38900
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
base: main
Are you sure you want to change the base?
Conversation
All references to explicit declarations should be included in the index store, even when those references are themselves implicit. For example, a custom `appendInterpolation(custom:)` method in `DefaultStringInterpolation` is referenced implicitly via string interpolation: `"\(custom: 1)"`. Resolves: [SR-13792](https://bugs.swift.org/browse/SR-13792)
@@ -321,7 +328,8 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) { | |||
} | |||
} | |||
|
|||
if (!isa<InOutExpr>(E) && | |||
if (!IsImplicitDeclRefToExplicitDecl && | |||
!isa<InOutExpr>(E) && |
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.
Another option is to just add !isa<DeclRefExpr>(E)
here, but I'm not sure of the implications of that, so opted for the safer option.
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 agree that checking for implicit references to explicit decls is the safe choice here. There may be fully implicit cases that we want to handle, but my feeling is we're better off handling those on a case-by-case basis.
@swift-ci please smoke test |
I didn't realize there were more index related tests outside of I wonder then, if this change should only apply to Also looks like I should be able to remove some/all of |
The
I think it's worth adding to EDIT: There may be some more work to fix it for the cursor info case, but in principle I think it's fine for
I'm not sure I follow this part - what's the change that would make this possible? |
@benlangmuir @bnbarham @akyrtzi I'd like to get your thoughts on this. class ClassA {
init(){}
}
class ClassB {}
struct StructC {
var x = 0
}
func someFunc() {
_ = ClassA()
_ = ClassB()
_ = StructC()
_ = StructC(x: 0)
} Current I propose that we make these explicit references implicit, to match their declarations. |
I gave that a try, and came to the conclusion that these references should remain explicit. If we make them implicit, they're excluded from cursor info. So while they're technically implicit, I think it make sense to treat them as explicit. From the developer's perspective they look explicit, since they're references to explicit declarations. Thoughts? |
Yeah, I think the reference should be explicit here, even if the underlying decl is not. Just like a reference to a synthesized function (e.g. from Hashable or Codable synthesis) ought to be an explicit reference. |
So I definitely agree that any actual reference (whether to an explicit or implicit decl) should be explicit. I'm not so sure about the case in the PR though - it's fairly borderline as to whether it's an implicit reference or not. The label is explicit but the call really does seem implicit to me. If the only issue is that cursor info ignores implicit references but we want it do provide results for this case, I'd argue that we should just allow cursor info to visit them. I could be wrong, but my guess is that they were initially ignored because they sometimes don't have a source location, which would break Happy to take counter examples, but for the couple I can think of it would actually be useful to provide implicit references in the results - that applies for the |
Perhaps a way forward is to remove the explicit/implicit flag from references, and instead have cursor info look at the referenced decl when deciding if it should be included or not. I could be wrong, but I think in that case we'd only ever want to include explicit decls? What about others feature, e.g refactoring? In terms of detecting unused code, Periphery doesn't use the explicitness of the reference at all, only the declaration's. It looks like the work needed here it much greater than I'd originally anticipated. I wish I had more time to work on Swift 😅. |
SGTM |
I don't think we want to remove that flag from the index. I'd go ahead with what I said above, ie. just remove the implicit check on the reference in the cursor info resolver. |
Might that then include things like implicit property accessor decls in cursor info? I believe they have the same source location as the property themselves, so it sounds like they might slip past your change to Using the explicitness of the referenced decl would avoid cases like this I think. Is there a scenario in which we'd actually want a reference to an implicit decl included in cursor info? |
Also I'm still confused as to why we'd want explicit references to implicit constructors: #38900 (comment). This appears to have been an intentional change, added in 40c8904. |
I think it's reasonable for cursor info to return all involved symbols, whether implicit or not. Clients can then decide themselves whether to show them, ie. they could ignore symbols flagged with "synthesized" if there are non-synthesized symbols as well. An example there could be |
The discussion here focuses on what cursor-info should do, but AFAIK the way we walk the AST affects what symbol occurrences we get for indexing purposes. For the indexing data we need all the symbol references whether the declarations are implicit or not. For example, for the case of implicit constructors we want the capability to do an index query to find all the places where that particular type is constructed. |
Thanks, that makes sense. I'd rephrase my question a little then. Why do the references to the implicit constructors not have their implicit flag set? It has the unfortunate side effect of those references being included in cursor info, which causes Xcode to offer up the constructor as a jump to destination. If it's OK for those references to marked as implicit, it'd simplify the changes I need to make in this PR. |
The reference is explicit, the symbol is implicit/synthesized - which is now marked with |
Sorry you're right, I should have said that the reference being explicit was causing Xcode to display it, not merely it's presence in cursor info. |
New-ish but not brand new: #40062 |
All references to explicit declarations should be included in the index store, even when those references are themselves implicit. For example, a custom
appendInterpolation(custom:)
method inDefaultStringInterpolation
is referenced implicitly via string interpolation:"\(custom: 1)"
.Resolves: #56189
@benlangmuir