about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2016-12-12 14:51:40 -0800
committerEsteban Küber <esteban@kuber.com.ar>2016-12-14 13:46:13 -0800
commit5c130411e907b018aef90aabe766d04e989abe9e (patch)
tree215b0db299a74139c6aad7534b56b8cf935884eb
parentef09db0ff301b98f6980f4bd3dad6fb060d18daa (diff)
downloadrust-5c130411e907b018aef90aabe766d04e989abe9e.tar.gz
rust-5c130411e907b018aef90aabe766d04e989abe9e.zip
review comments
-rw-r--r--src/librustc/traits/error_reporting.rs34
-rw-r--r--src/test/compile-fail/E0277-2.rs34
2 files changed, 58 insertions, 10 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index db375f2be73..51f9c1b353e 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -457,11 +457,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         err
     }
 
+
+    /// Get the parent trait chain start
+    fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option<String> {
+        match code {
+            &ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
+                let parent_trait_ref = self.resolve_type_vars_if_possible(
+                    &data.parent_trait_ref);
+                match self.get_parent_trait_ref(&data.parent_code) {
+                    Some(t) => Some(t),
+                    None => Some(format!("{}", parent_trait_ref.0.self_ty())),
+                }
+            }
+            _ => None,
+        }
+    }
+
     pub fn report_selection_error(&self,
                                   obligation: &PredicateObligation<'tcx>,
                                   error: &SelectionError<'tcx>)
     {
         let span = obligation.cause.span;
+
         let mut err = match *error {
             SelectionError::Unimplemented => {
                 if let ObligationCauseCode::CompareImplMethodObligation {
@@ -486,16 +503,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                 return;
                             } else {
                                 let trait_ref = trait_predicate.to_poly_trait_ref();
-
-                                let (post_message, pre_message) =
-                                    if let ObligationCauseCode::BuiltinDerivedObligation(ref data)
-                                        = obligation.cause.code {
-                                    let parent_trait_ref = self.resolve_type_vars_if_possible(
-                                        &data.parent_trait_ref);
-                                    (format!(" in `{}`", parent_trait_ref.0.self_ty()),
-                                     format!("within `{}`, ", parent_trait_ref.0.self_ty()))
-                                } else {
-                                    (String::new(), String::new())
+                                let (post_message, pre_message) = match self.get_parent_trait_ref(
+                                    &obligation.cause.code)
+                                {
+                                    Some(t) => {
+                                        (format!(" in `{}`", t), format!("within `{}`, ", t))
+                                    }
+                                    None => (String::new(), String::new()),
                                 };
                                 let mut err = struct_span_err!(
                                     self.tcx.sess,
diff --git a/src/test/compile-fail/E0277-2.rs b/src/test/compile-fail/E0277-2.rs
new file mode 100644
index 00000000000..211c0e6f890
--- /dev/null
+++ b/src/test/compile-fail/E0277-2.rs
@@ -0,0 +1,34 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo {
+    bar: Bar
+}
+
+struct Bar {
+    baz: Baz
+}
+
+struct Baz {
+    x: *const u8
+}
+
+fn is_send<T: Send>() { }
+
+fn main() {
+    is_send::<Foo>();
+    //~^ ERROR the trait bound `*const u8: std::marker::Send` is not satisfied in `Foo`
+    //~| NOTE within `Foo`, the trait `std::marker::Send` is not implemented for `*const u8`
+    //~| NOTE: `*const u8` cannot be sent between threads safely
+    //~| NOTE: required because it appears within the type `Baz`
+    //~| NOTE: required because it appears within the type `Bar`
+    //~| NOTE: required because it appears within the type `Foo`
+    //~| NOTE: required by `is_send`
+}