@@ -199,6 +199,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
199
199
return ;
200
200
}
201
201
202
+ // If the expression is of type () and it's the return expression of a block,
203
+ // we suggest adding a separate return expression instead.
204
+ // (To avoid things like suggesting `Ok(while .. { .. })`.)
205
+ if expr_ty. is_unit ( ) {
206
+ if let Some ( hir:: Node :: Block ( & hir:: Block {
207
+ span : block_span, expr : Some ( e) , ..
208
+ } ) ) = self . tcx . hir ( ) . find ( self . tcx . hir ( ) . get_parent_node ( expr. hir_id ) )
209
+ {
210
+ if e. hir_id == expr. hir_id {
211
+ if let Some ( span) = expr. span . find_ancestor_inside ( block_span) {
212
+ let return_suggestions =
213
+ if self . tcx . is_diagnostic_item ( sym:: Result , expected_adt. did ) {
214
+ vec ! [ "Ok(())" . to_string( ) ]
215
+ } else if self . tcx . is_diagnostic_item ( sym:: Option , expected_adt. did )
216
+ {
217
+ vec ! [ "None" . to_string( ) , "Some(())" . to_string( ) ]
218
+ } else {
219
+ return ;
220
+ } ;
221
+ if let Some ( indent) =
222
+ self . tcx . sess . source_map ( ) . indentation_before ( span. shrink_to_lo ( ) )
223
+ {
224
+ // Add a semicolon, except after `}`.
225
+ let semicolon =
226
+ match self . tcx . sess . source_map ( ) . span_to_snippet ( span) {
227
+ Ok ( s) if s. ends_with ( '}' ) => "" ,
228
+ _ => ";" ,
229
+ } ;
230
+ err. multipart_suggestions (
231
+ "try adding an expression at the end of the block" ,
232
+ return_suggestions. into_iter ( ) . map ( |r| {
233
+ vec ! [ (
234
+ span. shrink_to_hi( ) ,
235
+ format!( "{}\n {}{}" , semicolon, indent, r) ,
236
+ ) ]
237
+ } ) ,
238
+ Applicability :: MaybeIncorrect ,
239
+ ) ;
240
+ }
241
+ return ;
242
+ }
243
+ }
244
+ }
245
+ }
246
+
202
247
let mut compatible_variants = expected_adt
203
248
. variants
204
249
. iter ( )
0 commit comments