diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index d2c3b8b2d5652..ca4604c60c580 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -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 { + 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 = 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 = 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), diff --git a/compiler/rustc_codegen_cranelift/patches/0030-stdlib-Revert-use-raw-dylib-for-Windows-futex-APIs.patch b/compiler/rustc_codegen_cranelift/patches/0030-stdlib-Revert-use-raw-dylib-for-Windows-futex-APIs.patch new file mode 100644 index 0000000000000..21f5ee9cc6ea0 --- /dev/null +++ b/compiler/rustc_codegen_cranelift/patches/0030-stdlib-Revert-use-raw-dylib-for-Windows-futex-APIs.patch @@ -0,0 +1,37 @@ +From 0d741cf82c3c908616abd39dc84ebf7d8702e0c3 Mon Sep 17 00:00:00 2001 +From: Chris Denton +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 + diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index 7a77f2c0dbbf1..78d05a6e1951b 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs @@ -70,21 +70,21 @@ pub fn reverse_post_order( } /// A "depth-first search" iterator for a directed graph. -pub struct DepthFirstSearch<'graph, G> +pub struct DepthFirstSearch where - G: ?Sized + DirectedGraph + Successors, + G: DirectedGraph + Successors, { - graph: &'graph G, + graph: G, stack: Vec, visited: BitSet, } -impl<'graph, G> DepthFirstSearch<'graph, G> +impl DepthFirstSearch 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 std::fmt::Debug for DepthFirstSearch<'_, G> +impl std::fmt::Debug for DepthFirstSearch 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 Iterator for DepthFirstSearch<'_, G> +impl Iterator for DepthFirstSearch where - G: ?Sized + DirectedGraph + Successors, + G: DirectedGraph + Successors, { type Item = G::Node; diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs index 3ae3023a91b34..103ddd917bf84 100644 --- a/compiler/rustc_data_structures/src/graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/mod.rs @@ -46,9 +46,35 @@ where .is_some() } -pub fn depth_first_search(graph: &G, from: G::Node) -> iterate::DepthFirstSearch<'_, G> +pub fn depth_first_search(graph: G, from: G::Node) -> iterate::DepthFirstSearch where - G: ?Sized + Successors, + G: Successors, { iterate::DepthFirstSearch::new(graph).with_start_node(from) } + +pub fn depth_first_search_as_undirected( + graph: G, + from: G::Node, +) -> iterate::DepthFirstSearch> +where + G: Successors + Predecessors, +{ + struct AsUndirected(G); + + impl DirectedGraph for AsUndirected { + type Node = G::Node; + + fn num_nodes(&self) -> usize { + self.0.num_nodes() + } + } + + impl Successors for AsUndirected { + fn successors(&self, node: Self::Node) -> impl Iterator { + self.0.successors(node).chain(self.0.predecessors(node)) + } + } + + iterate::DepthFirstSearch::new(AsUndirected(graph)).with_start_node(from) +} diff --git a/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs b/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs index 26c86469fad84..120244c8918a0 100644 --- a/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs @@ -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 { - /// 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 { + // This is basically a `HashMap, If>)>` -- 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, + /// Targets (or sources for back refs) of edges edge_targets: Vec, } -impl VecGraph { +impl VecGraph { 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 = edge_pairs.iter().map(|&(_, target)| target).collect(); - - // 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); - } - } + // Fill back references + if BR { + // Pop the special "last" entry, it will be replaced by first back ref + node_starts.pop(); - // 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()); - } + // Re-sort the edges so that they are sorted by target + edge_pairs.sort_by_key(|&(src, tgt)| (tgt, src)); - assert_eq!(node_starts.len(), num_nodes + 1); + 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, + ); + } 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 DirectedGraph for VecGraph { +impl VecGraph { + /// 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( + num_nodes: usize, + sorted_edge_sources: &mut dyn Iterator, + associated_edge_targets: &mut dyn Iterator, + edge_targets: &mut Vec, + node_starts: &mut IndexVec, +) { + 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 DirectedGraph for VecGraph { 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 NumEdges for VecGraph { +impl NumEdges for VecGraph { 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 Successors for VecGraph { +impl Successors for VecGraph { fn successors(&self, node: N) -> impl Iterator { self.successors(node).iter().cloned() } } + +impl Predecessors for VecGraph { + fn predecessors(&self, node: Self::Node) -> impl Iterator { + self.predecessors(node).iter().cloned() + } +} diff --git a/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs b/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs index 87c8d25f09492..a077d9d081364 100644 --- a/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs +++ b/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs @@ -18,10 +18,18 @@ fn create_graph() -> VecGraph { VecGraph::new(7, vec![(0, 1), (1, 2), (1, 3), (3, 4), (5, 1)]) } +fn create_graph_with_back_refs() -> VecGraph { + // 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]); } diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index 06f8dd4a4c6cd..6e8efa3e7c182 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -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 } } diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index ca84e930c2439..83fff98bad56c 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -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, } } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index cc525f2ac2f37..3c18afe1a78ec 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -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::().ok().map(Scalar::from_f16), + ty::FloatTy::F16 => { + let mut f = num.parse::().ok()?; + if neg { + f = -f; + } + Some(Scalar::from_f16(f)) + } ty::FloatTy::F32 => { let Ok(rust_f) = num.parse::() 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::().ok().map(Scalar::from_f128), + ty::FloatTy::F128 => { + let mut f = num.parse::().ok()?; + if neg { + f = -f; + } + Some(Scalar::from_f128(f)) + } } } diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 058539e171755..1abb1d29562d9 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -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; diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs index 8c68ea114dbd2..8f1744fc5fbb7 100644 --- a/library/core/src/iter/adapters/array_chunks.rs +++ b/library/core/src/iter/adapters/array_chunks.rs @@ -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> { + pub fn into_remainder(mut self) -> Option> { + if self.remainder.is_none() { + while let Some(_) = self.next() {} + } self.remainder } } diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 0052fcbb94a81..5699937cdb49b 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -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. diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index 1c828bac4b662..9d58ce05f018b 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -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, diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index aa5998876d9ab..336d18a1df1c6 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -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"), }; diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr index ab32883a03562..42beed4ecdec3 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr @@ -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 | diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr index 9774e1e1a793b..d88781ed22549 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr @@ -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: diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr index 9774e1e1a793b..d88781ed22549 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr @@ -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: diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr index f89cee0b86332..bc3e4858716e3 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr @@ -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 | diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr index 7f035eb5e8575..a2fa4c1d590d0 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr @@ -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 | diff --git a/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr b/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr index 4723eddaa67be..447f7cae6ce9d 100644 --- a/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr +++ b/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr @@ -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 diff --git a/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr b/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr index 9c6dd10079edb..bae34149807fc 100644 --- a/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr +++ b/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr @@ -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 diff --git a/src/tools/miri/tests/fail/panic/bad_unwind.stderr b/src/tools/miri/tests/fail/panic/bad_unwind.stderr index e4af01feb8d7a..230e8337c7cd1 100644 --- a/src/tools/miri/tests/fail/panic/bad_unwind.stderr +++ b/src/tools/miri/tests/fail/panic/bad_unwind.stderr @@ -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 | diff --git a/src/tools/miri/tests/fail/panic/double_panic.stderr b/src/tools/miri/tests/fail/panic/double_panic.stderr index e3cacbd27bac6..3b7a1511fa0b6 100644 --- a/src/tools/miri/tests/fail/panic/double_panic.stderr +++ b/src/tools/miri/tests/fail/panic/double_panic.stderr @@ -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: diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.stderr b/src/tools/miri/tests/fail/panic/panic_abort1.stderr index 60455693619f3..7694cc70b227a 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort1.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort1.stderr @@ -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 | diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.stderr b/src/tools/miri/tests/fail/panic/panic_abort2.stderr index 7bb27e4baa0a5..e6a4380ea5187 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort2.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort2.stderr @@ -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 | diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.stderr b/src/tools/miri/tests/fail/panic/panic_abort3.stderr index b46e8c2079580..23e2021eeef85 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort3.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort3.stderr @@ -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 | diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.stderr b/src/tools/miri/tests/fail/panic/panic_abort4.stderr index b15f720e43f13..20a0ddb901926 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort4.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort4.stderr @@ -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 | diff --git a/src/tools/miri/tests/fail/terminate-terminator.stderr b/src/tools/miri/tests/fail/terminate-terminator.stderr index 8dbc802bf5955..f737adc561d9c 100644 --- a/src/tools/miri/tests/fail/terminate-terminator.stderr +++ b/src/tools/miri/tests/fail/terminate-terminator.stderr @@ -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: diff --git a/src/tools/miri/tests/fail/unwind-action-terminate.stderr b/src/tools/miri/tests/fail/unwind-action-terminate.stderr index 1323a3971003c..7e722f7be3288 100644 --- a/src/tools/miri/tests/fail/unwind-action-terminate.stderr +++ b/src/tools/miri/tests/fail/unwind-action-terminate.stderr @@ -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: diff --git a/src/tools/miri/tests/panic/div-by-zero-2.stderr b/src/tools/miri/tests/panic/div-by-zero-2.stderr index 0f088ddd1a544..f0b84ea6fd606 100644 --- a/src/tools/miri/tests/panic/div-by-zero-2.stderr +++ b/src/tools/miri/tests/panic/div-by-zero-2.stderr @@ -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 diff --git a/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr b/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr index acc0e58885f23..f77f6f01119ec 100644 --- a/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr +++ b/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr @@ -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: diff --git a/src/tools/miri/tests/panic/oob_subslice.stderr b/src/tools/miri/tests/panic/oob_subslice.stderr index 2bccb60352e0a..c116f8eb5250e 100644 --- a/src/tools/miri/tests/panic/oob_subslice.stderr +++ b/src/tools/miri/tests/panic/oob_subslice.stderr @@ -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 diff --git a/src/tools/miri/tests/panic/overflowing-lsh-neg.stderr b/src/tools/miri/tests/panic/overflowing-lsh-neg.stderr index 2cff81c58af10..1d057ea5eb4ba 100644 --- a/src/tools/miri/tests/panic/overflowing-lsh-neg.stderr +++ b/src/tools/miri/tests/panic/overflowing-lsh-neg.stderr @@ -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 diff --git a/src/tools/miri/tests/panic/overflowing-rsh-1.stderr b/src/tools/miri/tests/panic/overflowing-rsh-1.stderr index 13117df5fc39a..d1a79400bfabe 100644 --- a/src/tools/miri/tests/panic/overflowing-rsh-1.stderr +++ b/src/tools/miri/tests/panic/overflowing-rsh-1.stderr @@ -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 diff --git a/src/tools/miri/tests/panic/overflowing-rsh-2.stderr b/src/tools/miri/tests/panic/overflowing-rsh-2.stderr index 986a66f899188..612b0c0c4c21f 100644 --- a/src/tools/miri/tests/panic/overflowing-rsh-2.stderr +++ b/src/tools/miri/tests/panic/overflowing-rsh-2.stderr @@ -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 diff --git a/src/tools/miri/tests/panic/panic2.stderr b/src/tools/miri/tests/panic/panic2.stderr index bee1af2bef662..792c71346fd6a 100644 --- a/src/tools/miri/tests/panic/panic2.stderr +++ b/src/tools/miri/tests/panic/panic2.stderr @@ -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 diff --git a/src/tools/miri/tests/panic/panic3.stderr b/src/tools/miri/tests/panic/panic3.stderr index 8dac000d291bc..f8016bc3912d2 100644 --- a/src/tools/miri/tests/panic/panic3.stderr +++ b/src/tools/miri/tests/panic/panic3.stderr @@ -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 diff --git a/src/tools/miri/tests/panic/panic4.stderr b/src/tools/miri/tests/panic/panic4.stderr index 13437fe7f0751..67410bf3b1a0e 100644 --- a/src/tools/miri/tests/panic/panic4.stderr +++ b/src/tools/miri/tests/panic/panic4.stderr @@ -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 diff --git a/src/tools/miri/tests/panic/transmute_fat2.stderr b/src/tools/miri/tests/panic/transmute_fat2.stderr index 1f09a2c1a082c..2ee01d469312b 100644 --- a/src/tools/miri/tests/panic/transmute_fat2.stderr +++ b/src/tools/miri/tests/panic/transmute_fat2.stderr @@ -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 diff --git a/src/tools/miri/tests/panic/unsupported_foreign_function.stderr b/src/tools/miri/tests/panic/unsupported_foreign_function.stderr index 4db1e2909618a..d0a7d8dafc5a4 100644 --- a/src/tools/miri/tests/panic/unsupported_foreign_function.stderr +++ b/src/tools/miri/tests/panic/unsupported_foreign_function.stderr @@ -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 diff --git a/src/tools/miri/tests/panic/unsupported_syscall.stderr b/src/tools/miri/tests/panic/unsupported_syscall.stderr index 40ba6671d5b6d..f802159cb1cf8 100644 --- a/src/tools/miri/tests/panic/unsupported_syscall.stderr +++ b/src/tools/miri/tests/panic/unsupported_syscall.stderr @@ -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 diff --git a/src/tools/miri/tests/pass/panic/catch_panic.stderr b/src/tools/miri/tests/pass/panic/catch_panic.stderr index cbcd626e39fb4..a472a5d80cb76 100644 --- a/src/tools/miri/tests/pass/panic/catch_panic.stderr +++ b/src/tools/miri/tests/pass/panic/catch_panic.stderr @@ -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 diff --git a/src/tools/miri/tests/pass/panic/concurrent-panic.stderr b/src/tools/miri/tests/pass/panic/concurrent-panic.stderr index 0bb3dcd8d248c..b2a5cf4922c88 100644 --- a/src/tools/miri/tests/pass/panic/concurrent-panic.stderr +++ b/src/tools/miri/tests/pass/panic/concurrent-panic.stderr @@ -3,6 +3,7 @@ Thread 1 reported it has started thread '' 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 diff --git a/src/tools/miri/tests/pass/panic/nested_panic_caught.stderr b/src/tools/miri/tests/pass/panic/nested_panic_caught.stderr index 4684beb33383a..3efb4be40f911 100644 --- a/src/tools/miri/tests/pass/panic/nested_panic_caught.stderr +++ b/src/tools/miri/tests/pass/panic/nested_panic_caught.stderr @@ -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: diff --git a/src/tools/miri/tests/pass/panic/thread_panic.stderr b/src/tools/miri/tests/pass/panic/thread_panic.stderr index badd409d13fab..bdfe4f98ba369 100644 --- a/src/tools/miri/tests/pass/panic/thread_panic.stderr +++ b/src/tools/miri/tests/pass/panic/thread_panic.stderr @@ -1,5 +1,6 @@ thread '' 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! diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs index 48e4c8a6225c4..e5fec67de7060 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs @@ -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 } diff --git a/tests/ui/fmt/no-inline-literals-out-of-range.rs b/tests/ui/fmt/no-inline-literals-out-of-range.rs new file mode 100644 index 0000000000000..d2532cdfbff61 --- /dev/null +++ b/tests/ui/fmt/no-inline-literals-out-of-range.rs @@ -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` +} diff --git a/tests/ui/fmt/no-inline-literals-out-of-range.stderr b/tests/ui/fmt/no-inline-literals-out-of-range.stderr new file mode 100644 index 0000000000000..78ec4888c27a3 --- /dev/null +++ b/tests/ui/fmt/no-inline-literals-out-of-range.stderr @@ -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 + diff --git a/tests/ui/lexer/emoji-literal-prefix.rs b/tests/ui/lexer/emoji-literal-prefix.rs new file mode 100644 index 0000000000000..ccc8d48d4cc3e --- /dev/null +++ b/tests/ui/lexer/emoji-literal-prefix.rs @@ -0,0 +1,8 @@ +macro_rules! lexes {($($_:tt)*) => {}} + +lexes!(🐛#); //~ ERROR identifiers cannot contain emoji +lexes!(🐛"foo"); +lexes!(🐛'q'); +lexes!(🐛'q); + +fn main() {} diff --git a/tests/ui/lexer/emoji-literal-prefix.stderr b/tests/ui/lexer/emoji-literal-prefix.stderr new file mode 100644 index 0000000000000..25aafed48ea9a --- /dev/null +++ b/tests/ui/lexer/emoji-literal-prefix.stderr @@ -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 + diff --git a/tests/ui/numbers-arithmetic/f16-f128-lit.rs b/tests/ui/numbers-arithmetic/f16-f128-lit.rs new file mode 100644 index 0000000000000..762436edb1663 --- /dev/null +++ b/tests/ui/numbers-arithmetic/f16-f128-lit.rs @@ -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); +}