Skip to content

Commit b91ccc3

Browse files
committed
On return type impl Trait for block with no expr point at last semi
1 parent b2c6b8c commit b91ccc3

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

src/librustc/traits/error_reporting.rs

+27-5
Original file line numberDiff line numberDiff line change
@@ -598,11 +598,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
598598
}
599599
}
600600

601-
pub fn report_selection_error(&self,
602-
obligation: &PredicateObligation<'tcx>,
603-
error: &SelectionError<'tcx>,
604-
fallback_has_occurred: bool)
605-
{
601+
pub fn report_selection_error(
602+
&self,
603+
obligation: &PredicateObligation<'tcx>,
604+
error: &SelectionError<'tcx>,
605+
fallback_has_occurred: bool,
606+
) {
606607
let span = obligation.cause.span;
607608

608609
let mut err = match *error {
@@ -647,6 +648,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
647648
trait_ref.to_predicate(), post_message)
648649
));
649650

651+
let parent_node = self.tcx.hir().get_parent_node(obligation.cause.body_id);
652+
let node = self.tcx.hir().find(parent_node);
653+
if let Some(hir::Node::Item(hir::Item {
654+
node: hir::ItemKind::Fn(decl, _, _, body_id),
655+
..
656+
})) = node {
657+
let body = self.tcx.hir().body(*body_id);
658+
if let hir::ExprKind::Block(blk, _) = &body.value.node {
659+
if decl.output.span().overlaps(span) && blk.expr.is_none() &&
660+
"()" == &trait_ref.self_ty().to_string()
661+
{
662+
// When encountering a method with a trait bound not satisfied
663+
// in the return type with a body that has no return, suggest
664+
// removal of semicolon on last statement.
665+
if let Some(ref stmt) = blk.stmts.last() {
666+
let sp = self.tcx.sess.source_map().end_point(stmt.span);
667+
err.span_label(sp, "consider removing this semicolon");
668+
}
669+
}
670+
}
671+
}
650672
let explanation =
651673
if obligation.cause.code == ObligationCauseCode::MainFunctionType {
652674
"consider using `()`, or a `Result`".to_owned()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
trait Bar {}
2+
impl Bar for u8 {}
3+
fn foo() -> impl Bar {
4+
5; //~^ ERROR the trait bound `(): Bar` is not satisfied
5+
}
6+
7+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0277]: the trait bound `(): Bar` is not satisfied
2+
--> $DIR/impl-trait-return-trailing-semicolon.rs:3:13
3+
|
4+
LL | fn foo() -> impl Bar {
5+
| ^^^^^^^^ the trait `Bar` is not implemented for `()`
6+
LL | 5; //~^ ERROR the trait bound `(): Bar` is not satisfied
7+
| - consider removing this semicolon
8+
|
9+
= note: the return type of a function must have a statically known size
10+
11+
error: aborting due to previous error
12+
13+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)