about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSmitty <me@smitop.com>2021-04-08 17:18:25 -0400
committerSmitty <me@smitop.com>2021-05-03 20:11:09 -0400
commitf84b4c51ce08a5db9a45017362a27cc33e6af34d (patch)
treef3b1cf40d7f065a745a133d3dd220d0c4cecce34
parent603a42ec5458c547b51173cfa48c23ad37b03c3f (diff)
downloadrust-f84b4c51ce08a5db9a45017362a27cc33e6af34d.tar.gz
rust-f84b4c51ce08a5db9a45017362a27cc33e6af34d.zip
Valid underscores in hex/octal/binary literal docs
Currently hex/octal/binary literals with computed values are displayed
like `0_xff_fff_fffu32`, which is invalid since underscores can't be in
the middle of integer prefixes. This properly formats prefixed integers.
-rw-r--r--src/librustdoc/clean/utils.rs23
-rw-r--r--src/librustdoc/clean/utils/tests.rs41
2 files changed, 62 insertions, 2 deletions
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 7df8b442e5a..20eae7cf680 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -16,6 +16,9 @@ use rustc_middle::ty::{self, DefIdTree, TyCtxt};
 use rustc_span::symbol::{kw, sym, Symbol};
 use std::mem;
 
+#[cfg(test)]
+mod tests;
+
 crate fn krate(cx: &mut DocContext<'_>) -> Crate {
     use crate::visit_lib::LibEmbargoVisitor;
 
@@ -335,11 +338,27 @@ crate fn print_evaluated_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<String>
 
 fn format_integer_with_underscore_sep(num: &str) -> String {
     let num_chars: Vec<_> = num.chars().collect();
-    let num_start_index = if num_chars.get(0) == Some(&'-') { 1 } else { 0 };
+    let mut num_start_index = if num_chars.get(0) == Some(&'-') { 1 } else { 0 };
+    let chunk_size = match num[num_start_index..].as_bytes() {
+        [b'0', b'b' | b'x', ..] => {
+            num_start_index += 2;
+            4
+        }
+        [b'0', b'o', ..] => {
+            num_start_index += 2;
+            let remaining_chars = num_chars.len() - num_start_index;
+            if remaining_chars <= 6 {
+                // don't add underscores to Unix permissions like 0755 or 100755
+                return num.to_string();
+            }
+            3
+        }
+        _ => 3,
+    };
 
     num_chars[..num_start_index]
         .iter()
-        .chain(num_chars[num_start_index..].rchunks(3).rev().intersperse(&['_']).flatten())
+        .chain(num_chars[num_start_index..].rchunks(chunk_size).rev().intersperse(&['_']).flatten())
         .collect()
 }
 
diff --git a/src/librustdoc/clean/utils/tests.rs b/src/librustdoc/clean/utils/tests.rs
new file mode 100644
index 00000000000..ebf4b495483
--- /dev/null
+++ b/src/librustdoc/clean/utils/tests.rs
@@ -0,0 +1,41 @@
+use super::*;
+
+#[test]
+fn int_format_decimal() {
+    assert_eq!(format_integer_with_underscore_sep("12345678"), "12_345_678");
+    assert_eq!(format_integer_with_underscore_sep("123"), "123");
+    assert_eq!(format_integer_with_underscore_sep("123459"), "123_459");
+    assert_eq!(format_integer_with_underscore_sep("-12345678"), "-12_345_678");
+    assert_eq!(format_integer_with_underscore_sep("-123"), "-123");
+    assert_eq!(format_integer_with_underscore_sep("-123459"), "-123_459");
+}
+
+#[test]
+fn int_format_hex() {
+    assert_eq!(format_integer_with_underscore_sep("0xab3"), "0xab3");
+    assert_eq!(format_integer_with_underscore_sep("0xa2345b"), "0xa2_345b");
+    assert_eq!(format_integer_with_underscore_sep("0xa2e6345b"), "0xa2e6_345b");
+    assert_eq!(format_integer_with_underscore_sep("-0xab3"), "-0xab3");
+    assert_eq!(format_integer_with_underscore_sep("-0xa2345b"), "-0xa2_345b");
+    assert_eq!(format_integer_with_underscore_sep("-0xa2e6345b"), "-0xa2e6_345b");
+}
+
+#[test]
+fn int_format_binary() {
+    assert_eq!(format_integer_with_underscore_sep("0o12345671"), "0o12_345_671");
+    assert_eq!(format_integer_with_underscore_sep("0o123"), "0o123");
+    assert_eq!(format_integer_with_underscore_sep("0o123451"), "0o123451");
+    assert_eq!(format_integer_with_underscore_sep("-0o12345671"), "-0o12_345_671");
+    assert_eq!(format_integer_with_underscore_sep("-0o123"), "-0o123");
+    assert_eq!(format_integer_with_underscore_sep("-0o123451"), "-0o123451");
+}
+
+#[test]
+fn int_format_octal() {
+    assert_eq!(format_integer_with_underscore_sep("0b101"), "0b101");
+    assert_eq!(format_integer_with_underscore_sep("0b101101011"), "0b1_0110_1011");
+    assert_eq!(format_integer_with_underscore_sep("0b01101011"), "0b0110_1011");
+    assert_eq!(format_integer_with_underscore_sep("-0b101"), "-0b101");
+    assert_eq!(format_integer_with_underscore_sep("-0b101101011"), "-0b1_0110_1011");
+    assert_eq!(format_integer_with_underscore_sep("-0b01101011"), "-0b0110_1011");
+}