@@ -18,6 +18,7 @@ use crate::util::nodemap::FxHashMap;
18
18
use crate :: astconv:: AstConv as _;
19
19
20
20
use errors:: { Applicability , DiagnosticBuilder , pluralise} ;
21
+ use syntax_pos:: hygiene:: DesugaringKind ;
21
22
use syntax:: ast;
22
23
use syntax:: symbol:: { Symbol , kw, sym} ;
23
24
use syntax:: source_map:: Span ;
@@ -150,8 +151,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
150
151
debug ! ( ">> type-checking: expr={:?} expected={:?}" ,
151
152
expr, expected) ;
152
153
154
+ // If when desugaring the try block we ok-wrapped an expression that diverges
155
+ // (e.g. `try { return }`) then technically the ok-wrapping expression is unreachable.
156
+ // But since it is autogenerated code the resulting warning is confusing for the user
157
+ // so we want avoid generating it.
158
+ // Ditto for the autogenerated `Try::from_ok(())` at the end of e.g. `try { return; }`.
159
+ let ( is_try_block_ok_wrapped_expr, is_try_block_generated_expr) = match expr. node {
160
+ ExprKind :: Call ( _, ref args) if expr. span . is_desugaring ( DesugaringKind :: TryBlock ) => {
161
+ ( true , args. len ( ) == 1 && args[ 0 ] . span . is_desugaring ( DesugaringKind :: TryBlock ) )
162
+ }
163
+ _ => ( false , false ) ,
164
+ } ;
165
+
153
166
// Warn for expressions after diverging siblings.
154
- self . warn_if_unreachable ( expr. hir_id , expr. span , "expression" ) ;
167
+ if !is_try_block_generated_expr {
168
+ self . warn_if_unreachable ( expr. hir_id , expr. span , "expression" ) ;
169
+ }
155
170
156
171
// Hide the outer diverging and has_errors flags.
157
172
let old_diverges = self . diverges . get ( ) ;
@@ -162,13 +177,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
162
177
let ty = self . check_expr_kind ( expr, expected, needs) ;
163
178
164
179
// Warn for non-block expressions with diverging children.
165
- match expr. kind {
166
- ExprKind :: Block ( ..) | ExprKind :: Loop ( ..) | ExprKind :: Match ( ..) => { } ,
167
- ExprKind :: Call ( ref callee, _) =>
168
- self . warn_if_unreachable ( expr. hir_id , callee. span , "call" ) ,
169
- ExprKind :: MethodCall ( _, ref span, _) =>
170
- self . warn_if_unreachable ( expr. hir_id , * span, "call" ) ,
171
- _ => self . warn_if_unreachable ( expr. hir_id , expr. span , "expression" ) ,
180
+ if !is_try_block_ok_wrapped_expr {
181
+ match expr. kind {
182
+ ExprKind :: Block ( ..) | ExprKind :: Loop ( ..) | ExprKind :: Match ( ..) => { } ,
183
+ ExprKind :: Call ( ref callee, _) =>
184
+ self . warn_if_unreachable ( expr. hir_id , callee. span , "call" ) ,
185
+ ExprKind :: MethodCall ( _, ref span, _) =>
186
+ self . warn_if_unreachable ( expr. hir_id , * span, "call" ) ,
187
+ _ => self . warn_if_unreachable ( expr. hir_id , expr. span , "expression" ) ,
188
+ }
172
189
}
173
190
174
191
// Any expression that produces a value of type `!` must have diverged
0 commit comments