Skip to content

Commit b24a3b8

Browse files
committed
rustc: Remove support for hyphens in crate names
This commit removes parser support for `extern crate "foo" as bar` as the renamed crate is now required to be an identifier. Additionally this commit enables hard errors on crate names that contain hyphens in them, they must now solely contain alphanumeric characters or underscores. If the crate name is inferred from the file name, however, the file name `foo-bar.rs` will have the crate name inferred as `foo_bar`. If a binary is being emitted it will have the name `foo-bar` and a library will have the name `libfoo_bar.rlib`. This commit is a breaking change for a number of reasons: * Old syntax is being removed. This was previously only issuing warnings. * The output for the compiler when input is received on stdin is now `rust_out` instead of `rust-out`. * The crate name for a crate in the file `foo-bar.rs` is now `foo_bar` which can affect infrastructure such as logging. [breaking-change]
1 parent 36ef29a commit b24a3b8

File tree

7 files changed

+40
-73
lines changed

7 files changed

+40
-73
lines changed

src/librustc/metadata/creader.rs

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

7575
pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
76-
let say = |s: &str, warn: bool| {
76+
let say = |s: &str| {
7777
match (sp, sess) {
7878
(_, None) => panic!("{}", s),
79-
(Some(sp), Some(sess)) if warn => sess.span_warn(sp, s),
8079
(Some(sp), Some(sess)) => sess.span_err(sp, s),
81-
(None, Some(sess)) if warn => sess.warn(s),
8280
(None, Some(sess)) => sess.err(s),
8381
}
8482
};
8583
if s.len() == 0 {
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);
84+
say("crate name must not be empty");
8985
}
9086
for c in s.chars() {
9187
if c.is_alphanumeric() { continue }
92-
if c == '_' || c == '-' { continue }
93-
say(&format!("invalid character `{}` in crate name: `{}`", c, s), false);
88+
if c == '_' { continue }
89+
say(&format!("invalid character `{}` in crate name: `{}`", c, s));
9490
}
9591
match sess {
9692
Some(sess) => sess.abort_if_errors(),
@@ -306,13 +302,7 @@ impl<'a> CrateReader<'a> {
306302
-> Option<ast::CrateNum> {
307303
let mut ret = None;
308304
self.sess.cstore.iter_crate_data(|cnum, data| {
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-
}
305+
if data.name != name { return }
316306

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

src/librustc_trans/back/link.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,19 @@ pub fn find_crate_name(sess: Option<&Session>,
159159
}
160160
if let Input::File(ref path) = *input {
161161
if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
162-
return validate(s.to_string(), None);
162+
if s.starts_with("-") {
163+
let msg = format!("crate names cannot start with a `-`, but \
164+
`{}` has a leading hyphen", s);
165+
if let Some(sess) = sess {
166+
sess.err(&msg);
167+
}
168+
} else {
169+
return validate(s.replace("-", "_"), None);
170+
}
163171
}
164172
}
165173

166-
"rust-out".to_string()
174+
"rust_out".to_string()
167175
}
168176

169177
pub fn build_link_meta(sess: &Session, krate: &ast::Crate,
@@ -455,7 +463,11 @@ pub fn filename_for_input(sess: &Session,
455463
}
456464
config::CrateTypeExecutable => {
457465
let suffix = &sess.target.target.options.exe_suffix;
458-
out_filename.with_file_name(&format!("{}{}", libname, suffix))
466+
if suffix.len() == 0 {
467+
out_filename.to_path_buf()
468+
} else {
469+
out_filename.with_extension(&suffix[1..])
470+
}
459471
}
460472
}
461473
}

src/librustdoc/test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
224224
// environment to ensure that the target loads the right libraries at
225225
// runtime. It would be a sad day if the *host* libraries were loaded as a
226226
// mistake.
227-
let mut cmd = Command::new(&outdir.path().join("rust-out"));
227+
let mut cmd = Command::new(&outdir.path().join("rust_out"));
228228
let var = DynamicLibrary::envvar();
229229
let newpath = {
230230
let path = env::var_os(var).unwrap_or(OsString::new());

src/libsyntax/parse/parser.rs

+10-37
Original file line numberDiff line numberDiff line change
@@ -4977,46 +4977,19 @@ impl<'a> Parser<'a> {
49774977
///
49784978
/// # Examples
49794979
///
4980-
/// extern crate url;
4981-
/// extern crate foo = "bar"; //deprecated
4982-
/// extern crate "bar" as foo;
4980+
/// extern crate foo;
4981+
/// extern crate bar as foo;
49834982
fn parse_item_extern_crate(&mut self,
4984-
lo: BytePos,
4985-
visibility: Visibility,
4986-
attrs: Vec<Attribute>)
4983+
lo: BytePos,
4984+
visibility: Visibility,
4985+
attrs: Vec<Attribute>)
49874986
-> P<Item> {
49884987

4989-
let (maybe_path, ident) = match self.token {
4990-
token::Ident(..) => {
4991-
let crate_name = self.parse_ident();
4992-
if self.eat_keyword(keywords::As) {
4993-
(Some(crate_name.name), self.parse_ident())
4994-
} else {
4995-
(None, crate_name)
4996-
}
4997-
},
4998-
token::Literal(token::Str_(..), suf) |
4999-
token::Literal(token::StrRaw(..), suf) => {
5000-
let sp = self.span;
5001-
self.expect_no_suffix(sp, "extern crate name", suf);
5002-
// forgo the internal suffix check of `parse_str` to
5003-
// avoid repeats (this unwrap will always succeed due
5004-
// to the restriction of the `match`)
5005-
let (s, _, _) = self.parse_optional_str().unwrap();
5006-
self.expect_keyword(keywords::As);
5007-
let the_ident = self.parse_ident();
5008-
self.obsolete(sp, ObsoleteSyntax::ExternCrateString);
5009-
let s = token::intern(&s);
5010-
(Some(s), the_ident)
5011-
},
5012-
_ => {
5013-
let span = self.span;
5014-
let token_str = self.this_token_to_string();
5015-
self.span_fatal(span,
5016-
&format!("expected extern crate name but \
5017-
found `{}`",
5018-
token_str));
5019-
}
4988+
let crate_name = self.parse_ident();
4989+
let (maybe_path, ident) = if self.eat_keyword(keywords::As) {
4990+
(Some(crate_name.name), self.parse_ident())
4991+
} else {
4992+
(None, crate_name)
50204993
};
50214994
self.expect(&token::Semi);
50224995

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

-14
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-include ../tools.mk
2+
3+
all:
4+
$(RUSTC) foo-bar.rs
5+
[ -f $(TMPDIR)/$(call BIN,foo-bar) ]
6+
[ -f $(TMPDIR)/libfoo_bar.rlib ]
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
extern crate "" as foo; //~ ERROR: crate name must not be empty
12-
//~^ WARNING: obsolete syntax
11+
#![crate_type = "lib"]
12+
#![crate_type = "bin"]
1313

1414
fn main() {}

0 commit comments

Comments
 (0)