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

Rollup of 10 pull requests #73499

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0687b78
Speed up bootstrap a little.
ehuss Jun 13, 2020
e32db84
Add rust features to print target features
aszenz Jun 14, 2020
607e851
Switch bootstrap metadata to --no-deps.
ehuss Jun 14, 2020
c2b920f
Show suite paths (`src/test/ui/...`) in help output.
ehuss Jun 14, 2020
f17fd7b
Add some doc comments regarding PathSet.
ehuss Jun 15, 2020
8e7606f
bootstrap/install.rs: support a nonexistent `prefix` in `x.py install`
nodakai Jun 14, 2020
4eef51a
Cache decoded predicate shorthands
matthewjasper Jun 10, 2020
4709f45
Cache flags and escaping vars for predicates
matthewjasper Jun 10, 2020
2e17245
Replace `is_global` call on data with call on predicate
matthewjasper Jun 10, 2020
a4337cc
Use `LocalDefId` for import IDs in trait map
petrochenkov Jun 14, 2020
fc13fd0
typeck: Use `LocalDefId`s for the unused trait import set
petrochenkov Jun 15, 2020
8956a7f
Only display other method receiver candidates if they actually apply
Aaron1011 Jun 15, 2020
792bd3b
lint: normalize projections using opaque types
davidtwco Jun 12, 2020
a19dfb5
Create new E0763 error code for unterminated byte constant
GuillaumeGomez Jun 12, 2020
bad252c
Update ui tests
GuillaumeGomez Jun 12, 2020
83e6c0e
Update CFGuard syntax
ajpaverd Jun 16, 2020
4506a35
add header for rust specific feature
aszenz Jun 16, 2020
9f50f84
break long line for formatting
aszenz Jun 16, 2020
457acbd
trim whitespace
aszenz Jun 16, 2020
caffb28
add blank line bw sections
aszenz Jun 17, 2020
f633dd3
Implement crate level only lints checking.
crlf0710 Jun 13, 2020
1189841
Rollup merge of #73180 - matthewjasper:predicate-cache, r=nikomatsakis
Manishearth Jun 19, 2020
0b50373
Rollup merge of #73280 - GuillaumeGomez:add-e0763, r=petrochenkov
Manishearth Jun 19, 2020
43fc34c
Rollup merge of #73287 - davidtwco:issue-73251-opaque-types-in-projec…
Manishearth Jun 19, 2020
2faa2a2
Rollup merge of #73300 - crlf0710:crate_level_only_check, r=petrochenkov
Manishearth Jun 19, 2020
1dfba21
Rollup merge of #73346 - aszenz:patch-1, r=cuviper
Manishearth Jun 19, 2020
50a7dce
Rollup merge of #73350 - nodakai:install-rs-support-nonexistent-prefi…
Manishearth Jun 19, 2020
2ec6bf0
Rollup merge of #73352 - ehuss:bootstrap-metadata, r=Mark-Simulacrum
Manishearth Jun 19, 2020
3e4140d
Rollup merge of #73357 - petrochenkov:tmap, r=davidtwco
Manishearth Jun 19, 2020
fc3e911
Rollup merge of #73382 - Aaron1011:fix/self-receiver-candidates, r=pe…
Manishearth Jun 19, 2020
dc3ca0f
Rollup merge of #73404 - ajpaverd:cfguard_syntax, r=Mark-Simulacrum
Manishearth Jun 19, 2020
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
56 changes: 43 additions & 13 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,21 @@ struct StepDescription {
name: &'static str,
}

/// Collection of paths used to match a task rule.
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub enum PathSet {
/// A collection of individual paths.
///
/// These are generally matched as a path suffix. For example, a
/// command-line value of `libstd` will match if `src/libstd` is in the
/// set.
Set(BTreeSet<PathBuf>),
/// A "suite" of paths.
///
/// These can match as a path suffix (like `Set`), or as a prefix. For
/// example, a command-line value of `src/test/ui/abi/variadic-ffi.rs`
/// will match `src/test/ui`. A command-line value of `ui` would also
/// match `src/test/ui`.
Suite(PathBuf),
}

Expand Down Expand Up @@ -251,21 +263,33 @@ impl<'a> ShouldRun<'a> {
self
}

// Unlike `krate` this will create just one pathset. As such, it probably shouldn't actually
// ever be used, but as we transition to having all rules properly handle passing krate(...) by
// actually doing something different for every crate passed.
/// Indicates it should run if the command-line selects the given crate or
/// any of its (local) dependencies.
///
/// Compared to `krate`, this treats the dependencies as aliases for the
/// same job. Generally it is preferred to use `krate`, and treat each
/// individual path separately. For example `./x.py test src/liballoc`
/// (which uses `krate`) will test just `liballoc`. However, `./x.py check
/// src/liballoc` (which uses `all_krates`) will check all of `libtest`.
/// `all_krates` should probably be removed at some point.
pub fn all_krates(mut self, name: &str) -> Self {
let mut set = BTreeSet::new();
for krate in self.builder.in_tree_crates(name) {
set.insert(PathBuf::from(&krate.path));
let path = krate.local_path(self.builder);
set.insert(path);
}
self.paths.insert(PathSet::Set(set));
self
}

/// Indicates it should run if the command-line selects the given crate or
/// any of its (local) dependencies.
///
/// `make_run` will be called separately for each matching command-line path.
pub fn krate(mut self, name: &str) -> Self {
for krate in self.builder.in_tree_crates(name) {
self.paths.insert(PathSet::one(&krate.path));
let path = krate.local_path(self.builder);
self.paths.insert(PathSet::one(path));
}
self
}
Expand Down Expand Up @@ -488,13 +512,19 @@ impl<'a> Builder<'a> {
should_run = (desc.should_run)(should_run);
}
let mut help = String::from("Available paths:\n");
let mut add_path = |path: &Path| {
help.push_str(&format!(" ./x.py {} {}\n", subcommand, path.display()));
};
for pathset in should_run.paths {
if let PathSet::Set(set) = pathset {
set.iter().for_each(|path| {
help.push_str(
format!(" ./x.py {} {}\n", subcommand, path.display()).as_str(),
)
})
match pathset {
PathSet::Set(set) => {
for path in set {
add_path(&path);
}
}
PathSet::Suite(path) => {
add_path(&path.join("..."));
}
}
}
Some(help)
Expand Down Expand Up @@ -1176,7 +1206,7 @@ impl<'a> Builder<'a> {
);
}

// If Control Flow Guard is enabled, pass the `control_flow_guard=checks` flag to rustc
// If Control Flow Guard is enabled, pass the `control-flow-guard` flag to rustc
// when compiling the standard library, since this might be linked into the final outputs
// produced by rustc. Since this mitigation is only available on Windows, only enable it
// for the standard library in case the compiler is run on a non-Windows platform.
Expand All @@ -1187,7 +1217,7 @@ impl<'a> Builder<'a> {
&& self.config.control_flow_guard
&& compiler.stage >= 1
{
rustflags.arg("-Zcontrol_flow_guard=checks");
rustflags.arg("-Zcontrol-flow-guard");
}

// For `cargo doc` invocations, make rustdoc print the Rust version into the docs
Expand Down
20 changes: 2 additions & 18 deletions src/bootstrap/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,8 +548,8 @@ impl Step for Rustc {
// Find dependencies for top level crates.
let mut compiler_crates = HashSet::new();
for root_crate in &["rustc_driver", "rustc_codegen_llvm", "rustc_codegen_ssa"] {
let interned_root_crate = INTERNER.intern_str(root_crate);
find_compiler_crates(builder, &interned_root_crate, &mut compiler_crates);
compiler_crates
.extend(builder.in_tree_crates(root_crate).into_iter().map(|krate| krate.name));
}

for krate in &compiler_crates {
Expand All @@ -564,22 +564,6 @@ impl Step for Rustc {
}
}

fn find_compiler_crates(
builder: &Builder<'_>,
name: &Interned<String>,
crates: &mut HashSet<Interned<String>>,
) {
// Add current crate.
crates.insert(*name);

// Look for dependencies.
for dep in builder.crates.get(name).unwrap().deps.iter() {
if builder.crates.get(dep).unwrap().is_local(builder) {
find_compiler_crates(builder, dep, crates);
}
}
}

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Rustdoc {
stage: u32,
Expand Down
7 changes: 2 additions & 5 deletions src/bootstrap/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ use std::process;
use getopts::Options;

use crate::builder::Builder;
use crate::cache::{Interned, INTERNER};
use crate::config::Config;
use crate::metadata;
use crate::{Build, DocTests};

use crate::cache::{Interned, INTERNER};

/// Deserialized version of all flags for this compile.
pub struct Flags {
pub verbose: usize, // number of -v args; each extra -v after the first is passed to Cargo
Expand Down Expand Up @@ -449,8 +447,7 @@ Arguments:
// All subcommands except `clean` can have an optional "Available paths" section
if matches.opt_present("verbose") {
let config = Config::parse(&["build".to_string()]);
let mut build = Build::new(config);
metadata::build(&mut build);
let build = Build::new(config);

let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str());
Expand Down
5 changes: 4 additions & 1 deletion src/bootstrap/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ fn install_sh(
let libdir_default = PathBuf::from("lib");
let mandir_default = datadir_default.join("man");
let prefix = builder.config.prefix.as_ref().map_or(prefix_default, |p| {
fs::canonicalize(p).unwrap_or_else(|_| panic!("could not canonicalize {}", p.display()))
fs::create_dir_all(p)
.unwrap_or_else(|err| panic!("could not create {}: {}", p.display(), err));
fs::canonicalize(p)
.unwrap_or_else(|err| panic!("could not canonicalize {}: {}", p.display(), err))
});
let sysconfdir = builder.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default);
let datadir = builder.config.datadir.as_ref().unwrap_or(&datadir_default);
Expand Down
25 changes: 16 additions & 9 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,7 @@ struct Crate {
}

impl Crate {
fn is_local(&self, build: &Build) -> bool {
self.path.starts_with(&build.config.src) && !self.path.to_string_lossy().ends_with("_shim")
}

fn local_path(&self, build: &Build) -> PathBuf {
assert!(self.is_local(build));
self.path.strip_prefix(&build.config.src).unwrap().into()
}
}
Expand Down Expand Up @@ -1079,17 +1074,29 @@ impl Build {
}
}

/// Returns a Vec of all the dependencies of the given root crate,
/// including transitive dependencies and the root itself. Only includes
/// "local" crates (those in the local source tree, not from a registry).
fn in_tree_crates(&self, root: &str) -> Vec<&Crate> {
let mut ret = Vec::new();
let mut list = vec![INTERNER.intern_str(root)];
let mut visited = HashSet::new();
while let Some(krate) = list.pop() {
let krate = &self.crates[&krate];
if krate.is_local(self) {
ret.push(krate);
}
ret.push(krate);
for dep in &krate.deps {
if visited.insert(dep) && dep != "build_helper" {
// Don't include optional deps if their features are not
// enabled. Ideally this would be computed from `cargo
// metadata --features …`, but that is somewhat slow. Just
// skip `build_helper` since there aren't any operations we
// want to perform on it. In the future, we may want to
// consider just filtering all build and dev dependencies in
// metadata::build.
if visited.insert(dep)
&& dep != "build_helper"
&& (dep != "profiler_builtins" || self.config.profiler)
&& (dep != "rustc_codegen_llvm" || self.config.llvm_enabled())
{
list.push(*dep);
}
}
Expand Down
62 changes: 13 additions & 49 deletions src/bootstrap/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::collections::HashMap;
use std::collections::HashSet;
use std::path::PathBuf;
use std::process::Command;

Expand All @@ -12,7 +10,6 @@ use crate::{Build, Crate};
#[derive(Deserialize)]
struct Output {
packages: Vec<Package>,
resolve: Resolve,
}

#[derive(Deserialize)]
Expand All @@ -21,72 +18,39 @@ struct Package {
name: String,
source: Option<String>,
manifest_path: String,
dependencies: Vec<Dependency>,
}

#[derive(Deserialize)]
struct Resolve {
nodes: Vec<ResolveNode>,
}

#[derive(Deserialize)]
struct ResolveNode {
id: String,
dependencies: Vec<String>,
struct Dependency {
name: String,
source: Option<String>,
}

pub fn build(build: &mut Build) {
let mut resolves = Vec::new();
build_krate(&build.std_features(), build, &mut resolves, "src/libstd");
build_krate("", build, &mut resolves, "src/libtest");
build_krate(&build.rustc_features(), build, &mut resolves, "src/rustc");

let mut id2name = HashMap::with_capacity(build.crates.len());
for (name, krate) in build.crates.iter() {
id2name.insert(krate.id.clone(), name.clone());
}

for node in resolves {
let name = match id2name.get(&node.id) {
Some(name) => name,
None => continue,
};

let krate = build.crates.get_mut(name).unwrap();
for dep in node.dependencies.iter() {
let dep = match id2name.get(dep) {
Some(dep) => dep,
None => continue,
};
krate.deps.insert(*dep);
}
}
}

fn build_krate(features: &str, build: &mut Build, resolves: &mut Vec<ResolveNode>, krate: &str) {
// Run `cargo metadata` to figure out what crates we're testing.
//
// Down below we're going to call `cargo test`, but to test the right set
// of packages we're going to have to know what `-p` arguments to pass it
// to know what crates to test. Here we run `cargo metadata` to learn about
// the dependency graph and what `-p` arguments there are.
let mut cargo = Command::new(&build.initial_cargo);
cargo
.arg("metadata")
.arg("--format-version")
.arg("1")
.arg("--features")
.arg(features)
.arg("--no-deps")
.arg("--manifest-path")
.arg(build.src.join(krate).join("Cargo.toml"));
.arg(build.src.join("Cargo.toml"));
let output = output(&mut cargo);
let output: Output = serde_json::from_str(&output).unwrap();
for package in output.packages {
if package.source.is_none() {
let name = INTERNER.intern_string(package.name);
let mut path = PathBuf::from(package.manifest_path);
path.pop();
build.crates.insert(name, Crate { name, id: package.id, deps: HashSet::new(), path });
let deps = package
.dependencies
.into_iter()
.filter(|dep| dep.source.is_none())
.map(|dep| INTERNER.intern_string(dep.name))
.collect();
build.crates.insert(name, Crate { name, id: package.id, deps, path });
}
}
resolves.extend(output.resolve.nodes);
}
10 changes: 2 additions & 8 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1648,14 +1648,8 @@ impl Step for Crate {
type Output = ();
const DEFAULT: bool = true;

fn should_run(mut run: ShouldRun<'_>) -> ShouldRun<'_> {
let builder = run.builder;
for krate in run.builder.in_tree_crates("test") {
if !(krate.name.starts_with("rustc_") && krate.name.ends_with("san")) {
run = run.path(krate.local_path(&builder).to_str().unwrap());
}
}
run
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.krate("test")
}

fn make_run(run: RunConfig<'_>) {
Expand Down
10 changes: 5 additions & 5 deletions src/doc/unstable-book/src/compiler-flags/control-flow-guard.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# `control_flow_guard`
# `control-flow-guard`

The tracking issue for this feature is: [#68793](https://github.com/rust-lang/rust/issues/68793).

------------------------

The rustc flag `-Z control_flow_guard=checks` enables the Windows [Control Flow Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) (CFG) platform security feature.
The rustc flag `-Z control-flow-guard` enables the Windows [Control Flow Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) (CFG) platform security feature.

CFG is an exploit mitigation designed to enforce control-flow integrity for software running on supported Windows platforms (Windows 8.1 onwards). Specifically, CFG uses runtime checks to validate the target address of every indirect call/jump before allowing the call to complete.

Expand All @@ -29,7 +29,7 @@ The CFG checks and metadata can potentially increase binary size and runtime ove

## Testing Control Flow Guard

The rustc flag `-Z control_flow_guard=nochecks` instructs LLVM to emit the list of valid call targets without inserting runtime checks. This flag should only be used for testing purposes as it does not provide security enforcement.
The rustc flag `-Z control-flow-guard=nochecks` instructs LLVM to emit the list of valid call targets without inserting runtime checks. This flag should only be used for testing purposes as it does not provide security enforcement.


## Control Flow Guard in libraries
Expand All @@ -44,14 +44,14 @@ For example:
```cmd
rustup toolchain install --force nightly
rustup component add rust-src
SET RUSTFLAGS=-Z control_flow_guard=checks
SET RUSTFLAGS=-Z control-flow-guard
cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc
```

```PowerShell
rustup toolchain install --force nightly
rustup component add rust-src
$Env:RUSTFLAGS = "-Z control_flow_guard=checks"
$Env:RUSTFLAGS = "-Z control-flow-guard"
cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc
```

Expand Down
1 change: 1 addition & 0 deletions src/librustc_error_codes/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ E0759: include_str!("./error_codes/E0759.md"),
E0760: include_str!("./error_codes/E0760.md"),
E0761: include_str!("./error_codes/E0761.md"),
E0762: include_str!("./error_codes/E0762.md"),
E0763: include_str!("./error_codes/E0763.md"),
;
// E0006, // merged with E0005
// E0008, // cannot bind by-move into a pattern guard
Expand Down
13 changes: 13 additions & 0 deletions src/librustc_error_codes/error_codes/E0763.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
A byte constant wasn't correctly ended.

Erroneous code example:

```compile_fail,E0763
let c = b'a; // error!
```

To fix this error, add the missing quote:

```
let c = b'a'; // ok!
```
Loading