Skip to content
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

[SR-8172] (T) Reported as Single-Element Tuple Rather Than T #50704

Closed
swift-ci opened this issue Jul 3, 2018 · 4 comments
Closed

[SR-8172] (T) Reported as Single-Element Tuple Rather Than T #50704

swift-ci opened this issue Jul 3, 2018 · 4 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. good first issue Good for newcomers

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Jul 3, 2018

Previous ID SR-8172
Radar rdar://problem/41851225
Original Reporter Matt Rips (JIRA User)
Type Bug
Status Resolved
Resolution Won't Do

Attachment: Download

Environment

Xcode 10 Beta

Swift 4.2

Additional Detail from JIRA
Votes 0
Component/s Source Tooling
Labels Bug, StarterBug
Assignee None
Priority Medium

md5: cc8906ad455bcb2e5245f0bf038e8a91

Issue Description:

When the type of a value is declared with organizational parentheses around the type name (or the value), Xcode's Quick Help reports the type as if it is a single-element tuple type. This reporting is confusing to users. It gives the impression that single-element tuples are allowed.

MINIMAL EXAMPLES:

// Minimal example #​1
let a: (Int) = 42  
// the explicit type of a is Int;
// but Xcode reports the type of a as being (Int) 

// Minimal example #​2
let b = (42)
// the implicit type of b is Int;
// but Xcode reports the type of b as being (Int) 

In the examples, above, the values are both of type Int. The parentheses surrounding Int are meaningless formatting parentheses. For purposes of representation to the user, the type should be reported as being a plain Int, without the parentheses.

BUG: Xcode's Quick Help reports the type declaration of each as (Int), a single-element tuple–something that does not currently exist in the Swift language. See the screenshot, below.

EVALUATION: I understand that, under the hood, the compiler utilizes single-element tuples, and generally guards against allowing that implementation detail to leak out to the user. I believe this bug to be an example of leakage.

In this case, the bug is (I'm guessing) more an issue of how Xcode populates the Quick Help interface, rather than an issue that can be addressed from the compiler side. Yet, this bug is rooted in the parser and type checker, where the type is managed as an (Int) rather than an Int.

QUESTIONS: Is it necessary for the compiler to internally utilize single-element tuples? What is the purpose of an unlabelled single-element tuple? Would it be preferable for the internal compiler model to better align with the external model implemented by the user?

MORE DATA: The post-type-checking state of the AST for Example #2 is set forth, below.

QUICK HELP FOR EXAMPLE #1:

AST FOR EXAMPLE #2:

{panel:title=let b = (42)}
(source_file

(top_level_code_decl

(**brace_stmt**

  (**pattern_binding_decl**

    (**pattern_named** <span color="#d04437">type='(Int)'</span> 'b')

    (**paren_expr** type='(Int)' location=example.swift:2:10 range=\[example.swift:2:9 - line:2:12\]

      (**call_expr** implicit type='Int' location=example.swift:2:10 range=\[example.swift:2:10 - line:2:10\] nothrow arg_labels=\_builtinIntegerLiteral:

        (**constructor_ref_call_expr** implicit type='(\_MaxBuiltinIntegerType) -\> Int' location=example.swift:2:10 range=\[example.swift:2:10 - line:2:10\] nothrow

          (**declref_expr** implicit type='(Int.Type) -\> (\_MaxBuiltinIntegerType) -\> Int' location=example.swift:2:10 range=\[example.swift:2:10 - line:2:10\] **decl=Swift.(file).Int.init(\_builtinIntegerLiteral🙂** function_ref=single)

          (**type_expr** implicit type='Int.Type' location=example.swift:2:10 range=\[example.swift:2:10 - line:2:10\] typerepr='Int'))

        (<span color="#d04437">**tuple_expr**</span> implicit type='(\_builtinIntegerLiteral: Int2048)' location=example.swift:2:10 range=\[example.swift:2:10 - line:2:10\] names=\_builtinIntegerLiteral

          (**integer_literal_expr** type='Int2048' location=example.swift:2:10 range=\[example.swift:2:10 - line:2:10\] value=42)))))

))

(var_decl "b" type='(Int)' interface type='(Int)' access=internal let storage_kind=stored))

@belkadan
Copy link
Contributor

belkadan commented Jul 5, 2018

@swift-ci create

@ahoppen
Copy link
Contributor

ahoppen commented Jul 5, 2018

Thanks for the very detailed bug report, Matt Rips (JIRA User). We should probably detect single-element tuples in SourceKit and remove the wrapping before returning them as a SourceKit response.

@jckarter
Copy link
Member

To be clear, these aren't single-element tuples. The parens are part of the type sugar, but don't affect the canonical type; Int and (Int) are the same. We normally intentionally preserve type sugar, and I'm not sure we want to special-case throw it away here. If the user wrote `let x: (Int)` explicitly for whatever reason, that seems like what they'd expect to see. Maybe we should change the type checking so that `(42)` doesn't infer as `(Int)` though; that seems pointless.

@jepers
Copy link

jepers commented Dec 15, 2018

Perhaps related to SR-8109, eg this:

let t = (foo: 123)
let u = t.foo * 2
print(u) // prints 246

which still compiles with def toolchain of Xcode 10.1 but crashes compiler with recent dev snapshots. EDIT: Seems like that will be fixed by: #21343

--

@jckarter:

> If the user wrote `let x: (Int)` explicitly for whatever reason, that seems like what they'd expect to see.

For what reason would the user want to write `let x: (Int)` instead of `let x: Int` and expect to see it as some mystical undocumented "parenthesis type-sugar"?

AFAICS, supporting and exposing this to the user in the above case seems as pointless as this:

> Maybe we should change the type checking so that `(42)` doesn't infer as `(Int)` though; that seems pointless.

Are there any situations where surfacing this type-sugar-thing to the user is necessary (rather than just confusing)?

I reformulated this question in a post to this relevant forum thread.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

5 participants