diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2016-12-12 14:51:40 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2016-12-14 13:46:13 -0800 |
| commit | 5c130411e907b018aef90aabe766d04e989abe9e (patch) | |
| tree | 215b0db299a74139c6aad7534b56b8cf935884eb | |
| parent | ef09db0ff301b98f6980f4bd3dad6fb060d18daa (diff) | |
| download | rust-5c130411e907b018aef90aabe766d04e989abe9e.tar.gz rust-5c130411e907b018aef90aabe766d04e989abe9e.zip | |
review comments
| -rw-r--r-- | src/librustc/traits/error_reporting.rs | 34 | ||||
| -rw-r--r-- | src/test/compile-fail/E0277-2.rs | 34 |
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` +} |
