Skip to content

Commit

Permalink
Auto merge of #69062 - Dylan-DPC:rollup-7wpjpqu, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 8 pull requests

Successful merges:

 - #66498 (Remove unused feature gates)
 - #68816 (Tweak borrow error on `FnMut` when `Fn` is expected)
 - #68824 (Enable Control Flow Guard in rustbuild)
 - #69022 (traits: preallocate 2 Vecs of known initial size)
 - #69031 (Use `dyn Trait` more in tests)
 - #69044 (Don't run coherence twice for future-compat lints)
 - #69047 (Don't rustfmt check the vendor directory.)
 - #69055 (Clean up E0307 explanation)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Feb 11, 2020
2 parents 95e0a2c + 82a366a commit 3f32e30
Show file tree
Hide file tree
Showing 45 changed files with 533 additions and 375 deletions.
4 changes: 4 additions & 0 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@
# Use LLVM libunwind as the implementation for Rust's unwinder.
#llvm-libunwind = false

# Enable Windows Control Flow Guard checks in the standard library.
# This only applies from stage 1 onwards, and only for Windows targets.
#control-flow-guard = false

# =============================================================================
# Options for specific targets
#
Expand Down
1 change: 1 addition & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ merge_derives = false
# tidy only checks files which are not ignored, each entry follows gitignore style
ignore = [
"build",
"/vendor/",

# tests for now are not formatted, as they are sometimes pretty-printing constrained
# (and generally rustfmt can move around comments in UI-testing incompatible ways)
Expand Down
14 changes: 14 additions & 0 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,20 @@ impl<'a> Builder<'a> {
);
}

// If Control Flow Guard is enabled, pass the `control_flow_guard=checks` 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.
// This is not needed for stage 0 artifacts because these will only be used for building
// the stage 1 compiler.
if cfg!(windows)
&& mode == Mode::Std
&& self.config.control_flow_guard
&& compiler.stage >= 1
{
rustflags.arg("-Zcontrol_flow_guard=checks");
}

// For `cargo doc` invocations, make rustdoc print the Rust version into the docs
cargo.env("RUSTDOC_CRATE_VERSION", self.rust_version());

Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ pub struct Config {
pub targets: Vec<Interned<String>>,
pub local_rebuild: bool,
pub jemalloc: bool,
pub control_flow_guard: bool,

// dist misc
pub dist_sign_folder: Option<PathBuf>,
Expand Down Expand Up @@ -333,6 +334,7 @@ struct Rust {
jemalloc: Option<bool>,
test_compare_mode: Option<bool>,
llvm_libunwind: Option<bool>,
control_flow_guard: Option<bool>,
}

/// TOML representation of how each build target is configured.
Expand Down Expand Up @@ -580,6 +582,7 @@ impl Config {
set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir);
config.rust_thin_lto_import_instr_limit = rust.thin_lto_import_instr_limit;
set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo);
set(&mut config.control_flow_guard, rust.control_flow_guard);

if let Some(ref backends) = rust.codegen_backends {
config.rust_codegen_backends =
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def v(*args):
o("lldb", "rust.lldb", "build lldb")
o("missing-tools", "dist.missing-tools", "allow failures when building tools")
o("use-libcxx", "llvm.use-libcxx", "build LLVM with libc++")
o("control-flow-guard", "rust.control-flow-guard", "Enable Control Flow Guard")

o("cflags", "llvm.cflags", "build LLVM with these extra compiler flags")
o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags")
Expand Down
1 change: 0 additions & 1 deletion src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@
//! More documentation can be found in each respective module below, and you can
//! also check out the `src/bootstrap/README.md` file for more information.

#![feature(core_intrinsics)]
#![feature(drain_filter)]

use std::cell::{Cell, RefCell};
Expand Down
34 changes: 34 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/control-flow-guard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# `control_flow_guard`

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

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

The `-Zcontrol_flow_guard=checks` compiler flag enables the Windows [Control Flow Guard][cfguard-docs] platform security feature. When enabled, the compiler outputs a list of valid indirect call targets, and inserts runtime checks on all indirect jump instructions to ensure that the destination is in the list of valid call targets.

[cfguard-docs]: https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard

For testing purposes, the `-Zcontrol_flow_guard=nochecks` compiler flag can be used to emit only the list of valid call targets, but not the runtime checks.

It is strongly recommended to also enable Control Flow Guard checks in all linked libraries, including the standard library.

To enable Control Flow Guard in the standard library, you can use the [cargo `-Zbuild-std` functionality][build-std] to recompile the standard library with the same configuration options as the main program.

[build-std]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std

For example:
```cmd
rustup toolchain install --force nightly
rustup component add rust-src
SET RUSTFLAGS=-Zcontrol_flow_guard=checks
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 = "-Zcontrol_flow_guard=checks"
cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc
```

Alternatively, if you are building the standard library from source, you can set `control-flow-guard = true` in the config.toml file.
7 changes: 0 additions & 7 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
//! This API is completely unstable and subject to change.

#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(arbitrary_self_types)]
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(box_syntax)]
Expand All @@ -39,21 +38,15 @@
#![feature(marker_trait_attr)]
#![feature(extern_types)]
#![feature(nll)]
#![feature(optin_builtin_traits)]
#![feature(option_expect_none)]
#![feature(range_is_empty)]
#![feature(specialization)]
#![feature(unboxed_closures)]
#![feature(thread_local)]
#![feature(trace_macros)]
#![feature(trusted_len)]
#![feature(vec_remove_item)]
#![feature(stmt_expr_attributes)]
#![feature(integer_atomics)]
#![feature(test)]
#![feature(in_band_lifetimes)]
#![feature(crate_visibility_modifier)]
#![feature(log_syntax)]
#![feature(associated_type_bounds)]
#![feature(rustc_attrs)]
#![feature(hash_raw_entry)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3472,7 +3472,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// that order.
let predicates = tcx.predicates_of(def_id);
assert_eq!(predicates.parent, None);
let mut obligations = Vec::new();
let mut obligations = Vec::with_capacity(predicates.predicates.len());
for (predicate, _) in predicates.predicates {
let predicate = normalize_with_depth_to(
self,
Expand Down
73 changes: 43 additions & 30 deletions src/librustc/traits/specialize/specialization_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ impl<'tcx> Children {
impl_def_id, simplified_self, possible_sibling,
);

let overlap_error = |overlap: traits::coherence::OverlapResult<'_>| {
// Found overlap, but no specialization; error out.
let create_overlap_error = |overlap: traits::coherence::OverlapResult<'_>| {
let trait_ref = overlap.impl_header.trait_ref.unwrap();
let self_ty = trait_ref.self_ty();

OverlapError {
with_impl: possible_sibling,
trait_desc: trait_ref.print_only_trait_path().to_string(),
Expand All @@ -106,21 +106,49 @@ impl<'tcx> Children {
}
};

let allowed_to_overlap =
tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling);
let report_overlap_error = |overlap: traits::coherence::OverlapResult<'_>,
last_lint: &mut _| {
// Found overlap, but no specialization; error out or report future-compat warning.

// Do we *still* get overlap if we disable the future-incompatible modes?
let should_err = traits::overlapping_impls(
tcx,
possible_sibling,
impl_def_id,
traits::SkipLeakCheck::default(),
|_| true,
|| false,
);

let error = create_overlap_error(overlap);

if should_err {
Err(error)
} else {
*last_lint = Some(FutureCompatOverlapError {
error,
kind: FutureCompatOverlapErrorKind::LeakCheck,
});

Ok((false, false))
}
};

let last_lint_mut = &mut last_lint;
let (le, ge) = traits::overlapping_impls(
tcx,
possible_sibling,
impl_def_id,
traits::SkipLeakCheck::default(),
traits::SkipLeakCheck::Yes,
|overlap| {
if let Some(overlap_kind) = &allowed_to_overlap {
if let Some(overlap_kind) =
tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling)
{
match overlap_kind {
ty::ImplOverlapKind::Permitted { marker: _ } => {}
ty::ImplOverlapKind::Issue33140 => {
last_lint = Some(FutureCompatOverlapError {
error: overlap_error(overlap),
*last_lint_mut = Some(FutureCompatOverlapError {
error: create_overlap_error(overlap),
kind: FutureCompatOverlapErrorKind::Issue33140,
});
}
Expand All @@ -132,7 +160,11 @@ impl<'tcx> Children {
let le = tcx.specializes((impl_def_id, possible_sibling));
let ge = tcx.specializes((possible_sibling, impl_def_id));

if le == ge { Err(overlap_error(overlap)) } else { Ok((le, ge)) }
if le == ge {
report_overlap_error(overlap, last_lint_mut)
} else {
Ok((le, ge))
}
},
|| Ok((false, false)),
)?;
Expand All @@ -153,27 +185,8 @@ impl<'tcx> Children {

replace_children.push(possible_sibling);
} else {
if let None = allowed_to_overlap {
// Do future-compat checks for overlap.

if last_lint.is_none() {
traits::overlapping_impls(
tcx,
possible_sibling,
impl_def_id,
traits::SkipLeakCheck::Yes,
|overlap| {
last_lint = Some(FutureCompatOverlapError {
error: overlap_error(overlap),
kind: FutureCompatOverlapErrorKind::LeakCheck,
});
},
|| (),
);
}
}

// no overlap (error bailed already via ?)
// Either there's no overlap, or the overlap was already reported by
// `overlap_error`.
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/librustc/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,15 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
let cause = self.cause(traits::MiscObligation);
let infcx = &mut self.infcx;
let param_env = self.param_env;
let mut obligations = Vec::new();
self.out.iter().inspect(|pred| assert!(!pred.has_escaping_bound_vars())).for_each(|pred| {
let mut obligations = Vec::with_capacity(self.out.len());
for pred in &self.out {
assert!(!pred.has_escaping_bound_vars());
let mut selcx = traits::SelectionContext::new(infcx);
let i = obligations.len();
let value =
traits::normalize_to(&mut selcx, param_env, cause.clone(), pred, &mut obligations);
obligations.insert(i, value);
});
}
obligations
}

Expand Down
15 changes: 4 additions & 11 deletions src/librustc_codegen_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,11 @@

#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(const_cstr_unchecked)]
#![feature(crate_visibility_modifier)]
#![feature(extern_types)]
#![feature(in_band_lifetimes)]
#![feature(libc)]
#![feature(nll)]
#![feature(optin_builtin_traits)]
#![feature(concat_idents)]
#![feature(link_args)]
#![feature(static_nobundle)]
#![feature(trusted_len)]
#![recursion_limit = "256"]

Expand Down Expand Up @@ -196,7 +189,7 @@ unsafe impl Sync for LlvmCodegenBackend {}

impl LlvmCodegenBackend {
pub fn new() -> Box<dyn CodegenBackend> {
box LlvmCodegenBackend(())
Box::new(LlvmCodegenBackend(()))
}
}

Expand Down Expand Up @@ -245,7 +238,7 @@ impl CodegenBackend for LlvmCodegenBackend {
}

fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
box metadata::LlvmMetadataLoader
Box::new(metadata::LlvmMetadataLoader)
}

fn provide(&self, providers: &mut ty::query::Providers<'_>) {
Expand All @@ -262,12 +255,12 @@ impl CodegenBackend for LlvmCodegenBackend {
metadata: EncodedMetadata,
need_metadata_module: bool,
) -> Box<dyn Any> {
box rustc_codegen_ssa::base::codegen_crate(
Box::new(rustc_codegen_ssa::base::codegen_crate(
LlvmCodegenBackend(()),
tcx,
metadata,
need_metadata_module,
)
))
}

fn join_codegen(
Expand Down
16 changes: 9 additions & 7 deletions src/librustc_codegen_llvm/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ impl MetadataLoader for LlvmMetadataLoader {
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
// internally to read the file. We also avoid even using a memcpy by
// just keeping the archive along while the metadata is in use.
let archive = ArchiveRO::open(filename).map(|ar| OwningRef::new(box ar)).map_err(|e| {
debug!("llvm didn't like `{}`: {}", filename.display(), e);
format!("failed to read rlib metadata in '{}': {}", filename.display(), e)
})?;
let archive =
ArchiveRO::open(filename).map(|ar| OwningRef::new(Box::new(ar))).map_err(|e| {
debug!("llvm didn't like `{}`: {}", filename.display(), e);
format!("failed to read rlib metadata in '{}': {}", filename.display(), e)
})?;
let buf: OwningRef<_, [u8]> = archive.try_map(|ar| {
ar.iter()
.filter_map(|s| s.ok())
Expand All @@ -44,9 +45,10 @@ impl MetadataLoader for LlvmMetadataLoader {
let buf = path_to_c_string(filename);
let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr())
.ok_or_else(|| format!("error reading library: '{}'", filename.display()))?;
let of = ObjectFile::new(mb).map(|of| OwningRef::new(box of)).ok_or_else(|| {
format!("provided path not an object file: '{}'", filename.display())
})?;
let of =
ObjectFile::new(mb).map(|of| OwningRef::new(Box::new(of))).ok_or_else(|| {
format!("provided path not an object file: '{}'", filename.display())
})?;
let buf = of.try_map(|of| search_meta_section(of, target, filename))?;
Ok(rustc_erase_owner!(buf))
}
Expand Down
4 changes: 0 additions & 4 deletions src/librustc_codegen_ssa/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(core_intrinsics)]
#![feature(libc)]
#![feature(stmt_expr_attributes)]
#![feature(try_blocks)]
#![feature(in_band_lifetimes)]
#![feature(nll)]
Expand Down
4 changes: 0 additions & 4 deletions src/librustc_codegen_utils/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
//! This API is completely unstable and subject to change.

#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(arbitrary_self_types)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(core_intrinsics)]
#![feature(never_type)]
#![feature(nll)]
#![feature(in_band_lifetimes)]
Expand Down
Loading

0 comments on commit 3f32e30

Please sign in to comment.