@@ -199,6 +199,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
199199 return ;
200200 }
201201
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+
202247 let mut compatible_variants = expected_adt
203248 . variants
204249 . iter ( )
0 commit comments