From a3bf27b1db29887b49614934105a105d1b8d09fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 25 Jul 2018 22:18:47 -0700 Subject: [PATCH 1/2] Suggest underscore when using dashes in crate namet push fork --- src/libsyntax/parse/parser.rs | 44 ++++++++++++++++++++++++++++--- src/test/ui/bad-crate-name.rs | 15 +++++++++++ src/test/ui/bad-crate-name.stderr | 19 +++++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/bad-crate-name.rs create mode 100644 src/test/ui/bad-crate-name.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2eaa56ebeb826..6dab7865eeadb 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6508,6 +6508,40 @@ impl<'a> Parser<'a> { }) } + fn parse_crate_name_with_dashes( + &mut self, + error_msg: &str, + suggestion_msg: &str, + ) -> PResult<'a, ast::Ident> { + let mut ident = self.parse_ident()?; + let mut idents = vec![]; + let mut replacement = vec![]; + let mut fixed_crate_name = false; + // Accept `extern crate name-like-this` for better diagnostics + let dash = token::Token::BinOp(token::BinOpToken::Minus); + if self.token == dash { // Do not include `-` as part of the expected tokens list + while self.eat(&dash) { + fixed_crate_name = true; + replacement.push((self.prev_span, "_".to_string())); + idents.push(self.parse_ident()?); + } + } + if fixed_crate_name { + let fixed_name_sp = ident.span.to(idents.last().unwrap().span); + let mut fixed_name = format!("{}", ident.name); + for part in idents { + fixed_name.push_str(&format!("_{}", part.name)); + } + ident = Ident::from_str(&fixed_name).with_span_pos(fixed_name_sp); + + let mut err = self.struct_span_err(fixed_name_sp, error_msg); + err.span_label(fixed_name_sp, "dash-separated idents are not valid"); + err.multipart_suggestion(suggestion_msg, replacement); + err.emit(); + } + Ok(ident) + } + /// Parse extern crate links /// /// # Examples @@ -6519,11 +6553,15 @@ impl<'a> Parser<'a> { visibility: Visibility, attrs: Vec) -> PResult<'a, P> { - let orig_name = self.parse_ident()?; + // Accept `extern crate name-like-this` for better diagnostics + let ident = self.parse_crate_name_with_dashes( + "crate name using dashes are not valid in `extern crate` statements", + "if the original crate name uses dashes you need to use underscores in the code", + )?; let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? { - (rename, Some(orig_name.name)) + (rename, Some(ident.name)) } else { - (orig_name, None) + (ident, None) }; self.expect(&token::Semi)?; diff --git a/src/test/ui/bad-crate-name.rs b/src/test/ui/bad-crate-name.rs new file mode 100644 index 0000000000000..70e1806a20b54 --- /dev/null +++ b/src/test/ui/bad-crate-name.rs @@ -0,0 +1,15 @@ +// 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. + +extern crate krate-name-here; +//~^ ERROR crate name using dashes are not valid in `extern crate` statements +//~| ERROR can't find crate for `krate_name_here` + +fn main() {} diff --git a/src/test/ui/bad-crate-name.stderr b/src/test/ui/bad-crate-name.stderr new file mode 100644 index 0000000000000..8348badeeeb17 --- /dev/null +++ b/src/test/ui/bad-crate-name.stderr @@ -0,0 +1,19 @@ +error: crate name using dashes are not valid in `extern crate` statements + --> $DIR/bad-crate-name.rs:11:14 + | +LL | extern crate krate-name-here; + | ^^^^^^^^^^^^^^^ dash-separated idents are not valid +help: if the original crate name uses dashes you need to use underscores in the code + | +LL | extern crate krate_name_here; + | ^ ^ + +error[E0463]: can't find crate for `krate_name_here` + --> $DIR/bad-crate-name.rs:11:1 + | +LL | extern crate krate-name-here; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0463`. From 647d295fb2fbd3e46a517332d5023dc51ae6e317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 27 Jul 2018 13:11:48 -0700 Subject: [PATCH 2/2] review comments --- src/libsyntax/parse/parser.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6dab7865eeadb..49debfa43906a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6508,11 +6508,10 @@ impl<'a> Parser<'a> { }) } - fn parse_crate_name_with_dashes( - &mut self, - error_msg: &str, - suggestion_msg: &str, - ) -> PResult<'a, ast::Ident> { + fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> { + let error_msg = "crate name using dashes are not valid in `extern crate` statements"; + let suggestion_msg = "if the original crate name uses dashes you need to use underscores \ + in the code"; let mut ident = self.parse_ident()?; let mut idents = vec![]; let mut replacement = vec![]; @@ -6554,14 +6553,11 @@ impl<'a> Parser<'a> { attrs: Vec) -> PResult<'a, P> { // Accept `extern crate name-like-this` for better diagnostics - let ident = self.parse_crate_name_with_dashes( - "crate name using dashes are not valid in `extern crate` statements", - "if the original crate name uses dashes you need to use underscores in the code", - )?; + let orig_name = self.parse_crate_name_with_dashes()?; let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? { - (rename, Some(ident.name)) + (rename, Some(orig_name.name)) } else { - (ident, None) + (orig_name, None) }; self.expect(&token::Semi)?;