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-13367] Assigning individual tuple elements with try? failing #55807

Closed
swift-ci opened this issue Aug 8, 2020 · 7 comments
Closed

[SR-13367] Assigning individual tuple elements with try? failing #55807

swift-ci opened this issue Aug 8, 2020 · 7 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation type checker Area → compiler: Semantic analysis

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Aug 8, 2020

Previous ID SR-13367
Radar None
Original Reporter srinikhil07 (JIRA User)
Type Bug
Status Closed
Resolution Invalid
Environment

I checked the above with last week's master.

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, DiagnosticsQoI, TypeChecker
Assignee None
Priority Medium

md5: 60ec239da460851c2aa26971cbbd5732

Issue Description:

Hi,

The below code snippet reproduces the issue.

func returnSingle() throws -> String { 
 return"Swift" 
} 
func returnTuple() throws -> (String, String) { 
return("Swift", "Five") 
} 

func returnTupleWithoutThrows() -> (String, String) { 
return("Swift", "Five") 
} 

func test() { 
   let test0 =try? returnSingle()
   print(test0 ??"") 
   let tuple =try? returnTuple() 
   //less standard way 
   let(test1, test2)=returnTupleWithoutThrows() 
   let(test3, test4)=try? returnTuple() //error
}
 

Initially, my method didn't throw `returnTupleWithoutThrows()` but then I had to add throws so I changed my function to `returnTuple()`. This made the compiler to complain with below error at call site.

type of expression is ambiguous without more context

I think the compiler should either accept the expression or should throw a valid error if any for the below expression

let(test3, test4)=try? returnTuple() //error
@LucianoPAlmeida
Copy link
Collaborator

That indeed has this bad message on 5.3 but on near master, I'm seeing

func returnSingle() throws -> String { 
  return"Swift" 
} 
func returnTuple() throws -> (String, String) { 
  return("Swift", "Five") 
} 

func returnTupleWithoutThrows() -> (String, String) { 
  return("Swift", "Five") 
} 

func test() { 
   let test0 = try? returnSingle()
   print(test0 ?? "") 
   let tuple = try? returnTuple() 
   //less standard way 
   let(test1, test2) = returnTupleWithoutThrows() 
   let(test3, test4) = try? returnTuple() //error: value of optional type '(String, String)?' not unwrapped; did you mean to use 'try!' or chain with '?'?
}

Which to me seems correct ...

@swift-ci
Copy link
Collaborator Author

swift-ci commented Aug 8, 2020

Comment by Nikhil (JIRA)

@LucianoPAlmeida

Okay, but any idea why the compiler doesn't complain for below two statements

let test0 = try? returnSingle()
 let tuple = try? returnTuple()

But does so for

let(test3, test4) = try? returnTuple() //error: value of optional type '(String, String)?' not unwrapped; did you mean to use 'try!' or chain with '?'?

I am not sure if they are consistent.

@LucianoPAlmeida
Copy link
Collaborator

I think that is because a `tuple` variable is allowed to be inferred as `(String, String)?` and the same for the test0 which is also allowed to be inferred as `String?`. But in the example ` let(test3, test4) = try? returnTuple()` it cannot be an optional type because in order to destructure and assign each element to test3 and test4 it has to be guaranteed always to be a compatible tuple type. Think of it that way, what will you expect from value of test3 and test4 if `try? returnTuple()` is `nil`? That is the same for a case like bellow where a `returnTupleWithoutThrows` returns an optional tuple

func returnTupleWithoutThrows() -> (String, String)? {
  return("Swift", "Five")
}

func test() {
  let(test1, test2) = returnTupleWithoutThrows()//error: value of optional type '(String, String)?' not unwrapped; did you mean to use 'try!' or chain with '?'?
}

@LucianoPAlmeida
Copy link
Collaborator

Note that assume test3 and test4 will be both `nil` if `try? returnTuple()` is `nil` would be incorrect because `(String?, String?)` it is not equivalent to `(String, String)?` That is why I think optional tuples are not allowed in this case 🙂

@swift-ci
Copy link
Collaborator Author

swift-ci commented Aug 8, 2020

Comment by Nikhil (JIRA)

@LucianoPAlmeida Ok. Thanks for the explanation, I get it now. We can close this. You said near master has this fixed, please tell me where can I check this.

@LucianoPAlmeida
Copy link
Collaborator

I did run the compiler on a test file that I was running for an issue I was working on with // RUN: %target-typecheck-verify-swift

But normally https://swift.godbolt.org you can easily check this without having to download and install the whole toolchain, or you can download the toolchain onn https://swift.org/download/#snapshots

@swift-ci
Copy link
Collaborator Author

swift-ci commented Aug 9, 2020

Comment by Nikhil (JIRA)

@LucianoPAlmeida thank you for the info.

@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. compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

2 participants