@@ -237,9 +237,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
237237 _ => self . warn_if_unreachable ( expr. hir_id , expr. span , "expression" ) ,
238238 }
239239
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.
241242 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+ }
243265 }
244266
245267 // Record the type, which applies it effects.
0 commit comments