about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2018-10-09 18:44:07 -0700
committerEsteban Küber <esteban@kuber.com.ar>2018-10-09 18:44:07 -0700
commitcd7c8182dd48b2562153324915ba236f3c33cc5d (patch)
tree6d438f7beb184ac854c53f9f110767ed90d95cef
parent0e07c4281c343e9e15a0a8fca79538ad1a8eb513 (diff)
downloadrust-cd7c8182dd48b2562153324915ba236f3c33cc5d.tar.gz
rust-cd7c8182dd48b2562153324915ba236f3c33cc5d.zip
Add more targetting filters for arrays to rustc_on_unimplemented
-rw-r--r--src/librustc/traits/error_reporting.rs38
1 files changed, 34 insertions, 4 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index da2173fead3..a7ebd0c8965 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
         ) {