Skip to content

[Diagnostics] Fix diagnostics to produce valid rename fixit for SubscriptExpr #39091

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

Merged
merged 2 commits into from
Aug 31, 2021

Conversation

mininny
Copy link
Contributor

@mininny mininny commented Aug 29, 2021

Current fixit for renamed subscripts isn't working.

struct Foo {
  subscript(_ index: Int) -> String { "hello" }

  @available(*, deprecated, renamed: "subscript(_:)")
  subscript(offset offset: Int) -> String { "hello" }
}

The resulting fix-it changes self[42] into self.subscript, which loses information, and doesn't even compile.

This PR adds support for renaming between subscripts, as well as between subscript and function calls by adding special handling for subscripts.

Resolves SR-15091

@mininny mininny force-pushed the fix-rename-subscript branch from e669592 to a5093d4 Compare August 29, 2021 15:26
@mininny mininny force-pushed the fix-rename-subscript branch from a5093d4 to 51176d4 Compare August 29, 2021 15:27
@mininny mininny changed the title Fix diagnostics to produce valid rename fixit for SubscriptExpr [Diagnostics] Fix diagnostics to produce valid rename fixit for SubscriptExpr Aug 29, 2021
Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, I have left a couple of comments inline.

// replace square brackets with parens.

diag.fixItReplace(SE->getIndex()->getStartLoc(),
("." + baseReplace.str()).str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the leading . be added to the string as a very first thing instead of concatenating here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that can happen since subscripts should always have self or a variable before the square bracket if my understanding is correct.

But this could happen in function → subscript rename, where the self. is implicitly created before the function.

function(param: 1) // implicit self.
→ should not be fixed to
[param: 1]

So I added an extra check in such scenario to check if the base expression of the function's call expression is implicit, and add self if it is. I'm assuming that if the function's base expression can be made implicit, it will always be self and be inside the same decl context. Is it correct, or should have to be checking for the decl context as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm only suggesting to append "." to a string itself instead of using concatenation in the diagnose which would just end up allocating even more strings.


func testUnavailableSubscripts(_ x: UnavailableSubscripts) {
_ = self[old: 3] // expected-error {{'subscript(old:)' has been renamed to 'subscript(new:)'}} {{14-17=new}}
_ = x[old: 3] // expected-error {{'subscript(old:)' has been renamed to 'subscript(new:)'}} {{11-14=new}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a couple of examples where subscript is renamed into a function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a test case for subscript→function few lines below on 1213-1214 :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I completely missed [ fix-it for that case...

@xedin xedin requested a review from rintaro August 30, 2021 17:01
@@ -1405,6 +1405,11 @@ ParsedDeclName swift::parseDeclName(StringRef name) {
baseName = baseName.substr(7);
}

// If the base name is prefixed by "subscript", it's an subscript.
if (baseName.startswith("subscript")) {
Copy link
Member

@rintaro rintaro Aug 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

baseName == "subscript" is more relevant? At least, we should not treat, for example, subscriptTo(_:) as isSubscript

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks :) I changed it to compare it directly

@mininny mininny force-pushed the fix-rename-subscript branch from 64e72f4 to 47a95b7 Compare August 31, 2021 14:46
@mininny mininny force-pushed the fix-rename-subscript branch from 47a95b7 to 3e8b076 Compare August 31, 2021 14:48
@xedin
Copy link
Contributor

xedin commented Aug 31, 2021

@swift-ci please smoke test

@xedin
Copy link
Contributor

xedin commented Aug 31, 2021

@swift-ci please smoke test Windows platform

1 similar comment
@xedin
Copy link
Contributor

xedin commented Aug 31, 2021

@swift-ci please smoke test Windows platform

@xedin xedin merged commit 9c8cfb3 into swiftlang:main Aug 31, 2021
@mininny mininny deleted the fix-rename-subscript branch September 1, 2021 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants