Skip to content

Commit 123a754

Browse files
committed
Auto merge of #23546 - alexcrichton:hyphens, r=brson
The compiler will now issue a warning for crates that have syntax of the form `extern crate "foo" as bar`, but it will still continue to accept this syntax. Additionally, the string `foo-bar` will match the crate name `foo_bar` to assist in the transition period as well. This patch will land hopefully in tandem with a Cargo patch that will start translating all crate names to have underscores instead of hyphens. cc #23533
2 parents ed81038 + eb2f1d9 commit 123a754

File tree

67 files changed

+144
-145
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+144
-145
lines changed

src/librustc/metadata/creader.rs

+20-12
Original file line numberDiff line numberDiff line change
@@ -73,22 +73,24 @@ struct CrateInfo {
7373
}
7474

7575
pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
76-
let err = |s: &str| {
76+
let say = |s: &str, warn: bool| {
7777
match (sp, sess) {
7878
(_, None) => panic!("{}", s),
79+
(Some(sp), Some(sess)) if warn => sess.span_warn(sp, s),
7980
(Some(sp), Some(sess)) => sess.span_err(sp, s),
81+
(None, Some(sess)) if warn => sess.warn(s),
8082
(None, Some(sess)) => sess.err(s),
8183
}
8284
};
8385
if s.len() == 0 {
84-
err("crate name must not be empty");
85-
} else if s.char_at(0) == '-' {
86-
err(&format!("crate name cannot start with a hyphen: {}", s));
86+
say("crate name must not be empty", false);
87+
} else if s.contains("-") {
88+
say(&format!("crate names soon cannot contain hyphens: {}", s), true);
8789
}
8890
for c in s.chars() {
8991
if c.is_alphanumeric() { continue }
9092
if c == '_' || c == '-' { continue }
91-
err(&format!("invalid character `{}` in crate name: `{}`", c, s));
93+
say(&format!("invalid character `{}` in crate name: `{}`", c, s), false);
9294
}
9395
match sess {
9496
Some(sess) => sess.abort_if_errors(),
@@ -153,8 +155,9 @@ impl<'a> CrateReader<'a> {
153155
}
154156
}
155157

156-
// Traverses an AST, reading all the information about use'd crates and extern
157-
// libraries necessary for later resolving, typechecking, linking, etc.
158+
// Traverses an AST, reading all the information about use'd crates and
159+
// extern libraries necessary for later resolving, typechecking, linking,
160+
// etc.
158161
pub fn read_crates(&mut self, krate: &ast::Crate) {
159162
self.process_crate(krate);
160163
visit::walk_crate(self, krate);
@@ -184,11 +187,10 @@ impl<'a> CrateReader<'a> {
184187
debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
185188
ident, path_opt);
186189
let name = match *path_opt {
187-
Some((ref path_str, _)) => {
188-
let name = path_str.to_string();
189-
validate_crate_name(Some(self.sess), &name[..],
190+
Some(name) => {
191+
validate_crate_name(Some(self.sess), name.as_str(),
190192
Some(i.span));
191-
name
193+
name.as_str().to_string()
192194
}
193195
None => ident.to_string(),
194196
};
@@ -304,7 +306,13 @@ impl<'a> CrateReader<'a> {
304306
-> Option<ast::CrateNum> {
305307
let mut ret = None;
306308
self.sess.cstore.iter_crate_data(|cnum, data| {
307-
if data.name != name { return }
309+
// For now we do a "fuzzy match" on crate names by considering
310+
// hyphens equal to underscores. This is purely meant to be a
311+
// transitionary feature while we deprecate the quote syntax of
312+
// `extern crate` statements.
313+
if data.name != name.replace("-", "_") {
314+
return
315+
}
308316

309317
match hash {
310318
Some(hash) if *hash == data.hash() => { ret = Some(cnum); return }

src/librustc_trans/save/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1165,7 +1165,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
11651165
let name = get_ident(item.ident);
11661166
let name = &name;
11671167
let location = match *s {
1168-
Some((ref s, _)) => s.to_string(),
1168+
Some(s) => s.to_string(),
11691169
None => name.to_string(),
11701170
};
11711171
let alias_span = self.span.span_for_last_ident(item.span);

src/librustdoc/visit_ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
237237
ast::ItemExternCrate(ref p) => {
238238
let path = match *p {
239239
None => None,
240-
Some((ref x, _)) => Some(x.to_string()),
240+
Some(x) => Some(x.to_string()),
241241
};
242242
om.extern_crates.push(ExternCrate {
243243
name: name,

src/libsyntax/ast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1771,8 +1771,8 @@ pub struct Item {
17711771
pub enum Item_ {
17721772
/// An`extern crate` item, with optional original crate name,
17731773
///
1774-
/// e.g. `extern crate foo` or `extern crate "foo-bar" as foo`
1775-
ItemExternCrate(Option<(InternedString, StrStyle)>),
1774+
/// e.g. `extern crate foo` or `extern crate foo_bar as foo`
1775+
ItemExternCrate(Option<Name>),
17761776
/// A `use` or `pub use` item
17771777
ItemUse(P<ViewPath>),
17781778

src/libsyntax/parse/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1060,7 +1060,7 @@ mod test {
10601060
let vitem_s = item_to_string(&*vitem);
10611061
assert_eq!(&vitem_s[..], ex_s);
10621062

1063-
let ex_s = "extern crate \"foo\" as bar;";
1063+
let ex_s = "extern crate foo as bar;";
10641064
let vitem = string_to_item(ex_s.to_string()).unwrap();
10651065
let vitem_s = item_to_string(&*vitem);
10661066
assert_eq!(&vitem_s[..], ex_s);

src/libsyntax/parse/obsolete.rs

+6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use ptr::P;
2424
pub enum ObsoleteSyntax {
2525
ClosureKind,
2626
EmptyIndex,
27+
ExternCrateString,
2728
}
2829

2930
pub trait ParserObsoleteMethods {
@@ -56,6 +57,11 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
5657
"write `[..]` instead",
5758
false, // warning for now
5859
),
60+
ObsoleteSyntax::ExternCrateString => (
61+
"\"crate-name\"",
62+
"use an identifier not in quotes instead",
63+
false, // warning for now
64+
),
5965
};
6066

6167
self.report(sp, kind, kind_str, desc, error);

src/libsyntax/parse/parser.rs

+12-20
Original file line numberDiff line numberDiff line change
@@ -4986,37 +4986,28 @@ impl<'a> Parser<'a> {
49864986
attrs: Vec<Attribute>)
49874987
-> P<Item> {
49884988

4989-
let span = self.span;
49904989
let (maybe_path, ident) = match self.token {
49914990
token::Ident(..) => {
4992-
let the_ident = self.parse_ident();
4993-
let path = if self.eat_keyword_noexpect(keywords::As) {
4994-
// skip the ident if there is one
4995-
if self.token.is_ident() { self.bump(); }
4996-
4997-
self.span_err(span, "expected `;`, found `as`");
4998-
self.fileline_help(span,
4999-
&format!("perhaps you meant to enclose the crate name `{}` in \
5000-
a string?",
5001-
the_ident.as_str()));
5002-
None
4991+
let crate_name = self.parse_ident();
4992+
if self.eat_keyword(keywords::As) {
4993+
(Some(crate_name.name), self.parse_ident())
50034994
} else {
5004-
None
5005-
};
5006-
self.expect(&token::Semi);
5007-
(path, the_ident)
4995+
(None, crate_name)
4996+
}
50084997
},
5009-
token::Literal(token::Str_(..), suf) | token::Literal(token::StrRaw(..), suf) => {
4998+
token::Literal(token::Str_(..), suf) |
4999+
token::Literal(token::StrRaw(..), suf) => {
50105000
let sp = self.span;
50115001
self.expect_no_suffix(sp, "extern crate name", suf);
50125002
// forgo the internal suffix check of `parse_str` to
50135003
// avoid repeats (this unwrap will always succeed due
50145004
// to the restriction of the `match`)
5015-
let (s, style, _) = self.parse_optional_str().unwrap();
5005+
let (s, _, _) = self.parse_optional_str().unwrap();
50165006
self.expect_keyword(keywords::As);
50175007
let the_ident = self.parse_ident();
5018-
self.expect(&token::Semi);
5019-
(Some((s, style)), the_ident)
5008+
self.obsolete(sp, ObsoleteSyntax::ExternCrateString);
5009+
let s = token::intern(&s);
5010+
(Some(s), the_ident)
50205011
},
50215012
_ => {
50225013
let span = self.span;
@@ -5027,6 +5018,7 @@ impl<'a> Parser<'a> {
50275018
token_str));
50285019
}
50295020
};
5021+
self.expect(&token::Semi);
50305022

50315023
let last_span = self.last_span;
50325024
self.mk_item(lo,

src/libsyntax/print/pprust.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -821,8 +821,13 @@ impl<'a> State<'a> {
821821
ast::ItemExternCrate(ref optional_path) => {
822822
try!(self.head(&visibility_qualified(item.vis,
823823
"extern crate")));
824-
if let Some((ref p, style)) = *optional_path {
825-
try!(self.print_string(p, style));
824+
if let Some(p) = *optional_path {
825+
let val = token::get_name(p);
826+
if val.contains("-") {
827+
try!(self.print_string(&val, ast::CookedStr));
828+
} else {
829+
try!(self.print_name(p));
830+
}
826831
try!(space(&mut self.s));
827832
try!(word(&mut self.s, "as"));
828833
try!(space(&mut self.s));

src/libsyntax/std_inject.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ impl fold::Folder for StandardLibraryInjector {
5454

5555
// The name to use in `extern crate "name" as std;`
5656
let actual_crate_name = match self.alt_std_name {
57-
Some(ref s) => token::intern_and_get_ident(&s[..]),
58-
None => token::intern_and_get_ident("std"),
57+
Some(ref s) => token::intern(&s),
58+
None => token::intern("std"),
5959
};
6060

6161
krate.module.items.insert(0, P(ast::Item {
@@ -64,7 +64,7 @@ impl fold::Folder for StandardLibraryInjector {
6464
attrs: vec!(
6565
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
6666
InternedString::new("macro_use")))),
67-
node: ast::ItemExternCrate(Some((actual_crate_name, ast::CookedStr))),
67+
node: ast::ItemExternCrate(Some(actual_crate_name)),
6868
vis: ast::Inherited,
6969
span: DUMMY_SP
7070
}));
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/test/compile-fail/bad-crate-id.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
// except according to those terms.
1010

1111
extern crate "" as foo; //~ ERROR: crate name must not be empty
12+
//~^ WARNING: obsolete syntax
1213

1314
fn main() {}

src/test/compile-fail/bad-crate-id2.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
// except according to those terms.
1010

1111
extern crate "#a" as bar; //~ ERROR: invalid character `#` in crate name: `#a`
12+
//~^ WARNING: obsolete syntax
1213

1314
fn main() {}

src/test/compile-fail/coherence-all-remote.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// aux-build:coherence-lib.rs
11+
// aux-build:coherence_lib.rs
1212

13-
extern crate "coherence-lib" as lib;
13+
extern crate coherence_lib as lib;
1414
use lib::Remote1;
1515

1616
impl<T> Remote1<T> for isize { }

src/test/compile-fail/coherence-bigint-param.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// aux-build:coherence-lib.rs
11+
// aux-build:coherence_lib.rs
1212

13-
extern crate "coherence-lib" as lib;
13+
extern crate coherence_lib as lib;
1414
use lib::Remote1;
1515

1616
pub struct BigInt;

src/test/compile-fail/coherence-cow-no-cover.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// aux-build:coherence-lib.rs
11+
// aux-build:coherence_lib.rs
1212

1313
// Test that it's not ok for U to appear uncovered
1414

15-
extern crate "coherence-lib" as lib;
15+
extern crate coherence_lib as lib;
1616
use lib::{Remote,Pair};
1717

1818
pub struct Cover<T>(T);

src/test/compile-fail/coherence-lone-type-parameter.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// aux-build:coherence-lib.rs
11+
// aux-build:coherence_lib.rs
1212

13-
extern crate "coherence-lib" as lib;
13+
extern crate coherence_lib as lib;
1414
use lib::Remote;
1515

1616
impl<T> Remote for T { }

src/test/compile-fail/coherence-orphan.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
// except according to those terms.
1010

1111
// ignore-tidy-linelength
12-
// aux-build:coherence-orphan-lib.rs
12+
// aux-build:coherence_orphan_lib.rs
1313

1414
#![feature(optin_builtin_traits)]
1515

16-
extern crate "coherence-orphan-lib" as lib;
16+
extern crate coherence_orphan_lib as lib;
1717

1818
use lib::TheTrait;
1919

src/test/compile-fail/coherence-overlapping-pairs.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// aux-build:coherence-lib.rs
11+
// aux-build:coherence_lib.rs
1212

13-
extern crate "coherence-lib" as lib;
13+
extern crate coherence_lib as lib;
1414
use lib::Remote;
1515

1616
struct Foo;

src/test/compile-fail/coherence-pair-covered-uncovered-1.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
// Test that the same coverage rules apply even if the local type appears in the
1212
// list of type parameters, not the self type.
1313

14-
// aux-build:coherence-lib.rs
14+
// aux-build:coherence_lib.rs
1515

16-
extern crate "coherence-lib" as lib;
16+
extern crate coherence_lib as lib;
1717
use lib::{Remote1, Pair};
1818

1919
pub struct Local<T>(T);

src/test/compile-fail/coherence-pair-covered-uncovered.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// aux-build:coherence-lib.rs
11+
// aux-build:coherence_lib.rs
1212

13-
extern crate "coherence-lib" as lib;
13+
extern crate coherence_lib as lib;
1414
use lib::{Remote, Pair};
1515

1616
struct Local<T>(T);

src/test/compile-fail/derive-no-std-not-supported.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
extern crate core;
1515
extern crate rand;
16-
extern crate "serialize" as rustc_serialize;
16+
extern crate serialize as rustc_serialize;
1717

1818
#[derive(Rand)] //~ ERROR this trait cannot be derived
1919
//~^ WARNING `#[derive(Rand)]` is deprecated

src/test/compile-fail/issue-11680.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// aux-build:issue-11680.rs
11+
// aux-build:issue_11680.rs
1212

13-
extern crate "issue-11680" as other;
13+
extern crate issue_11680 as other;
1414

1515
fn main() {
1616
let _b = other::Foo::Bar(1);

src/test/compile-fail/issue-12612.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// aux-build:issue-12612-1.rs
11+
// aux-build:issue_12612_1.rs
1212

13-
extern crate "issue-12612-1" as foo;
13+
extern crate issue_12612_1 as foo;
1414

1515
use foo::bar;
1616

src/test/compile-fail/issue-16725.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// aux-build:issue-16725.rs
11+
// aux-build:issue_16725.rs
1212

13-
extern crate "issue-16725" as foo;
13+
extern crate issue_16725 as foo;
1414

1515
fn main() {
1616
unsafe { foo::bar(); }

src/test/compile-fail/issue-17718-const-privacy.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// aux-build:issue-17718-const-privacy.rs
11+
// aux-build:issue_17718_const_privacy.rs
1212

13-
extern crate "issue-17718-const-privacy" as other;
13+
extern crate issue_17718_const_privacy as other;
1414

1515
use a::B; //~ ERROR: const `B` is private
1616
use other::{

0 commit comments

Comments
 (0)