Skip to content

[beta] Rollup backports #54750

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

Merged
merged 5 commits into from
Oct 2, 2018
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
25 changes: 25 additions & 0 deletions src/librustc/hir/map/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,31 @@ impl DefPath {
s
}

/// Return filename friendly string of the DefPah with the
/// crate-prefix.
pub fn to_string_friendly<F>(&self, crate_imported_name: F) -> String
where F: FnOnce(CrateNum) -> Symbol
{
let crate_name_str = crate_imported_name(self.krate).as_str();
let mut s = String::with_capacity(crate_name_str.len() + self.data.len() * 16);

write!(s, "::{}", crate_name_str).unwrap();

for component in &self.data {
if component.disambiguator == 0 {
write!(s, "::{}", component.data.as_interned_str()).unwrap();
} else {
write!(s,
"{}[{}]",
component.data.as_interned_str(),
component.disambiguator)
.unwrap();
}
}

s
}

/// Return filename friendly string of the DefPah without
/// the crate-prefix. This method is useful if you don't have
/// a TyCtxt available.
Expand Down
18 changes: 17 additions & 1 deletion src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use syntax::parse;
use syntax::parse::ParseSess;
use syntax::{ast, source_map};
use syntax::feature_gate::AttributeType;
use syntax_pos::{MultiSpan, Span};
use syntax_pos::{MultiSpan, Span, symbol::Symbol};
use util::profiling::SelfProfiler;

use rustc_target::spec::PanicStrategy;
Expand Down Expand Up @@ -164,6 +164,10 @@ pub struct Session {

/// Cap lint level specified by a driver specifically.
pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,

/// All the crate names specified with `--extern`, and the builtin ones.
/// Starting with the Rust 2018 edition, absolute paths resolve in this set.
pub extern_prelude: FxHashSet<Symbol>,
}

pub struct PerfStats {
Expand Down Expand Up @@ -1109,6 +1113,17 @@ pub fn build_session_(
};
let working_dir = file_path_mapping.map_prefix(working_dir);

let mut extern_prelude: FxHashSet<Symbol> =
sopts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect();

// HACK(eddyb) this ignores the `no_{core,std}` attributes.
// FIXME(eddyb) warn (somewhere) if core/std is used with `no_{core,std}`.
// if !attr::contains_name(&krate.attrs, "no_core") {
// if !attr::contains_name(&krate.attrs, "no_std") {
extern_prelude.insert(Symbol::intern("core"));
extern_prelude.insert(Symbol::intern("std"));
extern_prelude.insert(Symbol::intern("meta"));

let sess = Session {
target: target_cfg,
host,
Expand Down Expand Up @@ -1183,6 +1198,7 @@ pub fn build_session_(
has_global_allocator: Once::new(),
has_panic_handler: Once::new(),
driver_lint_caps: FxHashMap(),
extern_prelude,
};

validate_commandline_args_with_session_available(&sess);
Expand Down
1 change: 1 addition & 0 deletions src/librustc/ty/query/on_disk_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,7 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<interpret::AllocId> for CacheDecoder<'a, '
alloc_decoding_session.decode_alloc_id(self)
}
}

impl<'a, 'tcx, 'x> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx, 'x> {
fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
let tag: u8 = Decodable::decode(self)?;
Expand Down
1 change: 1 addition & 0 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ impl<'a> CrateLoader<'a> {

let cmeta = cstore::CrateMetadata {
name: crate_root.name,
imported_name: ident,
extern_crate: Lock::new(None),
def_path_table: Lrc::new(def_path_table),
trait_impls,
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_metadata/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,13 @@ pub struct ImportedSourceFile {
}

pub struct CrateMetadata {
/// Original name of the crate.
pub name: Symbol,

/// Name of the crate as imported. I.e. if imported with
/// `extern crate foo as bar;` this will be `bar`.
pub imported_name: Symbol,

/// Information about the extern crate that caused this crate to
/// be loaded. If this is `None`, then the crate was injected
/// (e.g., by the allocator)
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_metadata/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,7 @@ impl cstore::CStore {
let data = self.get_crate_data(id.krate);
if let Some(ref proc_macros) = data.proc_macros {
return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone());
} else if data.name == "proc_macro" &&
self.get_crate_data(id.krate).item_name(id.index) == "quote" {
} else if data.name == "proc_macro" && data.item_name(id.index) == "quote" {
use syntax::ext::base::SyntaxExtension;
use syntax_ext::proc_macro_impl::BangProcMacro;

Expand All @@ -454,8 +453,9 @@ impl cstore::CStore {
return LoadedMacro::ProcMacro(Lrc::new(ext));
}

let (name, def) = data.get_macro(id.index);
let source_name = FileName::Macros(name.to_string());
let def = data.get_macro(id.index);
let macro_full_name = data.def_path(id.index).to_string_friendly(|_| data.imported_name);
let source_name = FileName::Macros(macro_full_name);

let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body);
let local_span = Span::new(source_file.start_pos, source_file.end_pos, NO_EXPANSION);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1101,10 +1101,10 @@ impl<'a, 'tcx> CrateMetadata {
}
}

pub fn get_macro(&self, id: DefIndex) -> (InternedString, MacroDef) {
pub fn get_macro(&self, id: DefIndex) -> MacroDef {
let entry = self.entry(id);
match entry.kind {
EntryKind::MacroDef(macro_def) => (self.item_name(id), macro_def.decode(self)),
EntryKind::MacroDef(macro_def) => macro_def.decode(self),
_ => bug!(),
}
}
Expand Down
20 changes: 3 additions & 17 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1350,7 +1350,6 @@ pub struct Resolver<'a, 'b: 'a> {
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>,
Expand Down Expand Up @@ -1663,17 +1662,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
DefCollector::new(&mut definitions, Mark::root())
.collect_root(crate_name, session.local_crate_disambiguator());

let mut extern_prelude: FxHashSet<Name> =
session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect();

// HACK(eddyb) this ignore the `no_{core,std}` attributes.
// FIXME(eddyb) warn (elsewhere) if core/std is used with `no_{core,std}`.
// if !attr::contains_name(&krate.attrs, "no_core") {
// if !attr::contains_name(&krate.attrs, "no_std") {
extern_prelude.insert(Symbol::intern("core"));
extern_prelude.insert(Symbol::intern("std"));
extern_prelude.insert(Symbol::intern("meta"));

let mut invocations = FxHashMap();
invocations.insert(Mark::root(),
arenas.alloc_invocation_data(InvocationData::root(graph_root)));
Expand All @@ -1692,7 +1680,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
// AST.
graph_root,
prelude: None,
extern_prelude,

has_self: FxHashSet(),
field_names: FxHashMap(),
Expand Down Expand Up @@ -1963,7 +1950,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {

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 record_used && ns == TypeNS && self.session.extern_prelude.contains(&ident.name) {
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);
Expand Down Expand Up @@ -3950,7 +3937,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
} else {
// Items from the prelude
if !module.no_implicit_prelude {
names.extend(self.extern_prelude.iter().cloned());
names.extend(self.session.extern_prelude.iter().cloned());
if let Some(prelude) = self.prelude {
add_module_candidates(prelude, &mut names);
}
Expand Down Expand Up @@ -4396,8 +4383,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
);

if self.session.rust_2018() {
let extern_prelude_names = self.extern_prelude.clone();
for &name in extern_prelude_names.iter() {
for &name in &self.session.extern_prelude {
let ident = Ident::with_empty_ctxt(name);
match self.crate_loader.maybe_process_path_extern(name, ident.span) {
Some(crate_id) => {
Expand Down
22 changes: 11 additions & 11 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// 5. Standard library prelude (de-facto closed, controlled).
// 6. Language prelude (closed, controlled).
// (Macro NS)
// 0. Derive helpers (open, not controlled). All ambiguities with other names
// are currently reported as errors. They should be higher in priority than preludes
// and probably even names in modules according to the "general principles" above. They
// also should be subject to restricted shadowing because are effectively produced by
// derives (you need to resolve the derive first to add helpers into scope), but they
// should be available before the derive is expanded for compatibility.
// It's mess in general, so we are being conservative for now.
// 1. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
// (open, not controlled).
// 2. `macro_use` prelude (open, the open part is from macro expansions, not controlled).
Expand All @@ -583,13 +590,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// 2b. Standard library prelude is currently implemented as `macro-use` (closed, controlled)
// 3. Language prelude: builtin macros (closed, controlled, except for legacy plugins).
// 4. Language prelude: builtin attributes (closed, controlled).
// N (unordered). Derive helpers (open, not controlled). All ambiguities with other names
// are currently reported as errors. They should be higher in priority than preludes
// and maybe even names in modules according to the "general principles" above. They
// also should be subject to restricted shadowing because are effectively produced by
// derives (you need to resolve the derive first to add helpers into scope), but they
// should be available before the derive is expanded for compatibility.
// It's mess in general, so we are being conservative for now.

assert!(ns == TypeNS || ns == MacroNS);
assert!(force || !record_used); // `record_used` implies `force`
Expand Down Expand Up @@ -621,7 +621,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
}

// Go through all the scopes and try to resolve the name.
let mut where_to_resolve = WhereToResolve::Module(parent_scope.module);
let mut where_to_resolve = WhereToResolve::DeriveHelpers;
let mut use_prelude = !parent_scope.module.no_implicit_prelude;
loop {
let result = match where_to_resolve {
Expand Down Expand Up @@ -681,7 +681,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
result
}
WhereToResolve::ExternPrelude => {
if use_prelude && self.extern_prelude.contains(&ident.name) {
if use_prelude && self.session.extern_prelude.contains(&ident.name) {
let crate_id =
self.crate_loader.process_path_extern(ident.name, ident.span);
let crate_root =
Expand Down Expand Up @@ -751,8 +751,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
}
WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros,
WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs,
WhereToResolve::BuiltinAttrs => WhereToResolve::DeriveHelpers,
WhereToResolve::DeriveHelpers => break, // nowhere else to search
WhereToResolve::BuiltinAttrs => break, // nowhere else to search
WhereToResolve::DeriveHelpers => WhereToResolve::Module(parent_scope.module),
WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude,
WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude,
WhereToResolve::StdLibPrelude => WhereToResolve::BuiltinTypes,
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_resolve/resolve_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
if !(
ns == TypeNS &&
!ident.is_path_segment_keyword() &&
self.extern_prelude.contains(&ident.name)
self.session.extern_prelude.contains(&ident.name)
) {
// ... unless the crate name is not in the `extern_prelude`.
return binding;
Expand All @@ -218,7 +218,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
} else if
ns == TypeNS &&
!ident.is_path_segment_keyword() &&
self.extern_prelude.contains(&ident.name)
self.session.extern_prelude.contains(&ident.name)
{
let crate_id =
self.crate_loader.process_path_extern(ident.name, ident.span);
Expand Down Expand Up @@ -735,7 +735,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
let uniform_paths_feature = self.session.features_untracked().uniform_paths;
for ((span, _, ns), results) in uniform_paths_canaries {
let name = results.name;
let external_crate = if ns == TypeNS && self.extern_prelude.contains(&name) {
let external_crate = if ns == TypeNS && self.session.extern_prelude.contains(&name) {
let crate_id =
self.crate_loader.process_path_extern(name, span);
Some(Def::Mod(DefId { krate: crate_id, index: CRATE_DEF_INDEX }))
Expand Down
16 changes: 9 additions & 7 deletions src/librustc_typeck/check_unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,13 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
});

for extern_crate in &crates_to_lint {
assert!(extern_crate.def_id.is_local());
let id = tcx.hir.as_local_node_id(extern_crate.def_id).unwrap();
let item = tcx.hir.expect_item(id);

// If the crate is fully unused, we suggest removing it altogether.
// We do this in any edition.
if extern_crate.warn_if_unused {
if let Some(&span) = unused_extern_crates.get(&extern_crate.def_id) {
assert_eq!(extern_crate.def_id.krate, LOCAL_CRATE);
let hir_id = tcx.hir.definitions().def_index_to_hir_id(extern_crate.def_id.index);
let id = tcx.hir.hir_to_node_id(hir_id);
let msg = "unused extern crate";
tcx.struct_span_lint_node(lint, id, span, msg)
.span_suggestion_short_with_applicability(
Expand All @@ -157,6 +155,13 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
continue;
}

// If the extern crate isn't in the extern prelude,
// there is no way it can be written as an `use`.
let orig_name = extern_crate.orig_name.unwrap_or(item.name);
if !tcx.sess.extern_prelude.contains(&orig_name) {
continue;
}

// If the extern crate has any attributes, they may have funky
// semantics we can't faithfully represent using `use` (most
// notably `#[macro_use]`). Ignore it.
Expand All @@ -165,9 +170,6 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
}

// Otherwise, we can convert it into a `use` of some kind.
let hir_id = tcx.hir.definitions().def_index_to_hir_id(extern_crate.def_id.index);
let id = tcx.hir.hir_to_node_id(hir_id);
let item = tcx.hir.expect_item(id);
let msg = "`extern crate` is not idiomatic in the new edition";
let help = format!(
"convert it to a `{}`",
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ impl<'a> StripUnconfigured<'a> {
parser.expect(&token::Comma)?;
let lo = parser.span.lo();
let (path, tokens) = parser.parse_meta_item_unrestricted()?;
parser.eat(&token::Comma); // Optional trailing comma
parser.expect(&token::CloseDelim(token::Paren))?;
Ok((cfg, path, tokens, parser.prev_span.with_lo(lo)))
}) {
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax_pos/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ scoped_thread_local!(pub static GLOBALS: Globals);
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)]
pub enum FileName {
Real(PathBuf),
/// e.g. "std" macros
/// A macro. This includes the full name of the macro, so that there are no clashes.
Macros(String),
/// call to `quote!`
QuoteExpansion,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@
// aux-build:derive-b.rs
// ignore-stage1

#![allow(warnings)]

#[macro_use]
extern crate derive_b;

#[B] //~ ERROR `B` is a derive mode
#[C]
#[B]
#[C] //~ ERROR attribute `C` is currently unknown to the compiler
#[B(D)]
#[B(E = "foo")]
#[B(arbitrary tokens)]
Expand Down
10 changes: 10 additions & 0 deletions src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,13 @@ pub fn derive_foo(input: TokenStream) -> TokenStream {
pub fn derive_bar(input: TokenStream) -> TokenStream {
panic!("lolnope");
}

#[proc_macro_derive(WithHelper, attributes(helper))]
pub fn with_helper(input: TokenStream) -> TokenStream {
TokenStream::new()
}

#[proc_macro_attribute]
pub fn helper(_: TokenStream, input: TokenStream) -> TokenStream {
input
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// aux-build:plugin.rs
// ignore-stage1

#[macro_use(WithHelper)]
extern crate plugin;

use plugin::helper;

#[derive(WithHelper)]
#[helper] //~ ERROR `helper` is ambiguous
struct S;

fn main() {}
Loading