mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Rollup merge of #136336 - nnethercote:overhaul-rustc_middle-util, r=jieyouxu
Overhaul `rustc_middle::util` It's an odd module with some odd stuff in it. r? `@Noratrieb`
This commit is contained in:
commit
95f746d2ef
@ -3777,7 +3777,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
if let Some(Terminator { kind: TerminatorKind::Call { call_source, fn_span, .. }, .. }) =
|
||||
&self.body[loan.reserve_location.block].terminator
|
||||
&& let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
|
||||
&& let Some((method_did, method_args)) = mir::find_self_call(
|
||||
tcx,
|
||||
self.body,
|
||||
loan.assigned_place.local,
|
||||
|
@ -17,7 +17,7 @@ use rustc_middle::mir::tcx::PlaceTy;
|
||||
use rustc_middle::mir::{
|
||||
AggregateKind, CallSource, ConstOperand, ConstraintCategory, FakeReadCause, Local, LocalInfo,
|
||||
LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement,
|
||||
StatementKind, Terminator, TerminatorKind,
|
||||
StatementKind, Terminator, TerminatorKind, find_self_call,
|
||||
};
|
||||
use rustc_middle::ty::print::Print;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
@ -1016,12 +1016,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
kind: TerminatorKind::Call { fn_span, call_source, .. }, ..
|
||||
}) = &self.body[location.block].terminator
|
||||
{
|
||||
let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
|
||||
self.infcx.tcx,
|
||||
self.body,
|
||||
target_temp,
|
||||
location.block,
|
||||
) else {
|
||||
let Some((method_did, method_args)) =
|
||||
find_self_call(self.infcx.tcx, self.body, target_temp, location.block)
|
||||
else {
|
||||
return normal_ret;
|
||||
};
|
||||
|
||||
|
@ -76,6 +76,7 @@ pub mod sync;
|
||||
pub mod tagged_ptr;
|
||||
pub mod temp_dir;
|
||||
pub mod thinvec;
|
||||
pub mod thousands;
|
||||
pub mod transitive_relation;
|
||||
pub mod unhash;
|
||||
pub mod unord;
|
||||
|
16
compiler/rustc_data_structures/src/thousands/mod.rs
Normal file
16
compiler/rustc_data_structures/src/thousands/mod.rs
Normal file
@ -0,0 +1,16 @@
|
||||
//! This is an extremely bare-bones alternative to the `thousands` crate on
|
||||
//! crates.io, for printing large numbers in a readable fashion.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
// Converts the number to a string, with underscores as the thousands separator.
|
||||
pub fn format_with_underscores(n: usize) -> String {
|
||||
let mut s = n.to_string();
|
||||
let mut i = s.len();
|
||||
while i > 3 {
|
||||
i -= 3;
|
||||
s.insert(i, '_');
|
||||
}
|
||||
s
|
||||
}
|
14
compiler/rustc_data_structures/src/thousands/tests.rs
Normal file
14
compiler/rustc_data_structures/src/thousands/tests.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_format_with_underscores() {
|
||||
assert_eq!("0", format_with_underscores(0));
|
||||
assert_eq!("1", format_with_underscores(1));
|
||||
assert_eq!("99", format_with_underscores(99));
|
||||
assert_eq!("345", format_with_underscores(345));
|
||||
assert_eq!("1_000", format_with_underscores(1_000));
|
||||
assert_eq!("12_001", format_with_underscores(12_001));
|
||||
assert_eq!("999_999", format_with_underscores(999_999));
|
||||
assert_eq!("1_000_000", format_with_underscores(1_000_000));
|
||||
assert_eq!("12_345_678", format_with_underscores(12_345_678));
|
||||
}
|
@ -9,6 +9,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||
use rustc_data_structures::memmap::{Mmap, MmapMut};
|
||||
use rustc_data_structures::sync::{Lrc, join, par_for_each_in};
|
||||
use rustc_data_structures::temp_dir::MaybeTempDir;
|
||||
use rustc_data_structures::thousands::format_with_underscores;
|
||||
use rustc_feature::Features;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE, LocalDefId, LocalDefIdSet};
|
||||
@ -22,7 +23,6 @@ use rustc_middle::traits::specialization_graph;
|
||||
use rustc_middle::ty::codec::TyEncoder;
|
||||
use rustc_middle::ty::fast_reject::{self, TreatParams};
|
||||
use rustc_middle::ty::{AssocItemContainer, SymbolName};
|
||||
use rustc_middle::util::common::to_readable_str;
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque};
|
||||
use rustc_session::config::{CrateType, OptLevel};
|
||||
@ -782,7 +782,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
"{} {:<23}{:>10} ({:4.1}%)",
|
||||
prefix,
|
||||
label,
|
||||
to_readable_str(size),
|
||||
format_with_underscores(size),
|
||||
perc(size)
|
||||
);
|
||||
}
|
||||
@ -791,7 +791,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
"{} {:<23}{:>10} (of which {:.1}% are zero bytes)",
|
||||
prefix,
|
||||
"Total",
|
||||
to_readable_str(total_bytes),
|
||||
format_with_underscores(total_bytes),
|
||||
perc(zero_bytes)
|
||||
);
|
||||
eprintln!("{prefix}");
|
||||
|
@ -4,8 +4,8 @@
|
||||
///
|
||||
/// If you have a span available, you should use [`span_bug`] instead.
|
||||
///
|
||||
/// If the bug should only be emitted when compilation didn't fail, [`DiagCtxtHandle::span_delayed_bug`]
|
||||
/// may be useful.
|
||||
/// If the bug should only be emitted when compilation didn't fail,
|
||||
/// [`DiagCtxtHandle::span_delayed_bug`] may be useful.
|
||||
///
|
||||
/// [`DiagCtxtHandle::span_delayed_bug`]: rustc_errors::DiagCtxtHandle::span_delayed_bug
|
||||
/// [`span_bug`]: crate::span_bug
|
||||
@ -14,14 +14,8 @@ macro_rules! bug {
|
||||
() => (
|
||||
$crate::bug!("impossible case reached")
|
||||
);
|
||||
($msg:expr) => (
|
||||
$crate::util::bug::bug_fmt(::std::format_args!($msg))
|
||||
);
|
||||
($msg:expr,) => (
|
||||
$crate::bug!($msg)
|
||||
);
|
||||
($fmt:expr, $($arg:tt)+) => (
|
||||
$crate::util::bug::bug_fmt(::std::format_args!($fmt, $($arg)+))
|
||||
($($arg:tt)+) => (
|
||||
$crate::util::bug::bug_fmt(::std::format_args!($($arg)+))
|
||||
);
|
||||
}
|
||||
|
||||
@ -30,20 +24,14 @@ macro_rules! bug {
|
||||
/// at the code the compiler was compiling when it ICEd. This is the preferred way to trigger
|
||||
/// ICEs.
|
||||
///
|
||||
/// If the bug should only be emitted when compilation didn't fail, [`DiagCtxtHandle::span_delayed_bug`]
|
||||
/// may be useful.
|
||||
/// If the bug should only be emitted when compilation didn't fail,
|
||||
/// [`DiagCtxtHandle::span_delayed_bug`] may be useful.
|
||||
///
|
||||
/// [`DiagCtxtHandle::span_delayed_bug`]: rustc_errors::DiagCtxtHandle::span_delayed_bug
|
||||
#[macro_export]
|
||||
macro_rules! span_bug {
|
||||
($span:expr, $msg:expr) => (
|
||||
$crate::util::bug::span_bug_fmt($span, ::std::format_args!($msg))
|
||||
);
|
||||
($span:expr, $msg:expr,) => (
|
||||
$crate::span_bug!($span, $msg)
|
||||
);
|
||||
($span:expr, $fmt:expr, $($arg:tt)+) => (
|
||||
$crate::util::bug::span_bug_fmt($span, ::std::format_args!($fmt, $($arg)+))
|
||||
($span:expr, $($arg:tt)+) => (
|
||||
$crate::util::bug::span_bug_fmt($span, ::std::format_args!($($arg)+))
|
||||
);
|
||||
}
|
||||
|
||||
@ -53,7 +41,6 @@ macro_rules! span_bug {
|
||||
// When possible, use one of these (relatively) convenient macros to write
|
||||
// the impls for you.
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! TrivialLiftImpls {
|
||||
($($ty:ty),+ $(,)?) => {
|
||||
$(
|
||||
@ -69,7 +56,6 @@ macro_rules! TrivialLiftImpls {
|
||||
|
||||
/// Used for types that are `Copy` and which **do not care about arena
|
||||
/// allocated data** (i.e., don't need to be folded).
|
||||
#[macro_export]
|
||||
macro_rules! TrivialTypeTraversalImpls {
|
||||
($($ty:ty),+ $(,)?) => {
|
||||
$(
|
||||
@ -104,7 +90,6 @@ macro_rules! TrivialTypeTraversalImpls {
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! TrivialTypeTraversalAndLiftImpls {
|
||||
($($t:tt)*) => {
|
||||
TrivialTypeTraversalImpls! { $($t)* }
|
||||
|
@ -27,7 +27,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisit
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol};
|
||||
use tracing::trace;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
pub use self::query::*;
|
||||
use self::visit::TyContext;
|
||||
@ -1796,6 +1796,47 @@ impl DefLocation {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the specified `local` is used as the `self` parameter of a method call
|
||||
/// in the provided `BasicBlock`. If it is, then the `DefId` of the called method is
|
||||
/// returned.
|
||||
pub fn find_self_call<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
local: Local,
|
||||
block: BasicBlock,
|
||||
) -> Option<(DefId, GenericArgsRef<'tcx>)> {
|
||||
debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator);
|
||||
if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
|
||||
&body[block].terminator
|
||||
&& let Operand::Constant(box ConstOperand { const_, .. }) = func
|
||||
&& let ty::FnDef(def_id, fn_args) = *const_.ty().kind()
|
||||
&& let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
|
||||
tcx.opt_associated_item(def_id)
|
||||
&& let [Spanned { node: Operand::Move(self_place) | Operand::Copy(self_place), .. }, ..] =
|
||||
**args
|
||||
{
|
||||
if self_place.as_local() == Some(local) {
|
||||
return Some((def_id, fn_args));
|
||||
}
|
||||
|
||||
// Handle the case where `self_place` gets reborrowed.
|
||||
// This happens when the receiver is `&T`.
|
||||
for stmt in &body[block].statements {
|
||||
if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind
|
||||
&& let Some(reborrow_local) = place.as_local()
|
||||
&& self_place.as_local() == Some(reborrow_local)
|
||||
&& let Rvalue::Ref(_, _, deref_place) = rvalue
|
||||
&& let PlaceRef { local: deref_local, projection: [ProjectionElem::Deref] } =
|
||||
deref_place.as_ref()
|
||||
&& deref_local == local
|
||||
{
|
||||
return Some((def_id, fn_args));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
|
@ -428,7 +428,7 @@ pub enum IsConstable {
|
||||
Ctor,
|
||||
}
|
||||
|
||||
crate::TrivialTypeTraversalAndLiftImpls! {
|
||||
TrivialTypeTraversalAndLiftImpls! {
|
||||
IsConstable,
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// These functions are used by macro expansion for bug! and span_bug!
|
||||
// These functions are used by macro expansion for `bug!` and `span_bug!`.
|
||||
|
||||
use std::fmt;
|
||||
use std::panic::{Location, panic_any};
|
||||
@ -8,15 +8,15 @@ use rustc_span::Span;
|
||||
|
||||
use crate::ty::{TyCtxt, tls};
|
||||
|
||||
// This wrapper makes for more compact code at callsites than calling `opt_span_buf_fmt` directly.
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
#[track_caller]
|
||||
pub fn bug_fmt(args: fmt::Arguments<'_>) -> ! {
|
||||
// this wrapper mostly exists so I don't have to write a fully
|
||||
// qualified path of None::<Span> inside the bug!() macro definition
|
||||
opt_span_bug_fmt(None::<Span>, args, Location::caller());
|
||||
}
|
||||
|
||||
// This wrapper makes for more compact code at callsites than calling `opt_span_buf_fmt` directly.
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
#[track_caller]
|
||||
|
@ -1,22 +0,0 @@
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub fn to_readable_str(mut val: usize) -> String {
|
||||
let mut groups = vec![];
|
||||
loop {
|
||||
let group = val % 1000;
|
||||
|
||||
val /= 1000;
|
||||
|
||||
if val == 0 {
|
||||
groups.push(group.to_string());
|
||||
break;
|
||||
} else {
|
||||
groups.push(format!("{group:03}"));
|
||||
}
|
||||
}
|
||||
|
||||
groups.reverse();
|
||||
|
||||
groups.join("_")
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_to_readable_str() {
|
||||
assert_eq!("0", to_readable_str(0));
|
||||
assert_eq!("1", to_readable_str(1));
|
||||
assert_eq!("99", to_readable_str(99));
|
||||
assert_eq!("999", to_readable_str(999));
|
||||
assert_eq!("1_000", to_readable_str(1_000));
|
||||
assert_eq!("1_001", to_readable_str(1_001));
|
||||
assert_eq!("999_999", to_readable_str(999_999));
|
||||
assert_eq!("1_000_000", to_readable_str(1_000_000));
|
||||
assert_eq!("1_234_567", to_readable_str(1_234_567));
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::mir::*;
|
||||
use crate::ty::{self, GenericArgsRef, TyCtxt};
|
||||
|
||||
/// Checks if the specified `local` is used as the `self` parameter of a method call
|
||||
/// in the provided `BasicBlock`. If it is, then the `DefId` of the called method is
|
||||
/// returned.
|
||||
pub fn find_self_call<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
local: Local,
|
||||
block: BasicBlock,
|
||||
) -> Option<(DefId, GenericArgsRef<'tcx>)> {
|
||||
debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator);
|
||||
if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
|
||||
&body[block].terminator
|
||||
&& let Operand::Constant(box ConstOperand { const_, .. }) = func
|
||||
&& let ty::FnDef(def_id, fn_args) = *const_.ty().kind()
|
||||
&& let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
|
||||
tcx.opt_associated_item(def_id)
|
||||
&& let [Spanned { node: Operand::Move(self_place) | Operand::Copy(self_place), .. }, ..] =
|
||||
**args
|
||||
{
|
||||
if self_place.as_local() == Some(local) {
|
||||
return Some((def_id, fn_args));
|
||||
}
|
||||
|
||||
// Handle the case where `self_place` gets reborrowed.
|
||||
// This happens when the receiver is `&T`.
|
||||
for stmt in &body[block].statements {
|
||||
if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind
|
||||
&& let Some(reborrow_local) = place.as_local()
|
||||
&& self_place.as_local() == Some(reborrow_local)
|
||||
&& let Rvalue::Ref(_, _, deref_place) = rvalue
|
||||
&& let PlaceRef { local: deref_local, projection: [ProjectionElem::Deref] } =
|
||||
deref_place.as_ref()
|
||||
&& deref_local == local
|
||||
{
|
||||
return Some((def_id, fn_args));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
@ -1,8 +1,4 @@
|
||||
pub mod bug;
|
||||
pub mod common;
|
||||
pub mod find_self_call;
|
||||
|
||||
pub use find_self_call::find_self_call;
|
||||
|
||||
#[derive(Default, Copy, Clone)]
|
||||
pub struct Providers {
|
||||
|
@ -133,7 +133,7 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> {
|
||||
// the `self` parameter of a method call (as the terminator of our current
|
||||
// BasicBlock). If so, we emit a more specific lint.
|
||||
let method_did = self.target_local.and_then(|target_local| {
|
||||
rustc_middle::util::find_self_call(self.tcx, self.body, target_local, loc.block)
|
||||
find_self_call(self.tcx, self.body, target_local, loc.block)
|
||||
});
|
||||
let lint_loc =
|
||||
if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc };
|
||||
|
@ -5,10 +5,10 @@
|
||||
use rustc_ast::visit::BoundKind;
|
||||
use rustc_ast::{self as ast, NodeId, visit as ast_visit};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::thousands::format_with_underscores;
|
||||
use rustc_hir::{self as hir, AmbigArg, HirId, intravisit as hir_visit};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_middle::util::common::to_readable_str;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
|
||||
@ -144,10 +144,10 @@ impl<'k> StatCollector<'k> {
|
||||
"{} {:<18}{:>10} ({:4.1}%){:>14}{:>14}",
|
||||
prefix,
|
||||
label,
|
||||
to_readable_str(size),
|
||||
format_with_underscores(size),
|
||||
percent(size, total_size),
|
||||
to_readable_str(node.stats.count),
|
||||
to_readable_str(node.stats.size)
|
||||
format_with_underscores(node.stats.count),
|
||||
format_with_underscores(node.stats.size)
|
||||
);
|
||||
if !node.subnodes.is_empty() {
|
||||
// We will soon sort, so the initial order does not matter.
|
||||
@ -163,9 +163,9 @@ impl<'k> StatCollector<'k> {
|
||||
"{} - {:<18}{:>10} ({:4.1}%){:>14}",
|
||||
prefix,
|
||||
label,
|
||||
to_readable_str(size),
|
||||
format_with_underscores(size),
|
||||
percent(size, total_size),
|
||||
to_readable_str(subnode.count),
|
||||
format_with_underscores(subnode.count),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -175,8 +175,8 @@ impl<'k> StatCollector<'k> {
|
||||
"{} {:<18}{:>10} {:>14}",
|
||||
prefix,
|
||||
"Total",
|
||||
to_readable_str(total_size),
|
||||
to_readable_str(total_count),
|
||||
format_with_underscores(total_size),
|
||||
format_with_underscores(total_count),
|
||||
);
|
||||
eprintln!("{prefix}");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user