]> git.lizzy.rs Git - rust.git/blobdiff - src/libfmt_macros/lib.rs
Rollup merge of #66391 - estebank:if-else-async-ice, r=Centril
[rust.git] / src / libfmt_macros / lib.rs
index f9c1be20b8bc132aed7ac28364713e714427a797..24b19028ac1179e65cff77613606a4eb8666fd03 100644 (file)
@@ -35,7 +35,7 @@ fn to(self, end: InnerOffset) -> InnerSpan {
 
 /// A piece is a portion of the format string which represents the next part
 /// to emit. These are emitted as a stream by the `Parser` class.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub enum Piece<'a> {
     /// A literal string which should directly be emitted
     String(&'a str),
@@ -45,7 +45,7 @@ pub enum Piece<'a> {
 }
 
 /// Representation of an argument specification.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub struct Argument<'a> {
     /// Where to find this argument
     pub position: Position,
@@ -54,7 +54,7 @@ pub struct Argument<'a> {
 }
 
 /// Specification for the formatting of an argument in the format string.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub struct FormatSpec<'a> {
     /// Optionally specified character to fill alignment with.
     pub fill: Option<char>,
@@ -74,10 +74,12 @@ pub struct FormatSpec<'a> {
     /// this argument, this can be empty or any number of characters, although
     /// it is required to be one word.
     pub ty: &'a str,
+    /// The span of the descriptor string (for diagnostics).
+    pub ty_span: Option<InnerSpan>,
 }
 
 /// Enum describing where an argument for a format can be located.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub enum Position {
     /// The argument is implied to be located at an index
     ArgumentImplicitlyIs(usize),
@@ -97,7 +99,7 @@ pub fn index(&self) -> Option<usize> {
 }
 
 /// Enum of alignments which are supported.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub enum Alignment {
     /// The value will be aligned to the left.
     AlignLeft,
@@ -111,7 +113,7 @@ pub enum Alignment {
 
 /// Various flags which can be applied to format strings. The meaning of these
 /// flags is defined by the formatters themselves.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub enum Flag {
     /// A `+` will be used to denote positive numbers.
     FlagSignPlus,
@@ -131,7 +133,7 @@ pub enum Flag {
 
 /// A count is used for the precision and width parameters of an integer, and
 /// can reference either an argument or a literal integer.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub enum Count {
     /// The count is specified explicitly.
     CountIs(usize),
@@ -410,7 +412,7 @@ fn string(&mut self, start: usize) -> &'a str {
         &self.input[start..self.input.len()]
     }
 
-    /// Parses an Argument structure, or what's contained within braces inside the format string
+    /// Parses an `Argument` structure, or what's contained within braces inside the format string.
     fn argument(&mut self) -> Argument<'a> {
         let pos = self.position();
         let format = self.format();
@@ -464,7 +466,7 @@ fn position(&mut self) -> Option<Position> {
     }
 
     /// Parses a format specifier at the current position, returning all of the
-    /// relevant information in the FormatSpec struct.
+    /// relevant information in the `FormatSpec` struct.
     fn format(&mut self) -> FormatSpec<'a> {
         let mut spec = FormatSpec {
             fill: None,
@@ -475,6 +477,7 @@ fn format(&mut self) -> FormatSpec<'a> {
             width: CountImplied,
             width_span: None,
             ty: &self.input[..0],
+            ty_span: None,
         };
         if !self.consume(':') {
             return spec;
@@ -548,6 +551,7 @@ fn format(&mut self) -> FormatSpec<'a> {
                 spec.precision_span = sp;
             }
         }
+        let ty_span_start = self.cur.peek().map(|(pos, _)| *pos);
         // Optional radix followed by the actual format specifier
         if self.consume('x') {
             if self.consume('?') {
@@ -567,11 +571,17 @@ fn format(&mut self) -> FormatSpec<'a> {
             spec.ty = "?";
         } else {
             spec.ty = self.word();
+            let ty_span_end = self.cur.peek().map(|(pos, _)| *pos);
+            if !spec.ty.is_empty() {
+                spec.ty_span = ty_span_start
+                    .and_then(|s| ty_span_end.map(|e| (s, e)))
+                    .map(|(start, end)| self.to_span_index(start).to(self.to_span_index(end)));
+            }
         }
         spec
     }
 
-    /// Parses a Count parameter at the current position. This does not check
+    /// Parses a `Count` parameter at the current position. This does not check
     /// for 'CountIsNextParam' because that is only used in precision, not
     /// width.
     fn count(&mut self, start: usize) -> (Count, Option<InnerSpan>) {