]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Remove support for hyphens in crate names
authorAlex Crichton <alex@alexcrichton.com>
Fri, 27 Mar 2015 00:35:13 +0000 (17:35 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 27 Mar 2015 17:19:59 +0000 (10:19 -0700)
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]

src/librustc/metadata/creader.rs
src/librustc_trans/back/link.rs
src/librustdoc/test.rs
src/libsyntax/parse/parser.rs
src/test/compile-fail/bad-crate-id.rs [deleted file]
src/test/compile-fail/bad-crate-id2.rs [deleted file]
src/test/run-make/output-with-hyphens/Makefile [new file with mode: 0644]
src/test/run-make/output-with-hyphens/foo-bar.rs [new file with mode: 0644]

index 7d8789c3cd1a81873f6a32c5ecb25781a6bbe9af..b6a8525675e456c64afad6b7c8ee895eebb3d948 100644 (file)
@@ -73,24 +73,20 @@ struct CrateInfo {
 }
 
 pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
-    let say = |s: &str, warn: bool| {
+    let say = |s: &str| {
         match (sp, sess) {
             (_, None) => panic!("{}", s),
-            (Some(sp), Some(sess)) if warn => sess.span_warn(sp, s),
             (Some(sp), Some(sess)) => sess.span_err(sp, s),
-            (None, Some(sess)) if warn => sess.warn(s),
             (None, Some(sess)) => sess.err(s),
         }
     };
     if s.len() == 0 {
-        say("crate name must not be empty", false);
-    } else if s.contains("-") {
-        say(&format!("crate names soon cannot contain hyphens: {}", s), true);
+        say("crate name must not be empty");
     }
     for c in s.chars() {
         if c.is_alphanumeric() { continue }
-        if c == '_' || c == '-' { continue }
-        say(&format!("invalid character `{}` in crate name: `{}`", c, s), false);
+        if c == '_'  { continue }
+        say(&format!("invalid character `{}` in crate name: `{}`", c, s));
     }
     match sess {
         Some(sess) => sess.abort_if_errors(),
@@ -306,13 +302,7 @@ fn existing_match(&self, name: &str, hash: Option<&Svh>, kind: PathKind)
                       -> Option<ast::CrateNum> {
         let mut ret = None;
         self.sess.cstore.iter_crate_data(|cnum, data| {
-            // For now we do a "fuzzy match" on crate names by considering
-            // hyphens equal to underscores. This is purely meant to be a
-            // transitionary feature while we deprecate the quote syntax of
-            // `extern crate` statements.
-            if data.name != name.replace("-", "_") {
-                return
-            }
+            if data.name != name { return }
 
             match hash {
                 Some(hash) if *hash == data.hash() => { ret = Some(cnum); return }
index bb7880161d5d4e364b2ebc7701468e64d3820a77..8347571a480590f3fe889bc93be0659bafbbd4f7 100644 (file)
@@ -159,11 +159,19 @@ pub fn find_crate_name(sess: Option<&Session>,
     }
     if let Input::File(ref path) = *input {
         if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
-            return validate(s.to_string(), None);
+            if s.starts_with("-") {
+                let msg = format!("crate names cannot start with a `-`, but \
+                                   `{}` has a leading hyphen", s);
+                if let Some(sess) = sess {
+                    sess.err(&msg);
+                }
+            } else {
+                return validate(s.replace("-", "_"), None);
+            }
         }
     }
 
-    "rust-out".to_string()
+    "rust_out".to_string()
 }
 
 pub fn build_link_meta(sess: &Session, krate: &ast::Crate,
@@ -455,7 +463,11 @@ pub fn filename_for_input(sess: &Session,
         }
         config::CrateTypeExecutable => {
             let suffix = &sess.target.target.options.exe_suffix;
-            out_filename.with_file_name(&format!("{}{}", libname, suffix))
+            if suffix.len() == 0 {
+                out_filename.to_path_buf()
+            } else {
+                out_filename.with_extension(&suffix[1..])
+            }
         }
     }
 }
index 7b37a5a9d1c8167e6fd19f3f60aa1222b291cc47..8e25ee095a043c5626228d40c5105654c273e066 100644 (file)
@@ -224,7 +224,7 @@ fn drop(&mut self) {
     // environment to ensure that the target loads the right libraries at
     // runtime. It would be a sad day if the *host* libraries were loaded as a
     // mistake.
-    let mut cmd = Command::new(&outdir.path().join("rust-out"));
+    let mut cmd = Command::new(&outdir.path().join("rust_out"));
     let var = DynamicLibrary::envvar();
     let newpath = {
         let path = env::var_os(var).unwrap_or(OsString::new());
index 220ea30256e03cba2014e41a1bdb663671b95e49..92795bb200275309e723891ee2ef285ae7401879 100644 (file)
@@ -4977,46 +4977,19 @@ fn parse_item_foreign_static(&mut self, vis: ast::Visibility,
     ///
     /// # Examples
     ///
-    /// extern crate url;
-    /// extern crate foo = "bar"; //deprecated
-    /// extern crate "bar" as foo;
+    /// extern crate foo;
+    /// extern crate bar as foo;
     fn parse_item_extern_crate(&mut self,
-                                lo: BytePos,
-                                visibility: Visibility,
-                                attrs: Vec<Attribute>)
+                               lo: BytePos,
+                               visibility: Visibility,
+                               attrs: Vec<Attribute>)
                                 -> P<Item> {
 
-        let (maybe_path, ident) = match self.token {
-            token::Ident(..) => {
-                let crate_name = self.parse_ident();
-                if self.eat_keyword(keywords::As) {
-                    (Some(crate_name.name), self.parse_ident())
-                } else {
-                    (None, crate_name)
-                }
-            },
-            token::Literal(token::Str_(..), suf) |
-            token::Literal(token::StrRaw(..), suf) => {
-                let sp = self.span;
-                self.expect_no_suffix(sp, "extern crate name", suf);
-                // forgo the internal suffix check of `parse_str` to
-                // avoid repeats (this unwrap will always succeed due
-                // to the restriction of the `match`)
-                let (s, _, _) = self.parse_optional_str().unwrap();
-                self.expect_keyword(keywords::As);
-                let the_ident = self.parse_ident();
-                self.obsolete(sp, ObsoleteSyntax::ExternCrateString);
-                let s = token::intern(&s);
-                (Some(s), the_ident)
-            },
-            _ => {
-                let span = self.span;
-                let token_str = self.this_token_to_string();
-                self.span_fatal(span,
-                                &format!("expected extern crate name but \
-                                         found `{}`",
-                                        token_str));
-            }
+        let crate_name = self.parse_ident();
+        let (maybe_path, ident) = if self.eat_keyword(keywords::As) {
+            (Some(crate_name.name), self.parse_ident())
+        } else {
+            (None, crate_name)
         };
         self.expect(&token::Semi);
 
diff --git a/src/test/compile-fail/bad-crate-id.rs b/src/test/compile-fail/bad-crate-id.rs
deleted file mode 100644 (file)
index 193666f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-extern crate "" as foo; //~ ERROR: crate name must not be empty
-//~^ WARNING: obsolete syntax
-
-fn main() {}
diff --git a/src/test/compile-fail/bad-crate-id2.rs b/src/test/compile-fail/bad-crate-id2.rs
deleted file mode 100644 (file)
index 29df0fa..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-extern crate "#a" as bar; //~ ERROR: invalid character `#` in crate name: `#a`
-//~^ WARNING: obsolete syntax
-
-fn main() {}
diff --git a/src/test/run-make/output-with-hyphens/Makefile b/src/test/run-make/output-with-hyphens/Makefile
new file mode 100644 (file)
index 0000000..783d826
--- /dev/null
@@ -0,0 +1,6 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) foo-bar.rs
+       [ -f $(TMPDIR)/$(call BIN,foo-bar) ]
+       [ -f $(TMPDIR)/libfoo_bar.rlib ]
diff --git a/src/test/run-make/output-with-hyphens/foo-bar.rs b/src/test/run-make/output-with-hyphens/foo-bar.rs
new file mode 100644 (file)
index 0000000..2f93b2d
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "lib"]
+#![crate_type = "bin"]
+
+fn main() {}