]> git.lizzy.rs Git - rust.git/commitdiff
review comments
authorEsteban Küber <esteban@kuber.com.ar>
Mon, 12 Dec 2016 22:51:40 +0000 (14:51 -0800)
committerEsteban Küber <esteban@kuber.com.ar>
Wed, 14 Dec 2016 21:46:13 +0000 (13:46 -0800)
src/librustc/traits/error_reporting.rs
src/test/compile-fail/E0277-2.rs [new file with mode: 0644]

index db375f2be735b08ad0fe2158eec4220035e9b892..51f9c1b353e27d0b0cec92c7519b3ece13d731d1 100644 (file)
@@ -457,11 +457,28 @@ pub fn report_extra_impl_obligation(&self,
         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 @@ pub fn report_selection_error(&self,
                                 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 (file)
index 0000000..211c0e6
--- /dev/null
@@ -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`
+}