{"id":20644,"date":"2018-02-20T15:08:13","date_gmt":"2018-02-20T20:08:13","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=20644"},"modified":"2018-02-20T15:08:13","modified_gmt":"2018-02-20T20:08:13","slug":"when-swift-makes-you-use-throws-instead-of-rethrows","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2018\/02\/20\/when-swift-makes-you-use-throws-instead-of-rethrows\/","title":{"rendered":"When Swift Makes You Use &ldquo;throws&rdquo; Instead of &ldquo;rethrows&rdquo;"},"content":{"rendered":"<p><a href=\"https:\/\/forums.swift.org\/t\/pitch-rethrows-unchecked\/10078\">Brent Royal-Gordon<\/a>:<\/p>\n<blockquote cite=\"https:\/\/forums.swift.org\/t\/pitch-rethrows-unchecked\/10078\"><p><code>rethrows<\/code> lets you specify that a function can only throw if one of the functions passed to it as a parameter can throw. It enforces this by only allowing <code>try<\/code> to be applied to calls to those functions or <code>rethrows<\/code> functions which are being passed those functions, and only allowing <code>throws<\/code> inside a <code>catch<\/code> block.<\/p>\n<p>However, this enforcement can sometimes get in the way. For example, this function only throws if the function it is passed throws, but the compiler cannot statically prove this to itself[&#8230;]<\/p>\n<p>[&#8230;]<\/p>\n<p>It is possible to work around this by exploiting certain bugs in the <code>rethrows<\/code> checking&mdash;the <code>Dispatch<\/code> overlay does this to add error handling to <code>DispatchQueue.sync(execute:)<\/code>&mdash;but this is not ideal for obvious reasons.<\/p><\/blockquote>\n\n<p>Via <a href=\"https:\/\/oleb.net\/blog\/2018\/02\/performandwait\/\">Ole Begemann<\/a>:<\/p>\n<blockquote cite=\"https:\/\/oleb.net\/blog\/2018\/02\/performandwait\/\">\n<p>We can use the same trick for our problem. <a href=\"https:\/\/github.com\/apple\/swift\/blob\/bb157a070ec6534e4b534456d208b03adc07704b\/stdlib\/public\/SDK\/Dispatch\/Queue.swift#L228-L249\">Check out the relevant code in the Swift repository<\/a>. And here&rsquo;s the verbatim copy of the code (I only changed the function names) for <code>performAndWait<\/code>[&#8230;]<\/p>\n<p>[&#8230;]<\/p>\n<p><code>performAndWait<\/code> now calls through to a private helper function that takes two throwing functions (the original block and an error handler) and this convinces the compiler that the <code>rethrows<\/code> invariant holds.<\/p>\n<\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Brent Royal-Gordon: rethrows lets you specify that a function can only throw if one of the functions passed to it as a parameter can throw. It enforces this by only allowing try to be applied to calls to those functions or rethrows functions which are being passed those functions, and only allowing throws inside a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"","apple_news_api_id":"","apple_news_api_modified_at":"","apple_news_api_revision":"","apple_news_api_share_url":"","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[109,31,1472,30,1529,71,901],"class_list":["post-20644","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-coredata","tag-ios","tag-ios-11","tag-mac","tag-macos-10-13","tag-programming","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/20644","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=20644"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/20644\/revisions"}],"predecessor-version":[{"id":20645,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/20644\/revisions\/20645"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=20644"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=20644"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=20644"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}