@@ -845,13 +845,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
845845 ) ;
846846 }
847847
848- let ( destination, target ) =
848+ let ( destination, is_diverging ) =
849849 if let TerminatorKind :: Call { destination, target, .. } = term. kind {
850- ( destination, target)
850+ ( destination, target. is_none ( ) )
851851 } else {
852- ( RETURN_PLACE . into ( ) , Some ( BasicBlock :: ZERO ) )
852+ // Tail calls don't actually
853+ ( RETURN_PLACE . into ( ) , false )
853854 } ;
854- self . check_call_dest ( term, & sig, destination, target , term_location) ;
855+ self . check_call_dest ( term, & sig, destination, is_diverging , term_location) ;
855856
856857 // The ordinary liveness rules will ensure that all
857858 // regions in the type of the callee are live here. We
@@ -1878,65 +1879,61 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
18781879 term : & Terminator < ' tcx > ,
18791880 sig : & ty:: FnSig < ' tcx > ,
18801881 destination : Place < ' tcx > ,
1881- target : Option < BasicBlock > ,
1882+ is_diverging : bool ,
18821883 term_location : Location ,
18831884 ) {
18841885 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- }
1886+ if is_diverging {
1887+ // The signature in this call can reference region variables,
1888+ // so erase them before calling a query.
1889+ let output_ty = self . tcx ( ) . erase_regions ( sig. output ( ) ) ;
1890+ if !output_ty
1891+ . is_privately_uninhabited ( self . tcx ( ) , self . infcx . typing_env ( self . infcx . param_env ) )
1892+ {
1893+ span_mirbug ! ( self , term, "call to converging function {:?} w/o dest" , sig) ;
1894+ }
1895+ } else {
1896+ let dest_ty = destination. ty ( self . body , tcx) . ty ;
1897+ let dest_ty = self . normalize ( dest_ty, term_location) ;
1898+ let category = match destination. as_local ( ) {
1899+ Some ( RETURN_PLACE ) => {
1900+ if let DefiningTy :: Const ( def_id, _) | DefiningTy :: InlineConst ( def_id, _) =
1901+ self . universal_regions . defining_ty
1902+ {
1903+ if tcx. is_static ( def_id) {
1904+ ConstraintCategory :: UseAsStatic
18991905 } else {
1900- ConstraintCategory :: Return ( ReturnConstraint :: Normal )
1906+ ConstraintCategory :: UseAsConst
19011907 }
1908+ } else {
1909+ ConstraintCategory :: Return ( ReturnConstraint :: Normal )
19021910 }
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- ) ;
19211911 }
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) ;
1912+ Some ( l) if !self . body . local_decls [ l] . is_user_variable ( ) => {
1913+ ConstraintCategory :: Boring
19281914 }
1915+ // The return type of a call is interesting for diagnostics.
1916+ _ => ConstraintCategory :: Assignment ,
1917+ } ;
1918+
1919+ let locations = term_location. to_locations ( ) ;
1920+
1921+ if let Err ( terr) = self . sub_types ( sig. output ( ) , dest_ty, locations, category) {
1922+ span_mirbug ! (
1923+ self ,
1924+ term,
1925+ "call dest mismatch ({:?} <- {:?}): {:?}" ,
1926+ dest_ty,
1927+ sig. output( ) ,
1928+ terr
1929+ ) ;
19291930 }
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- }
1931+
1932+ // When `unsized_fn_params` is not enabled,
1933+ // this check is done at `check_local`.
1934+ if self . unsized_feature_enabled ( ) {
1935+ let span = term. source_info . span ;
1936+ self . ensure_place_sized ( dest_ty, span) ;
19401937 }
19411938 }
19421939 }
0 commit comments