Skip to content

Commit 4c55c83

Browse files
committed
Auto merge of rust-lang#93655 - matthiaskrgr:rollup-dm88b02, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#90132 (Stabilize `-Z instrument-coverage` as `-C instrument-coverage`) - rust-lang#91589 (impl `Arc::unwrap_or_clone`) - rust-lang#93495 (kmc-solid: Fix off-by-one error in `SystemTime::now`) - rust-lang#93576 (Emit more valid HTML from rustdoc) - rust-lang#93608 (Clean up `find_library_crate`) - rust-lang#93612 (doc: use U+2212 for minus sign in integer MIN/MAX text) - rust-lang#93615 (Fix `isize` optimization in `StableHasher` for big-endian architectures) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 71226d7 + 2d62bd0 commit 4c55c83

File tree

63 files changed

+408
-338
lines changed

Some content is hidden

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

63 files changed

+408
-338
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
3939
// LLVM 12.
4040
let version = coverageinfo::mapping_version();
4141
if version < 4 {
42-
tcx.sess.fatal("rustc option `-Z instrument-coverage` requires LLVM 12 or higher.");
42+
tcx.sess.fatal("rustc option `-C instrument-coverage` requires LLVM 12 or higher.");
4343
}
4444

4545
debug!("Generating coverage map for CodegenUnit: `{}`", cx.codegen_unit.name());
@@ -274,7 +274,7 @@ fn save_function_record(
274274
/// (functions referenced by other "used" or public items). Any other functions considered unused,
275275
/// or "Unreachable", were still parsed and processed through the MIR stage, but were not
276276
/// codegenned. (Note that `-Clink-dead-code` can force some unused code to be codegenned, but
277-
/// that flag is known to cause other errors, when combined with `-Z instrument-coverage`; and
277+
/// that flag is known to cause other errors, when combined with `-C instrument-coverage`; and
278278
/// `-Clink-dead-code` will not generate code for unused generic functions.)
279279
///
280280
/// We can find the unused functions (including generic functions) by the set difference of all MIR

compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ pub trait CoverageInfoMethods<'tcx>: BackendTypes {
2222

2323
pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
2424
/// Returns true if the function source hash was added to the coverage map (even if it had
25-
/// already been added, for this instance). Returns false *only* if `-Z instrument-coverage` is
25+
/// already been added, for this instance). Returns false *only* if `-C instrument-coverage` is
2626
/// not enabled (a coverage map is not being generated).
2727
fn set_function_source_hash(
2828
&mut self,
2929
instance: Instance<'tcx>,
3030
function_source_hash: u64,
3131
) -> bool;
3232

33-
/// Returns true if the counter was added to the coverage map; false if `-Z instrument-coverage`
33+
/// Returns true if the counter was added to the coverage map; false if `-C instrument-coverage`
3434
/// is not enabled (a coverage map is not being generated).
3535
fn add_coverage_counter(
3636
&mut self,
@@ -40,7 +40,7 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
4040
) -> bool;
4141

4242
/// Returns true if the expression was added to the coverage map; false if
43-
/// `-Z instrument-coverage` is not enabled (a coverage map is not being generated).
43+
/// `-C instrument-coverage` is not enabled (a coverage map is not being generated).
4444
fn add_coverage_counter_expression(
4545
&mut self,
4646
instance: Instance<'tcx>,
@@ -51,7 +51,7 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
5151
region: Option<CodeRegion>,
5252
) -> bool;
5353

54-
/// Returns true if the region was added to the coverage map; false if `-Z instrument-coverage`
54+
/// Returns true if the region was added to the coverage map; false if `-C instrument-coverage`
5555
/// is not enabled (a coverage map is not being generated).
5656
fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool;
5757
}

compiler/rustc_data_structures/src/stable_hasher.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -133,18 +133,18 @@ impl Hasher for StableHasher {
133133

134134
#[inline]
135135
fn write_isize(&mut self, i: isize) {
136-
// Always treat isize as i64 so we get the same results on 32 and 64 bit
136+
// Always treat isize as a 64-bit number so we get the same results on 32 and 64 bit
137137
// platforms. This is important for symbol hashes when cross compiling,
138138
// for example. Sign extending here is preferable as it means that the
139139
// same negative number hashes the same on both 32 and 64 bit platforms.
140-
let value = (i as i64).to_le() as u64;
140+
let value = i as u64;
141141

142142
// Cold path
143143
#[cold]
144144
#[inline(never)]
145145
fn hash_value(state: &mut SipHasher128, value: u64) {
146146
state.write_u8(0xFF);
147-
state.write_u64(value);
147+
state.write_u64(value.to_le());
148148
}
149149

150150
// `isize` values often seem to have a small (positive) numeric value in practice.
@@ -161,6 +161,10 @@ impl Hasher for StableHasher {
161161
// 8 bytes. Since this prefix cannot occur when we hash a single byte, when we hash two
162162
// `isize`s that fit within a different amount of bytes, they should always produce a different
163163
// byte stream for the hasher.
164+
//
165+
// To ensure that this optimization hashes the exact same bytes on both little-endian and
166+
// big-endian architectures, we compare the value with 0xFF before we convert the number
167+
// into a unified representation (little-endian).
164168
if value < 0xFF {
165169
self.state.write_u8(value as u8);
166170
} else {

compiler/rustc_data_structures/src/stable_hasher/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,5 @@ fn test_isize_compression() {
159159
check_hash(0xAAAA, 0xAAAAAA);
160160
check_hash(0xAAAAAA, 0xAAAAAAAA);
161161
check_hash(0xFF, 0xFFFFFFFFFFFFFFFF);
162+
check_hash(u64::MAX /* -1 */, 1);
162163
}

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ fn test_codegen_options_tracking_hash() {
575575
tracked!(force_frame_pointers, Some(false));
576576
tracked!(force_unwind_tables, Some(true));
577577
tracked!(inline_threshold, Some(0xf007ba11));
578+
tracked!(instrument_coverage, Some(InstrumentCoverage::All));
578579
tracked!(linker_plugin_lto, LinkerPluginLto::LinkerPluginAuto);
579580
tracked!(link_dead_code, Some(true));
580581
tracked!(llvm_args, vec![String::from("1"), String::from("2")]);

compiler/rustc_metadata/src/locator.rs

+53-44
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ use rustc_data_structures::sync::MetadataRef;
223223
use rustc_errors::{struct_span_err, FatalError};
224224
use rustc_session::config::{self, CrateType};
225225
use rustc_session::cstore::{CrateSource, MetadataLoader};
226-
use rustc_session::filesearch::{FileDoesntMatch, FileMatches, FileSearch};
226+
use rustc_session::filesearch::FileSearch;
227227
use rustc_session::search_paths::PathKind;
228228
use rustc_session::utils::CanonicalizedPath;
229229
use rustc_session::Session;
@@ -371,15 +371,20 @@ impl<'a> CrateLocator<'a> {
371371
extra_prefix: &str,
372372
seen_paths: &mut FxHashSet<PathBuf>,
373373
) -> Result<Option<Library>, CrateError> {
374-
// want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
375-
let dylib_prefix = format!("{}{}{}", self.target.dll_prefix, self.crate_name, extra_prefix);
376-
let rlib_prefix = format!("lib{}{}", self.crate_name, extra_prefix);
374+
let rmeta_prefix = &format!("lib{}{}", self.crate_name, extra_prefix);
375+
let rlib_prefix = rmeta_prefix;
376+
let dylib_prefix =
377+
&format!("{}{}{}", self.target.dll_prefix, self.crate_name, extra_prefix);
377378
let staticlib_prefix =
378-
format!("{}{}{}", self.target.staticlib_prefix, self.crate_name, extra_prefix);
379+
&format!("{}{}{}", self.target.staticlib_prefix, self.crate_name, extra_prefix);
380+
381+
let rmeta_suffix = ".rmeta";
382+
let rlib_suffix = ".rlib";
383+
let dylib_suffix = &self.target.dll_suffix;
384+
let staticlib_suffix = &self.target.staticlib_suffix;
379385

380386
let mut candidates: FxHashMap<_, (FxHashMap<_, _>, FxHashMap<_, _>, FxHashMap<_, _>)> =
381387
Default::default();
382-
let mut staticlibs = vec![];
383388

384389
// First, find all possible candidate rlibs and dylibs purely based on
385390
// the name of the files themselves. We're trying to match against an
@@ -394,46 +399,50 @@ impl<'a> CrateLocator<'a> {
394399
// of the crate id (path/name/id).
395400
//
396401
// The goal of this step is to look at as little metadata as possible.
397-
self.filesearch.search(|spf, kind| {
398-
let file = match &spf.file_name_str {
399-
None => return FileDoesntMatch,
400-
Some(file) => file,
401-
};
402-
let (hash, found_kind) = if file.starts_with(&rlib_prefix) && file.ends_with(".rlib") {
403-
(&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib)
404-
} else if file.starts_with(&rlib_prefix) && file.ends_with(".rmeta") {
405-
(&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta)
406-
} else if file.starts_with(&dylib_prefix) && file.ends_with(&self.target.dll_suffix) {
407-
(
408-
&file[(dylib_prefix.len())..(file.len() - self.target.dll_suffix.len())],
409-
CrateFlavor::Dylib,
410-
)
411-
} else {
412-
if file.starts_with(&staticlib_prefix)
413-
&& file.ends_with(&self.target.staticlib_suffix)
414-
{
415-
staticlibs
416-
.push(CrateMismatch { path: spf.path.clone(), got: "static".to_string() });
417-
}
418-
return FileDoesntMatch;
419-
};
402+
// Unfortunately, the prefix-based matching sometimes is over-eager.
403+
// E.g. if `rlib_suffix` is `libstd` it'll match the file
404+
// `libstd_detect-8d6701fb958915ad.rlib` (incorrect) as well as
405+
// `libstd-f3ab5b1dea981f17.rlib` (correct). But this is hard to avoid
406+
// given that `extra_filename` comes from the `-C extra-filename`
407+
// option and thus can be anything, and the incorrect match will be
408+
// handled safely in `extract_one`.
409+
for search_path in self.filesearch.search_paths() {
410+
debug!("searching {}", search_path.dir.display());
411+
for spf in search_path.files.iter() {
412+
debug!("testing {}", spf.path.display());
413+
414+
let f = &spf.file_name_str;
415+
let (hash, kind) = if f.starts_with(rlib_prefix) && f.ends_with(rlib_suffix) {
416+
(&f[rlib_prefix.len()..(f.len() - rlib_suffix.len())], CrateFlavor::Rlib)
417+
} else if f.starts_with(rmeta_prefix) && f.ends_with(rmeta_suffix) {
418+
(&f[rmeta_prefix.len()..(f.len() - rmeta_suffix.len())], CrateFlavor::Rmeta)
419+
} else if f.starts_with(dylib_prefix) && f.ends_with(dylib_suffix) {
420+
(&f[dylib_prefix.len()..(f.len() - dylib_suffix.len())], CrateFlavor::Dylib)
421+
} else {
422+
if f.starts_with(staticlib_prefix) && f.ends_with(staticlib_suffix) {
423+
self.crate_rejections.via_kind.push(CrateMismatch {
424+
path: spf.path.clone(),
425+
got: "static".to_string(),
426+
});
427+
}
428+
continue;
429+
};
420430

421-
info!("lib candidate: {}", spf.path.display());
431+
info!("lib candidate: {}", spf.path.display());
422432

423-
let (rlibs, rmetas, dylibs) = candidates.entry(hash.to_string()).or_default();
424-
let path = fs::canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone());
425-
if seen_paths.contains(&path) {
426-
return FileDoesntMatch;
427-
};
428-
seen_paths.insert(path.clone());
429-
match found_kind {
430-
CrateFlavor::Rlib => rlibs.insert(path, kind),
431-
CrateFlavor::Rmeta => rmetas.insert(path, kind),
432-
CrateFlavor::Dylib => dylibs.insert(path, kind),
433-
};
434-
FileMatches
435-
});
436-
self.crate_rejections.via_kind.extend(staticlibs);
433+
let (rlibs, rmetas, dylibs) = candidates.entry(hash.to_string()).or_default();
434+
let path = fs::canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone());
435+
if seen_paths.contains(&path) {
436+
continue;
437+
};
438+
seen_paths.insert(path.clone());
439+
match kind {
440+
CrateFlavor::Rlib => rlibs.insert(path, search_path.kind),
441+
CrateFlavor::Rmeta => rmetas.insert(path, search_path.kind),
442+
CrateFlavor::Dylib => dylibs.insert(path, search_path.kind),
443+
};
444+
}
445+
}
437446

438447
// We have now collected all known libraries into a set of candidates
439448
// keyed of the filename hash listed. For each filename, we also have a

compiler/rustc_middle/src/mir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1577,7 +1577,7 @@ pub enum StatementKind<'tcx> {
15771577
/// - `Bivariant` -- no effect
15781578
AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>, ty::Variance),
15791579

1580-
/// Marks the start of a "coverage region", injected with '-Zinstrument-coverage'. A
1580+
/// Marks the start of a "coverage region", injected with '-Cinstrument-coverage'. A
15811581
/// `Coverage` statement carries metadata about the coverage region, used to inject a coverage
15821582
/// map into the binary. If `Coverage::kind` is a `Counter`, the statement also generates
15831583
/// executable code, to increment a counter variable at runtime, each time the code region is

compiler/rustc_middle/src/mir/query.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ pub struct DestructuredConst<'tcx> {
390390
}
391391

392392
/// Coverage information summarized from a MIR if instrumented for source code coverage (see
393-
/// compiler option `-Zinstrument-coverage`). This information is generated by the
393+
/// compiler option `-Cinstrument-coverage`). This information is generated by the
394394
/// `InstrumentCoverage` MIR pass and can be retrieved via the `coverageinfo` query.
395395
#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable)]
396396
pub struct CoverageInfo {

compiler/rustc_middle/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ rustc_queries! {
384384
}
385385

386386
/// Returns coverage summary info for a function, after executing the `InstrumentCoverage`
387-
/// MIR pass (assuming the -Zinstrument-coverage option is enabled).
387+
/// MIR pass (assuming the -Cinstrument-coverage option is enabled).
388388
query coverageinfo(key: ty::InstanceDef<'tcx>) -> mir::CoverageInfo {
389389
desc { |tcx| "retrieving coverage info from MIR for `{}`", tcx.def_path_str(key.def_id()) }
390390
storage(ArenaCacheSelector<'tcx>)

compiler/rustc_mir_transform/src/coverage/debug.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//!
44
//! To enable coverage, include the rustc command line option:
55
//!
6-
//! * `-Z instrument-coverage`
6+
//! * `-C instrument-coverage`
77
//!
88
//! MIR Dump Files, with additional `CoverageGraph` graphviz and `CoverageSpan` spanview
99
//! ------------------------------------------------------------------------------------

compiler/rustc_mir_transform/src/simplify.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
303303
/// evaluation: `if false { ... }`.
304304
///
305305
/// Those statements are bypassed by redirecting paths in the CFG around the
306-
/// `dead blocks`; but with `-Z instrument-coverage`, the dead blocks usually
306+
/// `dead blocks`; but with `-C instrument-coverage`, the dead blocks usually
307307
/// include `Coverage` statements representing the Rust source code regions to
308308
/// be counted at runtime. Without these `Coverage` statements, the regions are
309309
/// lost, and the Rust source code will show no coverage information.

compiler/rustc_session/src/config.rs

+40-14
Original file line numberDiff line numberDiff line change
@@ -127,16 +127,16 @@ pub enum MirSpanview {
127127
Block,
128128
}
129129

130-
/// The different settings that the `-Z instrument-coverage` flag can have.
130+
/// The different settings that the `-C instrument-coverage` flag can have.
131131
///
132-
/// Coverage instrumentation now supports combining `-Z instrument-coverage`
132+
/// Coverage instrumentation now supports combining `-C instrument-coverage`
133133
/// with compiler and linker optimization (enabled with `-O` or `-C opt-level=1`
134134
/// and higher). Nevertheless, there are many variables, depending on options
135135
/// selected, code structure, and enabled attributes. If errors are encountered,
136136
/// either while compiling or when generating `llvm-cov show` reports, consider
137137
/// lowering the optimization level, including or excluding `-C link-dead-code`,
138-
/// or using `-Z instrument-coverage=except-unused-functions` or `-Z
139-
/// instrument-coverage=except-unused-generics`.
138+
/// or using `-Zunstable-options -C instrument-coverage=except-unused-functions`
139+
/// or `-Zunstable-options -C instrument-coverage=except-unused-generics`.
140140
///
141141
/// Note that `ExceptUnusedFunctions` means: When `mapgen.rs` generates the
142142
/// coverage map, it will not attempt to generate synthetic functions for unused
@@ -148,13 +148,13 @@ pub enum MirSpanview {
148148
/// unless the function has type parameters.
149149
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
150150
pub enum InstrumentCoverage {
151-
/// Default `-Z instrument-coverage` or `-Z instrument-coverage=statement`
151+
/// Default `-C instrument-coverage` or `-C instrument-coverage=statement`
152152
All,
153-
/// `-Z instrument-coverage=except-unused-generics`
153+
/// `-Zunstable-options -C instrument-coverage=except-unused-generics`
154154
ExceptUnusedGenerics,
155-
/// `-Z instrument-coverage=except-unused-functions`
155+
/// `-Zunstable-options -C instrument-coverage=except-unused-functions`
156156
ExceptUnusedFunctions,
157-
/// `-Z instrument-coverage=off` (or `no`, etc.)
157+
/// `-C instrument-coverage=off` (or `no`, etc.)
158158
Off,
159159
}
160160

@@ -2195,18 +2195,44 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
21952195
_ => {}
21962196
}
21972197

2198-
if debugging_opts.instrument_coverage.is_some()
2199-
&& debugging_opts.instrument_coverage != Some(InstrumentCoverage::Off)
2200-
{
2198+
// Handle both `-Z instrument-coverage` and `-C instrument-coverage`; the latter takes
2199+
// precedence.
2200+
match (cg.instrument_coverage, debugging_opts.instrument_coverage) {
2201+
(Some(ic_c), Some(ic_z)) if ic_c != ic_z => {
2202+
early_error(
2203+
error_format,
2204+
"incompatible values passed for `-C instrument-coverage` \
2205+
and `-Z instrument-coverage`",
2206+
);
2207+
}
2208+
(Some(InstrumentCoverage::Off | InstrumentCoverage::All), _) => {}
2209+
(Some(_), _) if !debugging_opts.unstable_options => {
2210+
early_error(
2211+
error_format,
2212+
"`-C instrument-coverage=except-*` requires `-Z unstable-options`",
2213+
);
2214+
}
2215+
(None, None) => {}
2216+
(None, ic) => {
2217+
early_warn(
2218+
error_format,
2219+
"`-Z instrument-coverage` is deprecated; use `-C instrument-coverage`",
2220+
);
2221+
cg.instrument_coverage = ic;
2222+
}
2223+
_ => {}
2224+
}
2225+
2226+
if cg.instrument_coverage.is_some() && cg.instrument_coverage != Some(InstrumentCoverage::Off) {
22012227
if cg.profile_generate.enabled() || cg.profile_use.is_some() {
22022228
early_error(
22032229
error_format,
2204-
"option `-Z instrument-coverage` is not compatible with either `-C profile-use` \
2230+
"option `-C instrument-coverage` is not compatible with either `-C profile-use` \
22052231
or `-C profile-generate`",
22062232
);
22072233
}
22082234

2209-
// `-Z instrument-coverage` implies `-C symbol-mangling-version=v0` - to ensure consistent
2235+
// `-C instrument-coverage` implies `-C symbol-mangling-version=v0` - to ensure consistent
22102236
// and reversible name mangling. Note, LLVM coverage tools can analyze coverage over
22112237
// multiple runs, including some changes to source code; so mangled names must be consistent
22122238
// across compilations.
@@ -2215,7 +2241,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
22152241
Some(SymbolManglingVersion::Legacy) => {
22162242
early_warn(
22172243
error_format,
2218-
"-Z instrument-coverage requires symbol mangling version `v0`, \
2244+
"-C instrument-coverage requires symbol mangling version `v0`, \
22192245
but `-C symbol-mangling-version=legacy` was specified",
22202246
);
22212247
}

0 commit comments

Comments
 (0)