mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
Auto merge of #124147 - workingjubilee:rollup-7pjnzr6, r=workingjubilee
Rollup of 7 pull requests Successful merges: - #123406 (Force exhaustion in iter::ArrayChunks::into_remainder) - #123752 (Properly handle emojis as literal prefix in macros) - #123935 (Don't inline integer literals when they overflow - new attempt) - #123980 ( Add an opt-in to store incoming edges in `VecGraph` + misc) - #124019 (Use raw-dylib for Windows synchronization functions) - #124110 (Fix negating `f16` and `f128` constants) - #124116 (when suggesting RUST_BACKTRACE=1, add a special note for Miri's env var isolation) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0ed85d0c8d
@ -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.
|
||||
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -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();
|
||||
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -1,99 +1,235 @@
|
||||
use crate::graph::{DirectedGraph, NumEdges, Successors};
|
||||
use crate::graph::{DirectedGraph, NumEdges, Predecessors, Successors};
|
||||
use rustc_index::{Idx, IndexVec};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub struct VecGraph<N: Idx> {
|
||||
/// Maps from a given node to an index where the set of successors
|
||||
/// for that node starts. The index indexes into the `edges`
|
||||
/// vector. To find the range for a given node, we look up the
|
||||
/// start for that node and then the start for the next node
|
||||
/// (i.e., with an index 1 higher) and get the range between the
|
||||
/// two. This vector always has an extra entry so that this works
|
||||
/// even for the max element.
|
||||
/// A directed graph, efficient for cases where node indices are pre-existing.
|
||||
///
|
||||
/// If `BR` is true, the graph will store back-references, allowing you to get predecessors.
|
||||
pub struct VecGraph<N: Idx, const BR: bool = false> {
|
||||
// This is basically a `HashMap<N, (Vec<N>, If<BR, Vec<N>>)>` -- a map from a node index, to
|
||||
// a list of targets of outgoing edges and (if enabled) a list of sources of incoming edges.
|
||||
//
|
||||
// However, it is condensed into two arrays as an optimization.
|
||||
//
|
||||
// `node_starts[n]` is the start of the list of targets of outgoing edges for node `n`.
|
||||
// So you can get node's successors with `edge_targets[node_starts[n]..node_starts[n + 1]]`.
|
||||
//
|
||||
// If `BR` is true (back references are enabled), then `node_starts[n + edge_count]` is the
|
||||
// start of the list of *sources* of incoming edges. You can get predecessors of a node
|
||||
// similarly to its successors but offsetting by `edge_count`. `edge_count` is
|
||||
// `edge_targets.len()/2` (again, in case BR is true) because half of the vec is back refs.
|
||||
//
|
||||
// All of this might be confusing, so here is an example graph and its representation:
|
||||
//
|
||||
// n3 ----+
|
||||
// ^ | (if BR = true)
|
||||
// | v outgoing edges incoming edges
|
||||
// n0 -> n1 -> n2 ______________ __________________
|
||||
// / \ / \
|
||||
// node indices[1]: n0, n1, n2, n3, n0, n1, n2, n3, n/a
|
||||
// vec indices: n0, n1, n2, n3, n4, n5, n6, n7, n8
|
||||
// node_starts: [0, 1, 3, 4 4, 4, 5, 7, 8]
|
||||
// | | | | | | | | |
|
||||
// | | +---+ +---+ | +---+ |
|
||||
// | | | | | | |
|
||||
// v v v v v v v
|
||||
// edge_targets: [n1, n2, n3, n2 n0, n1, n3, n1]
|
||||
// / \____/ | | \____/ \
|
||||
// n0->n1 / | | \ n3<-n1
|
||||
// / n3->n2 [2] n1<-n0 [2] \
|
||||
// n1->n2, n1->n3 n2<-n1, n2<-n3
|
||||
//
|
||||
// The incoming edges are basically stored in the same way as outgoing edges, but offset and
|
||||
// the graph they store is the inverse of the original. Last index in the `node_starts` array
|
||||
// always points to one-past-the-end, so that we don't need to bound check `node_starts[n + 1]`
|
||||
//
|
||||
// [1]: "node indices" are the indices a user of `VecGraph` might use,
|
||||
// note that they are different from "vec indices",
|
||||
// which are the real indices you need to index `node_starts`
|
||||
//
|
||||
// [2]: Note that even though n2 also points to here,
|
||||
// the next index also points here, so n2 has no
|
||||
// successors (`edge_targets[3..3] = []`).
|
||||
// Similarly with n0 and incoming edges
|
||||
//
|
||||
// If this is still confusing... then sorry :(
|
||||
//
|
||||
/// Indices into `edge_targets` that signify a start of list of edges.
|
||||
node_starts: IndexVec<N, usize>,
|
||||
|
||||
/// Targets (or sources for back refs) of edges
|
||||
edge_targets: Vec<N>,
|
||||
}
|
||||
|
||||
impl<N: Idx + Ord> VecGraph<N> {
|
||||
impl<N: Idx + Ord, const BR: bool> VecGraph<N, BR> {
|
||||
pub fn new(num_nodes: usize, mut edge_pairs: Vec<(N, N)>) -> Self {
|
||||
let num_edges = edge_pairs.len();
|
||||
|
||||
let nodes_cap = match BR {
|
||||
// +1 for special entry at the end, pointing one past the end of `edge_targets`
|
||||
false => num_nodes + 1,
|
||||
// *2 for back references
|
||||
true => (num_nodes * 2) + 1,
|
||||
};
|
||||
|
||||
let edges_cap = match BR {
|
||||
false => num_edges,
|
||||
// *2 for back references
|
||||
true => num_edges * 2,
|
||||
};
|
||||
|
||||
let mut node_starts = IndexVec::with_capacity(nodes_cap);
|
||||
let mut edge_targets = Vec::with_capacity(edges_cap);
|
||||
|
||||
// Sort the edges by the source -- this is important.
|
||||
edge_pairs.sort();
|
||||
|
||||
let num_edges = edge_pairs.len();
|
||||
// Fill forward references
|
||||
create_index(
|
||||
num_nodes,
|
||||
&mut edge_pairs.iter().map(|&(src, _)| src),
|
||||
&mut edge_pairs.iter().map(|&(_, tgt)| tgt),
|
||||
&mut edge_targets,
|
||||
&mut node_starts,
|
||||
);
|
||||
|
||||
// Store the *target* of each edge into `edge_targets`.
|
||||
let edge_targets: Vec<N> = edge_pairs.iter().map(|&(_, target)| target).collect();
|
||||
// Fill back references
|
||||
if BR {
|
||||
// Pop the special "last" entry, it will be replaced by first back ref
|
||||
node_starts.pop();
|
||||
|
||||
// Create the *edge starts* array. We are iterating over the
|
||||
// (sorted) edge pairs. We maintain the invariant that the
|
||||
// length of the `node_starts` array is enough to store the
|
||||
// current source node -- so when we see that the source node
|
||||
// for an edge is greater than the current length, we grow the
|
||||
// edge-starts array by just enough.
|
||||
let mut node_starts = IndexVec::with_capacity(num_edges);
|
||||
for (index, &(source, _)) in edge_pairs.iter().enumerate() {
|
||||
// If we have a list like `[(0, x), (2, y)]`:
|
||||
//
|
||||
// - Start out with `node_starts` of `[]`
|
||||
// - Iterate to `(0, x)` at index 0:
|
||||
// - Push one entry because `node_starts.len()` (0) is <= the source (0)
|
||||
// - Leaving us with `node_starts` of `[0]`
|
||||
// - Iterate to `(2, y)` at index 1:
|
||||
// - Push one entry because `node_starts.len()` (1) is <= the source (2)
|
||||
// - Push one entry because `node_starts.len()` (2) is <= the source (2)
|
||||
// - Leaving us with `node_starts` of `[0, 1, 1]`
|
||||
// - Loop terminates
|
||||
while node_starts.len() <= source.index() {
|
||||
node_starts.push(index);
|
||||
}
|
||||
// Re-sort the edges so that they are sorted by target
|
||||
edge_pairs.sort_by_key(|&(src, tgt)| (tgt, src));
|
||||
|
||||
create_index(
|
||||
// Back essentially double the number of nodes
|
||||
num_nodes * 2,
|
||||
// NB: the source/target are switched here too
|
||||
// NB: we double the key index, so that we can later use *2 to get the back references
|
||||
&mut edge_pairs.iter().map(|&(_, tgt)| N::new(tgt.index() + num_nodes)),
|
||||
&mut edge_pairs.iter().map(|&(src, _)| src),
|
||||
&mut edge_targets,
|
||||
&mut node_starts,
|
||||
);
|
||||
}
|
||||
|
||||
// Pad out the `node_starts` array so that it has `num_nodes +
|
||||
// 1` entries. Continuing our example above, if `num_nodes` is
|
||||
// be `3`, we would push one more index: `[0, 1, 1, 2]`.
|
||||
//
|
||||
// Interpretation of that vector:
|
||||
//
|
||||
// [0, 1, 1, 2]
|
||||
// ---- range for N=2
|
||||
// ---- range for N=1
|
||||
// ---- range for N=0
|
||||
while node_starts.len() <= num_nodes {
|
||||
node_starts.push(edge_targets.len());
|
||||
}
|
||||
|
||||
assert_eq!(node_starts.len(), num_nodes + 1);
|
||||
|
||||
Self { node_starts, edge_targets }
|
||||
}
|
||||
|
||||
/// Gets the successors for `source` as a slice.
|
||||
pub fn successors(&self, source: N) -> &[N] {
|
||||
assert!(source.index() < self.num_nodes());
|
||||
|
||||
let start_index = self.node_starts[source];
|
||||
let end_index = self.node_starts[source.plus(1)];
|
||||
&self.edge_targets[start_index..end_index]
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Idx> DirectedGraph for VecGraph<N> {
|
||||
impl<N: Idx + Ord> VecGraph<N, true> {
|
||||
/// Gets the predecessors for `target` as a slice.
|
||||
pub fn predecessors(&self, target: N) -> &[N] {
|
||||
assert!(target.index() < self.num_nodes());
|
||||
|
||||
let target = N::new(target.index() + self.num_nodes());
|
||||
|
||||
let start_index = self.node_starts[target];
|
||||
let end_index = self.node_starts[target.plus(1)];
|
||||
&self.edge_targets[start_index..end_index]
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates/initializes the index for the [`VecGraph`]. A helper for [`VecGraph::new`].
|
||||
///
|
||||
/// - `num_nodes` is the target number of nodes in the graph
|
||||
/// - `sorted_edge_sources` are the edge sources, sorted
|
||||
/// - `associated_edge_targets` are the edge *targets* in the same order as sources
|
||||
/// - `edge_targets` is the vec of targets to be extended
|
||||
/// - `node_starts` is the index to be filled
|
||||
fn create_index<N: Idx + Ord>(
|
||||
num_nodes: usize,
|
||||
sorted_edge_sources: &mut dyn Iterator<Item = N>,
|
||||
associated_edge_targets: &mut dyn Iterator<Item = N>,
|
||||
edge_targets: &mut Vec<N>,
|
||||
node_starts: &mut IndexVec<N, usize>,
|
||||
) {
|
||||
let offset = edge_targets.len();
|
||||
|
||||
// Store the *target* of each edge into `edge_targets`.
|
||||
edge_targets.extend(associated_edge_targets);
|
||||
|
||||
// Create the *edge starts* array. We are iterating over the
|
||||
// (sorted) edge pairs. We maintain the invariant that the
|
||||
// length of the `node_starts` array is enough to store the
|
||||
// current source node -- so when we see that the source node
|
||||
// for an edge is greater than the current length, we grow the
|
||||
// edge-starts array by just enough.
|
||||
for (index, source) in sorted_edge_sources.enumerate() {
|
||||
// If we have a list like `[(0, x), (2, y)]`:
|
||||
//
|
||||
// - Start out with `node_starts` of `[]`
|
||||
// - Iterate to `(0, x)` at index 0:
|
||||
// - Push one entry because `node_starts.len()` (0) is <= the source (0)
|
||||
// - Leaving us with `node_starts` of `[0]`
|
||||
// - Iterate to `(2, y)` at index 1:
|
||||
// - Push one entry because `node_starts.len()` (1) is <= the source (2)
|
||||
// - Push one entry because `node_starts.len()` (2) is <= the source (2)
|
||||
// - Leaving us with `node_starts` of `[0, 1, 1]`
|
||||
// - Loop terminates
|
||||
while node_starts.len() <= source.index() {
|
||||
node_starts.push(index + offset);
|
||||
}
|
||||
}
|
||||
|
||||
// Pad out the `node_starts` array so that it has `num_nodes +
|
||||
// 1` entries. Continuing our example above, if `num_nodes` is
|
||||
// be `3`, we would push one more index: `[0, 1, 1, 2]`.
|
||||
//
|
||||
// Interpretation of that vector:
|
||||
//
|
||||
// [0, 1, 1, 2]
|
||||
// ---- range for N=2
|
||||
// ---- range for N=1
|
||||
// ---- range for N=0
|
||||
while node_starts.len() <= num_nodes {
|
||||
node_starts.push(edge_targets.len());
|
||||
}
|
||||
|
||||
assert_eq!(node_starts.len(), num_nodes + 1);
|
||||
}
|
||||
|
||||
impl<N: Idx, const BR: bool> DirectedGraph for VecGraph<N, BR> {
|
||||
type Node = N;
|
||||
|
||||
fn num_nodes(&self) -> usize {
|
||||
self.node_starts.len() - 1
|
||||
match BR {
|
||||
false => self.node_starts.len() - 1,
|
||||
// If back refs are enabled, half of the array is said back refs
|
||||
true => (self.node_starts.len() - 1) / 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Idx> NumEdges for VecGraph<N> {
|
||||
impl<N: Idx, const BR: bool> NumEdges for VecGraph<N, BR> {
|
||||
fn num_edges(&self) -> usize {
|
||||
self.edge_targets.len()
|
||||
match BR {
|
||||
false => self.edge_targets.len(),
|
||||
// If back refs are enabled, half of the array is reversed edges for them
|
||||
true => self.edge_targets.len() / 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Idx + Ord> Successors for VecGraph<N> {
|
||||
impl<N: Idx + Ord, const BR: bool> Successors for VecGraph<N, BR> {
|
||||
fn successors(&self, node: N) -> impl Iterator<Item = Self::Node> {
|
||||
self.successors(node).iter().cloned()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Idx + Ord> Predecessors for VecGraph<N, true> {
|
||||
fn predecessors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
|
||||
self.predecessors(node).iter().cloned()
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,18 @@ fn create_graph() -> VecGraph<usize> {
|
||||
VecGraph::new(7, vec![(0, 1), (1, 2), (1, 3), (3, 4), (5, 1)])
|
||||
}
|
||||
|
||||
fn create_graph_with_back_refs() -> VecGraph<usize, true> {
|
||||
// Same as above
|
||||
VecGraph::new(7, vec![(0, 1), (1, 2), (1, 3), (3, 4), (5, 1)])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn num_nodes() {
|
||||
let graph = create_graph();
|
||||
assert_eq!(graph.num_nodes(), 7);
|
||||
|
||||
let graph = create_graph_with_back_refs();
|
||||
assert_eq!(graph.num_nodes(), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -34,6 +42,27 @@ fn successors() {
|
||||
assert_eq!(graph.successors(4), &[] as &[usize]);
|
||||
assert_eq!(graph.successors(5), &[1]);
|
||||
assert_eq!(graph.successors(6), &[] as &[usize]);
|
||||
|
||||
let graph = create_graph_with_back_refs();
|
||||
assert_eq!(graph.successors(0), &[1]);
|
||||
assert_eq!(graph.successors(1), &[2, 3]);
|
||||
assert_eq!(graph.successors(2), &[] as &[usize]);
|
||||
assert_eq!(graph.successors(3), &[4]);
|
||||
assert_eq!(graph.successors(4), &[] as &[usize]);
|
||||
assert_eq!(graph.successors(5), &[1]);
|
||||
assert_eq!(graph.successors(6), &[] as &[usize]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn predecessors() {
|
||||
let graph = create_graph_with_back_refs();
|
||||
assert_eq!(graph.predecessors(0), &[]);
|
||||
assert_eq!(graph.predecessors(1), &[0, 5]);
|
||||
assert_eq!(graph.predecessors(2), &[1]);
|
||||
assert_eq!(graph.predecessors(3), &[1]);
|
||||
assert_eq!(graph.predecessors(4), &[3]);
|
||||
assert_eq!(graph.predecessors(5), &[]);
|
||||
assert_eq!(graph.predecessors(6), &[]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -41,4 +70,8 @@ fn dfs() {
|
||||
let graph = create_graph();
|
||||
let dfs: Vec<_> = graph::depth_first_search(&graph, 0).collect();
|
||||
assert_eq!(dfs, vec![0, 1, 3, 4, 2]);
|
||||
|
||||
let graph = create_graph_with_back_refs();
|
||||
let dfs: Vec<_> = graph::depth_first_search(&graph, 0).collect();
|
||||
assert_eq!(dfs, vec![0, 1, 3, 4, 2]);
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ impl<'tcx> MiniGraph<'tcx> {
|
||||
edges.push((source_node, target_node));
|
||||
},
|
||||
);
|
||||
let graph = VecGraph::new(nodes.len(), edges);
|
||||
let graph = VecGraph::<_, false>::new(nodes.len(), edges);
|
||||
let sccs = Sccs::new(&graph);
|
||||
Self { nodes, sccs }
|
||||
}
|
||||
|
@ -88,6 +88,10 @@ pub enum TokenKind {
|
||||
/// tokens.
|
||||
UnknownPrefix,
|
||||
|
||||
/// Similar to the above, but *always* an error on every edition. This is used
|
||||
/// for emoji identifier recovery, as those are not meant to be ever accepted.
|
||||
InvalidPrefix,
|
||||
|
||||
/// Examples: `12u8`, `1.0e-40`, `b"123"`. Note that `_` is an invalid
|
||||
/// suffix, but may be present here on string and float literals. Users of
|
||||
/// this type will need to check for and reject that case.
|
||||
@ -528,7 +532,7 @@ impl Cursor<'_> {
|
||||
// Known prefixes must have been handled earlier. So if
|
||||
// we see a prefix here, it is definitely an unknown prefix.
|
||||
match self.first() {
|
||||
'#' | '"' | '\'' => UnknownPrefix,
|
||||
'#' | '"' | '\'' => InvalidPrefix,
|
||||
_ => InvalidIdent,
|
||||
}
|
||||
}
|
||||
|
@ -1023,7 +1023,13 @@ pub(crate) fn parse_float_into_scalar(
|
||||
let num = num.as_str();
|
||||
match float_ty {
|
||||
// FIXME(f16_f128): When available, compare to the library parser as with `f32` and `f64`
|
||||
ty::FloatTy::F16 => num.parse::<Half>().ok().map(Scalar::from_f16),
|
||||
ty::FloatTy::F16 => {
|
||||
let mut f = num.parse::<Half>().ok()?;
|
||||
if neg {
|
||||
f = -f;
|
||||
}
|
||||
Some(Scalar::from_f16(f))
|
||||
}
|
||||
ty::FloatTy::F32 => {
|
||||
let Ok(rust_f) = num.parse::<f32>() else { return None };
|
||||
let mut f = num
|
||||
@ -1071,7 +1077,13 @@ pub(crate) fn parse_float_into_scalar(
|
||||
Some(Scalar::from_f64(f))
|
||||
}
|
||||
// FIXME(f16_f128): When available, compare to the library parser as with `f32` and `f64`
|
||||
ty::FloatTy::F128 => num.parse::<Quad>().ok().map(Scalar::from_f128),
|
||||
ty::FloatTy::F128 => {
|
||||
let mut f = num.parse::<Quad>().ok()?;
|
||||
if neg {
|
||||
f = -f;
|
||||
}
|
||||
Some(Scalar::from_f128(f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,6 +204,7 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
|
||||
self.ident(start)
|
||||
}
|
||||
rustc_lexer::TokenKind::InvalidIdent
|
||||
| rustc_lexer::TokenKind::InvalidPrefix
|
||||
// Do not recover an identifier with emoji if the codepoint is a confusable
|
||||
// with a recoverable substitution token, like `➖`.
|
||||
if !UNICODE_ARRAY
|
||||
@ -301,7 +302,9 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
|
||||
rustc_lexer::TokenKind::Caret => token::BinOp(token::Caret),
|
||||
rustc_lexer::TokenKind::Percent => token::BinOp(token::Percent),
|
||||
|
||||
rustc_lexer::TokenKind::Unknown | rustc_lexer::TokenKind::InvalidIdent => {
|
||||
rustc_lexer::TokenKind::Unknown
|
||||
| rustc_lexer::TokenKind::InvalidIdent
|
||||
| rustc_lexer::TokenKind::InvalidPrefix => {
|
||||
// Don't emit diagnostics for sequences of the same invalid token
|
||||
if swallow_next_invalid > 0 {
|
||||
swallow_next_invalid -= 1;
|
||||
|
@ -34,9 +34,22 @@ where
|
||||
/// Returns an iterator over the remaining elements of the original iterator
|
||||
/// that are not going to be returned by this iterator. The returned
|
||||
/// iterator will yield at most `N-1` elements.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # // Also serves as a regression test for https://github.com/rust-lang/rust/issues/123333
|
||||
/// # #![feature(iter_array_chunks)]
|
||||
/// let x = [1,2,3,4,5].into_iter().array_chunks::<2>();
|
||||
/// let mut rem = x.into_remainder().unwrap();
|
||||
/// assert_eq!(rem.next(), Some(5));
|
||||
/// assert_eq!(rem.next(), None);
|
||||
/// ```
|
||||
#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
|
||||
#[inline]
|
||||
pub fn into_remainder(self) -> Option<array::IntoIter<I::Item, N>> {
|
||||
pub fn into_remainder(mut self) -> Option<array::IntoIter<I::Item, N>> {
|
||||
if self.remainder.is_none() {
|
||||
while let Some(_) = self.next() {}
|
||||
}
|
||||
self.remainder
|
||||
}
|
||||
}
|
||||
|
@ -277,6 +277,13 @@ fn default_hook(info: &PanicInfo<'_>) {
|
||||
"note: run with `RUST_BACKTRACE=1` environment variable to display a \
|
||||
backtrace"
|
||||
);
|
||||
if cfg!(miri) {
|
||||
let _ = writeln!(
|
||||
err,
|
||||
"note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` \
|
||||
for the environment variable to have an effect"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// If backtraces aren't supported or are forced-off, do nothing.
|
||||
|
@ -357,7 +357,19 @@ compat_fn_with_fallback! {
|
||||
}
|
||||
|
||||
#[cfg(not(target_vendor = "win7"))]
|
||||
#[link(name = "synchronization")]
|
||||
// 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")
|
||||
)]
|
||||
extern "system" {
|
||||
pub fn WaitOnAddress(
|
||||
address: *const c_void,
|
||||
|
@ -876,9 +876,10 @@ impl<'src> Classifier<'src> {
|
||||
},
|
||||
Some(c) => c,
|
||||
},
|
||||
TokenKind::RawIdent | TokenKind::UnknownPrefix | TokenKind::InvalidIdent => {
|
||||
Class::Ident(self.new_span(before, text))
|
||||
}
|
||||
TokenKind::RawIdent
|
||||
| TokenKind::UnknownPrefix
|
||||
| TokenKind::InvalidPrefix
|
||||
| TokenKind::InvalidIdent => Class::Ident(self.new_span(before, text)),
|
||||
TokenKind::Lifetime { .. } => Class::Lifetime,
|
||||
TokenKind::Eof => panic!("Eof in advance"),
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/exported_symbol_bad_unwind1.rs:LL:CC:
|
||||
explicit panic
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
|
||||
--> $DIR/exported_symbol_bad_unwind1.rs:LL:CC
|
||||
|
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/exported_symbol_bad_unwind2.rs:LL:CC:
|
||||
explicit panic
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
|
||||
panic in a function that cannot unwind
|
||||
stack backtrace:
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/exported_symbol_bad_unwind2.rs:LL:CC:
|
||||
explicit panic
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
|
||||
panic in a function that cannot unwind
|
||||
stack backtrace:
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/exported_symbol_bad_unwind2.rs:LL:CC:
|
||||
explicit panic
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
|
||||
--> $DIR/exported_symbol_bad_unwind2.rs:LL:CC
|
||||
|
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/return_pointer_on_unwind.rs:LL:CC:
|
||||
explicit panic
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
|
||||
--> $DIR/return_pointer_on_unwind.rs:LL:CC
|
||||
|
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
|
||||
aborted execution: attempted to instantiate uninhabited type `!`
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
thread caused non-unwinding panic. aborting.
|
||||
error: abnormal termination: the program aborted execution
|
||||
--> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
|
||||
aborted execution: attempted to zero-initialize type `fn()`, which is invalid
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
thread caused non-unwinding panic. aborting.
|
||||
error: abnormal termination: the program aborted execution
|
||||
--> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/bad_unwind.rs:LL:CC:
|
||||
explicit panic
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
|
||||
--> $DIR/bad_unwind.rs:LL:CC
|
||||
|
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/double_panic.rs:LL:CC:
|
||||
first
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
thread 'main' panicked at $DIR/double_panic.rs:LL:CC:
|
||||
second
|
||||
stack backtrace:
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/panic_abort1.rs:LL:CC:
|
||||
panicking from libstd
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
error: abnormal termination: the program aborted execution
|
||||
--> RUSTLIB/panic_abort/src/lib.rs:LL:CC
|
||||
|
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/panic_abort2.rs:LL:CC:
|
||||
42-panicking from libstd
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
error: abnormal termination: the program aborted execution
|
||||
--> RUSTLIB/panic_abort/src/lib.rs:LL:CC
|
||||
|
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/panic_abort3.rs:LL:CC:
|
||||
panicking from libcore
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
error: abnormal termination: the program aborted execution
|
||||
--> RUSTLIB/panic_abort/src/lib.rs:LL:CC
|
||||
|
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/panic_abort4.rs:LL:CC:
|
||||
42-panicking from libcore
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
error: abnormal termination: the program aborted execution
|
||||
--> RUSTLIB/panic_abort/src/lib.rs:LL:CC
|
||||
|
|
||||
|
@ -3,6 +3,7 @@ warning: You have explicitly enabled MIR optimizations, overriding Miri's defaul
|
||||
thread 'main' panicked at $DIR/terminate-terminator.rs:LL:CC:
|
||||
explicit panic
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
|
||||
panic in a function that cannot unwind
|
||||
stack backtrace:
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/unwind-action-terminate.rs:LL:CC:
|
||||
explicit panic
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
|
||||
panic in a function that cannot unwind
|
||||
stack backtrace:
|
||||
|
@ -1,3 +1,4 @@
|
||||
thread 'main' panicked at $DIR/div-by-zero-2.rs:LL:CC:
|
||||
attempt to divide by zero
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/exported_symbol_good_unwind.rs:LL:CC:
|
||||
explicit panic
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
thread 'main' panicked at $DIR/exported_symbol_good_unwind.rs:LL:CC:
|
||||
explicit panic
|
||||
thread 'main' panicked at $DIR/exported_symbol_good_unwind.rs:LL:CC:
|
||||
|
@ -1,3 +1,4 @@
|
||||
thread 'main' panicked at $DIR/oob_subslice.rs:LL:CC:
|
||||
range end index 5 out of range for slice of length 4
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
|
@ -1,3 +1,4 @@
|
||||
thread 'main' panicked at $DIR/overflowing-lsh-neg.rs:LL:CC:
|
||||
attempt to shift left with overflow
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
|
@ -1,3 +1,4 @@
|
||||
thread 'main' panicked at $DIR/overflowing-rsh-1.rs:LL:CC:
|
||||
attempt to shift right with overflow
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
|
@ -1,3 +1,4 @@
|
||||
thread 'main' panicked at $DIR/overflowing-rsh-2.rs:LL:CC:
|
||||
attempt to shift right with overflow
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
|
@ -1,3 +1,4 @@
|
||||
thread 'main' panicked at $DIR/panic2.rs:LL:CC:
|
||||
42-panicking from libstd
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
|
@ -1,3 +1,4 @@
|
||||
thread 'main' panicked at $DIR/panic3.rs:LL:CC:
|
||||
panicking from libcore
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
|
@ -1,3 +1,4 @@
|
||||
thread 'main' panicked at $DIR/panic4.rs:LL:CC:
|
||||
42-panicking from libcore
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
|
@ -1,3 +1,4 @@
|
||||
thread 'main' panicked at $DIR/transmute_fat2.rs:LL:CC:
|
||||
index out of bounds: the len is 0 but the index is 0
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
|
@ -1,3 +1,4 @@
|
||||
thread 'main' panicked at $DIR/unsupported_foreign_function.rs:LL:CC:
|
||||
unsupported Miri functionality: can't call foreign function `foo` on $OS
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
|
@ -1,3 +1,4 @@
|
||||
thread 'main' panicked at $DIR/unsupported_syscall.rs:LL:CC:
|
||||
unsupported Miri functionality: can't execute syscall with ID 0
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/catch_panic.rs:LL:CC:
|
||||
Hello from std::panic
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
Caught panic message (&str): Hello from std::panic
|
||||
thread 'main' panicked at $DIR/catch_panic.rs:LL:CC:
|
||||
Hello from std::panic: 1
|
||||
|
@ -3,6 +3,7 @@ Thread 1 reported it has started
|
||||
thread '<unnamed>' panicked at $DIR/concurrent-panic.rs:LL:CC:
|
||||
panic in thread 2
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
Thread 2 blocking on thread 1
|
||||
Thread 2 reported it has started
|
||||
Unlocking mutex
|
||||
|
@ -1,6 +1,7 @@
|
||||
thread 'main' panicked at $DIR/nested_panic_caught.rs:LL:CC:
|
||||
once
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
thread 'main' panicked at $DIR/nested_panic_caught.rs:LL:CC:
|
||||
twice
|
||||
stack backtrace:
|
||||
|
@ -1,5 +1,6 @@
|
||||
thread '<unnamed>' panicked at $DIR/thread_panic.rs:LL:CC:
|
||||
Hello!
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||
thread 'childthread' panicked at $DIR/thread_panic.rs:LL:CC:
|
||||
Hello, world!
|
||||
|
@ -178,7 +178,7 @@ impl<'a> Converter<'a> {
|
||||
rustc_lexer::TokenKind::Ident => {
|
||||
SyntaxKind::from_keyword(token_text).unwrap_or(IDENT)
|
||||
}
|
||||
rustc_lexer::TokenKind::InvalidIdent => {
|
||||
rustc_lexer::TokenKind::InvalidPrefix | rustc_lexer::TokenKind::InvalidIdent => {
|
||||
err = "Ident contains invalid characters";
|
||||
IDENT
|
||||
}
|
||||
|
14
tests/ui/fmt/no-inline-literals-out-of-range.rs
Normal file
14
tests/ui/fmt/no-inline-literals-out-of-range.rs
Normal file
@ -0,0 +1,14 @@
|
||||
//@ only-64bit
|
||||
|
||||
fn main() {
|
||||
format_args!("{}", 0x8f_i8); // issue #115423
|
||||
//~^ ERROR literal out of range for `i8`
|
||||
format_args!("{}", 0xffff_ffff_u8); // issue #116633
|
||||
//~^ ERROR literal out of range for `u8`
|
||||
format_args!("{}", 0xffff_ffff_ffff_ffff_ffff_usize);
|
||||
//~^ ERROR literal out of range for `usize`
|
||||
format_args!("{}", 0x8000_0000_0000_0000_isize);
|
||||
//~^ ERROR literal out of range for `isize`
|
||||
format_args!("{}", 0xffff_ffff); // treat unsuffixed literals as i32
|
||||
//~^ ERROR literal out of range for `i32`
|
||||
}
|
56
tests/ui/fmt/no-inline-literals-out-of-range.stderr
Normal file
56
tests/ui/fmt/no-inline-literals-out-of-range.stderr
Normal file
@ -0,0 +1,56 @@
|
||||
error: literal out of range for `i8`
|
||||
--> $DIR/no-inline-literals-out-of-range.rs:4:24
|
||||
|
|
||||
LL | format_args!("{}", 0x8f_i8); // issue #115423
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: the literal `0x8f_i8` (decimal `143`) does not fit into the type `i8` and will become `-113i8`
|
||||
= note: `#[deny(overflowing_literals)]` on by default
|
||||
help: consider using the type `u8` instead
|
||||
|
|
||||
LL | format_args!("{}", 0x8f_u8); // issue #115423
|
||||
| ~~~~~~~
|
||||
help: to use as a negative number (decimal `-113`), consider using the type `u8` for the literal and cast it to `i8`
|
||||
|
|
||||
LL | format_args!("{}", 0x8f_u8 as i8); // issue #115423
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: literal out of range for `u8`
|
||||
--> $DIR/no-inline-literals-out-of-range.rs:6:24
|
||||
|
|
||||
LL | format_args!("{}", 0xffff_ffff_u8); // issue #116633
|
||||
| ^^^^^^^^^^^^^^ help: consider using the type `u32` instead: `0xffff_ffff_u32`
|
||||
|
|
||||
= note: the literal `0xffff_ffff_u8` (decimal `4294967295`) does not fit into the type `u8` and will become `255u8`
|
||||
|
||||
error: literal out of range for `usize`
|
||||
--> $DIR/no-inline-literals-out-of-range.rs:8:24
|
||||
|
|
||||
LL | format_args!("{}", 0xffff_ffff_ffff_ffff_ffff_usize);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the literal `0xffff_ffff_ffff_ffff_ffff_usize` (decimal `1208925819614629174706175`) does not fit into the type `usize` and will become `18446744073709551615usize`
|
||||
|
||||
error: literal out of range for `isize`
|
||||
--> $DIR/no-inline-literals-out-of-range.rs:10:24
|
||||
|
|
||||
LL | format_args!("{}", 0x8000_0000_0000_0000_isize);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the literal `0x8000_0000_0000_0000_isize` (decimal `9223372036854775808`) does not fit into the type `isize` and will become `-9223372036854775808isize`
|
||||
|
||||
error: literal out of range for `i32`
|
||||
--> $DIR/no-inline-literals-out-of-range.rs:12:24
|
||||
|
|
||||
LL | format_args!("{}", 0xffff_ffff); // treat unsuffixed literals as i32
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: the literal `0xffff_ffff` (decimal `4294967295`) does not fit into the type `i32` and will become `-1i32`
|
||||
= help: consider using the type `u32` instead
|
||||
help: to use as a negative number (decimal `-1`), consider using the type `u32` for the literal and cast it to `i32`
|
||||
|
|
||||
LL | format_args!("{}", 0xffff_ffffu32 as i32); // treat unsuffixed literals as i32
|
||||
| ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
8
tests/ui/lexer/emoji-literal-prefix.rs
Normal file
8
tests/ui/lexer/emoji-literal-prefix.rs
Normal file
@ -0,0 +1,8 @@
|
||||
macro_rules! lexes {($($_:tt)*) => {}}
|
||||
|
||||
lexes!(🐛#); //~ ERROR identifiers cannot contain emoji
|
||||
lexes!(🐛"foo");
|
||||
lexes!(🐛'q');
|
||||
lexes!(🐛'q);
|
||||
|
||||
fn main() {}
|
14
tests/ui/lexer/emoji-literal-prefix.stderr
Normal file
14
tests/ui/lexer/emoji-literal-prefix.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: identifiers cannot contain emoji: `🐛`
|
||||
--> $DIR/emoji-literal-prefix.rs:3:8
|
||||
|
|
||||
LL | lexes!(🐛#);
|
||||
| ^^
|
||||
LL | lexes!(🐛"foo");
|
||||
| ^^
|
||||
LL | lexes!(🐛'q');
|
||||
| ^^
|
||||
LL | lexes!(🐛'q);
|
||||
| ^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
16
tests/ui/numbers-arithmetic/f16-f128-lit.rs
Normal file
16
tests/ui/numbers-arithmetic/f16-f128-lit.rs
Normal file
@ -0,0 +1,16 @@
|
||||
//@ run-pass
|
||||
|
||||
#![feature(f16)]
|
||||
#![feature(f128)]
|
||||
|
||||
fn main() {
|
||||
assert_eq!(0.0_f16.to_bits(), 0x0000);
|
||||
assert_eq!((-0.0_f16).to_bits(), 0x8000);
|
||||
assert_eq!(10.0_f16.to_bits(), 0x4900);
|
||||
assert_eq!((-10.0_f16).to_bits(), 0xC900);
|
||||
|
||||
assert_eq!(0.0_f128.to_bits(), 0x0000_0000_0000_0000_0000_0000_0000_0000);
|
||||
assert_eq!((-0.0_f128).to_bits(), 0x8000_0000_0000_0000_0000_0000_0000_0000);
|
||||
assert_eq!(10.0_f128.to_bits(), 0x4002_4000_0000_0000_0000_0000_0000_0000);
|
||||
assert_eq!((-10.0_f128).to_bits(), 0xC002_4000_0000_0000_0000_0000_0000_0000);
|
||||
}
|
Loading…
Reference in New Issue
Block a user