graph_root: Module<'a>,
prelude: Option<Module<'a>>,
+ extern_prelude: FxHashSet<Name>,
/// n.b. This is used only for better diagnostics, not name resolution itself.
has_self: FxHashSet<DefId>,
// AST.
graph_root,
prelude: None,
+ extern_prelude: session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect(),
has_self: FxHashSet(),
field_names: FxHashMap(),
}
}
- match self.prelude {
- Some(prelude) if !module.no_implicit_prelude => {
- self.resolve_ident_in_module_unadjusted(prelude, ident, ns, false, false, path_span)
- .ok().map(LexicalScopeBinding::Item)
+ if !module.no_implicit_prelude {
+ // `record_used` means that we don't try to load crates during speculative resolution
+ if record_used && ns == TypeNS && self.extern_prelude.contains(&ident.name) {
+ if !self.session.features_untracked().extern_prelude {
+ feature_err(&self.session.parse_sess, "extern_prelude",
+ ident.span, GateIssue::Language,
+ "access to extern crates through prelude is experimental").emit();
+ }
+
+ let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
+ let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
+ self.populate_module_if_necessary(crate_root);
+
+ let binding = (crate_root, ty::Visibility::Public,
+ ident.span, Mark::root()).to_name_binding(self.arenas);
+ return Some(LexicalScopeBinding::Item(binding));
+ }
+ if let Some(prelude) = self.prelude {
+ if let Ok(binding) = self.resolve_ident_in_module_unadjusted(prelude, ident, ns,
+ false, false, path_span) {
+ return Some(LexicalScopeBinding::Item(binding));
+ }
}
- _ => None,
}
+
+ None
}
fn hygienic_lexical_parent(&mut self, mut module: Module<'a>, span: &mut Span)
// We can see through blocks
} else {
// Items from the prelude
- if let Some(prelude) = self.prelude {
- if !module.no_implicit_prelude {
+ if !module.no_implicit_prelude {
+ names.extend(self.extern_prelude.iter().cloned());
+ if let Some(prelude) = self.prelude {
add_module_candidates(prelude, &mut names);
}
}
(active, generic_associated_types, "1.23.0", Some(44265), None),
// Resolve absolute paths as paths from other crates
- (active, extern_absolute_paths, "1.24.0", Some(44660), None),
+ (active, extern_absolute_paths, "1.24.0", Some(44660), Some(Edition::Edition2018)),
// `foo.rs` as an alternative to `foo/mod.rs`
(active, non_modrs_mods, "1.24.0", Some(44660), Some(Edition::Edition2018)),
// #[doc(alias = "...")]
(active, doc_alias, "1.27.0", Some(50146), None),
+
+ // Access to crate names passed via `--extern` through prelude
+ (active, extern_prelude, "1.27.0", Some(44660), Some(Edition::Edition2018)),
);
declare_features! (
--- /dev/null
+-include ../tools.mk
+
+all:
+ $(RUSTC) ep-lib.rs
+ $(RUSTC) ep-vec.rs
+
+ $(RUSTC) basic.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib
+ $(RUSTC) shadow-mod.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib
+ $(RUSTC) shadow-prelude.rs --extern Vec=$(TMPDIR)/libep_vec.rlib
+ $(RUSTC) feature-gate.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "access to extern crates through prelude is experimental"
+ $(RUSTC) relative-only.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "unresolved import"
+ $(RUSTC) relative-only.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "failed to resolve"
--- /dev/null
+// Copyright 2018 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.
+
+#![feature(extern_prelude)]
+
+fn main() {
+ let s = ep_lib::S; // It works
+ s.external();
+}
--- /dev/null
+// Copyright 2017 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 = "rlib"]
+
+pub struct S;
+
+impl S {
+ pub fn external(&self) {}
+}
--- /dev/null
+// Copyright 2017 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 = "rlib"]
+
+pub fn new(arg1: f32, arg2: ()) {}
--- /dev/null
+// Copyright 2018 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.
+
+fn main() {
+ let s = ep_lib::S; // Feature error
+}
--- /dev/null
+// Copyright 2018 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 prelude names are not available by absolute paths
+
+#![feature(extern_prelude)]
+
+use ep_lib::S;
+
+fn main() {
+ let s = ::ep_lib::S;
+}
--- /dev/null
+// Copyright 2018 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.
+
+// Local module shadows `ep_lib` from extern prelude
+
+mod ep_lib {
+ pub struct S;
+
+ impl S {
+ pub fn internal(&self) {}
+ }
+}
+
+fn main() {
+ let s = ep_lib::S;
+ s.internal(); // OK
+}
--- /dev/null
+// Copyright 2018 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 prelude shadows standard library prelude
+
+#![feature(extern_prelude)]
+
+fn main() {
+ let x = Vec::new(0f32, ()); // OK
+}
--- /dev/null
+// 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.
+
+// compile-flags: --extern LooksLikeExternCrate=/path/to/nowhere
+
+mod m {
+ pub struct LooksLikeExternCrate;
+}
+
+fn main() {
+ // OK, speculative resolution for `unused_qualifications` doesn't try
+ // to resolve this as an extern crate and load that crate
+ let s = m::LooksLikeExternCrate {};
+}
--- /dev/null
+// Copyright 2018 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.
+
+can-only-test-this-in-run-make-fulldeps //~ ERROR expected one of `!` or `::`, found `-`
--- /dev/null
+error: expected one of `!` or `::`, found `-`
+ --> $DIR/feature-gate-extern_prelude.rs:11:4
+ |
+LL | can-only-test-this-in-run-make-fulldeps //~ ERROR expected one of `!` or `::`, found `-`
+ | ^ expected one of `!` or `::` here
+
+error: aborting due to previous error
+