@@ -6508,6 +6508,40 @@ impl<'a> Parser<'a> {
6508
6508
} )
6509
6509
}
6510
6510
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
+
6511
6545
/// Parse extern crate links
6512
6546
///
6513
6547
/// # Examples
@@ -6519,11 +6553,15 @@ impl<'a> Parser<'a> {
6519
6553
visibility : Visibility ,
6520
6554
attrs : Vec < Attribute > )
6521
6555
-> 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
+ ) ?;
6523
6561
let ( item_name, orig_name) = if let Some ( rename) = self . parse_rename ( ) ? {
6524
- ( rename, Some ( orig_name . name ) )
6562
+ ( rename, Some ( ident . name ) )
6525
6563
} else {
6526
- ( orig_name , None )
6564
+ ( ident , None )
6527
6565
} ;
6528
6566
self . expect ( & token:: Semi ) ?;
6529
6567
0 commit comments