diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2019-12-15 22:20:30 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2020-01-08 09:30:27 -0800 |
| commit | 0dcdbaec0b49a149316719b32241d8975bd192c9 (patch) | |
| tree | b27c7c6580e22fe4acc7d4b4b64f95ac0b9613e9 /src/librustc | |
| parent | c55615155d161c8abb307db0019ab58545cd246b (diff) | |
| download | rust-0dcdbaec0b49a149316719b32241d8975bd192c9.tar.gz rust-0dcdbaec0b49a149316719b32241d8975bd192c9.zip | |
Point at the def span of trait refs E0277
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/infer/error_reporting/mod.rs | 9 | ||||
| -rw-r--r-- | src/librustc/traits/error_reporting.rs | 34 |
2 files changed, 37 insertions, 6 deletions
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index d0243dad700..d736d45a5a4 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -71,6 +71,7 @@ use rustc_hir::Node; use errors::{ pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticStyledString, }; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_error_codes::*; use rustc_span::{DesugaringKind, Pos, Span}; use rustc_target::spec::abi; @@ -1362,9 +1363,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let kind = match t.kind { ty::Closure(..) => "closure", ty::Opaque(..) => "opaque type", + ty::Generator(..) => "generator", + ty::Foreign(..) => "foreign type", _ => "", }; - if let ty::Closure(def_id, _) | ty::Opaque(def_id, _) = t.kind { + if let ty::Closure(def_id, _) + | ty::Opaque(def_id, _) + | ty::Generator(def_id, ..) + | ty::Foreign(def_id) = t.kind + { let span = self.tcx.def_span(def_id); // Avoid cluttering the output when the "found" and error span overlap: // diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 00251d55706..8c2cc412a48 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -446,7 +446,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { flags.push((sym::from_method, Some(method.to_string()))); } } - if let Some(t) = self.get_parent_trait_ref(&obligation.cause.code) { + if let Some((t, _)) = self.get_parent_trait_ref(&obligation.cause.code) { flags.push((sym::parent_trait, Some(t))); } @@ -665,13 +665,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } /// Gets the parent trait chain start - fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option<String> { + fn get_parent_trait_ref( + &self, + code: &ObligationCauseCode<'tcx>, + ) -> Option<(String, Option<Span>)> { match code { &ObligationCauseCode::BuiltinDerivedObligation(ref data) => { let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); match self.get_parent_trait_ref(&data.parent_code) { Some(t) => Some(t), - None => Some(parent_trait_ref.skip_binder().self_ty().to_string()), + None => { + let ty = parent_trait_ref.skip_binder().self_ty(); + let span = if let ty::Closure(def_id, _) + | ty::Opaque(def_id, _) + | ty::Generator(def_id, ..) + | ty::Foreign(def_id) = ty.kind + { + Some(self.tcx.def_span(def_id)) + } else { + None + }; + Some((ty.to_string(), span)) + } } } _ => None, @@ -719,9 +734,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return; } let trait_ref = trait_predicate.to_poly_trait_ref(); - let (post_message, pre_message) = self + let (post_message, pre_message, type_def) = self .get_parent_trait_ref(&obligation.cause.code) - .map(|t| (format!(" in `{}`", t), format!("within `{}`, ", t))) + .map(|(t, s)| { + ( + format!(" in `{}`", t), + format!("within `{}`, ", t), + s.map(|s| (format!("within this `{}`", t), s)), + ) + }) .unwrap_or_default(); let OnUnimplementedNote { message, label, note, enclosing_scope } = @@ -795,6 +816,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } else { err.span_label(span, explanation); } + if let Some((msg, span)) = type_def { + err.span_label(span, &msg); + } if let Some(ref s) = note { // If it has a custom `#[rustc_on_unimplemented]` note, let's display it err.note(s.as_str()); |
