about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-02-05 15:17:08 -0800
committerEsteban Küber <esteban@kuber.com.ar>2019-03-04 13:17:54 -0800
commit9e8a62b73449c82c5600eea7e8ce1683aa862be2 (patch)
tree9660af749fae70d231e22220eba2206754fe6a52 /src
parentc1d2d83ca3b5155468ab96b09a7c54568449b137 (diff)
downloadrust-9e8a62b73449c82c5600eea7e8ce1683aa862be2.tar.gz
rust-9e8a62b73449c82c5600eea7e8ce1683aa862be2.zip
On return type `impl Trait` for block with no expr point at last semi
Diffstat (limited to 'src')
-rw-r--r--src/librustc/traits/error_reporting.rs32
-rw-r--r--src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs7
-rw-r--r--src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr13
3 files changed, 47 insertions, 5 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 3eb49092fed..9262cbec9f4 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -598,11 +598,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
-    pub fn report_selection_error(&self,
-                                  obligation: &PredicateObligation<'tcx>,
-                                  error: &SelectionError<'tcx>,
-                                  fallback_has_occurred: bool)
-    {
+    pub fn report_selection_error(
+        &self,
+        obligation: &PredicateObligation<'tcx>,
+        error: &SelectionError<'tcx>,
+        fallback_has_occurred: bool,
+    ) {
         let span = obligation.cause.span;
 
         let mut err = match *error {
@@ -647,6 +648,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                          trait_ref.to_predicate(), post_message)
                             ));
 
+                        let parent_node = self.tcx.hir().get_parent_node(obligation.cause.body_id);
+                        let node = self.tcx.hir().find(parent_node);
+                        if let Some(hir::Node::Item(hir::Item {
+                            node: hir::ItemKind::Fn(decl, _, _, body_id),
+                            ..
+                        })) = node {
+                            let body = self.tcx.hir().body(*body_id);
+                            if let hir::ExprKind::Block(blk, _) = &body.value.node {
+                                if decl.output.span().overlaps(span) && blk.expr.is_none() &&
+                                    "()" == &trait_ref.self_ty().to_string()
+                                {
+                                    // When encountering a method with a trait bound not satisfied
+                                    // in the return type with a body that has no return, suggest
+                                    // removal of semicolon on last statement.
+                                    if let Some(ref stmt) = blk.stmts.last() {
+                                        let sp = self.tcx.sess.source_map().end_point(stmt.span);
+                                        err.span_label(sp, "consider removing this semicolon");
+                                    }
+                                }
+                            }
+                        }
                         let explanation =
                             if obligation.cause.code == ObligationCauseCode::MainFunctionType {
                                 "consider using `()`, or a `Result`".to_owned()
diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs
new file mode 100644
index 00000000000..e72a2d8ccc6
--- /dev/null
+++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs
@@ -0,0 +1,7 @@
+trait Bar {}
+impl Bar for u8 {}
+fn foo() -> impl Bar {
+    5; //~^ ERROR the trait bound `(): Bar` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr
new file mode 100644
index 00000000000..f26fb141ccf
--- /dev/null
+++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr
@@ -0,0 +1,13 @@
+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; //~^ ERROR the trait bound `(): Bar` is not satisfied
+   |      - consider removing this semicolon
+   |
+   = note: the return type of a function must have a statically known size
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.