rust-lang/rust · #165047
Change the span building of paths from first-to-last to chained
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