@@ -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 ;
@@ -147,8 +148,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
147148 debug ! ( ">> type-checking: expr={:?} expected={:?}" ,
148149 expr, expected) ;
149150
151+ // If when desugaring the try block we ok-wrapped an expression that diverges
152+ // (e.g. `try { return }`) then technically the ok-wrapping expression is unreachable.
153+ // But since it is autogenerated code the resulting warning is confusing for the user
154+ // so we want avoid generating it.
155+ // Ditto for the autogenerated `Try::from_ok(())` at the end of e.g. `try { return; }`.
156+ let ( is_try_block_ok_wrapped_expr, is_try_block_generated_expr) = match expr. node {
157+ ExprKind :: Call ( _, ref args) if expr. span . is_desugaring ( DesugaringKind :: TryBlock ) => {
158+ ( true , args. len ( ) == 1 && args[ 0 ] . span . is_desugaring ( DesugaringKind :: TryBlock ) )
159+ }
160+ _ => ( false , false ) ,
161+ } ;
162+
150163 // Warn for expressions after diverging siblings.
151- self . warn_if_unreachable ( expr. hir_id , expr. span , "expression" ) ;
164+ if !is_try_block_generated_expr {
165+ self . warn_if_unreachable ( expr. hir_id , expr. span , "expression" ) ;
166+ }
152167
153168 // Hide the outer diverging and has_errors flags.
154169 let old_diverges = self . diverges . get ( ) ;
@@ -159,13 +174,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
159174 let ty = self . check_expr_kind ( expr, expected, needs) ;
160175
161176 // Warn for non-block expressions with diverging children.
162- match expr. node {
163- ExprKind :: Block ( ..) | ExprKind :: Loop ( ..) | ExprKind :: Match ( ..) => { } ,
164- ExprKind :: Call ( ref callee, _) =>
165- self . warn_if_unreachable ( expr. hir_id , callee. span , "call" ) ,
166- ExprKind :: MethodCall ( _, ref span, _) =>
167- self . warn_if_unreachable ( expr. hir_id , * span, "call" ) ,
168- _ => self . warn_if_unreachable ( expr. hir_id , expr. span , "expression" ) ,
177+ if !is_try_block_ok_wrapped_expr {
178+ match expr. node {
179+ ExprKind :: Block ( ..) | ExprKind :: Loop ( ..) | ExprKind :: Match ( ..) => { } ,
180+ ExprKind :: Call ( ref callee, _) =>
181+ self . warn_if_unreachable ( expr. hir_id , callee. span , "call" ) ,
182+ ExprKind :: MethodCall ( _, ref span, _) =>
183+ self . warn_if_unreachable ( expr. hir_id , * span, "call" ) ,
184+ _ => self . warn_if_unreachable ( expr. hir_id , expr. span , "expression" ) ,
185+ }
169186 }
170187
171188 // Any expression that produces a value of type `!` must have diverged
0 commit comments