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 {
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,
--- /dev/null
+// 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`
+}