mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Auto merge of #55275 - petrochenkov:extself, r=eddyb
experiment: Support aliasing local crate root in extern prelude This PR provides some minimally invasive solution for the 2018 edition migration issue described in https://github.com/rust-lang/rust/issues/54647 and affecting proc macro crates. `extern crate NAME as RENAME;` now accepts `NAME`=`self` and interprets it as referring to the local crate. As with other `extern crate` items, `RENAME` in this case gets into extern prelude in accordance with https://github.com/rust-lang/rust/pull/54658, thus resolving https://github.com/rust-lang/rust/issues/54647. ```rust extern crate self as serde; // Adds local crate to extern prelude as `serde` ``` This solution doesn't introduce any new syntax and has minimal maintenance cost, so it can be easily deprecated if something better is found in the future. Closes https://github.com/rust-lang/rust/issues/54647
This commit is contained in:
commit
d311571906
@ -40,7 +40,7 @@ use syntax::ext::base::{MacroKind, SyntaxExtension};
|
||||
use syntax::ext::base::Determinacy::Undetermined;
|
||||
use syntax::ext::hygiene::Mark;
|
||||
use syntax::ext::tt::macro_rules;
|
||||
use syntax::feature_gate::is_builtin_attr;
|
||||
use syntax::feature_gate::{is_builtin_attr, emit_feature_err, GateIssue};
|
||||
use syntax::parse::token::{self, Token};
|
||||
use syntax::std_inject::injected_crate_name;
|
||||
use syntax::symbol::keywords;
|
||||
@ -344,9 +344,23 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||
}
|
||||
|
||||
ItemKind::ExternCrate(orig_name) => {
|
||||
let crate_id = self.crate_loader.process_extern_crate(item, &self.definitions);
|
||||
let module =
|
||||
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
|
||||
let module = if orig_name.is_none() && ident.name == keywords::SelfValue.name() {
|
||||
self.session
|
||||
.struct_span_err(item.span, "`extern crate self;` requires renaming")
|
||||
.span_suggestion(item.span, "try", "extern crate self as name;".into())
|
||||
.emit();
|
||||
return;
|
||||
} else if orig_name == Some(keywords::SelfValue.name()) {
|
||||
if !self.session.features_untracked().extern_crate_self {
|
||||
emit_feature_err(&self.session.parse_sess, "extern_crate_self", item.span,
|
||||
GateIssue::Language, "`extern crate self` is unstable");
|
||||
}
|
||||
self.graph_root
|
||||
} else {
|
||||
let crate_id = self.crate_loader.process_extern_crate(item, &self.definitions);
|
||||
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
|
||||
};
|
||||
|
||||
self.populate_module_if_necessary(module);
|
||||
if injected_crate_name().map_or(false, |name| ident.name == name) {
|
||||
self.injected_crate = Some(module);
|
||||
@ -768,6 +782,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||
span_err!(self.session, item.span, E0468,
|
||||
"an `extern crate` loading macros must be at the crate root");
|
||||
}
|
||||
if let ItemKind::ExternCrate(Some(orig_name)) = item.node {
|
||||
if orig_name == keywords::SelfValue.name() {
|
||||
self.session.span_err(attr.span,
|
||||
"`macro_use` is not supported on `extern crate self`");
|
||||
}
|
||||
}
|
||||
let ill_formed = |span| span_err!(self.session, span, E0466, "bad macro import");
|
||||
match attr.meta() {
|
||||
Some(meta) => match meta.node {
|
||||
|
@ -113,11 +113,12 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
|
||||
true
|
||||
})
|
||||
.filter(|&&(def_id, _)| {
|
||||
let cnum = tcx.extern_mod_stmt_cnum(def_id).unwrap();
|
||||
!tcx.is_compiler_builtins(cnum)
|
||||
&& !tcx.is_panic_runtime(cnum)
|
||||
&& !tcx.has_global_allocator(cnum)
|
||||
&& !tcx.has_panic_handler(cnum)
|
||||
tcx.extern_mod_stmt_cnum(def_id).map_or(true, |cnum| {
|
||||
!tcx.is_compiler_builtins(cnum) &&
|
||||
!tcx.is_panic_runtime(cnum) &&
|
||||
!tcx.has_global_allocator(cnum) &&
|
||||
!tcx.has_panic_handler(cnum)
|
||||
})
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
|
@ -492,6 +492,9 @@ declare_features! (
|
||||
|
||||
// `reason = ` in lint attributes and `expect` lint attribute
|
||||
(active, lint_reasons, "1.31.0", Some(54503), None),
|
||||
|
||||
// `extern crate self as foo;` puts local crate root into extern prelude under name `foo`.
|
||||
(active, extern_crate_self, "1.31.0", Some(54658), None),
|
||||
);
|
||||
|
||||
declare_features! (
|
||||
|
@ -6783,7 +6783,11 @@ impl<'a> Parser<'a> {
|
||||
let error_msg = "crate name using dashes are not valid in `extern crate` statements";
|
||||
let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
|
||||
in the code";
|
||||
let mut ident = self.parse_ident()?;
|
||||
let mut ident = if self.token.is_keyword(keywords::SelfValue) {
|
||||
self.parse_path_segment_ident()
|
||||
} else {
|
||||
self.parse_ident()
|
||||
}?;
|
||||
let mut idents = vec![];
|
||||
let mut replacement = vec![];
|
||||
let mut fixed_crate_name = false;
|
||||
|
@ -0,0 +1,3 @@
|
||||
extern crate self as foo; //~ ERROR `extern crate self` is unstable
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,11 @@
|
||||
error[E0658]: `extern crate self` is unstable (see issue #54658)
|
||||
--> $DIR/feature-gate-extern_crate_self.rs:1:1
|
||||
|
|
||||
LL | extern crate self as foo; //~ ERROR `extern crate self` is unstable
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(extern_crate_self)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
8
src/test/ui/imports/extern-crate-self-fail.rs
Normal file
8
src/test/ui/imports/extern-crate-self-fail.rs
Normal file
@ -0,0 +1,8 @@
|
||||
#![feature(extern_crate_self)]
|
||||
|
||||
extern crate self; //~ ERROR `extern crate self;` requires renaming
|
||||
|
||||
#[macro_use] //~ ERROR `macro_use` is not supported on `extern crate self`
|
||||
extern crate self as foo;
|
||||
|
||||
fn main() {}
|
14
src/test/ui/imports/extern-crate-self-fail.stderr
Normal file
14
src/test/ui/imports/extern-crate-self-fail.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: `extern crate self;` requires renaming
|
||||
--> $DIR/extern-crate-self-fail.rs:3:1
|
||||
|
|
||||
LL | extern crate self; //~ ERROR `extern crate self;` requires renaming
|
||||
| ^^^^^^^^^^^^^^^^^^ help: try: `extern crate self as name;`
|
||||
|
||||
error: `macro_use` is not supported on `extern crate self`
|
||||
--> $DIR/extern-crate-self-fail.rs:5:1
|
||||
|
|
||||
LL | #[macro_use] //~ ERROR `macro_use` is not supported on `extern crate self`
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
15
src/test/ui/imports/extern-crate-self-pass.rs
Normal file
15
src/test/ui/imports/extern-crate-self-pass.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// compile-pass
|
||||
|
||||
#![feature(extern_crate_self)]
|
||||
|
||||
extern crate self as foo;
|
||||
|
||||
struct S;
|
||||
|
||||
mod m {
|
||||
fn check() {
|
||||
foo::S; // OK
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user