rust-lang/rust · #165047

Change the span building of paths from first-to-last to chained

FranciscoTGouveia · merged Nov 10, 20264 files · 59 + / 15 −
compiler/rustc_parse/src/parser/path.rs43 + / 4 −
@@ -208,23 +208,35 @@ impl<'a> Parser<'a> {         }          let lo = self.token.span;+        let mut path_span = None;         let mut segments = ThinVec::new();         let mod_sep_ctxt = self.token.span.ctxt();         if self.eat_path_sep() {+            chain_span(&mut path_span, self.prev_token.span);             segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));         }-        self.parse_path_segments(&mut segments, style, ty_generics)?;-        Ok(Path { segments, span: lo.to(self.prev_token.span) })+        self.parse_path_segments_with_path_span(&mut segments, style, ty_generics, &mut path_span)?;+        Ok(Path { segments, span: path_span.unwrap() })     }      pub(super) fn parse_path_segments(         &mut self,         segments: &mut ThinVec<PathSegment>,         style: PathStyle,         ty_generics: Option<&Generics>,+    ) -> PResult<'a, ()> {+        self.parse_path_segments_with_path_span(segments, style, ty_generics, &mut None)+    }++    fn parse_path_segments_with_path_span(+        &mut self,+        segments: &mut ThinVec<PathSegment>,+        style: PathStyle,+        ty_generics: Option<&Generics>,+        path_span: &mut Option<Span>,     ) -> PResult<'a, ()> {         loop {-            let segment = self.parse_path_segment(style, ty_generics)?;+            let segment = self.parse_path_segment_with_path_span(style, ty_generics, path_span)?;             if style.has_generic_ambiguity() {                 // In order to check for trailing angle brackets, we must have finished                 // recursing (`parse_path_segment` can indirectly call this function),@@ -263,6 +275,7 @@ impl<'a> Parser<'a> {                         && self.look_ahead(1, |token| self.token.span.hi() == token.span.lo())                     {                         self.bump(); // bump past the colon+                        chain_span(path_span, self.prev_token.span);                         self.dcx().emit_err(PathSingleColon {                             span: self.prev_token.span,                             suggestion: self.prev_token.span.shrink_to_hi(),@@ -273,6 +286,7 @@ impl<'a> Parser<'a> {                  return Ok(());             }+            chain_span(path_span, self.prev_token.span); // `::`         }     } @@ -292,8 +306,18 @@ impl<'a> Parser<'a> {         &mut self,         style: PathStyle,         ty_generics: Option<&Generics>,+    ) -> PResult<'a, PathSegment> {+        self.parse_path_segment_with_path_span(style, ty_generics, &mut None)+    }++    fn parse_path_segment_with_path_span(+        &mut self,+        style: PathStyle,+        ty_generics: Option<&Generics>,+        path_span: &mut Option<Span>,     ) -> PResult<'a, PathSegment> {         let ident = self.parse_path_segment_ident()?;+        chain_span(path_span, self.prev_token.span);         let is_args_start = |token: &Token| {             matches!(token.kind, token::Lt | token::Shl | token::OpenParen | token::LArrow)         };@@ -330,7 +354,9 @@ impl<'a> Parser<'a> {                  // Generic arguments are found - `<`, `(`, `::<` or `::(`.                 // First, eat `::` if it exists.-                let _ = self.eat_path_sep();+                if self.eat_path_sep() {+                    chain_span(path_span, self.prev_token.span);+                }                  let lo = self.token.span;                 let args = if self.eat_lt() {@@ -468,6 +494,14 @@ impl<'a> Parser<'a> {                     ParenthesizedArgs { span, inputs, inputs_span, output }.into()                 }; +                match &args {+                    GenericArgs::Parenthesized(data) => {+                        chain_span(path_span, data.inputs_span);+                        chain_span(path_span, data.output.span());+                    }+                    _ => chain_span(path_span, args.span()),+                }+                 PathSegment { ident, args: Some(args), id: ast::DUMMY_NODE_ID }             } else {                 // Generic arguments are not found.@@ -1020,3 +1054,8 @@ impl<'a> Parser<'a> {         Err(())     } }++/// Chains `span` into `node_span`.+fn chain_span(node_span: &mut Option<Span>, span: Span) {+    *node_span = Some(node_span.map_or(span, |s| s.to(span)));+}
tests/ui/attributes/show_spans_macros.rs0 + / 1 −
@@ -15,7 +15,6 @@ mod foo {     pub const BAR: u8 = 1; } -// FIXME(#126763): the span should be `$a::$b` in the macro body. macro_rules! path {     ($a:tt, $b:tt) => {         let _ = $a::$b;
tests/ui/attributes/show_spans_macros.stderr9 + / 4 −
@@ -1,17 +1,22 @@ note: showing the spans of the path-  --> $DIR/show_spans_macros.rs:27:11+  --> $DIR/show_spans_macros.rs:20:17    |+LL | macro_rules! path {+LL |     ($a:tt, $b:tt) => {+LL |         let _ = $a::$b;+   |                 ^^^^^^+... LL |     path!(foo, BAR);-   |           ^^^^^^^^+   |     --------------- in this macro invocation  note: showing the spans of the expr-  --> $DIR/show_spans_macros.rs:41:12+  --> $DIR/show_spans_macros.rs:40:12    | LL |     field!(T, 0);    |            ^^^^  note: showing the spans of the expr-  --> $DIR/show_spans_macros.rs:41:12+  --> $DIR/show_spans_macros.rs:40:12    | LL |     field!(T, 0);    |            ^
tests/ui/proc-macro/mixed-site-span.stderr7 + / 6 −
@@ -172,10 +172,11 @@ LL |     invoke_with_ident!{krate input TokenItem}    |    = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct instead-  --> $DIR/auxiliary/mixed-site-span.rs:60:34+  --> $DIR/auxiliary/token-site-span.rs:20:39+   |+LL -     ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} };+LL +     ($m:ident $s:ident $i:ident) => { token_site_span::TokenItem as _ };    |-LL |     quote!(use $krate::$ident as token_site_span::TokenItem as _;)-   |                                  +++++++++++++++++++++++++++++  error[E0432]: unresolved import `$crate::TokenItem`   --> $DIR/mixed-site-span.rs:90:5@@ -187,10 +188,10 @@ LL |     with_crate!{krate input TokenItem}    |    = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct instead-  --> $DIR/auxiliary/mixed-site-span.rs:60:34    |-LL |     quote!(use $krate::$ident as token_site_span::TokenItem as _;)-   |                                  ++++++++++++++++++++++++++++++LL -     with_crate!{krate input TokenItem}+LL +     token_site_span::TokenItem as _+   |  error[E0432]: unresolved import `$crate`   --> $DIR/mixed-site-span.rs:91:5