about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2022-01-14 19:57:45 -0800
committerDavid Tolnay <dtolnay@gmail.com>2022-01-17 10:38:30 -0800
commit1b5ff95edbf938d96aa687c72f849d1a9ef15ff9 (patch)
treef73cc32272d73d3fc4b1ac606843e2ede3ab274c
parentabf1d94b1aff83b03c4f4d02c615e26ecf9c1484 (diff)
Replace confusing is_sorted_by in format_args implementation
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs28
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
2 files changed, 16 insertions, 13 deletions
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 50ef350feb6..491df287cd6 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -11,9 +11,9 @@ use rustc_expand::base::{self, *};
 use rustc_parse_format as parse;
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{MultiSpan, Span};
+use smallvec::SmallVec;
 
 use std::borrow::Cow;
-use std::cmp::Ordering;
 use std::collections::hash_map::Entry;
 
 #[derive(PartialEq)]
@@ -760,21 +760,23 @@ impl<'a, 'b> Context<'a, 'b> {
         // "{1} {0}"), or may have multiple entries referring to the same
         // element of original_args ("{0} {0}").
         //
-        // The following Iterator<Item = (usize, &ArgumentType)> has one item
-        // per element of our output slice, identifying the index of which
-        // element of original_args it's passing, and that argument's type.
-        let fmt_arg_index_and_ty = self
-            .arg_unique_types
-            .iter()
-            .enumerate()
-            .flat_map(|(i, unique_types)| unique_types.iter().map(move |ty| (i, ty)))
-            .chain(self.count_args.iter().map(|i| (*i, &Count)));
+        // The following vector has one item per element of our output slice,
+        // identifying the index of which element of original_args it's passing,
+        // and that argument's type.
+        let mut fmt_arg_index_and_ty = SmallVec::<[(usize, &ArgumentType); 8]>::new();
+        for (i, unique_types) in self.arg_unique_types.iter().enumerate() {
+            fmt_arg_index_and_ty.extend(unique_types.iter().map(|ty| (i, ty)));
+        }
+        fmt_arg_index_and_ty.extend(self.count_args.iter().map(|&i| (i, &Count)));
 
         // Figure out whether there are permuted or repeated elements. If not,
         // we can generate simpler code.
-        let nicely_ordered = fmt_arg_index_and_ty
-            .clone()
-            .is_sorted_by(|(i, _), (j, _)| (i < j).then_some(Ordering::Less));
+        //
+        // The sequence has no indices out of order or repeated if: for every
+        // adjacent pair of elements, the first one's index is less than the
+        // second one's index.
+        let nicely_ordered =
+            fmt_arg_index_and_ty.array_windows().all(|[(i, _i_ty), (j, _j_ty)]| i < j);
 
         // We want to emit:
         //
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 68edcb1b92c..6c16c285492 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -2,6 +2,7 @@
 //! injecting code into the crate before it is lowered to HIR.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(array_windows)]
 #![feature(box_patterns)]
 #![feature(bool_to_option)]
 #![feature(crate_visibility_modifier)]