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

Create a derive macro for HashStable and allow proc macros in rustc #58013

Merged
merged 11 commits into from
Mar 8, 2019
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
11 changes: 11 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2365,6 +2365,7 @@ dependencies = [
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_fs_util 0.0.0",
"rustc_macros 0.1.0",
"rustc_target 0.0.0",
"scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
Expand Down Expand Up @@ -2817,6 +2818,16 @@ dependencies = [
"core 0.0.0",
]

[[package]]
name = "rustc_macros"
version = "0.1.0"
dependencies = [
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "rustc_metadata"
version = "0.0.0"
Expand Down
21 changes: 14 additions & 7 deletions src/bootstrap/bin/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ fn main() {

cmd.arg("-Zexternal-macro-backtrace");

// 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.
Expand Down Expand Up @@ -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);
}
Expand All @@ -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_COMPILER").is_some() {
cmd.arg("--cfg").arg("parallel_compiler");
}
Expand Down
11 changes: 11 additions & 0 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -812,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");
Expand Down
12 changes: 8 additions & 4 deletions src/bootstrap/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -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");
}
}
Expand Down
74 changes: 55 additions & 19 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -431,8 +432,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");
}
Expand Down Expand Up @@ -496,8 +501,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,
});
Expand Down Expand Up @@ -592,8 +597,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");
}
}
Expand Down Expand Up @@ -1015,10 +1024,20 @@ 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
) {
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 {
builder.copy(&path, &sysroot_host_dst.join(path.file_name().unwrap()));
} else {
builder.copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
}
}
}

Expand Down Expand Up @@ -1047,8 +1066,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 {
Expand All @@ -1063,15 +1088,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;
}

Expand Down Expand Up @@ -1124,10 +1153,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
Expand All @@ -1140,12 +1169,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");
}
Expand All @@ -1157,15 +1187,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(
Expand Down Expand Up @@ -1211,13 +1241,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>,
Expand Down
7 changes: 4 additions & 3 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1129,7 +1129,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();
}
Expand All @@ -1142,8 +1142,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
}
Expand Down
3 changes: 2 additions & 1 deletion src/bootstrap/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ impl Step for ToolBuild {
compile::CargoMessage::CompilerArtifact {
package_id,
features,
filenames
filenames,
target: _,
} => {
(package_id, features, filenames)
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ rustc-rayon = "0.1.2"
rustc-rayon-core = "0.1.2"
rustc_apfloat = { path = "../librustc_apfloat" }
rustc_target = { path = "../librustc_target" }
rustc_macros = { path = "../librustc_macros" }
rustc_data_structures = { path = "../librustc_data_structures" }
errors = { path = "../librustc_errors", package = "rustc_errors" }
serialize = { path = "../libserialize" }
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use crate::ty::query::Providers;

use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync};
use rustc_data_structures::thin_vec::ThinVec;
use rustc_macros::HashStable;

use serialize::{self, Encoder, Encodable, Decoder, Decodable};
use std::collections::{BTreeSet, BTreeMap};
Expand Down Expand Up @@ -149,7 +150,7 @@ pub const DUMMY_HIR_ID: HirId = HirId {

pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX;

#[derive(Clone, RustcEncodable, RustcDecodable, Copy)]
#[derive(Clone, RustcEncodable, RustcDecodable, Copy, HashStable)]
pub struct Lifetime {
pub hir_id: HirId,
pub span: Span,
Expand Down
6 changes: 0 additions & 6 deletions src/librustc/ich/impls_hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,6 @@ impl_stable_hash_for!(struct ast::Label {
ident
});

impl_stable_hash_for!(struct hir::Lifetime {
hir_id,
span,
name
});

impl_stable_hash_for!(struct hir::Path {
span,
def,
Expand Down
10 changes: 2 additions & 8 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,8 @@ pub mod util {
pub mod bug;
}

// A private module so that macro-expanded idents like
// `::rustc::lint::Lint` will also work in `rustc` itself.
//
// `libstd` uses the same trick.
#[doc(hidden)]
mod rustc {
pub use crate::lint;
}
// Allows macros to refer to this crate as `::rustc`
extern crate self as rustc;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know that was possible :)


// FIXME(#27438): right now the unit tests of librustc don't refer to any actual
// functions generated in librustc_data_structures (all
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,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"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for being so late to see this, but can an issue be opened to track this "feature"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #64671

no_codegen: bool = (false, parse_bool, [TRACKED],
"run all passes except codegen; no output"),
treat_err_as_bug: bool = (false, parse_bool, [TRACKED],
Expand Down
Loading