Skip to content
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

Rollup of 7 pull requests #124147

Merged
merged 21 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d9a8903
force exhaustion in iter::ArrayChunks::into_remainder
krtab Apr 3, 2024
19821ad
Properly handle emojis as literal prefix in macros
estebank Apr 10, 2024
857f5dd
Don't inline integer literals when out of range
tstsrt Apr 14, 2024
757f5bb
Fix formatting
tstsrt Apr 14, 2024
38c4885
Add more test cases
tstsrt Apr 14, 2024
4c8d210
Improve semantics of int_ty_max functions
tstsrt Apr 14, 2024
86a5765
Add an opt-in to store incoming edges in `VecGraph` + some docs
WaffleLapkin Apr 15, 2024
7d2cb3d
Make `graph::DepthFirstSearch` accept `G` by value
WaffleLapkin Apr 15, 2024
fa134b5
Add `graph::depth_first_search_as_undirected`
WaffleLapkin Apr 15, 2024
f68529f
Use raw-dylib for Windows futex APIs
ChrisDenton Apr 16, 2024
5b024d6
Cranelift: Revert raw-dylib for Windows futex APIs
ChrisDenton Apr 16, 2024
cc12a1b
Fix negating `f16` and `f128` constants
beetrees Apr 18, 2024
3e63398
when suggesting RUST_BACKTRACE=1, add a special note for Miri's env v…
RalfJung Apr 18, 2024
523fe2b
Add tests for predecessor-aware `VecGraph` mode
WaffleLapkin Apr 18, 2024
3831cbb
Rollup merge of #123406 - krtab:fix_remainder_iterchunk, r=scottmcm
workingjubilee Apr 19, 2024
0a0a5a9
Rollup merge of #123752 - estebank:emoji-prefix, r=wesleywiser
workingjubilee Apr 19, 2024
f174c31
Rollup merge of #123935 - tstsrt:fix-115423, r=oli-obk
workingjubilee Apr 19, 2024
2b94e02
Rollup merge of #123980 - WaffleLapkin:graph-average-refactor, r=wesl…
workingjubilee Apr 19, 2024
55c35dd
Rollup merge of #124019 - ChrisDenton:futex-raw-dylib, r=joboet
workingjubilee Apr 19, 2024
f36ca7a
Rollup merge of #124110 - beetrees:neg-f16-f128, r=compiler-errors
workingjubilee Apr 19, 2024
c8d58fa
Rollup merge of #124116 - RalfJung:miri-rust-backtrace, r=Nilstrieb
workingjubilee Apr 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 117 additions & 77 deletions compiler/rustc_ast_lowering/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,126 @@ impl<'hir> LoweringContext<'_, 'hir> {
let mut fmt = Cow::Borrowed(fmt);
if self.tcx.sess.opts.unstable_opts.flatten_format_args {
fmt = flatten_format_args(fmt);
fmt = inline_literals(fmt);
fmt = self.inline_literals(fmt);
}
expand_format_args(self, sp, &fmt, allow_const)
}

/// Try to convert a literal into an interned string
fn try_inline_lit(&self, lit: token::Lit) -> Option<Symbol> {
match LitKind::from_token_lit(lit) {
Ok(LitKind::Str(s, _)) => Some(s),
Ok(LitKind::Int(n, ty)) => {
match ty {
// unsuffixed integer literals are assumed to be i32's
LitIntType::Unsuffixed => {
(n <= i32::MAX as u128).then_some(Symbol::intern(&n.to_string()))
}
LitIntType::Signed(int_ty) => {
let max_literal = self.int_ty_max(int_ty);
(n <= max_literal).then_some(Symbol::intern(&n.to_string()))
}
LitIntType::Unsigned(uint_ty) => {
let max_literal = self.uint_ty_max(uint_ty);
(n <= max_literal).then_some(Symbol::intern(&n.to_string()))
}
}
}
_ => None,
}
}

/// Get the maximum value of int_ty. It is platform-dependent due to the byte size of isize
fn int_ty_max(&self, int_ty: IntTy) -> u128 {
match int_ty {
IntTy::Isize => self.tcx.data_layout.pointer_size.signed_int_max() as u128,
IntTy::I8 => i8::MAX as u128,
IntTy::I16 => i16::MAX as u128,
IntTy::I32 => i32::MAX as u128,
IntTy::I64 => i64::MAX as u128,
IntTy::I128 => i128::MAX as u128,
}
}

/// Get the maximum value of uint_ty. It is platform-dependent due to the byte size of usize
fn uint_ty_max(&self, uint_ty: UintTy) -> u128 {
match uint_ty {
UintTy::Usize => self.tcx.data_layout.pointer_size.unsigned_int_max(),
UintTy::U8 => u8::MAX as u128,
UintTy::U16 => u16::MAX as u128,
UintTy::U32 => u32::MAX as u128,
UintTy::U64 => u64::MAX as u128,
UintTy::U128 => u128::MAX as u128,
}
}

/// Inline literals into the format string.
///
/// Turns
///
/// `format_args!("Hello, {}! {} {}", "World", 123, x)`
///
/// into
///
/// `format_args!("Hello, World! 123 {}", x)`.
fn inline_literals<'fmt>(&self, mut fmt: Cow<'fmt, FormatArgs>) -> Cow<'fmt, FormatArgs> {
let mut was_inlined = vec![false; fmt.arguments.all_args().len()];
let mut inlined_anything = false;

for i in 0..fmt.template.len() {
let FormatArgsPiece::Placeholder(placeholder) = &fmt.template[i] else { continue };
let Ok(arg_index) = placeholder.argument.index else { continue };

let mut literal = None;

if let FormatTrait::Display = placeholder.format_trait
&& placeholder.format_options == Default::default()
&& let arg = fmt.arguments.all_args()[arg_index].expr.peel_parens_and_refs()
&& let ExprKind::Lit(lit) = arg.kind
{
literal = self.try_inline_lit(lit);
}

if let Some(literal) = literal {
// Now we need to mutate the outer FormatArgs.
// If this is the first time, this clones the outer FormatArgs.
let fmt = fmt.to_mut();
// Replace the placeholder with the literal.
fmt.template[i] = FormatArgsPiece::Literal(literal);
was_inlined[arg_index] = true;
inlined_anything = true;
}
}

// Remove the arguments that were inlined.
if inlined_anything {
let fmt = fmt.to_mut();

let mut remove = was_inlined;

// Don't remove anything that's still used.
for_all_argument_indexes(&mut fmt.template, |index| remove[*index] = false);

// Drop all the arguments that are marked for removal.
let mut remove_it = remove.iter();
fmt.arguments.all_args_mut().retain(|_| remove_it.next() != Some(&true));

// Calculate the mapping of old to new indexes for the remaining arguments.
let index_map: Vec<usize> = remove
.into_iter()
.scan(0, |i, remove| {
let mapped = *i;
*i += !remove as usize;
Some(mapped)
})
.collect();

// Correct the indexes that refer to arguments that have shifted position.
for_all_argument_indexes(&mut fmt.template, |index| *index = index_map[*index]);
}

fmt
}
}

/// Flattens nested `format_args!()` into one.
Expand Down Expand Up @@ -103,82 +219,6 @@ fn flatten_format_args(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
fmt
}

/// Inline literals into the format string.
///
/// Turns
///
/// `format_args!("Hello, {}! {} {}", "World", 123, x)`
///
/// into
///
/// `format_args!("Hello, World! 123 {}", x)`.
fn inline_literals(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
let mut was_inlined = vec![false; fmt.arguments.all_args().len()];
let mut inlined_anything = false;

for i in 0..fmt.template.len() {
let FormatArgsPiece::Placeholder(placeholder) = &fmt.template[i] else { continue };
let Ok(arg_index) = placeholder.argument.index else { continue };

let mut literal = None;

if let FormatTrait::Display = placeholder.format_trait
&& placeholder.format_options == Default::default()
&& let arg = fmt.arguments.all_args()[arg_index].expr.peel_parens_and_refs()
&& let ExprKind::Lit(lit) = arg.kind
{
if let token::LitKind::Str | token::LitKind::StrRaw(_) = lit.kind
&& let Ok(LitKind::Str(s, _)) = LitKind::from_token_lit(lit)
{
literal = Some(s);
} else if let token::LitKind::Integer = lit.kind
&& let Ok(LitKind::Int(n, _)) = LitKind::from_token_lit(lit)
{
literal = Some(Symbol::intern(&n.to_string()));
}
}

if let Some(literal) = literal {
// Now we need to mutate the outer FormatArgs.
// If this is the first time, this clones the outer FormatArgs.
let fmt = fmt.to_mut();
// Replace the placeholder with the literal.
fmt.template[i] = FormatArgsPiece::Literal(literal);
was_inlined[arg_index] = true;
inlined_anything = true;
}
}

// Remove the arguments that were inlined.
if inlined_anything {
let fmt = fmt.to_mut();

let mut remove = was_inlined;

// Don't remove anything that's still used.
for_all_argument_indexes(&mut fmt.template, |index| remove[*index] = false);

// Drop all the arguments that are marked for removal.
let mut remove_it = remove.iter();
fmt.arguments.all_args_mut().retain(|_| remove_it.next() != Some(&true));

// Calculate the mapping of old to new indexes for the remaining arguments.
let index_map: Vec<usize> = remove
.into_iter()
.scan(0, |i, remove| {
let mapped = *i;
*i += !remove as usize;
Some(mapped)
})
.collect();

// Correct the indexes that refer to arguments that have shifted position.
for_all_argument_indexes(&mut fmt.template, |index| *index = index_map[*index]);
}

fmt
}

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
enum ArgumentType {
Format(FormatTrait),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
From 0d741cf82c3c908616abd39dc84ebf7d8702e0c3 Mon Sep 17 00:00:00 2001
From: Chris Denton <chris@chrisdenton.dev>
Date: Tue, 16 Apr 2024 15:51:34 +0000
Subject: [PATCH] Revert use raw-dylib for Windows futex APIs

---
library/std/src/sys/pal/windows/c.rs | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index 9d58ce05f01..1c828bac4b6 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -357,19 +357,7 @@ pub fn GetTempPath2W(bufferlength: u32, buffer: PWSTR) -> u32 {
}

#[cfg(not(target_vendor = "win7"))]
-// Use raw-dylib to import synchronization functions to workaround issues with the older mingw import library.
-#[cfg_attr(
- target_arch = "x86",
- link(
- name = "api-ms-win-core-synch-l1-2-0",
- kind = "raw-dylib",
- import_name_type = "undecorated"
- )
-)]
-#[cfg_attr(
- not(target_arch = "x86"),
- link(name = "api-ms-win-core-synch-l1-2-0", kind = "raw-dylib")
-)]
+#[link(name = "synchronization")]
extern "system" {
pub fn WaitOnAddress(
address: *const c_void,
--
2.42.0.windows.2

22 changes: 11 additions & 11 deletions compiler/rustc_data_structures/src/graph/iterate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,21 @@ pub fn reverse_post_order<G: DirectedGraph + Successors>(
}

/// A "depth-first search" iterator for a directed graph.
pub struct DepthFirstSearch<'graph, G>
pub struct DepthFirstSearch<G>
where
G: ?Sized + DirectedGraph + Successors,
G: DirectedGraph + Successors,
{
graph: &'graph G,
graph: G,
stack: Vec<G::Node>,
visited: BitSet<G::Node>,
}

impl<'graph, G> DepthFirstSearch<'graph, G>
impl<G> DepthFirstSearch<G>
where
G: ?Sized + DirectedGraph + Successors,
G: DirectedGraph + Successors,
{
pub fn new(graph: &'graph G) -> Self {
Self { graph, stack: vec![], visited: BitSet::new_empty(graph.num_nodes()) }
pub fn new(graph: G) -> Self {
Self { stack: vec![], visited: BitSet::new_empty(graph.num_nodes()), graph }
}

/// Version of `push_start_node` that is convenient for chained
Expand Down Expand Up @@ -125,9 +125,9 @@ where
}
}

impl<G> std::fmt::Debug for DepthFirstSearch<'_, G>
impl<G> std::fmt::Debug for DepthFirstSearch<G>
where
G: ?Sized + DirectedGraph + Successors,
G: DirectedGraph + Successors,
{
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut f = fmt.debug_set();
Expand All @@ -138,9 +138,9 @@ where
}
}

impl<G> Iterator for DepthFirstSearch<'_, G>
impl<G> Iterator for DepthFirstSearch<G>
where
G: ?Sized + DirectedGraph + Successors,
G: DirectedGraph + Successors,
{
type Item = G::Node;

Expand Down
30 changes: 28 additions & 2 deletions compiler/rustc_data_structures/src/graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,35 @@ where
.is_some()
}

pub fn depth_first_search<G>(graph: &G, from: G::Node) -> iterate::DepthFirstSearch<'_, G>
pub fn depth_first_search<G>(graph: G, from: G::Node) -> iterate::DepthFirstSearch<G>
where
G: ?Sized + Successors,
G: Successors,
{
iterate::DepthFirstSearch::new(graph).with_start_node(from)
}

pub fn depth_first_search_as_undirected<G>(
graph: G,
from: G::Node,
) -> iterate::DepthFirstSearch<impl Successors<Node = G::Node>>
where
G: Successors + Predecessors,
{
struct AsUndirected<G>(G);

impl<G: DirectedGraph> DirectedGraph for AsUndirected<G> {
type Node = G::Node;

fn num_nodes(&self) -> usize {
self.0.num_nodes()
}
}

impl<G: Successors + Predecessors> Successors for AsUndirected<G> {
fn successors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
self.0.successors(node).chain(self.0.predecessors(node))
}
}

iterate::DepthFirstSearch::new(AsUndirected(graph)).with_start_node(from)
}
Loading
Loading