Skip to content

Commit 453e242

Browse files
committed
Improve suggestion for unit Option/Result at the end of a block.
1 parent 483cff7 commit 453e242

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

compiler/rustc_typeck/src/check/demand.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)