Skip to content

Commit 7579ba9

Browse files
authored
Rollup merge of rust-lang#58204 - estebank:impl-trait-semi, r=zackmdavis
On return type `impl Trait` for block with no expr point at last semi Partial solution, doesn't actually validate that the last statement in the function body can satisfy the trait bound, but it's a good incremental improvement over the status quo. ``` error[E0277]: the trait bound `(): Bar` is not satisfied --> $DIR/impl-trait-return-trailing-semicolon.rs:3:13 | LL | fn foo() -> impl Bar { | ^^^^^^^^ the trait `Bar` is not implemented for `()` LL | 5; | - consider removing this semicolon | = note: the return type of a function must have a statically known size ``` Partially addresses rust-lang#54771.
2 parents a603e2a + 0afda05 commit 7579ba9

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

src/librustc/traits/error_reporting.rs

+28-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,28 @@ 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+
// FIXME(estebank): When encountering a method with a trait
663+
// bound not satisfied in the return type with a body that has
664+
// no return, suggest removal of semicolon on last statement.
665+
// Once that is added, close #54771.
666+
if let Some(ref stmt) = blk.stmts.last() {
667+
let sp = self.tcx.sess.source_map().end_point(stmt.span);
668+
err.span_label(sp, "consider removing this semicolon");
669+
}
670+
}
671+
}
672+
}
650673
let explanation =
651674
if obligation.cause.code == ObligationCauseCode::MainFunctionType {
652675
"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)