Skip to content

Rollup of 10 pull requests #134289

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

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
612adbb
Bounds-check with PtrMetadata instead of Len in MIR
scottmcm Dec 2, 2024
2ce89ee
Add a test for mangling of named constants in const generics and arra…
oli-obk Dec 9, 2024
9ecdc54
Try to evaluate constants in legacy mangling
oli-obk Dec 9, 2024
eb10db0
Make some types and methods related to Polonius + Miri public.
willcrichton Dec 12, 2024
de53fe2
coverage: Tidy up creation of covmap records
Zalathar Dec 12, 2024
5f5745b
coverage: Tidy up creation of covfun records
Zalathar Dec 12, 2024
2a6a7be
don't show the full linker args unless `--verbose` is passed
jyn514 Dec 25, 2023
3a90c47
Fix powerpc64 big-endian FreeBSD ABI
taiki-e Oct 25, 2024
7fb2fc0
feat: clarify how to use `black_box()`
BD103 Dec 5, 2024
2e412fe
Remove `Lexer`'s dependency on `Parser`.
nnethercote Dec 12, 2024
8200c1e
rustdoc-search: fix mismatched path when parent re-exported twice
notriddle Dec 12, 2024
4d5d470
Make BorrowSet/BorrowData fields accessible via public getters
willcrichton Dec 12, 2024
65a54a7
Tweak multispan rendering
estebank Dec 11, 2024
49a22a4
Filter empty lines, comments and delimiters from previous to last mul…
estebank Dec 11, 2024
38249be
Don't retag the `PtrMetadata(&raw const *_n)` in slice indexing
scottmcm Dec 13, 2024
98318c5
rustdoc-search: update test with now-shorter function path
notriddle Dec 13, 2024
ad82d9f
Fix miri tests
estebank Dec 12, 2024
9f1044e
Account for `///` when rendering multiline spans
estebank Dec 13, 2024
d2a98f7
Update compiler/rustc_const_eval/src/interpret/step.rs
scottmcm Dec 13, 2024
96dbb58
Rollup merge of #132150 - taiki-e:ppc64-freebsd-abi, r=pnkfelix
Zalathar Dec 14, 2024
5d965bf
Rollup merge of #133633 - jyn514:hide-linker-args, r=bjorn3,jyn514
Zalathar Dec 14, 2024
7a8f680
Rollup merge of #133734 - scottmcm:lower-indexing-to-ptrmetadata, r=d…
Zalathar Dec 14, 2024
4a9526d
Rollup merge of #133942 - BD103:black-box-docs, r=saethlin
Zalathar Dec 14, 2024
3b5b129
Rollup merge of #134081 - oli-obk:push-prpsqxxynxnq, r=BoxyUwU
Zalathar Dec 14, 2024
4fcc959
Rollup merge of #134181 - estebank:trim-render, r=oli-obk
Zalathar Dec 14, 2024
8e2a805
Rollup merge of #134191 - willcrichton:dev, r=RalfJung,lqd
Zalathar Dec 14, 2024
a326ab7
Rollup merge of #134192 - nnethercote:rm-Lexer-Parser-dep, r=compiler…
Zalathar Dec 14, 2024
b3c2d8f
Rollup merge of #134208 - Zalathar:covmap-covfun, r=compiler-errors
Zalathar Dec 14, 2024
086c41b
Rollup merge of #134231 - notriddle:notriddle/mismatched-path, r=Guil…
Zalathar Dec 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
50 changes: 48 additions & 2 deletions compiler/rustc_borrowck/src/borrow_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,25 @@ pub struct BorrowSet<'tcx> {
pub(crate) locals_state_at_exit: LocalsStateAtExit,
}

// These methods are public to support borrowck consumers.
impl<'tcx> BorrowSet<'tcx> {
pub fn location_map(&self) -> &FxIndexMap<Location, BorrowData<'tcx>> {
&self.location_map
}

pub fn activation_map(&self) -> &FxIndexMap<Location, Vec<BorrowIndex>> {
&self.activation_map
}

pub fn local_map(&self) -> &FxIndexMap<mir::Local, FxIndexSet<BorrowIndex>> {
&self.local_map
}

pub fn locals_state_at_exit(&self) -> &LocalsStateAtExit {
&self.locals_state_at_exit
}
}

impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
type Output = BorrowData<'tcx>;

Expand All @@ -45,7 +64,7 @@ impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
/// Location where a two-phase borrow is activated, if a borrow
/// is in fact a two-phase borrow.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub(crate) enum TwoPhaseActivation {
pub enum TwoPhaseActivation {
NotTwoPhase,
NotActivated,
ActivatedAt(Location),
Expand All @@ -68,6 +87,33 @@ pub struct BorrowData<'tcx> {
pub(crate) assigned_place: mir::Place<'tcx>,
}

// These methods are public to support borrowck consumers.
impl<'tcx> BorrowData<'tcx> {
pub fn reserve_location(&self) -> Location {
self.reserve_location
}

pub fn activation_location(&self) -> TwoPhaseActivation {
self.activation_location
}

pub fn kind(&self) -> mir::BorrowKind {
self.kind
}

pub fn region(&self) -> RegionVid {
self.region
}

pub fn borrowed_place(&self) -> mir::Place<'tcx> {
self.borrowed_place
}

pub fn assigned_place(&self) -> mir::Place<'tcx> {
self.assigned_place
}
}

impl<'tcx> fmt::Display for BorrowData<'tcx> {
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
let kind = match self.kind {
Expand Down Expand Up @@ -120,7 +166,7 @@ impl LocalsStateAtExit {
}

impl<'tcx> BorrowSet<'tcx> {
pub(crate) fn build(
pub fn build(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
locals_are_invalidated_at_exit: bool,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/consumers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::mir::{Body, Promoted};
use rustc_middle::ty::TyCtxt;

pub use super::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation};
pub use super::constraints::OutlivesConstraint;
pub use super::dataflow::{BorrowIndex, Borrows, calculate_borrows_out_of_scope_at_location};
pub use super::facts::{AllFacts as PoloniusInput, RustcFacts};
pub use super::facts::{AllFacts as PoloniusInput, PoloniusRegionVid, RustcFacts};
pub use super::location::{LocationTable, RichLocation};
pub use super::nll::PoloniusOutput;
pub use super::place_ext::PlaceExt;
pub use super::places_conflict::{PlaceConflictBias, places_conflict};
pub use super::region_infer::RegionInferenceContext;
use crate::borrow_set::BorrowSet;

/// Options determining the output behavior of [`get_body_with_borrowck_facts`].
///
Expand Down
67 changes: 32 additions & 35 deletions compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {

// Encode all filenames referenced by coverage mappings in this CGU.
let filenames_buffer = global_file_table.make_filenames_buffer(tcx);

let filenames_size = filenames_buffer.len();
let filenames_val = cx.const_bytes(&filenames_buffer);
let filenames_ref = llvm_cov::hash_bytes(&filenames_buffer);
// The `llvm-cov` tool uses this hash to associate each covfun record with
// its corresponding filenames table, since the final binary will typically
// contain multiple covmap records from different compilation units.
let filenames_hash = llvm_cov::hash_bytes(&filenames_buffer);

let mut unused_function_names = Vec::new();

Expand All @@ -101,7 +101,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
for covfun in &covfun_records {
unused_function_names.extend(covfun.mangled_function_name_if_unused());

covfun::generate_covfun_record(cx, filenames_ref, covfun)
covfun::generate_covfun_record(cx, filenames_hash, covfun)
}

// For unused functions, we need to take their mangled names and store them
Expand All @@ -126,7 +126,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
// Generate the coverage map header, which contains the filenames used by
// this CGU's coverage mappings, and store it in a well-known global.
// (This is skipped if we returned early due to having no covfun records.)
generate_covmap_record(cx, covmap_version, filenames_size, filenames_val);
generate_covmap_record(cx, covmap_version, &filenames_buffer);
}

/// Maps "global" (per-CGU) file ID numbers to their underlying filenames.
Expand Down Expand Up @@ -225,38 +225,35 @@ fn span_file_name(tcx: TyCtxt<'_>, span: Span) -> Symbol {
/// Generates the contents of the covmap record for this CGU, which mostly
/// consists of a header and a list of filenames. The record is then stored
/// as a global variable in the `__llvm_covmap` section.
fn generate_covmap_record<'ll>(
cx: &CodegenCx<'ll, '_>,
version: u32,
filenames_size: usize,
filenames_val: &'ll llvm::Value,
) {
debug!("cov map: filenames_size = {}, 0-based version = {}", filenames_size, version);

// Create the coverage data header (Note, fields 0 and 2 are now always zero,
// as of `llvm::coverage::CovMapVersion::Version4`.)
let zero_was_n_records_val = cx.const_u32(0);
let filenames_size_val = cx.const_u32(filenames_size as u32);
let zero_was_coverage_size_val = cx.const_u32(0);
let version_val = cx.const_u32(version);
let cov_data_header_val = cx.const_struct(
&[zero_was_n_records_val, filenames_size_val, zero_was_coverage_size_val, version_val],
/*packed=*/ false,
fn generate_covmap_record<'ll>(cx: &CodegenCx<'ll, '_>, version: u32, filenames_buffer: &[u8]) {
// A covmap record consists of four target-endian u32 values, followed by
// the encoded filenames table. Two of the header fields are unused in
// modern versions of the LLVM coverage mapping format, and are always 0.
// <https://llvm.org/docs/CoverageMappingFormat.html#llvm-ir-representation>
// See also `src/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp`.
let covmap_header = cx.const_struct(
&[
cx.const_u32(0), // (unused)
cx.const_u32(filenames_buffer.len() as u32),
cx.const_u32(0), // (unused)
cx.const_u32(version),
],
/* packed */ false,
);

// Create the complete LLVM coverage data value to add to the LLVM IR
let covmap_data =
cx.const_struct(&[cov_data_header_val, filenames_val], /*packed=*/ false);

let llglobal = llvm::add_global(cx.llmod, cx.val_ty(covmap_data), &llvm_cov::covmap_var_name());
llvm::set_initializer(llglobal, covmap_data);
llvm::set_global_constant(llglobal, true);
llvm::set_linkage(llglobal, llvm::Linkage::PrivateLinkage);
llvm::set_section(llglobal, &llvm_cov::covmap_section_name(cx.llmod));
let covmap_record = cx
.const_struct(&[covmap_header, cx.const_bytes(filenames_buffer)], /* packed */ false);

let covmap_global =
llvm::add_global(cx.llmod, cx.val_ty(covmap_record), &llvm_cov::covmap_var_name());
llvm::set_initializer(covmap_global, covmap_record);
llvm::set_global_constant(covmap_global, true);
llvm::set_linkage(covmap_global, llvm::Linkage::PrivateLinkage);
llvm::set_section(covmap_global, &llvm_cov::covmap_section_name(cx.llmod));
// LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
// <https://llvm.org/docs/CoverageMappingFormat.html>
llvm::set_alignment(llglobal, Align::EIGHT);
cx.add_used_global(llglobal);
llvm::set_alignment(covmap_global, Align::EIGHT);

cx.add_used_global(covmap_global);
}

/// Each CGU will normally only emit coverage metadata for the functions that it actually generates.
Expand Down
59 changes: 29 additions & 30 deletions compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ fn fill_region_tables<'tcx>(
/// as a global variable in the `__llvm_covfun` section.
pub(crate) fn generate_covfun_record<'tcx>(
cx: &CodegenCx<'_, 'tcx>,
filenames_ref: u64,
filenames_hash: u64,
covfun: &CovfunRecord<'tcx>,
) {
let &CovfunRecord {
Expand All @@ -155,46 +155,45 @@ pub(crate) fn generate_covfun_record<'tcx>(
regions,
);

// Concatenate the encoded coverage mappings
let coverage_mapping_size = coverage_mapping_buffer.len();
let coverage_mapping_val = cx.const_bytes(&coverage_mapping_buffer);

// A covfun record consists of four target-endian integers, followed by the
// encoded mapping data in bytes. Note that the length field is 32 bits.
// <https://llvm.org/docs/CoverageMappingFormat.html#llvm-ir-representation>
// See also `src/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp` and
// `COVMAP_V3` in `src/llvm-project/llvm/include/llvm/ProfileData/InstrProfData.inc`.
let func_name_hash = llvm_cov::hash_bytes(mangled_function_name.as_bytes());
let func_name_hash_val = cx.const_u64(func_name_hash);
let coverage_mapping_size_val = cx.const_u32(coverage_mapping_size as u32);
let source_hash_val = cx.const_u64(source_hash);
let filenames_ref_val = cx.const_u64(filenames_ref);
let func_record_val = cx.const_struct(
let covfun_record = cx.const_struct(
&[
func_name_hash_val,
coverage_mapping_size_val,
source_hash_val,
filenames_ref_val,
coverage_mapping_val,
cx.const_u64(func_name_hash),
cx.const_u32(coverage_mapping_buffer.len() as u32),
cx.const_u64(source_hash),
cx.const_u64(filenames_hash),
cx.const_bytes(&coverage_mapping_buffer),
],
/*packed=*/ true,
// This struct needs to be packed, so that the 32-bit length field
// doesn't have unexpected padding.
true,
);

// Choose a variable name to hold this function's covfun data.
// Functions that are used have a suffix ("u") to distinguish them from
// unused copies of the same function (from different CGUs), so that if a
// linker sees both it won't discard the used copy's data.
let func_record_var_name =
CString::new(format!("__covrec_{:X}{}", func_name_hash, if is_used { "u" } else { "" }))
.unwrap();
debug!("function record var name: {:?}", func_record_var_name);

let llglobal = llvm::add_global(cx.llmod, cx.val_ty(func_record_val), &func_record_var_name);
llvm::set_initializer(llglobal, func_record_val);
llvm::set_global_constant(llglobal, true);
llvm::set_linkage(llglobal, llvm::Linkage::LinkOnceODRLinkage);
llvm::set_visibility(llglobal, llvm::Visibility::Hidden);
llvm::set_section(llglobal, cx.covfun_section_name());
let u = if is_used { "u" } else { "" };
let covfun_var_name = CString::new(format!("__covrec_{func_name_hash:X}{u}")).unwrap();
debug!("function record var name: {covfun_var_name:?}");

let covfun_global = llvm::add_global(cx.llmod, cx.val_ty(covfun_record), &covfun_var_name);
llvm::set_initializer(covfun_global, covfun_record);
llvm::set_global_constant(covfun_global, true);
llvm::set_linkage(covfun_global, llvm::Linkage::LinkOnceODRLinkage);
llvm::set_visibility(covfun_global, llvm::Visibility::Hidden);
llvm::set_section(covfun_global, cx.covfun_section_name());
// LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
// <https://llvm.org/docs/CoverageMappingFormat.html>
llvm::set_alignment(llglobal, Align::EIGHT);
llvm::set_alignment(covfun_global, Align::EIGHT);
if cx.target_spec().supports_comdat() {
llvm::set_comdat(cx.llmod, llglobal, &func_record_var_name);
llvm::set_comdat(cx.llmod, covfun_global, &covfun_var_name);
}
cx.add_used_global(llglobal);

cx.add_used_global(covfun_global);
}
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -992,12 +992,12 @@ fn link_natively(
let mut output = prog.stderr.clone();
output.extend_from_slice(&prog.stdout);
let escaped_output = escape_linker_output(&output, flavor);
// FIXME: Add UI tests for this error.
let err = errors::LinkingFailed {
linker_path: &linker_path,
exit_status: prog.status,
command: &cmd,
command: cmd,
escaped_output,
verbose: sess.opts.verbose,
};
sess.dcx().emit_err(err);
// If MSVC's `link.exe` was expected but the return code
Expand Down
70 changes: 66 additions & 4 deletions compiler/rustc_codegen_ssa/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Errors emitted by codegen_ssa

use std::borrow::Cow;
use std::ffi::OsString;
use std::io::Error;
use std::num::ParseIntError;
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -345,21 +346,82 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for ThorinErrorWrapper {
}

pub(crate) struct LinkingFailed<'a> {
pub linker_path: &'a PathBuf,
pub linker_path: &'a Path,
pub exit_status: ExitStatus,
pub command: &'a Command,
pub command: Command,
pub escaped_output: String,
pub verbose: bool,
}

impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
fn into_diag(mut self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let mut diag = Diag::new(dcx, level, fluent::codegen_ssa_linking_failed);
diag.arg("linker_path", format!("{}", self.linker_path.display()));
diag.arg("exit_status", format!("{}", self.exit_status));

let contains_undefined_ref = self.escaped_output.contains("undefined reference to");

diag.note(format!("{:?}", self.command)).note(self.escaped_output);
if self.verbose {
diag.note(format!("{:?}", self.command));
} else {
enum ArgGroup {
Regular(OsString),
Objects(usize),
Rlibs(PathBuf, Vec<OsString>),
}

// Omit rust object files and fold rlibs in the error by default to make linker errors a
// bit less verbose.
let orig_args = self.command.take_args();
let mut args: Vec<ArgGroup> = vec![];
for arg in orig_args {
if arg.as_encoded_bytes().ends_with(b".rcgu.o") {
if let Some(ArgGroup::Objects(n)) = args.last_mut() {
*n += 1;
} else {
args.push(ArgGroup::Objects(1));
}
} else if arg.as_encoded_bytes().ends_with(b".rlib") {
let rlib_path = Path::new(&arg);
let dir = rlib_path.parent().unwrap();
let filename = rlib_path.file_name().unwrap().to_owned();
if let Some(ArgGroup::Rlibs(parent, rlibs)) = args.last_mut() {
if parent == dir {
rlibs.push(filename);
} else {
args.push(ArgGroup::Rlibs(dir.to_owned(), vec![filename]));
}
} else {
args.push(ArgGroup::Rlibs(dir.to_owned(), vec![filename]));
}
} else {
args.push(ArgGroup::Regular(arg));
}
}
self.command.args(args.into_iter().map(|arg_group| match arg_group {
ArgGroup::Regular(arg) => arg,
ArgGroup::Objects(n) => OsString::from(format!("<{n} object files omitted>")),
ArgGroup::Rlibs(dir, rlibs) => {
let mut arg = dir.into_os_string();
arg.push("/{");
let mut first = true;
for rlib in rlibs {
if !first {
arg.push(",");
}
first = false;
arg.push(rlib);
}
arg.push("}");
arg
}
}));

diag.note(format!("{:?}", self.command));
diag.note("some arguments are omitted. use `--verbose` to show all linker arguments");
}

diag.note(self.escaped_output);

// Trying to match an error from OS linkers
// which by now we have no way to translate.
Expand Down
Loading
Loading