@@ -769,9 +769,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
769769            } 
770770            TerminatorKind :: Call  {  func,  args,  .. } 
771771            | TerminatorKind :: TailCall  {  func,  args,  .. }  => { 
772-                 let  call_source = match  term. kind  { 
773-                     TerminatorKind :: Call  {  call_source,  .. }  => call_source, 
774-                     TerminatorKind :: TailCall  {  .. }  => CallSource :: Normal , 
772+                 let  ( call_source,  destination,  is_diverging)  = match  term. kind  { 
773+                     TerminatorKind :: Call  {  call_source,  destination,  target,  .. }  => { 
774+                         ( call_source,  destination,  target. is_none ( ) ) 
775+                     } 
776+                     TerminatorKind :: TailCall  {  .. }  => { 
777+                         ( CallSource :: Normal ,  RETURN_PLACE . into ( ) ,  false ) 
778+                     } 
775779                    _ => unreachable ! ( ) , 
776780                } ; 
777781
@@ -845,9 +849,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
845849                    ) ; 
846850                } 
847851
848-                 if  let  TerminatorKind :: Call  {  destination,  target,  .. }  = term. kind  { 
849-                     self . check_call_dest ( term,  & sig,  destination,  target,  term_location) ; 
850-                 } 
852+                 self . check_call_dest ( term,  & sig,  destination,  is_diverging,  term_location) ; 
851853
852854                // The ordinary liveness rules will ensure that all 
853855                // regions in the type of the callee are live here. We 
@@ -1874,65 +1876,61 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
18741876        term :  & Terminator < ' tcx > , 
18751877        sig :  & ty:: FnSig < ' tcx > , 
18761878        destination :  Place < ' tcx > , 
1877-         target :   Option < BasicBlock > , 
1879+         is_diverging :   bool , 
18781880        term_location :  Location , 
18791881    )  { 
18801882        let  tcx = self . tcx ( ) ; 
1881-         match  target { 
1882-             Some ( _)  => { 
1883-                 let  dest_ty = destination. ty ( self . body ,  tcx) . ty ; 
1884-                 let  dest_ty = self . normalize ( dest_ty,  term_location) ; 
1885-                 let  category = match  destination. as_local ( )  { 
1886-                     Some ( RETURN_PLACE )  => { 
1887-                         if  let  DefiningTy :: Const ( def_id,  _)  | DefiningTy :: InlineConst ( def_id,  _)  =
1888-                             self . universal_regions . defining_ty 
1889-                         { 
1890-                             if  tcx. is_static ( def_id)  { 
1891-                                 ConstraintCategory :: UseAsStatic 
1892-                             }  else  { 
1893-                                 ConstraintCategory :: UseAsConst 
1894-                             } 
1883+         if  is_diverging { 
1884+             // The signature in this call can reference region variables, 
1885+             // so erase them before calling a query. 
1886+             let  output_ty = self . tcx ( ) . erase_regions ( sig. output ( ) ) ; 
1887+             if  !output_ty
1888+                 . is_privately_uninhabited ( self . tcx ( ) ,  self . infcx . typing_env ( self . infcx . param_env ) ) 
1889+             { 
1890+                 span_mirbug ! ( self ,  term,  "call to converging function {:?} w/o dest" ,  sig) ; 
1891+             } 
1892+         }  else  { 
1893+             let  dest_ty = destination. ty ( self . body ,  tcx) . ty ; 
1894+             let  dest_ty = self . normalize ( dest_ty,  term_location) ; 
1895+             let  category = match  destination. as_local ( )  { 
1896+                 Some ( RETURN_PLACE )  => { 
1897+                     if  let  DefiningTy :: Const ( def_id,  _)  | DefiningTy :: InlineConst ( def_id,  _)  =
1898+                         self . universal_regions . defining_ty 
1899+                     { 
1900+                         if  tcx. is_static ( def_id)  { 
1901+                             ConstraintCategory :: UseAsStatic 
18951902                        }  else  { 
1896-                             ConstraintCategory :: Return ( ReturnConstraint :: Normal ) 
1903+                             ConstraintCategory :: UseAsConst 
18971904                        } 
1905+                     }  else  { 
1906+                         ConstraintCategory :: Return ( ReturnConstraint :: Normal ) 
18981907                    } 
1899-                     Some ( l)  if  !self . body . local_decls [ l] . is_user_variable ( )  => { 
1900-                         ConstraintCategory :: Boring 
1901-                     } 
1902-                     // The return type of a call is interesting for diagnostics. 
1903-                     _ => ConstraintCategory :: Assignment , 
1904-                 } ; 
1905- 
1906-                 let  locations = term_location. to_locations ( ) ; 
1907- 
1908-                 if  let  Err ( terr)  = self . sub_types ( sig. output ( ) ,  dest_ty,  locations,  category)  { 
1909-                     span_mirbug ! ( 
1910-                         self , 
1911-                         term, 
1912-                         "call dest mismatch ({:?} <- {:?}): {:?}" , 
1913-                         dest_ty, 
1914-                         sig. output( ) , 
1915-                         terr
1916-                     ) ; 
19171908                } 
1918- 
1919-                 // When `unsized_fn_params` is not enabled, 
1920-                 // this check is done at `check_local`. 
1921-                 if  self . unsized_feature_enabled ( )  { 
1922-                     let  span = term. source_info . span ; 
1923-                     self . ensure_place_sized ( dest_ty,  span) ; 
1909+                 Some ( l)  if  !self . body . local_decls [ l] . is_user_variable ( )  => { 
1910+                     ConstraintCategory :: Boring 
19241911                } 
1912+                 // The return type of a call is interesting for diagnostics. 
1913+                 _ => ConstraintCategory :: Assignment , 
1914+             } ; 
1915+ 
1916+             let  locations = term_location. to_locations ( ) ; 
1917+ 
1918+             if  let  Err ( terr)  = self . sub_types ( sig. output ( ) ,  dest_ty,  locations,  category)  { 
1919+                 span_mirbug ! ( 
1920+                     self , 
1921+                     term, 
1922+                     "call dest mismatch ({:?} <- {:?}): {:?}" , 
1923+                     dest_ty, 
1924+                     sig. output( ) , 
1925+                     terr
1926+                 ) ; 
19251927            } 
1926-             None  => { 
1927-                 // The signature in this call can reference region variables, 
1928-                 // so erase them before calling a query. 
1929-                 let  output_ty = self . tcx ( ) . erase_regions ( sig. output ( ) ) ; 
1930-                 if  !output_ty. is_privately_uninhabited ( 
1931-                     self . tcx ( ) , 
1932-                     self . infcx . typing_env ( self . infcx . param_env ) , 
1933-                 )  { 
1934-                     span_mirbug ! ( self ,  term,  "call to converging function {:?} w/o dest" ,  sig) ; 
1935-                 } 
1928+ 
1929+             // When `unsized_fn_params` is not enabled, 
1930+             // this check is done at `check_local`. 
1931+             if  self . unsized_feature_enabled ( )  { 
1932+                 let  span = term. source_info . span ; 
1933+                 self . ensure_place_sized ( dest_ty,  span) ; 
19361934            } 
19371935        } 
19381936    } 
0 commit comments