Skip to content

Extend Optional-As-Any Warning to String Interpolation Segments #5110

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
Oct 6, 2016

Conversation

CodaFi
Copy link
Contributor

@CodaFi CodaFi commented Oct 4, 2016

An implementation of warnings for optional values in string interpolation segments. We now suggest that the user either

  • Insert .debugDescription
  • Insert a cast to T?

To explicitly request a debug string representation of an optional. Further discussion of this patch can be found on the list.

Resolves SR-1882.

Basic extension of the optional-to-any AST walker to incorporate
warnings for the as-of-now up and coming Swift evolution proposal.
@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 4, 2016

@swift-ci please smoke test.

@CodaFi CodaFi force-pushed the failure-is-not-an-optional branch from 3c86749 to 31a2141 Compare October 4, 2016 02:03
print("Always some, Always some, Always some: \(o as Int?)") // No warning
print("Always some, Always some, Always some: \(o.debugDescription)") // No warning.
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you rename the test case to match the new functionality? e.g.:
diag_unintended_optional_behavior.swift
or
diag_unintended_optional_uses.swift

@@ -2411,6 +2411,14 @@ NOTE(force_optional_to_any,none,
"force-unwrap the value to avoid this warning", ())
NOTE(silence_optional_to_any,none,
"explicitly cast to Any with 'as Any' to silence this warning", ())
WARNING(optional_in_string_interpolation_segment,none,
"optional value in string interpolation can have unintended behavior",
())
Copy link
Contributor

Choose a reason for hiding this comment

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

"unintended behavior" still seems to vague to me.

Can you try to find something more specific to use 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.

Perhaps a middle ground between the two diagnostics:

string interpolation produces a debug description for an optional value; did you mean to make this explicit?


if (auto segmentTy = segment->getType()) {
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 not sure the 'if' here is absolutely necessary.


if (auto segmentTy = segment->getType()) {
if (auto baseTy = segmentTy->getOptionalObjectType()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

In the spirit of http://llvm.org/docs/CodingStandards.html#use-early-exits-and-continue-to-simplify-code, can you assign baseTy before the if and then invert the test and make it continue, unindenting the following code?

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually baseTy is only used for the message here, so perhaps you could just skip having that and instead use segmentTy and not append the '?' below?

@CodaFi CodaFi force-pushed the failure-is-not-an-optional branch 3 times, most recently from f81bcae to d7a3ffa Compare October 4, 2016 03:35
@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 4, 2016

@rudkx That should do it.

@CodaFi CodaFi force-pushed the failure-is-not-an-optional branch from d7a3ffa to cb8b8b1 Compare October 4, 2016 03:36
@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 4, 2016

@swift-ci please smoke test.

@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 4, 2016

Sigh, macOS and Linux.

@shahmishal
Copy link
Member

@swift-ci Please smoke test Linux

@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 4, 2016

Thanks @shahmishal

auto segmentTy = segment->getType();
if (auto parenType = dyn_cast<ParenType>(segmentTy.getPointer())) {
segmentTy = parenType->getUnderlyingType();
}

Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't necessary. The call to getOptionalObjectType() strips the parens, and if you rework the diagnostics to print Types rather than StringRef I believe it strips parens as well.

Here is a quick tweak I just tried, to see what I mean: https://github.com/rudkx/swift/commit/6a43b76aeb5548d9f80bba98fdcbe4d5d58c79e7

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, that's what I was looking for. Thanks!

@CodaFi CodaFi force-pushed the failure-is-not-an-optional branch from cb8b8b1 to 0243497 Compare October 4, 2016 14:10
@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 4, 2016

@swift-ci please smoke test.

Copy link
Contributor

@rudkx rudkx left a comment

Choose a reason for hiding this comment

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

LGTM!

@rudkx
Copy link
Contributor

rudkx commented Oct 4, 2016

@swift-ci Please smoke test

@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 4, 2016

Gonna give the Swift evolution discussion a chance to settle down a bit before I commit this.

@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 6, 2016

⛵️

@CodaFi CodaFi merged commit 97a99ae into swiftlang:master Oct 6, 2016
@CodaFi CodaFi deleted the failure-is-not-an-optional branch October 6, 2016 19:27
@jrose-apple
Copy link
Contributor

Since both fix-its result in the same behavior, I'm inclined to say we should just pick one and drop the other note.

@jrose-apple
Copy link
Contributor

Arguably we should still offer the ?? <#default#> fix-it as well.

@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 7, 2016

Then i'd prefer to keep the debugDescription call over everything else.

@jckarter
Copy link
Contributor

jckarter commented Oct 7, 2016

debugDescription is intended as a customization point, not something you ever call directly. I don't think we should encourage people to use it explicitly.

@jrose-apple
Copy link
Contributor

That's a good point. String(reflecting:) is supposed to be the normal entry point.

@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 7, 2016

Hm, that's a good idea. I'll amend the diagnostic and shoot ya'll another pull request.

@jtbandes
Copy link
Contributor

jtbandes commented Oct 8, 2016

Thanks, this looks great! 😄

Minor recommendations:

  • did you mean to make this explicit? isn't very clear by itself. I would recommend simply removing the semicolon and this clause.
  • what would you think of suggesting as Optional instead of as [the argument type]?

@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 9, 2016

Thanks!

  • I disagree. The diagnostic needs to be as specific as possible about what the actual behavior of this expression is and why we intend to fix it.
  • Definitely cleaner than the existing cast. I'll include it in the patch.

lichtblau added a commit to lichtblau/Noze.io that referenced this pull request Mar 22, 2017
@clearbrian
Copy link

This just fills my log code full of (String(describing:someOptional) and Xcode Fix-it is broken doesnt appear all the time especially if theres two " ...(optional1) (optional2).
I though the point of swift was LESS code not I got (String(describing:.. everywhere

@CodaFi
Copy link
Contributor Author

CodaFi commented Mar 28, 2017

@clearbrian Please file an SR about specific bugs in Swift related to Optional-as-Any diagnostics, and radars about Xcode. It may just be that you're trying to apply stale fixits, it may be something deeper, but I can't tell from this comment alone.

In addition, the diagnostic should offer more ways to fix or silence this warning than the "long way" of going through the initializer. If you rely on logging a lot of optionals, and that optionality is relevant to the log, then consider an as cast to Optional

@superarts
Copy link

This is an example of fixing a problem by introducing another.

@paulrolfe
Copy link

@CodaFi Is there any way to silence these warnings without adding so many useless lines of code to my project? Like a compiler flag or something?

@CodaFi
Copy link
Contributor Author

CodaFi commented Apr 5, 2017

The fixit offers you multiple single-line avenues for doing just that. A cast with as Optional will also silence it. This warning is an extension of Optional-as-Any analysis. Any workarounds for that apply here as well

@CodaFi
Copy link
Contributor Author

CodaFi commented Apr 5, 2017

This issue is not the most appropriate avenue of discussion about this feature. Refer to the Swift evolution thread linked at the root for details about its inclusion and the problem it solves.

I'm locking this discussion.

@swiftlang swiftlang locked and limited conversation to collaborators Apr 5, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants