@@ -1082,11 +1082,19 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
1082
1082
GatherLocalsVisitor { fcx : & fcx, parent_id : outer_node_id, } . visit_body ( body) ;
1083
1083
1084
1084
// Add formal parameters.
1085
+ let mut uninhabited_args = vec ! [ ] ;
1085
1086
for ( arg_ty, arg) in fn_sig. inputs ( ) . iter ( ) . zip ( & body. arguments ) {
1086
1087
// Check the pattern.
1087
1088
fcx. check_pat_walk ( & arg. pat , arg_ty,
1088
1089
ty:: BindingMode :: BindByValue ( hir:: Mutability :: MutImmutable ) , true ) ;
1089
1090
1091
+ // If any of a function's parameters have a type that is uninhabited, then it
1092
+ // cannot be called (because its arguments cannot be constructed).
1093
+ let module = fcx. tcx . hir ( ) . get_module_parent ( fn_id) ;
1094
+ if fcx. tcx . is_ty_uninhabited_from ( module, arg_ty) {
1095
+ uninhabited_args. push ( arg) ;
1096
+ }
1097
+
1090
1098
// Check that argument is Sized.
1091
1099
// The check for a non-trivial pattern is a hack to avoid duplicate warnings
1092
1100
// for simple cases like `fn foo(x: Trait)`,
@@ -1098,6 +1106,28 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
1098
1106
fcx. write_ty ( arg. hir_id , arg_ty) ;
1099
1107
}
1100
1108
1109
+ if !uninhabited_args. is_empty ( ) {
1110
+ match fcx. tcx . hir ( ) . find ( fcx. tcx . hir ( ) . get_parent ( fn_id) ) {
1111
+ Some ( Node :: Item ( & hir:: Item { node : ItemKind :: Impl ( ..) , .. } ) ) => {
1112
+ // We only want to warn for functions with parameters of uninhabited types if they
1113
+ // are not required (e.g. trait implementations). In the future, such
1114
+ // implementations may be unnecessary, but for now they are required.
1115
+ }
1116
+ _ => {
1117
+ let mut err = fcx. tcx . struct_span_lint_node (
1118
+ lint:: builtin:: UNREACHABLE_CODE ,
1119
+ fn_id,
1120
+ fcx. tcx . hir ( ) . span ( fn_id) ,
1121
+ "functions with parameters of uninhabited types are uncallable" ,
1122
+ ) ;
1123
+ for arg in uninhabited_args {
1124
+ err. span_label ( arg. pat . span , format ! ( "this parameter has an uninhabited type" ) ) ;
1125
+ }
1126
+ err. emit ( ) ;
1127
+ }
1128
+ }
1129
+ }
1130
+
1101
1131
let fn_hir_id = fcx. tcx . hir ( ) . node_to_hir_id ( fn_id) ;
1102
1132
inherited. tables . borrow_mut ( ) . liberated_fn_sigs_mut ( ) . insert ( fn_hir_id, fn_sig) ;
1103
1133
0 commit comments