Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc: Add support for extern crate foo as bar #23546

Merged
merged 1 commit into from
Mar 25, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions src/librustc/metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,22 +73,24 @@ struct CrateInfo {
}

pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
let err = |s: &str| {
let say = |s: &str, warn: bool| {
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 {
err("crate name must not be empty");
} else if s.char_at(0) == '-' {
err(&format!("crate name cannot start with a hyphen: {}", s));
say("crate name must not be empty", false);
} else if s.contains("-") {
say(&format!("crate names soon cannot contain hyphens: {}", s), true);
}
for c in s.chars() {
if c.is_alphanumeric() { continue }
if c == '_' || c == '-' { continue }
err(&format!("invalid character `{}` in crate name: `{}`", c, s));
say(&format!("invalid character `{}` in crate name: `{}`", c, s), false);
}
match sess {
Some(sess) => sess.abort_if_errors(),
Expand Down Expand Up @@ -153,8 +155,9 @@ impl<'a> CrateReader<'a> {
}
}

// Traverses an AST, reading all the information about use'd crates and extern
// libraries necessary for later resolving, typechecking, linking, etc.
// Traverses an AST, reading all the information about use'd crates and
// extern libraries necessary for later resolving, typechecking, linking,
// etc.
pub fn read_crates(&mut self, krate: &ast::Crate) {
self.process_crate(krate);
visit::walk_crate(self, krate);
Expand Down Expand Up @@ -184,11 +187,10 @@ impl<'a> CrateReader<'a> {
debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
ident, path_opt);
let name = match *path_opt {
Some((ref path_str, _)) => {
let name = path_str.to_string();
validate_crate_name(Some(self.sess), &name[..],
Some(name) => {
validate_crate_name(Some(self.sess), name.as_str(),
Some(i.span));
name
name.as_str().to_string()
}
None => ident.to_string(),
};
Expand Down Expand Up @@ -304,7 +306,13 @@ impl<'a> CrateReader<'a> {
-> Option<ast::CrateNum> {
let mut ret = None;
self.sess.cstore.iter_crate_data(|cnum, data| {
if data.name != name { return }
// 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
}

match hash {
Some(hash) if *hash == data.hash() => { ret = Some(cnum); return }
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/save/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1165,7 +1165,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
let name = get_ident(item.ident);
let name = &name;
let location = match *s {
Some((ref s, _)) => s.to_string(),
Some(s) => s.to_string(),
None => name.to_string(),
};
let alias_span = self.span.span_for_last_ident(item.span);
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/visit_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
ast::ItemExternCrate(ref p) => {
let path = match *p {
None => None,
Some((ref x, _)) => Some(x.to_string()),
Some(x) => Some(x.to_string()),
};
om.extern_crates.push(ExternCrate {
name: name,
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1771,8 +1771,8 @@ pub struct Item {
pub enum Item_ {
/// An`extern crate` item, with optional original crate name,
///
/// e.g. `extern crate foo` or `extern crate "foo-bar" as foo`
ItemExternCrate(Option<(InternedString, StrStyle)>),
/// e.g. `extern crate foo` or `extern crate foo_bar as foo`
ItemExternCrate(Option<Name>),
/// A `use` or `pub use` item
ItemUse(P<ViewPath>),

Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1060,7 +1060,7 @@ mod test {
let vitem_s = item_to_string(&*vitem);
assert_eq!(&vitem_s[..], ex_s);

let ex_s = "extern crate \"foo\" as bar;";
let ex_s = "extern crate foo as bar;";
let vitem = string_to_item(ex_s.to_string()).unwrap();
let vitem_s = item_to_string(&*vitem);
assert_eq!(&vitem_s[..], ex_s);
Expand Down
6 changes: 6 additions & 0 deletions src/libsyntax/parse/obsolete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use ptr::P;
pub enum ObsoleteSyntax {
ClosureKind,
EmptyIndex,
ExternCrateString,
}

pub trait ParserObsoleteMethods {
Expand Down Expand Up @@ -56,6 +57,11 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
"write `[..]` instead",
false, // warning for now
),
ObsoleteSyntax::ExternCrateString => (
"\"crate-name\"",
"use an identifier not in quotes instead",
false, // warning for now
),
};

self.report(sp, kind, kind_str, desc, error);
Expand Down
32 changes: 12 additions & 20 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4986,37 +4986,28 @@ impl<'a> Parser<'a> {
attrs: Vec<Attribute>)
-> P<Item> {

let span = self.span;
let (maybe_path, ident) = match self.token {
token::Ident(..) => {
let the_ident = self.parse_ident();
let path = if self.eat_keyword_noexpect(keywords::As) {
// skip the ident if there is one
if self.token.is_ident() { self.bump(); }

self.span_err(span, "expected `;`, found `as`");
self.fileline_help(span,
&format!("perhaps you meant to enclose the crate name `{}` in \
a string?",
the_ident.as_str()));
None
let crate_name = self.parse_ident();
if self.eat_keyword(keywords::As) {
(Some(crate_name.name), self.parse_ident())
} else {
None
};
self.expect(&token::Semi);
(path, the_ident)
(None, crate_name)
}
},
token::Literal(token::Str_(..), suf) | token::Literal(token::StrRaw(..), suf) => {
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, style, _) = self.parse_optional_str().unwrap();
let (s, _, _) = self.parse_optional_str().unwrap();
self.expect_keyword(keywords::As);
let the_ident = self.parse_ident();
self.expect(&token::Semi);
(Some((s, style)), the_ident)
self.obsolete(sp, ObsoleteSyntax::ExternCrateString);
let s = token::intern(&s);
(Some(s), the_ident)
},
_ => {
let span = self.span;
Expand All @@ -5027,6 +5018,7 @@ impl<'a> Parser<'a> {
token_str));
}
};
self.expect(&token::Semi);

let last_span = self.last_span;
self.mk_item(lo,
Expand Down
9 changes: 7 additions & 2 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -821,8 +821,13 @@ impl<'a> State<'a> {
ast::ItemExternCrate(ref optional_path) => {
try!(self.head(&visibility_qualified(item.vis,
"extern crate")));
if let Some((ref p, style)) = *optional_path {
try!(self.print_string(p, style));
if let Some(p) = *optional_path {
let val = token::get_name(p);
if val.contains("-") {
try!(self.print_string(&val, ast::CookedStr));
} else {
try!(self.print_name(p));
}
try!(space(&mut self.s));
try!(word(&mut self.s, "as"));
try!(space(&mut self.s));
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/std_inject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ impl fold::Folder for StandardLibraryInjector {

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

krate.module.items.insert(0, P(ast::Item {
Expand All @@ -64,7 +64,7 @@ impl fold::Folder for StandardLibraryInjector {
attrs: vec!(
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
InternedString::new("macro_use")))),
node: ast::ItemExternCrate(Some((actual_crate_name, ast::CookedStr))),
node: ast::ItemExternCrate(Some(actual_crate_name)),
vis: ast::Inherited,
span: DUMMY_SP
}));
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions src/test/compile-fail/bad-crate-id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
// except according to those terms.

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

fn main() {}
1 change: 1 addition & 0 deletions src/test/compile-fail/bad-crate-id2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
// except according to those terms.

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

fn main() {}
4 changes: 2 additions & 2 deletions src/test/compile-fail/coherence-all-remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:coherence-lib.rs
// aux-build:coherence_lib.rs

extern crate "coherence-lib" as lib;
extern crate coherence_lib as lib;
use lib::Remote1;

impl<T> Remote1<T> for isize { }
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/coherence-bigint-param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:coherence-lib.rs
// aux-build:coherence_lib.rs

extern crate "coherence-lib" as lib;
extern crate coherence_lib as lib;
use lib::Remote1;

pub struct BigInt;
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/coherence-cow-no-cover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:coherence-lib.rs
// aux-build:coherence_lib.rs

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

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

pub struct Cover<T>(T);
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/coherence-lone-type-parameter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:coherence-lib.rs
// aux-build:coherence_lib.rs

extern crate "coherence-lib" as lib;
extern crate coherence_lib as lib;
use lib::Remote;

impl<T> Remote for T { }
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/coherence-orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
// except according to those terms.

// ignore-tidy-linelength
// aux-build:coherence-orphan-lib.rs
// aux-build:coherence_orphan_lib.rs

#![feature(optin_builtin_traits)]

extern crate "coherence-orphan-lib" as lib;
extern crate coherence_orphan_lib as lib;

use lib::TheTrait;

Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/coherence-overlapping-pairs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:coherence-lib.rs
// aux-build:coherence_lib.rs

extern crate "coherence-lib" as lib;
extern crate coherence_lib as lib;
use lib::Remote;

struct Foo;
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/coherence-pair-covered-uncovered-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
// Test that the same coverage rules apply even if the local type appears in the
// list of type parameters, not the self type.

// aux-build:coherence-lib.rs
// aux-build:coherence_lib.rs

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

pub struct Local<T>(T);
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/coherence-pair-covered-uncovered.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:coherence-lib.rs
// aux-build:coherence_lib.rs

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

struct Local<T>(T);
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/derive-no-std-not-supported.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

extern crate core;
extern crate rand;
extern crate "serialize" as rustc_serialize;
extern crate serialize as rustc_serialize;

#[derive(Rand)] //~ ERROR this trait cannot be derived
//~^ WARNING `#[derive(Rand)]` is deprecated
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/issue-11680.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:issue-11680.rs
// aux-build:issue_11680.rs

extern crate "issue-11680" as other;
extern crate issue_11680 as other;

fn main() {
let _b = other::Foo::Bar(1);
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/issue-12612.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:issue-12612-1.rs
// aux-build:issue_12612_1.rs

extern crate "issue-12612-1" as foo;
extern crate issue_12612_1 as foo;

use foo::bar;

Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/issue-16725.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:issue-16725.rs
// aux-build:issue_16725.rs

extern crate "issue-16725" as foo;
extern crate issue_16725 as foo;

fn main() {
unsafe { foo::bar(); }
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/issue-17718-const-privacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

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

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

use a::B; //~ ERROR: const `B` is private
use other::{
Expand Down
Loading