@@ -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