@@ -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,9 +849,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
845
849
) ;
846
850
}
847
851
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) ;
851
853
852
854
// The ordinary liveness rules will ensure that all
853
855
// regions in the type of the callee are live here. We
@@ -1874,65 +1876,61 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1874
1876
term : & Terminator < ' tcx > ,
1875
1877
sig : & ty:: FnSig < ' tcx > ,
1876
1878
destination : Place < ' tcx > ,
1877
- target : Option < BasicBlock > ,
1879
+ is_diverging : bool ,
1878
1880
term_location : Location ,
1879
1881
) {
1880
1882
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
1895
1902
} else {
1896
- ConstraintCategory :: Return ( ReturnConstraint :: Normal )
1903
+ ConstraintCategory :: UseAsConst
1897
1904
}
1905
+ } else {
1906
+ ConstraintCategory :: Return ( ReturnConstraint :: Normal )
1898
1907
}
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
- ) ;
1917
1908
}
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
1924
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
+ ) ;
1925
1927
}
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) ;
1936
1934
}
1937
1935
}
1938
1936
}
0 commit comments