@@ -769,9 +769,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
769
769
}
770
770
TerminatorKind :: Call { func, args, .. }
771
771
| 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
+ }
775
779
_ => unreachable ! ( ) ,
776
780
} ;
777
781
@@ -845,13 +849,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
845
849
) ;
846
850
}
847
851
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) ;
855
853
856
854
// The ordinary liveness rules will ensure that all
857
855
// regions in the type of the callee are live here. We
@@ -1878,65 +1876,61 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1878
1876
term : & Terminator < ' tcx > ,
1879
1877
sig : & ty:: FnSig < ' tcx > ,
1880
1878
destination : Place < ' tcx > ,
1881
- target : Option < BasicBlock > ,
1879
+ is_diverging : bool ,
1882
1880
term_location : Location ,
1883
1881
) {
1884
1882
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
1899
1902
} else {
1900
- ConstraintCategory :: Return ( ReturnConstraint :: Normal )
1903
+ ConstraintCategory :: UseAsConst
1901
1904
}
1905
+ } else {
1906
+ ConstraintCategory :: Return ( ReturnConstraint :: Normal )
1902
1907
}
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
- ) ;
1921
1908
}
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
1928
1911
}
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
+ ) ;
1929
1927
}
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) ;
1940
1934
}
1941
1935
}
1942
1936
}
0 commit comments