@@ -18,6 +18,7 @@ use crate::util::nodemap::FxHashMap;
1818use crate :: astconv:: AstConv as _;
1919
2020use errors:: { Applicability , DiagnosticBuilder , pluralise} ;
21+ use syntax_pos:: hygiene:: DesugaringKind ;
2122use syntax:: ast;
2223use syntax:: symbol:: { Symbol , kw, sym} ;
2324use syntax:: source_map:: Span ;
@@ -150,8 +151,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
150151 debug ! ( ">> type-checking: expr={:?} expected={:?}" ,
151152 expr, expected) ;
152153
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+
153166 // 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+ }
155170
156171 // Hide the outer diverging and has_errors flags.
157172 let old_diverges = self . diverges . get ( ) ;
@@ -162,13 +177,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
162177 let ty = self . check_expr_kind ( expr, expected, needs) ;
163178
164179 // 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+ }
172189 }
173190
174191 // Any expression that produces a value of type `!` must have diverged
0 commit comments