@@ -237,9 +237,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
237
237
_ => self . warn_if_unreachable ( expr. hir_id , expr. span , "expression" ) ,
238
238
}
239
239
240
- // Any expression that produces a value of type `!` must have diverged
240
+ // Any expression that produces a value of type `!` must have diverged,
241
+ // unless it's the place of a raw ref expr, or a scrutinee of a match.
241
242
if ty. is_never ( ) {
242
- self . diverges . set ( self . diverges . get ( ) | Diverges :: always ( expr. span ) ) ;
243
+ if matches ! ( expr. kind, hir:: ExprKind :: Unary ( hir:: UnOp :: Deref , _) ) {
244
+ match self . tcx . parent_hir_node ( expr. hir_id ) {
245
+ hir:: Node :: Expr ( hir:: Expr {
246
+ kind : hir:: ExprKind :: AddrOf ( hir:: BorrowKind :: Raw , ..) ,
247
+ ..
248
+ } ) => { }
249
+ hir:: Node :: Expr ( hir:: Expr {
250
+ kind : hir:: ExprKind :: Let ( hir:: LetExpr { init : target, .. } ) ,
251
+ ..
252
+ } )
253
+ | hir:: Node :: Expr ( hir:: Expr {
254
+ kind : hir:: ExprKind :: Match ( target, _, _) , ..
255
+ } )
256
+ | hir:: Node :: LetStmt ( hir:: LetStmt { init : Some ( target) , .. } )
257
+ if expr. hir_id == target. hir_id => { }
258
+ _ => {
259
+ self . diverges . set ( self . diverges . get ( ) | Diverges :: always ( expr. span ) ) ;
260
+ }
261
+ }
262
+ } else {
263
+ self . diverges . set ( self . diverges . get ( ) | Diverges :: always ( expr. span ) ) ;
264
+ }
243
265
}
244
266
245
267
// Record the type, which applies it effects.
0 commit comments