@@ -6508,6 +6508,40 @@ impl<'a> Parser<'a> {
65086508 } )
65096509 }
65106510
6511+ fn parse_crate_name_with_dashes (
6512+ & mut self ,
6513+ error_msg : & str ,
6514+ suggestion_msg : & str ,
6515+ ) -> PResult < ' a , ast:: Ident > {
6516+ let mut ident = self . parse_ident ( ) ?;
6517+ let mut idents = vec ! [ ] ;
6518+ let mut replacement = vec ! [ ] ;
6519+ let mut fixed_crate_name = false ;
6520+ // Accept `extern crate name-like-this` for better diagnostics
6521+ let dash = token:: Token :: BinOp ( token:: BinOpToken :: Minus ) ;
6522+ if self . token == dash { // Do not include `-` as part of the expected tokens list
6523+ while self . eat ( & dash) {
6524+ fixed_crate_name = true ;
6525+ replacement. push ( ( self . prev_span , "_" . to_string ( ) ) ) ;
6526+ idents. push ( self . parse_ident ( ) ?) ;
6527+ }
6528+ }
6529+ if fixed_crate_name {
6530+ let fixed_name_sp = ident. span . to ( idents. last ( ) . unwrap ( ) . span ) ;
6531+ let mut fixed_name = format ! ( "{}" , ident. name) ;
6532+ for part in idents {
6533+ fixed_name. push_str ( & format ! ( "_{}" , part. name) ) ;
6534+ }
6535+ ident = Ident :: from_str ( & fixed_name) . with_span_pos ( fixed_name_sp) ;
6536+
6537+ let mut err = self . struct_span_err ( fixed_name_sp, error_msg) ;
6538+ err. span_label ( fixed_name_sp, "dash-separated idents are not valid" ) ;
6539+ err. multipart_suggestion ( suggestion_msg, replacement) ;
6540+ err. emit ( ) ;
6541+ }
6542+ Ok ( ident)
6543+ }
6544+
65116545 /// Parse extern crate links
65126546 ///
65136547 /// # Examples
@@ -6519,11 +6553,15 @@ impl<'a> Parser<'a> {
65196553 visibility : Visibility ,
65206554 attrs : Vec < Attribute > )
65216555 -> PResult < ' a , P < Item > > {
6522- let orig_name = self . parse_ident ( ) ?;
6556+ // Accept `extern crate name-like-this` for better diagnostics
6557+ let ident = self . parse_crate_name_with_dashes (
6558+ "crate name using dashes are not valid in `extern crate` statements" ,
6559+ "if the original crate name uses dashes you need to use underscores in the code" ,
6560+ ) ?;
65236561 let ( item_name, orig_name) = if let Some ( rename) = self . parse_rename ( ) ? {
6524- ( rename, Some ( orig_name . name ) )
6562+ ( rename, Some ( ident . name ) )
65256563 } else {
6526- ( orig_name , None )
6564+ ( ident , None )
65276565 } ;
65286566 self . expect ( & token:: Semi ) ?;
65296567
0 commit comments