@@ -6514,6 +6514,39 @@ impl<'a> Parser<'a> {
65146514 } )
65156515 }
65166516
6517+ fn parse_crate_name_with_dashes ( & mut self ) -> PResult < ' a , ast:: Ident > {
6518+ let error_msg = "crate name using dashes are not valid in `extern crate` statements" ;
6519+ let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
6520+ in the code";
6521+ let mut ident = self . parse_ident ( ) ?;
6522+ let mut idents = vec ! [ ] ;
6523+ let mut replacement = vec ! [ ] ;
6524+ let mut fixed_crate_name = false ;
6525+ // Accept `extern crate name-like-this` for better diagnostics
6526+ let dash = token:: Token :: BinOp ( token:: BinOpToken :: Minus ) ;
6527+ if self . token == dash { // Do not include `-` as part of the expected tokens list
6528+ while self . eat ( & dash) {
6529+ fixed_crate_name = true ;
6530+ replacement. push ( ( self . prev_span , "_" . to_string ( ) ) ) ;
6531+ idents. push ( self . parse_ident ( ) ?) ;
6532+ }
6533+ }
6534+ if fixed_crate_name {
6535+ let fixed_name_sp = ident. span . to ( idents. last ( ) . unwrap ( ) . span ) ;
6536+ let mut fixed_name = format ! ( "{}" , ident. name) ;
6537+ for part in idents {
6538+ fixed_name. push_str ( & format ! ( "_{}" , part. name) ) ;
6539+ }
6540+ ident = Ident :: from_str ( & fixed_name) . with_span_pos ( fixed_name_sp) ;
6541+
6542+ let mut err = self . struct_span_err ( fixed_name_sp, error_msg) ;
6543+ err. span_label ( fixed_name_sp, "dash-separated idents are not valid" ) ;
6544+ err. multipart_suggestion ( suggestion_msg, replacement) ;
6545+ err. emit ( ) ;
6546+ }
6547+ Ok ( ident)
6548+ }
6549+
65176550 /// Parse extern crate links
65186551 ///
65196552 /// # Examples
@@ -6525,7 +6558,8 @@ impl<'a> Parser<'a> {
65256558 visibility : Visibility ,
65266559 attrs : Vec < Attribute > )
65276560 -> PResult < ' a , P < Item > > {
6528- let orig_name = self . parse_ident ( ) ?;
6561+ // Accept `extern crate name-like-this` for better diagnostics
6562+ let orig_name = self . parse_crate_name_with_dashes ( ) ?;
65296563 let ( item_name, orig_name) = if let Some ( rename) = self . parse_rename ( ) ? {
65306564 ( rename, Some ( orig_name. name ) )
65316565 } else {
0 commit comments