From e6bf3e2ddbfc7907cdf5f3eef0eee4b610200e4b Mon Sep 17 00:00:00 2001 From: Simon Martin Date: Sun, 20 May 2018 06:43:11 +0200 Subject: Issue #50636: Improve error diagnostic with missing commas after struct fields. --- src/libsyntax/parse/parser.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7b91c491700..013241bd6d6 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5797,9 +5797,18 @@ impl<'a> Parser<'a> { return Err(err); } } - _ => return Err(self.span_fatal_help(self.span, - &format!("expected `,`, or `}}`, found `{}`", self.this_token_to_string()), - "struct fields should be separated by commas")), + _ => { + let sp = self.sess.codemap().next_point(self.prev_span); + let mut err = self.struct_span_err(sp, &format!("expected `,`, or `}}`, found `{}`", + self.this_token_to_string())); + if self.token.is_ident() { + // This is likely another field; emit the diagnostic and keep going + err.span_suggestion(sp, "try adding a comma", ",".into()); + err.emit(); + } else { + return Err(err) + } + } } Ok(a_var) } -- cgit 1.4.1-3-g733a5 From 3b8f791bf60c0e77ec713356e841c836eb6a55fb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 21 May 2018 09:02:50 -0700 Subject: rustc: Fix procedural macros generating lifetime tokens This commit fixes an accidental regression from #50473 where lifetime tokens produced by procedural macros ended up getting lost in translation in the compiler and not actually producing parseable code. The issue lies in the fact that a lifetime's `Ident` is prefixed with `'`. The `glue` implementation for gluing joint tokens together forgot to take this into account so the lifetime inside of `Ident` was missing the leading tick! The `glue` implementation here is updated to create a new `Symbol` in these situations to manufacture a new `Ident` with a leading tick to ensure it parses correctly. Closes #50942 --- src/libsyntax/parse/token.rs | 9 +++++- .../proc-macro/auxiliary/gen-lifetime-token.rs | 35 ++++++++++++++++++++++ .../proc-macro/gen-lifetime-token.rs | 22 ++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass-fulldeps/proc-macro/auxiliary/gen-lifetime-token.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/gen-lifetime-token.rs (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 5575614a4d4..06af21b3747 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -22,6 +22,7 @@ use serialize::{Decodable, Decoder, Encodable, Encoder}; use symbol::keywords; use syntax::parse::parse_stream_from_source_str; use syntax_pos::{self, Span, FileName}; +use syntax_pos::symbol::{self, Symbol}; use tokenstream::{TokenStream, TokenTree}; use tokenstream; @@ -478,7 +479,13 @@ impl Token { _ => return None, }, SingleQuote => match joint { - Ident(ident, false) => Lifetime(ident), + Ident(ident, false) => { + let name = Symbol::intern(&format!("'{}", ident)); + Lifetime(symbol::Ident { + name, + span: ident.span, + }) + } _ => return None, }, diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/gen-lifetime-token.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/gen-lifetime-token.rs new file mode 100644 index 00000000000..e288050a928 --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/gen-lifetime-token.rs @@ -0,0 +1,35 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro] +pub fn bar(_input: TokenStream) -> TokenStream { + let mut ret = Vec::::new(); + ret.push(Ident::new("static", Span::call_site()).into()); + ret.push(Ident::new("FOO", Span::call_site()).into()); + ret.push(Punct::new(':', Spacing::Alone).into()); + ret.push(Punct::new('&', Spacing::Alone).into()); + ret.push(Punct::new('\'', Spacing::Joint).into()); + ret.push(Ident::new("static", Span::call_site()).into()); + ret.push(Ident::new("i32", Span::call_site()).into()); + ret.push(Punct::new('=', Spacing::Alone).into()); + ret.push(Punct::new('&', Spacing::Alone).into()); + ret.push(Literal::i32_unsuffixed(1).into()); + ret.push(Punct::new(';', Spacing::Alone).into()); + ret.into_iter().collect() +} diff --git a/src/test/run-pass-fulldeps/proc-macro/gen-lifetime-token.rs b/src/test/run-pass-fulldeps/proc-macro/gen-lifetime-token.rs new file mode 100644 index 00000000000..539e3aa8ecb --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/gen-lifetime-token.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:gen-lifetime-token.rs + +#![feature(proc_macro)] + +extern crate gen_lifetime_token as bar; + +bar::bar!(); + +fn main() { + let x: &'static i32 = FOO; + assert_eq!(*x, 1); +} -- cgit 1.4.1-3-g733a5