Skip to content

Commit

Permalink
Auto merge of rust-lang#122778 - GuillaumeGomez:rollup-u5ipoai, r=Gui…
Browse files Browse the repository at this point in the history
…llaumeGomez

Rollup of 8 pull requests

Successful merges:

 - rust-lang#122494 (Simplify key-based thread locals)
 - rust-lang#122644 (pattern analysis: add a custom test harness)
 - rust-lang#122723 (Use same file permissions for ar_archive_writer as the LLVM archive writer)
 - rust-lang#122729 (Relax SeqCst ordering in standard library.)
 - rust-lang#122740 (use more accurate terminology)
 - rust-lang#122764 (coverage: Remove incorrect assertions from counter allocation)
 - rust-lang#122765 (Add `usize::MAX` arg tests for Vec)
 - rust-lang#122776 (Rename `hir::Let` into `hir::LetExpr`)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 20, 2024
2 parents 94b72d6 + dd0d8cd commit 8b8d328
Show file tree
Hide file tree
Showing 53 changed files with 1,039 additions and 316 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock
Expand Up @@ -4440,6 +4440,8 @@ dependencies = [
"rustc_target",
"smallvec",
"tracing",
"tracing-subscriber",
"tracing-tree",
]

[[package]]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/expr.rs
Expand Up @@ -157,7 +157,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ExprKind::AddrOf(*k, *m, ohs)
}
ExprKind::Let(pat, scrutinee, span, is_recovered) => {
hir::ExprKind::Let(self.arena.alloc(hir::Let {
hir::ExprKind::Let(self.arena.alloc(hir::LetExpr {
span: self.lower_span(*span),
pat: self.lower_pat(pat),
ty: None,
Expand Down
37 changes: 21 additions & 16 deletions compiler/rustc_codegen_ssa/src/back/archive.rs
Expand Up @@ -13,7 +13,7 @@ use object::read::macho::FatArch;
use tempfile::Builder as TempFileBuilder;

use std::error::Error;
use std::fs::File;
use std::fs::{self, File};
use std::io::{self, Write};
use std::path::{Path, PathBuf};

Expand Down Expand Up @@ -276,29 +276,34 @@ impl<'a> ArArchiveBuilder<'a> {
// This prevents programs (including rustc) from attempting to read a partial archive.
// It also enables writing an archive with the same filename as a dependency on Windows as
// required by a test.
let mut archive_tmpfile = TempFileBuilder::new()
// The tempfile crate currently uses 0o600 as mode for the temporary files and directories
// it creates. We need it to be the default mode for back compat reasons however. (See
// #107495) To handle this we are telling tempfile to create a temporary directory instead
// and then inside this directory create a file using File::create.
let archive_tmpdir = TempFileBuilder::new()
.suffix(".temp-archive")
.tempfile_in(output.parent().unwrap_or_else(|| Path::new("")))
.map_err(|err| io_error_context("couldn't create a temp file", err))?;

write_archive_to_stream(
archive_tmpfile.as_file_mut(),
&entries,
true,
archive_kind,
true,
false,
)?;
.tempdir_in(output.parent().unwrap_or_else(|| Path::new("")))
.map_err(|err| {
io_error_context("couldn't create a directory for the temp file", err)
})?;
let archive_tmpfile_path = archive_tmpdir.path().join("tmp.a");
let mut archive_tmpfile = File::create_new(&archive_tmpfile_path)
.map_err(|err| io_error_context("couldn't create the temp file", err))?;

write_archive_to_stream(&mut archive_tmpfile, &entries, true, archive_kind, true, false)?;
drop(archive_tmpfile);

let any_entries = !entries.is_empty();
drop(entries);
// Drop src_archives to unmap all input archives, which is necessary if we want to write the
// output archive to the same location as an input archive on Windows.
drop(self.src_archives);

archive_tmpfile
.persist(output)
.map_err(|err| io_error_context("failed to rename archive file", err.error))?;
fs::rename(archive_tmpfile_path, output)
.map_err(|err| io_error_context("failed to rename archive file", err))?;
archive_tmpdir
.close()
.map_err(|err| io_error_context("failed to remove temporary directory", err))?;

Ok(any_entries)
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir/src/hir.rs
Expand Up @@ -1259,7 +1259,7 @@ pub struct Arm<'hir> {
/// In an `if let`, imagine it as `if (let <pat> = <expr>) { ... }`; in a let-else, it is part of
/// the desugaring to if-let. Only let-else supports the type annotation at present.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Let<'hir> {
pub struct LetExpr<'hir> {
pub span: Span,
pub pat: &'hir Pat<'hir>,
pub ty: Option<&'hir Ty<'hir>>,
Expand Down Expand Up @@ -1852,7 +1852,7 @@ pub enum ExprKind<'hir> {
///
/// These are not `Local` and only occur as expressions.
/// The `let Some(x) = foo()` in `if let Some(x) = foo()` is an example of `Let(..)`.
Let(&'hir Let<'hir>),
Let(&'hir LetExpr<'hir>),
/// An `if` block, with an optional else block.
///
/// I.e., `if <expr> { <expr> } else { <expr> }`.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/intravisit.rs
Expand Up @@ -753,7 +753,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
ExprKind::DropTemps(ref subexpression) => {
try_visit!(visitor.visit_expr(subexpression));
}
ExprKind::Let(Let { span: _, pat, ty, init, is_recovered: _ }) => {
ExprKind::Let(LetExpr { span: _, pat, ty, init, is_recovered: _ }) => {
// match the visit order in walk_local
try_visit!(visitor.visit_expr(init));
try_visit!(visitor.visit_pat(pat));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_pretty/src/lib.rs
Expand Up @@ -1387,7 +1387,7 @@ impl<'a> State<'a> {
// Print `}`:
self.bclose_maybe_open(expr.span, true);
}
hir::ExprKind::Let(&hir::Let { pat, ty, init, .. }) => {
hir::ExprKind::Let(&hir::LetExpr { pat, ty, init, .. }) => {
self.print_let(pat, ty, init);
}
hir::ExprKind::If(test, blk, elseopt) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/_match.rs
Expand Up @@ -317,7 +317,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.note("`if` expressions without `else` evaluate to `()`");
err.help("consider adding an `else` block that evaluates to the expected type");
*error = true;
if let ExprKind::Let(hir::Let { span, pat, init, .. }) = cond_expr.kind
if let ExprKind::Let(hir::LetExpr { span, pat, init, .. }) = cond_expr.kind
&& let ExprKind::Block(block, _) = then_expr.kind
// Refutability checks occur on the MIR, so we approximate it here by checking
// if we have an enum with a single variant or a struct in the pattern.
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Expand Up @@ -1261,7 +1261,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

pub(super) fn check_expr_let(&self, let_expr: &'tcx hir::Let<'tcx>, hir_id: HirId) -> Ty<'tcx> {
pub(super) fn check_expr_let(
&self,
let_expr: &'tcx hir::LetExpr<'tcx>,
hir_id: HirId,
) -> Ty<'tcx> {
// for let statements, this is done in check_stmt
let init = let_expr.init;
self.warn_if_unreachable(init.hir_id, init.span, "block in `let` expression");
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/expr_use_visitor.rs
Expand Up @@ -245,7 +245,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
}
}

hir::ExprKind::Let(hir::Let { pat, init, .. }) => {
hir::ExprKind::Let(hir::LetExpr { pat, init, .. }) => {
self.walk_local(init, pat, None, |t| t.borrow_expr(init, ty::ImmBorrow))
}

Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_hir_typeck/src/gather_locals.rs
Expand Up @@ -29,7 +29,7 @@ impl<'a> DeclOrigin<'a> {
}
}

/// A declaration is an abstraction of [hir::Local] and [hir::Let].
/// A declaration is an abstraction of [hir::Local] and [hir::LetExpr].
///
/// It must have a hir_id, as this is how we connect gather_locals to the check functions.
pub(super) struct Declaration<'a> {
Expand All @@ -48,9 +48,9 @@ impl<'a> From<&'a hir::Local<'a>> for Declaration<'a> {
}
}

impl<'a> From<(&'a hir::Let<'a>, hir::HirId)> for Declaration<'a> {
fn from((let_expr, hir_id): (&'a hir::Let<'a>, hir::HirId)) -> Self {
let hir::Let { pat, ty, span, init, is_recovered: _ } = *let_expr;
impl<'a> From<(&'a hir::LetExpr<'a>, hir::HirId)> for Declaration<'a> {
fn from((let_expr, hir_id): (&'a hir::LetExpr<'a>, hir::HirId)) -> Self {
let hir::LetExpr { pat, ty, span, init, is_recovered: _ } = *let_expr;
Declaration { hir_id, pat, ty, span, init: Some(init), origin: DeclOrigin::LetExpr }
}
}
Expand Down
39 changes: 4 additions & 35 deletions compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -1,13 +1,12 @@
use std::fmt::{self, Debug};

use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::graph::WithNumNodes;
use rustc_index::bit_set::BitSet;
use rustc_index::IndexVec;
use rustc_middle::mir::coverage::*;
use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId, Op};

use super::graph::{BasicCoverageBlock, CoverageGraph, TraverseCoverageGraphWithLoops};

use std::fmt::{self, Debug};
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, TraverseCoverageGraphWithLoops};

/// The coverage counter or counter expression associated with a particular
/// BCB node or BCB edge.
Expand All @@ -18,10 +17,6 @@ pub(super) enum BcbCounter {
}

impl BcbCounter {
fn is_expression(&self) -> bool {
matches!(self, Self::Expression { .. })
}

pub(super) fn as_term(&self) -> CovTerm {
match *self {
BcbCounter::Counter { id, .. } => CovTerm::Counter(id),
Expand Down Expand Up @@ -60,10 +55,6 @@ pub(super) struct CoverageCounters {
/// We currently don't iterate over this map, but if we do in the future,
/// switch it back to `FxIndexMap` to avoid query stability hazards.
bcb_edge_counters: FxHashMap<(BasicCoverageBlock, BasicCoverageBlock), BcbCounter>,
/// Tracks which BCBs have a counter associated with some incoming edge.
/// Only used by assertions, to verify that BCBs with incoming edge
/// counters do not have their own physical counters (expressions are allowed).
bcb_has_incoming_edge_counters: BitSet<BasicCoverageBlock>,
/// Table of expression data, associating each expression ID with its
/// corresponding operator (+ or -) and its LHS/RHS operands.
expressions: IndexVec<ExpressionId, Expression>,
Expand All @@ -83,7 +74,6 @@ impl CoverageCounters {
counter_increment_sites: IndexVec::new(),
bcb_counters: IndexVec::from_elem_n(None, num_bcbs),
bcb_edge_counters: FxHashMap::default(),
bcb_has_incoming_edge_counters: BitSet::new_empty(num_bcbs),
expressions: IndexVec::new(),
};

Expand Down Expand Up @@ -122,14 +112,6 @@ impl CoverageCounters {
}

fn set_bcb_counter(&mut self, bcb: BasicCoverageBlock, counter_kind: BcbCounter) -> BcbCounter {
assert!(
// If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
// have an expression (to be injected into an existing `BasicBlock` represented by this
// `BasicCoverageBlock`).
counter_kind.is_expression() || !self.bcb_has_incoming_edge_counters.contains(bcb),
"attempt to add a `Counter` to a BCB target with existing incoming edge counters"
);

if let Some(replaced) = self.bcb_counters[bcb].replace(counter_kind) {
bug!(
"attempt to set a BasicCoverageBlock coverage counter more than once; \
Expand All @@ -146,19 +128,6 @@ impl CoverageCounters {
to_bcb: BasicCoverageBlock,
counter_kind: BcbCounter,
) -> BcbCounter {
// If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
// have an expression (to be injected into an existing `BasicBlock` represented by this
// `BasicCoverageBlock`).
if let Some(node_counter) = self.bcb_counter(to_bcb)
&& !node_counter.is_expression()
{
bug!(
"attempt to add an incoming edge counter from {from_bcb:?} \
when the target BCB already has {node_counter:?}"
);
}

self.bcb_has_incoming_edge_counters.insert(to_bcb);
if let Some(replaced) = self.bcb_edge_counters.insert((from_bcb, to_bcb), counter_kind) {
bug!(
"attempt to set an edge counter more than once; from_bcb: \
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_pattern_analysis/Cargo.toml
Expand Up @@ -22,6 +22,10 @@ smallvec = { version = "1.8.1", features = ["union"] }
tracing = "0.1"
# tidy-alphabetical-end

[dev-dependencies]
tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "ansi"] }
tracing-tree = "0.2.0"

[features]
default = ["rustc"]
rustc = [
Expand Down
75 changes: 75 additions & 0 deletions compiler/rustc_pattern_analysis/src/constructor.rs
Expand Up @@ -819,6 +819,81 @@ impl<Cx: PatCx> Constructor<Cx> {
}
})
}

pub(crate) fn fmt_fields(
&self,
f: &mut fmt::Formatter<'_>,
ty: &Cx::Ty,
mut fields: impl Iterator<Item = impl fmt::Debug>,
) -> fmt::Result {
let mut first = true;
let mut start_or_continue = |s| {
if first {
first = false;
""
} else {
s
}
};
let mut start_or_comma = || start_or_continue(", ");

match self {
Struct | Variant(_) | UnionField => {
Cx::write_variant_name(f, self, ty)?;
// Without `cx`, we can't know which field corresponds to which, so we can't
// get the names of the fields. Instead we just display everything as a tuple
// struct, which should be good enough.
write!(f, "(")?;
for p in fields {
write!(f, "{}{:?}", start_or_comma(), p)?;
}
write!(f, ")")?;
}
// Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
// be careful to detect strings here. However a string literal pattern will never
// be reported as a non-exhaustiveness witness, so we can ignore this issue.
Ref => {
write!(f, "&{:?}", &fields.next().unwrap())?;
}
Slice(slice) => {
write!(f, "[")?;
match slice.kind {
SliceKind::FixedLen(_) => {
for p in fields {
write!(f, "{}{:?}", start_or_comma(), p)?;
}
}
SliceKind::VarLen(prefix_len, _) => {
for p in fields.by_ref().take(prefix_len) {
write!(f, "{}{:?}", start_or_comma(), p)?;
}
write!(f, "{}..", start_or_comma())?;
for p in fields {
write!(f, "{}{:?}", start_or_comma(), p)?;
}
}
}
write!(f, "]")?;
}
Bool(b) => write!(f, "{b}")?,
// Best-effort, will render signed ranges incorrectly
IntRange(range) => write!(f, "{range:?}")?,
F32Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
F64Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
Str(value) => write!(f, "{value:?}")?,
Opaque(..) => write!(f, "<constant pattern>")?,
Or => {
for pat in fields {
write!(f, "{}{:?}", start_or_continue(" | "), pat)?;
}
}
Never => write!(f, "!")?,
Wildcard | Missing | NonExhaustive | Hidden | PrivateUninhabited => {
write!(f, "_ : {:?}", ty)?
}
}
Ok(())
}
}

#[derive(Debug, Clone, Copy)]
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_pattern_analysis/src/lib.rs
Expand Up @@ -49,6 +49,12 @@ pub mod index {
}
}

impl<V> FromIterator<V> for IdxContainer<usize, V> {
fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
Self(iter.into_iter().enumerate().collect())
}
}

#[derive(Debug)]
pub struct IdxSet<T>(pub rustc_hash::FxHashSet<T>);
impl<T: Idx> IdxSet<T> {
Expand Down Expand Up @@ -120,7 +126,8 @@ pub trait PatCx: Sized + fmt::Debug {
/// `DeconstructedPat`. Only invoqued when `pat.ctor()` is `Struct | Variant(_) | UnionField`.
fn write_variant_name(
f: &mut fmt::Formatter<'_>,
pat: &crate::pat::DeconstructedPat<Self>,
ctor: &crate::constructor::Constructor<Self>,
ty: &Self::Ty,
) -> fmt::Result;

/// Raise a bug.
Expand Down

0 comments on commit 8b8d328

Please sign in to comment.