@@ -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,13 +849,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
845849 ) ;
846850 }
847851
848- let ( destination, target) =
849- if let TerminatorKind :: Call { destination, target, .. } = term. kind {
850- ( destination, target)
851- } else {
852- ( RETURN_PLACE . into ( ) , Some ( BasicBlock :: ZERO ) )
853- } ;
854- self . check_call_dest ( term, & sig, destination, target, term_location) ;
852+ self . check_call_dest ( term, & sig, destination, is_diverging, term_location) ;
855853
856854 // The ordinary liveness rules will ensure that all
857855 // regions in the type of the callee are live here. We
@@ -1878,65 +1876,61 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
18781876 term : & Terminator < ' tcx > ,
18791877 sig : & ty:: FnSig < ' tcx > ,
18801878 destination : Place < ' tcx > ,
1881- target : Option < BasicBlock > ,
1879+ is_diverging : bool ,
18821880 term_location : Location ,
18831881 ) {
18841882 let tcx = self . tcx ( ) ;
1885- match target {
1886- Some ( _) => {
1887- let dest_ty = destination. ty ( self . body , tcx) . ty ;
1888- let dest_ty = self . normalize ( dest_ty, term_location) ;
1889- let category = match destination. as_local ( ) {
1890- Some ( RETURN_PLACE ) => {
1891- if let DefiningTy :: Const ( def_id, _) | DefiningTy :: InlineConst ( def_id, _) =
1892- self . universal_regions . defining_ty
1893- {
1894- if tcx. is_static ( def_id) {
1895- ConstraintCategory :: UseAsStatic
1896- } else {
1897- ConstraintCategory :: UseAsConst
1898- }
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
18991902 } else {
1900- ConstraintCategory :: Return ( ReturnConstraint :: Normal )
1903+ ConstraintCategory :: UseAsConst
19011904 }
1905+ } else {
1906+ ConstraintCategory :: Return ( ReturnConstraint :: Normal )
19021907 }
1903- Some ( l) if !self . body . local_decls [ l] . is_user_variable ( ) => {
1904- ConstraintCategory :: Boring
1905- }
1906- // The return type of a call is interesting for diagnostics.
1907- _ => ConstraintCategory :: Assignment ,
1908- } ;
1909-
1910- let locations = term_location. to_locations ( ) ;
1911-
1912- if let Err ( terr) = self . sub_types ( sig. output ( ) , dest_ty, locations, category) {
1913- span_mirbug ! (
1914- self ,
1915- term,
1916- "call dest mismatch ({:?} <- {:?}): {:?}" ,
1917- dest_ty,
1918- sig. output( ) ,
1919- terr
1920- ) ;
19211908 }
1922-
1923- // When `unsized_fn_params` is not enabled,
1924- // this check is done at `check_local`.
1925- if self . unsized_feature_enabled ( ) {
1926- let span = term. source_info . span ;
1927- self . ensure_place_sized ( dest_ty, span) ;
1909+ Some ( l) if !self . body . local_decls [ l] . is_user_variable ( ) => {
1910+ ConstraintCategory :: Boring
19281911 }
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+ ) ;
19291927 }
1930- None => {
1931- // The signature in this call can reference region variables,
1932- // so erase them before calling a query.
1933- let output_ty = self . tcx ( ) . erase_regions ( sig. output ( ) ) ;
1934- if !output_ty. is_privately_uninhabited (
1935- self . tcx ( ) ,
1936- self . infcx . typing_env ( self . infcx . param_env ) ,
1937- ) {
1938- span_mirbug ! ( self , term, "call to converging function {:?} w/o dest" , sig) ;
1939- }
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) ;
19401934 }
19411935 }
19421936 }
0 commit comments