Skip to content

[CodeComplete] Use PrintOptionalAsImplicitlyUnwrapped to print IUO #18217

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 1 commit into from
Jul 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions lib/IDE/CodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2481,16 +2481,17 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
// What's left is the result type.
if (ResultType->isVoid()) {
OS << "Void";
} else if (!IsImplicitlyCurriedInstanceMethod
&& FD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>()) {
} else {
// As we did with parameters in addParamPatternFromFunction,
// for regular methods we'll print '!' after implicitly
// unwrapped optional results.
auto ObjectType = ResultType->getOptionalObjectType();
OS << ObjectType->getStringAsComponent();
Copy link
Member Author

@rintaro rintaro Jul 25, 2018

Choose a reason for hiding this comment

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

I couldn't find a reproducer for this crash. But we have several logs crashed in here. It means, result type is resolved as non-optional even when the function decl has ImplicitlyUnwrappedOptionalAttr.
@rudkx Are you able to come up with a possibility that causes this situation?

Copy link
Contributor

Choose a reason for hiding this comment

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

The only thing I can think of is that this is related to the adjustment of FunctionType earlier in the function.

OS << "!";
} else {
ResultType.print(OS);
bool IsIUO =
!IsImplicitlyCurriedInstanceMethod &&
FD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();

PrintOptions PO;
PO.PrintOptionalAsImplicitlyUnwrapped = IsIUO;
ResultType.print(OS, PO);
Copy link
Contributor

Choose a reason for hiding this comment

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

This fix is going to cause other problems. All optionals will be printed with !, so if e.g. if you try your change with a function that returns [Int?]!, I think you'll find it prints as [Int!]!.

This applies to the earlier fix for parameters as well.

Copy link
Member 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 so. This option only applies to the first Optional found.
https://github.com/apple/swift/blob/master/lib/AST/ASTPrinter.cpp#L3748-L3754

I will add a test case for it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah yes, you're right, I had forgotten the code ensured that.

}
}
Builder.addTypeAnnotation(TypeStr);
Expand Down
9 changes: 2 additions & 7 deletions lib/IDE/CodeCompletionResultBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,13 +372,8 @@ class CodeCompletionResultBuilder {

PrintOptions PO;
PO.SkipAttributes = true;
std::string TypeName;
if (IsIUO) {
assert(Ty->getOptionalObjectType());
TypeName = Ty->getOptionalObjectType()->getStringAsComponent(PO) + "!";
Copy link
Member Author

@rintaro rintaro Jul 25, 2018

Choose a reason for hiding this comment

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

In theory, this shouldn't crash. But this crash was caused by
https://github.com/apple/swift/blob/e9cb62d476496787ccc92c506e9059db58c96614/lib/IDE/CodeCompletion.cpp#L2177-L2180

This hack is not enough.

In fact, this fix still doesn't produce correct result, but at least, it fixes the crashes. I want to include this fix for 4.2. I will fix this FIXME for later releases.

} else {
TypeName = Ty->getString(PO);
}
PO.PrintOptionalAsImplicitlyUnwrapped = IsIUO;
std::string TypeName = Ty->getString(PO);
addChunkWithText(CodeCompletionString::Chunk::ChunkKind::CallParameterType,
TypeName);

Expand Down
14 changes: 12 additions & 2 deletions test/IDE/complete_crashes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -308,18 +308,28 @@ func test_28188259(x: ((Int) -> Void) -> Void) {
func test_40956846(
arg_40956846_1: inout Int!,
arg_40956846_2: Void!,
arg_40956846_3: (() -> Int)!,
arg_40956846_3: (() -> Int?)!,
arg_40956846_4: inout ((Int) -> Int)!
) {
let y = #^RDAR_40956846^#
}
// RDAR_40956846: Begin completions
// RDAR_40956846-DAG: Decl[LocalVar]/Local: arg_40956846_1[#inout Int!#]; name=arg_40956846_1
// RDAR_40956846-DAG: Decl[LocalVar]/Local: arg_40956846_2[#Void!#]; name=arg_40956846_2
// RDAR_40956846-DAG: Decl[LocalVar]/Local: arg_40956846_3[#(() -> Int)!#]; name=arg_40956846_3
// RDAR_40956846-DAG: Decl[LocalVar]/Local: arg_40956846_3[#(() -> Int?)!#]; name=arg_40956846_3
// RDAR_40956846-DAG: Decl[LocalVar]/Local: arg_40956846_4[#inout ((Int) -> Int)!#]; name=arg_40956846_4
// RDAR_40956846: End completions

// rdar://problem/42443512
// RUN: %target-swift-ide-test -code-completion -code-completion-token=RDAR_42443512 -source-filename=%s | %FileCheck %s -check-prefix=RDAR_42443512
class test_42443512 {
func foo(x: Int!) { }
static func test() {
self.foo#^RDAR_42443512^#
}
}
// RDAR_42443512: Begin completions

// rdar://problem/42452085
// RUN: %target-swift-ide-test -code-completion -code-completion-token=RDAR_42452085_1 -source-filename=%s | %FileCheck %s -check-prefix=RDAR_42452085
// RUN: %target-swift-ide-test -code-completion -code-completion-token=RDAR_42452085_2 -source-filename=%s | %FileCheck %s -check-prefix=RDAR_42452085
Expand Down