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

Start using serde_derive in a couple places in the compiler #56795

Closed
wants to merge 10 commits into from
Closed
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
3 changes: 3 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -2540,6 +2540,7 @@ version = "0.0.0"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]

@@ -2604,6 +2605,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_cratesio_shim 0.0.0",
"rustc_data_structures 0.0.0",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"syntax_pos 0.0.0",
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3217,6 +3219,7 @@ dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_data_structures 0.0.0",
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
21 changes: 14 additions & 7 deletions src/bootstrap/bin/rustc.rs
Original file line number Diff line number Diff line change
@@ -109,6 +109,12 @@ fn main() {
// actually downloaded, so we just always pass the `--sysroot` option.
cmd.arg("--sysroot").arg(&sysroot);

// Link crates to the proc macro crate for the target, but use a host proc macro crate
// to actually run the macros
if env::var_os("RUST_DUAL_PROC_MACROS").is_some() {
cmd.arg("-Zdual-proc-macros");
}

// When we build Rust dylibs they're all intended for intermediate
// usage, so make sure we pass the -Cprefer-dynamic flag instead of
// linking all deps statically into the dylib.
@@ -258,13 +264,6 @@ fn main() {
}
}

// Force all crates compiled by this compiler to (a) be unstable and (b)
// allow the `rustc_private` feature to link to other unstable crates
// also in the sysroot.
if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
cmd.arg("-Z").arg("force-unstable-if-unmarked");
}

if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") {
cmd.arg("--remap-path-prefix").arg(&map);
}
@@ -284,6 +283,14 @@ fn main() {
}
}

// Force all crates compiled by this compiler to (a) be unstable and (b)
// allow the `rustc_private` feature to link to other unstable crates
// also in the sysroot. We also do this for host crates, since those
// may be proc macros, in which case we might ship them.
if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() && (stage != "0" || target.is_some()) {
cmd.arg("-Z").arg("force-unstable-if-unmarked");
}

if env::var_os("RUSTC_PARALLEL_QUERIES").is_some() {
cmd.arg("--cfg").arg("parallel_queries");
}
12 changes: 12 additions & 0 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
@@ -608,6 +608,7 @@ impl<'a> Builder<'a> {
.join(self.target)
.join("lib");
let _ = fs::remove_dir_all(&sysroot);
eprintln!("creating sysroot {:?}", sysroot);
t!(fs::create_dir_all(&sysroot));
INTERNER.intern_path(sysroot)
}
@@ -811,6 +812,17 @@ impl<'a> Builder<'a> {
cargo.env("RUST_CHECK", "1");
}

match mode {
Mode::Std | Mode::Test | Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolTest=> {},
Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
// Build proc macros both for the host and the target
if target != compiler.host && cmd != "check" {
cargo.arg("-Zdual-proc-macros");
cargo.env("RUST_DUAL_PROC_MACROS", "1");
}
},
}

cargo.arg("-j").arg(self.jobs().to_string());
// Remove make-related flags to ensure Cargo can correctly set things up
cargo.env_remove("MAKEFLAGS");
12 changes: 8 additions & 4 deletions src/bootstrap/check.rs
Original file line number Diff line number Diff line change
@@ -42,7 +42,8 @@ impl Step for Std {
true);

let libdir = builder.sysroot_libdir(compiler, target);
add_to_sysroot(&builder, &libdir, &libstd_stamp(builder, compiler, target));
let hostdir = builder.sysroot_libdir(compiler, compiler.host);
add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
}
}

@@ -88,7 +89,8 @@ impl Step for Rustc {
true);

let libdir = builder.sysroot_libdir(compiler, target);
add_to_sysroot(&builder, &libdir, &librustc_stamp(builder, compiler, target));
let hostdir = builder.sysroot_libdir(compiler, compiler.host);
add_to_sysroot(&builder, &libdir, &hostdir, &librustc_stamp(builder, compiler, target));
}
}

@@ -175,7 +177,8 @@ impl Step for Test {
true);

let libdir = builder.sysroot_libdir(compiler, target);
add_to_sysroot(builder, &libdir, &libtest_stamp(builder, compiler, target));
let hostdir = builder.sysroot_libdir(compiler, compiler.host);
add_to_sysroot(builder, &libdir, &hostdir, &libtest_stamp(builder, compiler, target));
}
}

@@ -222,7 +225,8 @@ impl Step for Rustdoc {
true);

let libdir = builder.sysroot_libdir(compiler, target);
add_to_sysroot(&builder, &libdir, &rustdoc_stamp(builder, compiler, target));
let hostdir = builder.sysroot_libdir(compiler, compiler.host);
add_to_sysroot(&builder, &libdir, &hostdir, &rustdoc_stamp(builder, compiler, target));
builder.cargo(compiler, Mode::ToolRustc, target, "clean");
}
}
76 changes: 57 additions & 19 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
@@ -224,7 +224,8 @@ impl Step for StdLink {
target_compiler.host,
target));
let libdir = builder.sysroot_libdir(target_compiler, target);
add_to_sysroot(builder, &libdir, &libstd_stamp(builder, compiler, target));
let hostdir = builder.sysroot_libdir(target_compiler, compiler.host);
add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));

if builder.config.sanitizers && compiler.stage != 0 && target == "x86_64-apple-darwin" {
// The sanitizers are only built in stage1 or above, so the dylibs will
@@ -426,8 +427,12 @@ impl Step for TestLink {
&compiler.host,
target_compiler.host,
target));
add_to_sysroot(builder, &builder.sysroot_libdir(target_compiler, target),
&libtest_stamp(builder, compiler, target));
add_to_sysroot(
builder,
&builder.sysroot_libdir(target_compiler, target),
&builder.sysroot_libdir(target_compiler, compiler.host),
&libtest_stamp(builder, compiler, target)
);

builder.cargo(target_compiler, Mode::ToolTest, target, "clean");
}
@@ -491,8 +496,8 @@ impl Step for Rustc {
return;
}

// Ensure that build scripts have a std to link against.
builder.ensure(Std {
// Ensure that build scripts and proc macros have a std / libproc_macro to link against.
builder.ensure(Test {
compiler: builder.compiler(self.compiler.stage, builder.config.build),
target: builder.config.build,
});
@@ -587,8 +592,12 @@ impl Step for RustcLink {
&compiler.host,
target_compiler.host,
target));
add_to_sysroot(builder, &builder.sysroot_libdir(target_compiler, target),
&librustc_stamp(builder, compiler, target));
add_to_sysroot(
builder,
&builder.sysroot_libdir(target_compiler, target),
&builder.sysroot_libdir(target_compiler, compiler.host),
&librustc_stamp(builder, compiler, target)
);
builder.cargo(target_compiler, Mode::ToolRustc, target, "clean");
}
}
@@ -996,10 +1005,22 @@ impl Step for Assemble {
///
/// For a particular stage this will link the file listed in `stamp` into the
/// `sysroot_dst` provided.
pub fn add_to_sysroot(builder: &Builder, sysroot_dst: &Path, stamp: &Path) {
pub fn add_to_sysroot(
builder: &Builder,
sysroot_dst: &Path,
sysroot_host_dst: &Path,
stamp: &Path
) {
//eprintln!("add_to_sysroot - host dir {:?} - stamp {:?}", sysroot_host_dst, stamp);
t!(fs::create_dir_all(&sysroot_dst));
for path in builder.read_stamp_file(stamp) {
builder.copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
t!(fs::create_dir_all(&sysroot_host_dst));
for (path, host) in builder.read_stamp_file(stamp) {
if host {
eprintln!("add_to_sysroot host - copying {:?} to {:?}", path, sysroot_host_dst);
builder.copy(&path, &sysroot_host_dst.join(path.file_name().unwrap()));
} else {
builder.copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
}
}
}

@@ -1028,8 +1049,14 @@ pub fn run_cargo(builder: &Builder,
let mut deps = Vec::new();
let mut toplevel = Vec::new();
let ok = stream_cargo(builder, cargo, &mut |msg| {
let filenames = match msg {
CargoMessage::CompilerArtifact { filenames, .. } => filenames,
let (filenames, crate_types) = match msg {
CargoMessage::CompilerArtifact {
filenames,
target: CargoTarget {
crate_types,
},
..
} => (filenames, crate_types),
_ => return,
};
for filename in filenames {
@@ -1044,15 +1071,19 @@ pub fn run_cargo(builder: &Builder,
let filename = Path::new(&*filename);

// If this was an output file in the "host dir" we don't actually
// worry about it, it's not relevant for us.
// worry about it, it's not relevant for us
if filename.starts_with(&host_root_dir) {
// Unless it's a proc macro used in the compiler
if crate_types.iter().any(|t| t == "proc-macro") {
deps.push((filename.to_path_buf(), true));
}
continue;
}

// If this was output in the `deps` dir then this is a precise file
// name (hash included) so we start tracking it.
if filename.starts_with(&target_deps_dir) {
deps.push(filename.to_path_buf());
deps.push((filename.to_path_buf(), false));
continue;
}

@@ -1105,10 +1136,10 @@ pub fn run_cargo(builder: &Builder,
let candidate = format!("{}.lib", path_to_add);
let candidate = PathBuf::from(candidate);
if candidate.exists() {
deps.push(candidate);
deps.push((candidate, false));
}
}
deps.push(path_to_add.into());
deps.push((path_to_add.into(), false));
}

// Now we want to update the contents of the stamp file, if necessary. First
@@ -1121,12 +1152,13 @@ pub fn run_cargo(builder: &Builder,
let mut new_contents = Vec::new();
let mut max = None;
let mut max_path = None;
for dep in deps.iter() {
for (dep, proc_macro) in deps.iter() {
let mtime = mtime(dep);
if Some(mtime) > max {
max = Some(mtime);
max_path = Some(dep.clone());
}
new_contents.extend(if *proc_macro { b"h" } else { b"t" });
new_contents.extend(dep.to_str().unwrap().as_bytes());
new_contents.extend(b"\0");
}
@@ -1138,15 +1170,15 @@ pub fn run_cargo(builder: &Builder,
if contents_equal && max <= stamp_mtime {
builder.verbose(&format!("not updating {:?}; contents equal and {:?} <= {:?}",
stamp, max, stamp_mtime));
return deps
return deps.into_iter().map(|(d, _)| d).collect()
}
if max > stamp_mtime {
builder.verbose(&format!("updating {:?} as {:?} changed", stamp, max_path));
} else {
builder.verbose(&format!("updating {:?} as deps changed", stamp));
}
t!(fs::write(&stamp, &new_contents));
deps
deps.into_iter().map(|(d, _)| d).collect()
}

pub fn stream_cargo(
@@ -1192,13 +1224,19 @@ pub fn stream_cargo(
status.success()
}

#[derive(Deserialize)]
pub struct CargoTarget<'a> {
crate_types: Vec<Cow<'a, str>>,
}

#[derive(Deserialize)]
#[serde(tag = "reason", rename_all = "kebab-case")]
pub enum CargoMessage<'a> {
CompilerArtifact {
package_id: Cow<'a, str>,
features: Vec<Cow<'a, str>>,
filenames: Vec<Cow<'a, str>>,
target: CargoTarget<'a>,
},
BuildScriptExecuted {
package_id: Cow<'a, str>,
3 changes: 3 additions & 0 deletions src/bootstrap/configure.py
Original file line number Diff line number Diff line change
@@ -43,6 +43,7 @@ def v(*args):
o("sccache", None, "invoke gcc/clang via sccache to reuse object files between builds")
o("local-rust", None, "use an installed rustc rather than downloading a snapshot")
v("local-rust-root", None, "set prefix for local rust binary")
v("local-cargo", None, "set prefix for local rust binary")
o("local-rebuild", "build.local-rebuild", "assume local-rust matches the current version, for rebuilds; implies local-rust, and is implied if local-rust already matches the current version")
o("llvm-static-stdcpp", "llvm.static-libstdcpp", "statically link to libstdc++ for LLVM")
o("llvm-link-shared", "llvm.link-shared", "prefer shared linking to LLVM (llvm-config --link-shared)")
@@ -320,6 +321,8 @@ def set(key, value):
elif option.name == 'local-rust-root':
set('build.rustc', value + '/bin/rustc')
set('build.cargo', value + '/bin/cargo')
elif option.name == 'local-cargo':
set('build.cargo', value)
elif option.name == 'llvm-root':
set('target.{}.llvm-config'.format(build()), value + '/bin/llvm-config')
elif option.name == 'llvm-config':
9 changes: 5 additions & 4 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
@@ -104,7 +104,7 @@
//! also check out the `src/bootstrap/README.md` file for more information.
#![deny(bare_trait_objects)]
#![deny(warnings)]
//#![deny(warnings)]
#![feature(core_intrinsics)]
#![feature(drain_filter)]

@@ -1142,7 +1142,7 @@ impl Build {
ret
}

fn read_stamp_file(&self, stamp: &Path) -> Vec<PathBuf> {
fn read_stamp_file(&self, stamp: &Path) -> Vec<(PathBuf, bool)> {
if self.config.dry_run {
return Vec::new();
}
@@ -1155,8 +1155,9 @@ impl Build {
if part.is_empty() {
continue
}
let path = PathBuf::from(t!(str::from_utf8(part)));
paths.push(path);
let host = part[0] as char == 'h';
let path = PathBuf::from(t!(str::from_utf8(&part[1..])));
paths.push((path, host));
}
paths
}
10 changes: 5 additions & 5 deletions src/bootstrap/mk/Makefile.in
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
ifdef VERBOSE
Q :=
BOOTSTRAP_ARGS := -v
BOOTSTRAP_ARGS := -vv
else
Q := @
BOOTSTRAP_ARGS :=
BOOTSTRAP_ARGS := -vv
endif

ifdef EXCLUDE_CARGO
@@ -12,11 +12,11 @@ else
AUX_ARGS := src/tools/cargo src/tools/cargotest
endif

BOOTSTRAP := $(CFG_PYTHON) $(CFG_SRC_DIR)src/bootstrap/bootstrap.py
BOOTSTRAP := $(CFG_PYTHON) $(CFG_SRC_DIR)src/bootstrap/bootstrap.py -vv

all:
$(Q)$(BOOTSTRAP) build $(BOOTSTRAP_ARGS)
$(Q)$(BOOTSTRAP) doc $(BOOTSTRAP_ARGS)
$(Q)$(BOOTSTRAP) build -vv $(BOOTSTRAP_ARGS)
$(Q)$(BOOTSTRAP) doc -vv $(BOOTSTRAP_ARGS)

help:
$(Q)echo 'Welcome to the rustbuild build system!'
2 changes: 1 addition & 1 deletion src/bootstrap/test.rs
Original file line number Diff line number Diff line change
@@ -213,7 +213,7 @@ impl Step for Cargo {
});
let mut cargo = tool::prepare_tool_cargo(builder,
compiler,
Mode::ToolRustc,
Mode::ToolStd,
self.host,
"test",
"src/tools/cargo",
5 changes: 3 additions & 2 deletions src/bootstrap/tool.rs
Original file line number Diff line number Diff line change
@@ -92,7 +92,8 @@ impl Step for ToolBuild {
compile::CargoMessage::CompilerArtifact {
package_id,
features,
filenames
filenames,
target: _,
} => {
(package_id, features, filenames)
}
@@ -514,7 +515,7 @@ impl Step for Cargo {
compiler: self.compiler,
target: self.target,
tool: "cargo",
mode: Mode::ToolRustc,
mode: Mode::ToolStd,
path: "src/tools/cargo",
is_optional_tool: false,
source_type: SourceType::Submodule,
4 changes: 2 additions & 2 deletions src/ci/docker/dist-arm-linux/Dockerfile
Original file line number Diff line number Diff line change
@@ -32,5 +32,5 @@ ENV CC_arm_unknown_linux_gnueabi=arm-unknown-linux-gnueabi-gcc \

ENV HOSTS=arm-unknown-linux-gnueabi

ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs --local-cargo=/cargobin/target/release/cargo
ENV SCRIPT python2.7 ../x.py dist -vv --host $HOSTS --target $HOSTS
1 change: 1 addition & 0 deletions src/ci/docker/run.sh
Original file line number Diff line number Diff line change
@@ -127,6 +127,7 @@ exec docker \
--env TRAVIS_BRANCH \
--env TOOLSTATE_REPO_ACCESS_TOKEN \
--env CI_JOB_NAME="${CI_JOB_NAME-$IMAGE}" \
--volume "/home/john/dev/cargo:/cargobin" \
--volume "$HOME/.cargo:/cargo" \
--volume "$HOME/rustsrc:$HOME/rustsrc" \
--init \
4 changes: 4 additions & 0 deletions src/ci/run.sh
Original file line number Diff line number Diff line change
@@ -88,6 +88,10 @@ if [ "$RUN_CHECK_WITH_PARALLEL_QUERIES" != "" ]; then
rm -rf build
fi

#sh -x -c "curl https://sh.rustup.rs -sSf | sh -s -- -y"

#sh -x -c "cd /cargobin; /cargo/bin/cargo build --release"

travis_fold start configure
travis_time_start
$SRC/configure $RUST_CONFIGURE_ARGS
2 changes: 2 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
@@ -1216,6 +1216,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
Use with RUST_REGION_GRAPH=help for more info"),
parse_only: bool = (false, parse_bool, [UNTRACKED],
"parse only; do not compile, assemble, or link"),
dual_proc_macros: bool = (false, parse_bool, [TRACKED],
"load proc macros for both target and host, but only link to the target"),
no_codegen: bool = (false, parse_bool, [TRACKED],
"run all passes except codegen; no output"),
treat_err_as_bug: bool = (false, parse_bool, [TRACKED],
1 change: 1 addition & 0 deletions src/librustc/session/filesearch.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ pub enum FileMatch {

// A module for searching for libraries

#[derive(Clone)]
pub struct FileSearch<'a> {
sysroot: &'a Path,
triple: &'a str,
1 change: 1 addition & 0 deletions src/librustc_cratesio_shim/Cargo.toml
Original file line number Diff line number Diff line change
@@ -22,4 +22,5 @@ crate-type = ["dylib"]
[dependencies]
bitflags = "1.0"
log = "0.4"
serde = { version = "1.0", features = ["serde_derive"] }
unicode-width = "0.1.4"
1 change: 1 addition & 0 deletions src/librustc_cratesio_shim/src/lib.rs
Original file line number Diff line number Diff line change
@@ -6,4 +6,5 @@
extern crate bitflags;
extern crate log;
extern crate proc_macro;
extern crate serde;
extern crate unicode_width;
1 change: 1 addition & 0 deletions src/librustc_errors/Cargo.toml
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ serialize = { path = "../libserialize" }
syntax_pos = { path = "../libsyntax_pos" }
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
serde = { version = "1.0", features = ["serde_derive"] }
unicode-width = "0.1.4"
atty = "0.2"
termcolor = "1.0"
6 changes: 5 additions & 1 deletion src/librustc_errors/lib.rs
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ extern crate libc;
#[macro_use]
extern crate log;
extern crate rustc_data_structures;
extern crate serde;
extern crate serialize as rustc_serialize;
extern crate syntax_pos;
extern crate unicode_width;
@@ -35,6 +36,8 @@ use std::cell::Cell;
use std::{error, fmt};
use std::panic;

use serde::{Serialize, Deserialize};

use termcolor::{ColorSpec, Color};

mod diagnostic;
@@ -59,7 +62,8 @@ use syntax_pos::{BytePos,
/// All suggestions are marked with an `Applicability`. Tools use the applicability of a suggestion
/// to determine whether it should be automatically applied or if the user should be consulted
/// before applying the suggestion.
#[derive(Copy, Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq, Hash,
RustcEncodable, RustcDecodable, Serialize, Deserialize)]
pub enum Applicability {
/// The suggestion is definitely what the user intended. This suggestion should be
/// automatically applied.
159 changes: 106 additions & 53 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
@@ -187,13 +187,15 @@ impl<'a> CrateLoader<'a> {
});
}

fn register_crate(&mut self,
root: &Option<CratePaths>,
ident: Symbol,
span: Span,
lib: Library,
dep_kind: DepKind)
-> (CrateNum, Lrc<cstore::CrateMetadata>) {
fn register_crate(
&mut self,
host_lib: Option<Library>,
root: &Option<CratePaths>,
ident: Symbol,
span: Span,
lib: Library,
dep_kind: DepKind
) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
let crate_root = lib.metadata.get_root();
info!("register crate `extern crate {} as {}`", crate_root.name, ident);
self.verify_no_symbol_conflicts(span, &crate_root);
@@ -221,7 +223,16 @@ impl<'a> CrateLoader<'a> {
let dependencies: Vec<CrateNum> = cnum_map.iter().cloned().collect();

let proc_macros = crate_root.proc_macro_decls_static.map(|_| {
self.load_derive_macros(&crate_root, dylib.clone().map(|p| p.0), span)
if self.sess.opts.debugging_opts.dual_proc_macros {
let host_lib = host_lib.unwrap();
self.load_derive_macros(
&host_lib.metadata.get_root(),
host_lib.dylib.clone().map(|p| p.0),
span
)
} else {
self.load_derive_macros(&crate_root, dylib.clone().map(|p| p.0), span)
}
});

let def_path_table = record_time(&self.sess.perf_stats.decode_def_path_tables_time, || {
@@ -268,6 +279,61 @@ impl<'a> CrateLoader<'a> {
(cnum, cmeta)
}

fn load_proc_macro<'b> (
&mut self,
locate_ctxt: &mut locator::Context<'b>,
path_kind: PathKind,
) -> Option<(LoadResult, Option<Library>)>
where
'a: 'b
{
// Use a new locator Context so trying to load a proc macro doesn't affect the error
// message we emit
let mut proc_macro_locator = locate_ctxt.clone();

// Try to load a proc macro
proc_macro_locator.is_proc_macro = Some(true);

// Load the proc macro crate for the target
let (locator, target_result) = if self.sess.opts.debugging_opts.dual_proc_macros {
proc_macro_locator.reset();
let result = match self.load(&mut proc_macro_locator)? {
LoadResult::Previous(cnum) => return Some((LoadResult::Previous(cnum), None)),
LoadResult::Loaded(library) => Some(LoadResult::Loaded(library))
};
// Don't look for a matching hash when looking for the host crate.
// It won't be the same as the target crate hash
locate_ctxt.hash = None;
// Use the locate_ctxt when looking for the host proc macro crate, as that is required
// so we want it to affect the error message
(locate_ctxt, result)
} else {
(&mut proc_macro_locator, None)
};

// Load the proc macro crate for the host

locator.reset();
locator.is_proc_macro = Some(true);
locator.target = &self.sess.host;
locator.triple = TargetTriple::from_triple(config::host_triple());
locator.filesearch = self.sess.host_filesearch(path_kind);

let host_result = self.load(locator)?;

Some(if self.sess.opts.debugging_opts.dual_proc_macros {
let host_result = match host_result {
LoadResult::Previous(..) => {
panic!("host and target proc macros must be loaded in lock-step")
}
LoadResult::Loaded(library) => library
};
(target_result.unwrap(), Some(host_result))
} else {
(host_result, None)
})
}

fn resolve_crate<'b>(
&'b mut self,
root: &'b Option<CratePaths>,
@@ -280,53 +346,39 @@ impl<'a> CrateLoader<'a> {
mut dep_kind: DepKind,
) -> Result<(CrateNum, Lrc<cstore::CrateMetadata>), LoadError<'b>> {
info!("resolving crate `extern crate {} as {}`", name, ident);
let mut locate_ctxt = locator::Context {
sess: self.sess,
span,
ident,
crate_name: name,
hash: hash.map(|a| &*a),
extra_filename: extra_filename,
filesearch: self.sess.target_filesearch(path_kind),
target: &self.sess.target.target,
triple: self.sess.opts.target_triple.clone(),
root,
rejected_via_hash: vec![],
rejected_via_triple: vec![],
rejected_via_kind: vec![],
rejected_via_version: vec![],
rejected_via_filename: vec![],
should_match_name: true,
is_proc_macro: Some(false),
metadata_loader: &*self.cstore.metadata_loader,
};

let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
LoadResult::Previous(cnum)
(LoadResult::Previous(cnum), None)
} else {
info!("falling back to a load");
let mut locate_ctxt = locator::Context {
sess: self.sess,
span,
ident,
crate_name: name,
hash: hash.map(|a| &*a),
extra_filename: extra_filename,
filesearch: self.sess.target_filesearch(path_kind),
target: &self.sess.target.target,
triple: &self.sess.opts.target_triple,
root,
rejected_via_hash: vec![],
rejected_via_triple: vec![],
rejected_via_kind: vec![],
rejected_via_version: vec![],
rejected_via_filename: vec![],
should_match_name: true,
is_proc_macro: Some(false),
metadata_loader: &*self.cstore.metadata_loader,
};

self.load(&mut locate_ctxt).or_else(|| {
self.load(&mut locate_ctxt).map(|r| (r, None)).or_else(|| {
dep_kind = DepKind::UnexportedMacrosOnly;

let mut proc_macro_locator = locator::Context {
target: &self.sess.host,
triple: &TargetTriple::from_triple(config::host_triple()),
filesearch: self.sess.host_filesearch(path_kind),
rejected_via_hash: vec![],
rejected_via_triple: vec![],
rejected_via_kind: vec![],
rejected_via_version: vec![],
rejected_via_filename: vec![],
is_proc_macro: Some(true),
..locate_ctxt
};

self.load(&mut proc_macro_locator)
self.load_proc_macro(&mut locate_ctxt, path_kind)
}).ok_or_else(move || LoadError::LocatorError(locate_ctxt))?
};

match result {
LoadResult::Previous(cnum) => {
(LoadResult::Previous(cnum), None) => {
let data = self.cstore.get_crate_data(cnum);
if data.root.proc_macro_decls_static.is_some() {
dep_kind = DepKind::UnexportedMacrosOnly;
@@ -336,9 +388,10 @@ impl<'a> CrateLoader<'a> {
});
Ok((cnum, data))
}
LoadResult::Loaded(library) => {
Ok(self.register_crate(root, ident, span, library, dep_kind))
(LoadResult::Loaded(library), host_library) => {
Ok(self.register_crate(host_library, root, ident, span, library, dep_kind))
}
_ => panic!()
}
}

@@ -354,7 +407,7 @@ impl<'a> CrateLoader<'a> {
// don't want to match a host crate against an equivalent target one
// already loaded.
let root = library.metadata.get_root();
if locate_ctxt.triple == &self.sess.opts.target_triple {
if locate_ctxt.triple == self.sess.opts.target_triple {
let mut result = LoadResult::Loaded(library);
self.cstore.iter_crate_data(|cnum, data| {
if data.root.name == root.name && root.hash == data.root.hash {
@@ -450,9 +503,9 @@ impl<'a> CrateLoader<'a> {
fn read_extension_crate(&mut self, span: Span, orig_name: Symbol, rename: Symbol)
-> ExtensionCrate {
info!("read extension crate `extern crate {} as {}`", orig_name, rename);
let target_triple = &self.sess.opts.target_triple;
let target_triple = self.sess.opts.target_triple.clone();
let host_triple = TargetTriple::from_triple(config::host_triple());
let is_cross = target_triple != &host_triple;
let is_cross = target_triple != host_triple;
let mut target_only = false;
let mut locate_ctxt = locator::Context {
sess: self.sess,
@@ -463,7 +516,7 @@ impl<'a> CrateLoader<'a> {
extra_filename: None,
filesearch: self.sess.host_filesearch(PathKind::Crate),
target: &self.sess.host,
triple: &host_triple,
triple: host_triple,
root: &None,
rejected_via_hash: vec![],
rejected_via_triple: vec![],
2 changes: 1 addition & 1 deletion src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
@@ -647,7 +647,7 @@ impl<'a, 'tcx> CrateMetadata {

pub fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
match self.is_proc_macro(id) {
true => None,
true => self.root.proc_macro_stability.clone(),
false => self.entry(id).stability.map(|stab| stab.decode(self)),
}
}
6 changes: 5 additions & 1 deletion src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
@@ -489,7 +489,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} else {
None
},

proc_macro_stability: if is_proc_macro {
tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).map(|stab| stab.clone())
} else {
None
},
compiler_builtins: attr::contains_name(&attrs, "compiler_builtins"),
needs_allocator: attr::contains_name(&attrs, "needs_allocator"),
needs_panic_runtime: attr::contains_name(&attrs, "needs_panic_runtime"),
16 changes: 13 additions & 3 deletions src/librustc_metadata/locator.rs
Original file line number Diff line number Diff line change
@@ -241,11 +241,13 @@ use flate2::read::DeflateDecoder;

use rustc_data_structures::owning_ref::OwningRef;

#[derive(Clone)]
pub struct CrateMismatch {
path: PathBuf,
got: String,
}

#[derive(Clone)]
pub struct Context<'a> {
pub sess: &'a Session,
pub span: Span,
@@ -255,7 +257,7 @@ pub struct Context<'a> {
pub extra_filename: Option<&'a str>,
// points to either self.sess.target.target or self.sess.host, must match triple
pub target: &'a Target,
pub triple: &'a TargetTriple,
pub triple: TargetTriple,
pub filesearch: FileSearch<'a>,
pub root: &'a Option<CratePaths>,
pub rejected_via_hash: Vec<CrateMismatch>,
@@ -299,6 +301,14 @@ impl CratePaths {
}

impl<'a> Context<'a> {
pub fn reset(&mut self) {
self.rejected_via_hash.clear();
self.rejected_via_triple.clear();
self.rejected_via_kind.clear();
self.rejected_via_version.clear();
self.rejected_via_filename.clear();
}

pub fn maybe_load_library_crate(&mut self) -> Option<Library> {
let mut seen_paths = FxHashSet::default();
match self.extra_filename {
@@ -396,7 +406,7 @@ impl<'a> Context<'a> {
add);

if (self.ident == "std" || self.ident == "core")
&& self.triple != &TargetTriple::from_triple(config::host_triple()) {
&& self.triple != TargetTriple::from_triple(config::host_triple()) {
err.note(&format!("the `{}` target may not be installed", self.triple));
}
err.span_label(self.span, "can't find crate");
@@ -715,7 +725,7 @@ impl<'a> Context<'a> {
}
}

if &root.triple != self.triple {
if root.triple != self.triple {
info!("Rejecting via crate triple: expected {} got {}",
self.triple,
root.triple);
1 change: 1 addition & 0 deletions src/librustc_metadata/schema.rs
Original file line number Diff line number Diff line change
@@ -187,6 +187,7 @@ pub struct CrateRoot {
pub has_default_lib_allocator: bool,
pub plugin_registrar_fn: Option<DefIndex>,
pub proc_macro_decls_static: Option<DefIndex>,
pub proc_macro_stability: Option<attr::Stability>,

pub crate_deps: LazySeq<CrateDep>,
pub dylib_dependency_formats: LazySeq<Option<LinkagePreference>>,
1 change: 1 addition & 0 deletions src/libsyntax_pos/Cargo.toml
Original file line number Diff line number Diff line change
@@ -13,5 +13,6 @@ serialize = { path = "../libserialize" }
rustc_data_structures = { path = "../librustc_data_structures" }
arena = { path = "../libarena" }
scoped-tls = { version = "0.1.1", features = ["nightly"] }
serde = { version = "1.0", features = ["serde_derive"] }
unicode-width = "0.1.4"
cfg-if = "0.1.2"
8 changes: 7 additions & 1 deletion src/libsyntax_pos/lib.rs
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ extern crate rustc_data_structures;

#[macro_use]
extern crate scoped_tls;
extern crate serde;

use serialize::{Encodable, Decodable, Encoder, Decoder};

@@ -36,6 +37,8 @@ extern crate cfg_if;

extern crate unicode_width;

use serde::{Serialize, Deserialize};

pub mod edition;
pub mod hygiene;
pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnFormat, CompilerDesugaringKind};
@@ -77,7 +80,10 @@ impl Globals {
scoped_thread_local!(pub static GLOBALS: Globals);

/// Differentiates between real files and common virtual files.
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)]
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash,
RustcDecodable, RustcEncodable,
Serialize, Deserialize,
)]
pub enum FileName {
Real(PathBuf),
/// A macro. This includes the full name of the macro, so that there are no clashes.