From cd7c8182dd48b2562153324915ba236f3c33cc5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Oct 2018 18:44:07 -0700 Subject: [PATCH] Add more targetting filters for arrays to rustc_on_unimplemented --- src/librustc/traits/error_reporting.rs | 38 +++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index da2173fead37..a7ebd0c8965c 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -349,10 +349,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn on_unimplemented_note( &self, trait_ref: ty::PolyTraitRef<'tcx>, - obligation: &PredicateObligation<'tcx>) -> - OnUnimplementedNote - { - let def_id = self.impl_similar_to(trait_ref, obligation) + obligation: &PredicateObligation<'tcx>, + ) -> OnUnimplementedNote { + let def_id = self.impl_similar_to(trait_ref, obligation) .unwrap_or(trait_ref.def_id()); let trait_ref = *trait_ref.skip_binder(); @@ -410,6 +409,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { flags.push(("crate_local".to_owned(), None)); } + // Allow targetting all integers using `{integral}`, even if the exact type was resolved + if self_ty.is_integral() { + flags.push(("_Self".to_owned(), Some("{integral}".to_owned()))); + } + + if let ty::Array(aty, len) = self_ty.sty { + flags.push(("_Self".to_owned(), Some("[]".to_owned()))); + flags.push(("_Self".to_owned(), Some(format!("[{}]", aty)))); + if let Some(def) = aty.ty_adt_def() { + // We also want to be able to select the array's type's original + // signature with no type arguments resolved + flags.push(( + "_Self".to_owned(), + Some(format!("[{}]", self.tcx.type_of(def.did).to_string())), + )); + if let Some(len) = len.val.try_to_scalar().and_then(|scalar| { + scalar.to_u64().ok() + }) { + flags.push(( + "_Self".to_owned(), + Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)), + )); + } else { + flags.push(( + "_Self".to_owned(), + Some(format!("[{}; _]", self.tcx.type_of(def.did).to_string())), + )); + } + } + } + if let Ok(Some(command)) = OnUnimplementedDirective::of_item( self.tcx, trait_ref.def_id, def_id ) {