Skip to content

Commit 3f32e30

Browse files
committed
Auto merge of #69062 - Dylan-DPC:rollup-7wpjpqu, r=Dylan-DPC
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
2 parents 95e0a2c + 82a366a commit 3f32e30

File tree

45 files changed

+533
-375
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+533
-375
lines changed

config.toml.example

+4
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,10 @@
444444
# Use LLVM libunwind as the implementation for Rust's unwinder.
445445
#llvm-libunwind = false
446446

447+
# Enable Windows Control Flow Guard checks in the standard library.
448+
# This only applies from stage 1 onwards, and only for Windows targets.
449+
#control-flow-guard = false
450+
447451
# =============================================================================
448452
# Options for specific targets
449453
#

rustfmt.toml

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ merge_derives = false
77
# tidy only checks files which are not ignored, each entry follows gitignore style
88
ignore = [
99
"build",
10+
"/vendor/",
1011

1112
# tests for now are not formatted, as they are sometimes pretty-printing constrained
1213
# (and generally rustfmt can move around comments in UI-testing incompatible ways)

src/bootstrap/builder.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,20 @@ impl<'a> Builder<'a> {
11351135
);
11361136
}
11371137

1138+
// If Control Flow Guard is enabled, pass the `control_flow_guard=checks` flag to rustc
1139+
// when compiling the standard library, since this might be linked into the final outputs
1140+
// produced by rustc. Since this mitigation is only available on Windows, only enable it
1141+
// for the standard library in case the compiler is run on a non-Windows platform.
1142+
// This is not needed for stage 0 artifacts because these will only be used for building
1143+
// the stage 1 compiler.
1144+
if cfg!(windows)
1145+
&& mode == Mode::Std
1146+
&& self.config.control_flow_guard
1147+
&& compiler.stage >= 1
1148+
{
1149+
rustflags.arg("-Zcontrol_flow_guard=checks");
1150+
}
1151+
11381152
// For `cargo doc` invocations, make rustdoc print the Rust version into the docs
11391153
cargo.env("RUSTDOC_CRATE_VERSION", self.rust_version());
11401154

src/bootstrap/config.rs

+3
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ pub struct Config {
116116
pub targets: Vec<Interned<String>>,
117117
pub local_rebuild: bool,
118118
pub jemalloc: bool,
119+
pub control_flow_guard: bool,
119120

120121
// dist misc
121122
pub dist_sign_folder: Option<PathBuf>,
@@ -333,6 +334,7 @@ struct Rust {
333334
jemalloc: Option<bool>,
334335
test_compare_mode: Option<bool>,
335336
llvm_libunwind: Option<bool>,
337+
control_flow_guard: Option<bool>,
336338
}
337339

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

584587
if let Some(ref backends) = rust.codegen_backends {
585588
config.rust_codegen_backends =

src/bootstrap/configure.py

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def v(*args):
6060
o("lldb", "rust.lldb", "build lldb")
6161
o("missing-tools", "dist.missing-tools", "allow failures when building tools")
6262
o("use-libcxx", "llvm.use-libcxx", "build LLVM with libc++")
63+
o("control-flow-guard", "rust.control-flow-guard", "Enable Control Flow Guard")
6364

6465
o("cflags", "llvm.cflags", "build LLVM with these extra compiler flags")
6566
o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags")

src/bootstrap/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@
103103
//! More documentation can be found in each respective module below, and you can
104104
//! also check out the `src/bootstrap/README.md` file for more information.
105105
106-
#![feature(core_intrinsics)]
107106
#![feature(drain_filter)]
108107

109108
use std::cell::{Cell, RefCell};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# `control_flow_guard`
2+
3+
The tracking issue for this feature is: [#68793](https://github.com/rust-lang/rust/issues/68793).
4+
5+
------------------------
6+
7+
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.
8+
9+
[cfguard-docs]: https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard
10+
11+
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.
12+
13+
It is strongly recommended to also enable Control Flow Guard checks in all linked libraries, including the standard library.
14+
15+
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.
16+
17+
[build-std]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std
18+
19+
For example:
20+
```cmd
21+
rustup toolchain install --force nightly
22+
rustup component add rust-src
23+
SET RUSTFLAGS=-Zcontrol_flow_guard=checks
24+
cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc
25+
```
26+
27+
```PowerShell
28+
rustup toolchain install --force nightly
29+
rustup component add rust-src
30+
$Env:RUSTFLAGS = "-Zcontrol_flow_guard=checks"
31+
cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc
32+
```
33+
34+
Alternatively, if you are building the standard library from source, you can set `control-flow-guard = true` in the config.toml file.

src/librustc/lib.rs

-7
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
//! This API is completely unstable and subject to change.
2828
2929
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
30-
#![feature(arbitrary_self_types)]
3130
#![feature(bool_to_option)]
3231
#![feature(box_patterns)]
3332
#![feature(box_syntax)]
@@ -39,21 +38,15 @@
3938
#![feature(marker_trait_attr)]
4039
#![feature(extern_types)]
4140
#![feature(nll)]
42-
#![feature(optin_builtin_traits)]
4341
#![feature(option_expect_none)]
4442
#![feature(range_is_empty)]
4543
#![feature(specialization)]
46-
#![feature(unboxed_closures)]
47-
#![feature(thread_local)]
48-
#![feature(trace_macros)]
4944
#![feature(trusted_len)]
5045
#![feature(vec_remove_item)]
5146
#![feature(stmt_expr_attributes)]
52-
#![feature(integer_atomics)]
5347
#![feature(test)]
5448
#![feature(in_band_lifetimes)]
5549
#![feature(crate_visibility_modifier)]
56-
#![feature(log_syntax)]
5750
#![feature(associated_type_bounds)]
5851
#![feature(rustc_attrs)]
5952
#![feature(hash_raw_entry)]

src/librustc/traits/select.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3472,7 +3472,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
34723472
// that order.
34733473
let predicates = tcx.predicates_of(def_id);
34743474
assert_eq!(predicates.parent, None);
3475-
let mut obligations = Vec::new();
3475+
let mut obligations = Vec::with_capacity(predicates.predicates.len());
34763476
for (predicate, _) in predicates.predicates {
34773477
let predicate = normalize_with_depth_to(
34783478
self,

src/librustc/traits/specialize/specialization_graph.rs

+43-30
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ impl<'tcx> Children {
8686
impl_def_id, simplified_self, possible_sibling,
8787
);
8888

89-
let overlap_error = |overlap: traits::coherence::OverlapResult<'_>| {
90-
// Found overlap, but no specialization; error out.
89+
let create_overlap_error = |overlap: traits::coherence::OverlapResult<'_>| {
9190
let trait_ref = overlap.impl_header.trait_ref.unwrap();
9291
let self_ty = trait_ref.self_ty();
92+
9393
OverlapError {
9494
with_impl: possible_sibling,
9595
trait_desc: trait_ref.print_only_trait_path().to_string(),
@@ -106,21 +106,49 @@ impl<'tcx> Children {
106106
}
107107
};
108108

109-
let allowed_to_overlap =
110-
tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling);
109+
let report_overlap_error = |overlap: traits::coherence::OverlapResult<'_>,
110+
last_lint: &mut _| {
111+
// Found overlap, but no specialization; error out or report future-compat warning.
112+
113+
// Do we *still* get overlap if we disable the future-incompatible modes?
114+
let should_err = traits::overlapping_impls(
115+
tcx,
116+
possible_sibling,
117+
impl_def_id,
118+
traits::SkipLeakCheck::default(),
119+
|_| true,
120+
|| false,
121+
);
122+
123+
let error = create_overlap_error(overlap);
124+
125+
if should_err {
126+
Err(error)
127+
} else {
128+
*last_lint = Some(FutureCompatOverlapError {
129+
error,
130+
kind: FutureCompatOverlapErrorKind::LeakCheck,
131+
});
132+
133+
Ok((false, false))
134+
}
135+
};
111136

137+
let last_lint_mut = &mut last_lint;
112138
let (le, ge) = traits::overlapping_impls(
113139
tcx,
114140
possible_sibling,
115141
impl_def_id,
116-
traits::SkipLeakCheck::default(),
142+
traits::SkipLeakCheck::Yes,
117143
|overlap| {
118-
if let Some(overlap_kind) = &allowed_to_overlap {
144+
if let Some(overlap_kind) =
145+
tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling)
146+
{
119147
match overlap_kind {
120148
ty::ImplOverlapKind::Permitted { marker: _ } => {}
121149
ty::ImplOverlapKind::Issue33140 => {
122-
last_lint = Some(FutureCompatOverlapError {
123-
error: overlap_error(overlap),
150+
*last_lint_mut = Some(FutureCompatOverlapError {
151+
error: create_overlap_error(overlap),
124152
kind: FutureCompatOverlapErrorKind::Issue33140,
125153
});
126154
}
@@ -132,7 +160,11 @@ impl<'tcx> Children {
132160
let le = tcx.specializes((impl_def_id, possible_sibling));
133161
let ge = tcx.specializes((possible_sibling, impl_def_id));
134162

135-
if le == ge { Err(overlap_error(overlap)) } else { Ok((le, ge)) }
163+
if le == ge {
164+
report_overlap_error(overlap, last_lint_mut)
165+
} else {
166+
Ok((le, ge))
167+
}
136168
},
137169
|| Ok((false, false)),
138170
)?;
@@ -153,27 +185,8 @@ impl<'tcx> Children {
153185

154186
replace_children.push(possible_sibling);
155187
} else {
156-
if let None = allowed_to_overlap {
157-
// Do future-compat checks for overlap.
158-
159-
if last_lint.is_none() {
160-
traits::overlapping_impls(
161-
tcx,
162-
possible_sibling,
163-
impl_def_id,
164-
traits::SkipLeakCheck::Yes,
165-
|overlap| {
166-
last_lint = Some(FutureCompatOverlapError {
167-
error: overlap_error(overlap),
168-
kind: FutureCompatOverlapErrorKind::LeakCheck,
169-
});
170-
},
171-
|| (),
172-
);
173-
}
174-
}
175-
176-
// no overlap (error bailed already via ?)
188+
// Either there's no overlap, or the overlap was already reported by
189+
// `overlap_error`.
177190
}
178191
}
179192

src/librustc/traits/wf.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,15 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
143143
let cause = self.cause(traits::MiscObligation);
144144
let infcx = &mut self.infcx;
145145
let param_env = self.param_env;
146-
let mut obligations = Vec::new();
147-
self.out.iter().inspect(|pred| assert!(!pred.has_escaping_bound_vars())).for_each(|pred| {
146+
let mut obligations = Vec::with_capacity(self.out.len());
147+
for pred in &self.out {
148+
assert!(!pred.has_escaping_bound_vars());
148149
let mut selcx = traits::SelectionContext::new(infcx);
149150
let i = obligations.len();
150151
let value =
151152
traits::normalize_to(&mut selcx, param_env, cause.clone(), pred, &mut obligations);
152153
obligations.insert(i, value);
153-
});
154+
}
154155
obligations
155156
}
156157

src/librustc_codegen_llvm/lib.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,11 @@
66
77
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
88
#![feature(bool_to_option)]
9-
#![feature(box_patterns)]
10-
#![feature(box_syntax)]
119
#![feature(const_cstr_unchecked)]
1210
#![feature(crate_visibility_modifier)]
1311
#![feature(extern_types)]
1412
#![feature(in_band_lifetimes)]
15-
#![feature(libc)]
1613
#![feature(nll)]
17-
#![feature(optin_builtin_traits)]
18-
#![feature(concat_idents)]
19-
#![feature(link_args)]
20-
#![feature(static_nobundle)]
2114
#![feature(trusted_len)]
2215
#![recursion_limit = "256"]
2316

@@ -196,7 +189,7 @@ unsafe impl Sync for LlvmCodegenBackend {}
196189

197190
impl LlvmCodegenBackend {
198191
pub fn new() -> Box<dyn CodegenBackend> {
199-
box LlvmCodegenBackend(())
192+
Box::new(LlvmCodegenBackend(()))
200193
}
201194
}
202195

@@ -245,7 +238,7 @@ impl CodegenBackend for LlvmCodegenBackend {
245238
}
246239

247240
fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
248-
box metadata::LlvmMetadataLoader
241+
Box::new(metadata::LlvmMetadataLoader)
249242
}
250243

251244
fn provide(&self, providers: &mut ty::query::Providers<'_>) {
@@ -262,12 +255,12 @@ impl CodegenBackend for LlvmCodegenBackend {
262255
metadata: EncodedMetadata,
263256
need_metadata_module: bool,
264257
) -> Box<dyn Any> {
265-
box rustc_codegen_ssa::base::codegen_crate(
258+
Box::new(rustc_codegen_ssa::base::codegen_crate(
266259
LlvmCodegenBackend(()),
267260
tcx,
268261
metadata,
269262
need_metadata_module,
270-
)
263+
))
271264
}
272265

273266
fn join_codegen(

src/librustc_codegen_llvm/metadata.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ impl MetadataLoader for LlvmMetadataLoader {
2222
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
2323
// internally to read the file. We also avoid even using a memcpy by
2424
// just keeping the archive along while the metadata is in use.
25-
let archive = ArchiveRO::open(filename).map(|ar| OwningRef::new(box ar)).map_err(|e| {
26-
debug!("llvm didn't like `{}`: {}", filename.display(), e);
27-
format!("failed to read rlib metadata in '{}': {}", filename.display(), e)
28-
})?;
25+
let archive =
26+
ArchiveRO::open(filename).map(|ar| OwningRef::new(Box::new(ar))).map_err(|e| {
27+
debug!("llvm didn't like `{}`: {}", filename.display(), e);
28+
format!("failed to read rlib metadata in '{}': {}", filename.display(), e)
29+
})?;
2930
let buf: OwningRef<_, [u8]> = archive.try_map(|ar| {
3031
ar.iter()
3132
.filter_map(|s| s.ok())
@@ -44,9 +45,10 @@ impl MetadataLoader for LlvmMetadataLoader {
4445
let buf = path_to_c_string(filename);
4546
let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr())
4647
.ok_or_else(|| format!("error reading library: '{}'", filename.display()))?;
47-
let of = ObjectFile::new(mb).map(|of| OwningRef::new(box of)).ok_or_else(|| {
48-
format!("provided path not an object file: '{}'", filename.display())
49-
})?;
48+
let of =
49+
ObjectFile::new(mb).map(|of| OwningRef::new(Box::new(of))).ok_or_else(|| {
50+
format!("provided path not an object file: '{}'", filename.display())
51+
})?;
5052
let buf = of.try_map(|of| search_meta_section(of, target, filename))?;
5153
Ok(rustc_erase_owner!(buf))
5254
}

src/librustc_codegen_ssa/lib.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
22
#![feature(bool_to_option)]
33
#![feature(box_patterns)]
4-
#![feature(box_syntax)]
5-
#![feature(core_intrinsics)]
6-
#![feature(libc)]
7-
#![feature(stmt_expr_attributes)]
84
#![feature(try_blocks)]
95
#![feature(in_band_lifetimes)]
106
#![feature(nll)]

src/librustc_codegen_utils/lib.rs

-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@
33
//! This API is completely unstable and subject to change.
44
55
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
6-
#![feature(arbitrary_self_types)]
7-
#![feature(box_patterns)]
8-
#![feature(box_syntax)]
9-
#![feature(core_intrinsics)]
106
#![feature(never_type)]
117
#![feature(nll)]
128
#![feature(in_band_lifetimes)]

0 commit comments

Comments
 (0)