@@ -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 ;
@@ -147,8 +148,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
147
148
debug ! ( ">> type-checking: expr={:?} expected={:?}" ,
148
149
expr, expected) ;
149
150
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
+
150
163
// 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
+ }
152
167
153
168
// Hide the outer diverging and has_errors flags.
154
169
let old_diverges = self . diverges . get ( ) ;
@@ -159,13 +174,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
159
174
let ty = self . check_expr_kind ( expr, expected, needs) ;
160
175
161
176
// 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
+ }
169
186
}
170
187
171
188
// Any expression that produces a value of type `!` must have diverged
0 commit comments