Skip to content

Commit 4051473

Browse files
committed
Auto merge of #78661 - JohnTitor:rollup-er2isja, r=JohnTitor
Rollup of 5 pull requests Successful merges: - #78606 (Clarify handling of final line ending in str::lines()) - #78610 (Do not remove tokens before AST json serialization) - #78620 (Trivial fixes to bitwise operator documentation) - #78627 (Point out that total_cmp is no strict superset of partial comparison) - #78637 (Add fetch_update methods to AtomicBool and AtomicPtr) Failed merges: r? `@ghost`
2 parents 234099d + 50d7716 commit 4051473

15 files changed

+189
-158
lines changed

compiler/rustc_ast/src/tokenstream.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,9 @@ impl fmt::Debug for LazyTokenStream {
153153
}
154154

155155
impl<S: Encoder> Encodable<S> for LazyTokenStream {
156-
fn encode(&self, _s: &mut S) -> Result<(), S::Error> {
157-
panic!("Attempted to encode LazyTokenStream");
156+
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
157+
// Used by AST json printing.
158+
Encodable::encode(&self.create_token_stream(), s)
158159
}
159160
}
160161

compiler/rustc_interface/src/passes.rs

+2-88
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ use crate::interface::{Compiler, Result};
22
use crate::proc_macro_decls;
33
use crate::util;
44

5-
use rustc_ast::mut_visit::{self, MutVisitor};
6-
use rustc_ast::ptr::P;
7-
use rustc_ast::{self as ast, token, visit};
5+
use rustc_ast::mut_visit::MutVisitor;
6+
use rustc_ast::{self as ast, visit};
87
use rustc_codegen_ssa::back::link::emit_metadata;
98
use rustc_codegen_ssa::traits::CodegenBackend;
109
use rustc_data_structures::sync::{par_iter, Lrc, OnceCell, ParallelIterator, WorkerLocal};
@@ -37,7 +36,6 @@ use rustc_span::symbol::Symbol;
3736
use rustc_span::{FileName, RealFileName};
3837
use rustc_trait_selection::traits;
3938
use rustc_typeck as typeck;
40-
use smallvec::SmallVec;
4139
use tracing::{info, warn};
4240

4341
use rustc_serialize::json;
@@ -52,82 +50,6 @@ use std::path::PathBuf;
5250
use std::rc::Rc;
5351
use std::{env, fs, iter, mem};
5452

55-
/// Remove alls `LazyTokenStreams` from an AST struct
56-
/// Normally, this is done during AST lowering. However,
57-
/// printing the AST JSON requires us to serialize
58-
/// the entire AST, and we don't want to serialize
59-
/// a `LazyTokenStream`.
60-
struct TokenStripper;
61-
impl mut_visit::MutVisitor for TokenStripper {
62-
fn flat_map_item(&mut self, mut i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
63-
i.tokens = None;
64-
mut_visit::noop_flat_map_item(i, self)
65-
}
66-
fn flat_map_foreign_item(
67-
&mut self,
68-
mut i: P<ast::ForeignItem>,
69-
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
70-
i.tokens = None;
71-
mut_visit::noop_flat_map_foreign_item(i, self)
72-
}
73-
fn flat_map_trait_item(
74-
&mut self,
75-
mut i: P<ast::AssocItem>,
76-
) -> SmallVec<[P<ast::AssocItem>; 1]> {
77-
i.tokens = None;
78-
mut_visit::noop_flat_map_assoc_item(i, self)
79-
}
80-
fn flat_map_impl_item(&mut self, mut i: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
81-
i.tokens = None;
82-
mut_visit::noop_flat_map_assoc_item(i, self)
83-
}
84-
fn visit_block(&mut self, b: &mut P<ast::Block>) {
85-
b.tokens = None;
86-
mut_visit::noop_visit_block(b, self);
87-
}
88-
fn flat_map_stmt(&mut self, mut stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> {
89-
stmt.tokens = None;
90-
mut_visit::noop_flat_map_stmt(stmt, self)
91-
}
92-
fn visit_pat(&mut self, p: &mut P<ast::Pat>) {
93-
p.tokens = None;
94-
mut_visit::noop_visit_pat(p, self);
95-
}
96-
fn visit_ty(&mut self, ty: &mut P<ast::Ty>) {
97-
ty.tokens = None;
98-
mut_visit::noop_visit_ty(ty, self);
99-
}
100-
fn visit_attribute(&mut self, attr: &mut ast::Attribute) {
101-
attr.tokens = None;
102-
if let ast::AttrKind::Normal(ast::AttrItem { tokens, .. }) = &mut attr.kind {
103-
*tokens = None;
104-
}
105-
mut_visit::noop_visit_attribute(attr, self);
106-
}
107-
108-
fn visit_interpolated(&mut self, nt: &mut token::Nonterminal) {
109-
if let token::Nonterminal::NtMeta(meta) = nt {
110-
meta.tokens = None;
111-
}
112-
// Handles all of the other cases
113-
mut_visit::noop_visit_interpolated(nt, self);
114-
}
115-
116-
fn visit_path(&mut self, p: &mut ast::Path) {
117-
p.tokens = None;
118-
mut_visit::noop_visit_path(p, self);
119-
}
120-
fn visit_vis(&mut self, vis: &mut ast::Visibility) {
121-
vis.tokens = None;
122-
mut_visit::noop_visit_vis(vis, self);
123-
}
124-
fn visit_expr(&mut self, e: &mut P<ast::Expr>) {
125-
e.tokens = None;
126-
mut_visit::noop_visit_expr(e, self);
127-
}
128-
fn visit_mac(&mut self, _mac: &mut ast::MacCall) {}
129-
}
130-
13153
pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
13254
let krate = sess.time("parse_crate", || match input {
13355
Input::File(file) => parse_crate_from_file(file, &sess.parse_sess),
@@ -137,10 +59,6 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
13759
})?;
13860

13961
if sess.opts.debugging_opts.ast_json_noexpand {
140-
// Set any `token` fields to `None` before
141-
// we display the AST.
142-
let mut krate = krate.clone();
143-
TokenStripper.visit_crate(&mut krate);
14462
println!("{}", json::as_json(&krate));
14563
}
14664

@@ -464,10 +382,6 @@ fn configure_and_expand_inner<'a>(
464382
}
465383

466384
if sess.opts.debugging_opts.ast_json {
467-
// Set any `token` fields to `None` before
468-
// we display the AST.
469-
let mut krate = krate.clone();
470-
TokenStripper.visit_crate(&mut krate);
471385
println!("{}", json::as_json(&krate));
472386
}
473387

library/core/src/num/f32.rs

+4
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,10 @@ impl f32 {
876876
/// - Positive signaling NaN
877877
/// - Positive quiet NaN
878878
///
879+
/// Note that this function does not always agree with the [`PartialOrd`]
880+
/// and [`PartialEq`] implementations of `f32`. In particular, they regard
881+
/// negative and positive zero as equal, while `total_cmp` doesn't.
882+
///
879883
/// # Example
880884
/// ```
881885
/// #![feature(total_cmp)]

library/core/src/num/f64.rs

+4
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,10 @@ impl f64 {
890890
/// - Positive signaling NaN
891891
/// - Positive quiet NaN
892892
///
893+
/// Note that this function does not always agree with the [`PartialOrd`]
894+
/// and [`PartialEq`] implementations of `f64`. In particular, they regard
895+
/// negative and positive zero as equal, while `total_cmp` doesn't.
896+
///
893897
/// # Example
894898
/// ```
895899
/// #![feature(total_cmp)]

library/core/src/ops/bit.rs

+23-12
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,12 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
109109
/// fn bitand(self, Self(rhs): Self) -> Self::Output {
110110
/// let Self(lhs) = self;
111111
/// assert_eq!(lhs.len(), rhs.len());
112-
/// Self(lhs.iter()
112+
/// Self(
113+
/// lhs.iter()
113114
/// .zip(rhs.iter())
114-
/// .map(|(x, y)| *x && *y)
115-
/// .collect())
115+
/// .map(|(x, y)| *x & *y)
116+
/// .collect()
117+
/// )
116118
/// }
117119
/// }
118120
///
@@ -207,7 +209,12 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
207209
/// fn bitor(self, Self(rhs): Self) -> Self::Output {
208210
/// let Self(lhs) = self;
209211
/// assert_eq!(lhs.len(), rhs.len());
210-
/// Self(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x || *y).collect())
212+
/// Self(
213+
/// lhs.iter()
214+
/// .zip(rhs.iter())
215+
/// .map(|(x, y)| *x | *y)
216+
/// .collect()
217+
/// )
211218
/// }
212219
/// }
213220
///
@@ -302,10 +309,12 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
302309
/// fn bitxor(self, Self(rhs): Self) -> Self::Output {
303310
/// let Self(lhs) = self;
304311
/// assert_eq!(lhs.len(), rhs.len());
305-
/// Self(lhs.iter()
312+
/// Self(
313+
/// lhs.iter()
306314
/// .zip(rhs.iter())
307-
/// .map(|(x, y)| (*x || *y) && !(*x && *y))
308-
/// .collect())
315+
/// .map(|(x, y)| *x ^ *y)
316+
/// .collect()
317+
/// )
309318
/// }
310319
/// }
311320
///
@@ -643,11 +652,13 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
643652
/// // `rhs` is the "right-hand side" of the expression `a &= b`.
644653
/// fn bitand_assign(&mut self, rhs: Self) {
645654
/// assert_eq!(self.0.len(), rhs.0.len());
646-
/// *self = Self(self.0
647-
/// .iter()
648-
/// .zip(rhs.0.iter())
649-
/// .map(|(x, y)| *x && *y)
650-
/// .collect());
655+
/// *self = Self(
656+
/// self.0
657+
/// .iter()
658+
/// .zip(rhs.0.iter())
659+
/// .map(|(x, y)| *x & *y)
660+
/// .collect()
661+
/// );
651662
/// }
652663
/// }
653664
///

library/core/src/str/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,9 @@ impl str {
842842
/// Lines are ended with either a newline (`\n`) or a carriage return with
843843
/// a line feed (`\r\n`).
844844
///
845-
/// The final line ending is optional.
845+
/// The final line ending is optional. A string that ends with a final line
846+
/// ending will return the same lines as an otherwise identical string
847+
/// without a final line ending.
846848
///
847849
/// # Examples
848850
///

library/core/src/sync/atomic.rs

+125
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,64 @@ impl AtomicBool {
801801
pub fn as_mut_ptr(&self) -> *mut bool {
802802
self.v.get() as *mut bool
803803
}
804+
805+
/// Fetches the value, and applies a function to it that returns an optional
806+
/// new value. Returns a `Result` of `Ok(previous_value)` if the function
807+
/// returned `Some(_)`, else `Err(previous_value)`.
808+
///
809+
/// Note: This may call the function multiple times if the value has been
810+
/// changed from other threads in the meantime, as long as the function
811+
/// returns `Some(_)`, but the function will have been applied only once to
812+
/// the stored value.
813+
///
814+
/// `fetch_update` takes two [`Ordering`] arguments to describe the memory
815+
/// ordering of this operation. The first describes the required ordering for
816+
/// when the operation finally succeeds while the second describes the
817+
/// required ordering for loads. These correspond to the success and failure
818+
/// orderings of [`AtomicBool::compare_exchange`] respectively.
819+
///
820+
/// Using [`Acquire`] as success ordering makes the store part of this
821+
/// operation [`Relaxed`], and using [`Release`] makes the final successful
822+
/// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
823+
/// [`Acquire`] or [`Relaxed`] and must be equivalent to or weaker than the
824+
/// success ordering.
825+
///
826+
/// **Note:** This method is only available on platforms that support atomic
827+
/// operations on `u8`.
828+
///
829+
/// # Examples
830+
///
831+
/// ```rust
832+
/// #![feature(atomic_fetch_update)]
833+
/// use std::sync::atomic::{AtomicBool, Ordering};
834+
///
835+
/// let x = AtomicBool::new(false);
836+
/// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(false));
837+
/// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(false));
838+
/// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(true));
839+
/// assert_eq!(x.load(Ordering::SeqCst), false);
840+
/// ```
841+
#[inline]
842+
#[unstable(feature = "atomic_fetch_update", reason = "recently added", issue = "78639")]
843+
#[cfg(target_has_atomic = "8")]
844+
pub fn fetch_update<F>(
845+
&self,
846+
set_order: Ordering,
847+
fetch_order: Ordering,
848+
mut f: F,
849+
) -> Result<bool, bool>
850+
where
851+
F: FnMut(bool) -> Option<bool>,
852+
{
853+
let mut prev = self.load(fetch_order);
854+
while let Some(next) = f(prev) {
855+
match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
856+
x @ Ok(_) => return x,
857+
Err(next_prev) => prev = next_prev,
858+
}
859+
}
860+
Err(prev)
861+
}
804862
}
805863

806864
#[cfg(target_has_atomic_load_store = "ptr")]
@@ -1123,6 +1181,73 @@ impl<T> AtomicPtr<T> {
11231181
}
11241182
}
11251183
}
1184+
1185+
/// Fetches the value, and applies a function to it that returns an optional
1186+
/// new value. Returns a `Result` of `Ok(previous_value)` if the function
1187+
/// returned `Some(_)`, else `Err(previous_value)`.
1188+
///
1189+
/// Note: This may call the function multiple times if the value has been
1190+
/// changed from other threads in the meantime, as long as the function
1191+
/// returns `Some(_)`, but the function will have been applied only once to
1192+
/// the stored value.
1193+
///
1194+
/// `fetch_update` takes two [`Ordering`] arguments to describe the memory
1195+
/// ordering of this operation. The first describes the required ordering for
1196+
/// when the operation finally succeeds while the second describes the
1197+
/// required ordering for loads. These correspond to the success and failure
1198+
/// orderings of [`AtomicPtr::compare_exchange`] respectively.
1199+
///
1200+
/// Using [`Acquire`] as success ordering makes the store part of this
1201+
/// operation [`Relaxed`], and using [`Release`] makes the final successful
1202+
/// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
1203+
/// [`Acquire`] or [`Relaxed`] and must be equivalent to or weaker than the
1204+
/// success ordering.
1205+
///
1206+
/// **Note:** This method is only available on platforms that support atomic
1207+
/// operations on pointers.
1208+
///
1209+
/// # Examples
1210+
///
1211+
/// ```rust
1212+
/// #![feature(atomic_fetch_update)]
1213+
/// use std::sync::atomic::{AtomicPtr, Ordering};
1214+
///
1215+
/// let ptr: *mut _ = &mut 5;
1216+
/// let some_ptr = AtomicPtr::new(ptr);
1217+
///
1218+
/// let new: *mut _ = &mut 10;
1219+
/// assert_eq!(some_ptr.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(ptr));
1220+
/// let result = some_ptr.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
1221+
/// if x == ptr {
1222+
/// Some(new)
1223+
/// } else {
1224+
/// None
1225+
/// }
1226+
/// });
1227+
/// assert_eq!(result, Ok(ptr));
1228+
/// assert_eq!(some_ptr.load(Ordering::SeqCst), new);
1229+
/// ```
1230+
#[inline]
1231+
#[unstable(feature = "atomic_fetch_update", reason = "recently added", issue = "78639")]
1232+
#[cfg(target_has_atomic = "ptr")]
1233+
pub fn fetch_update<F>(
1234+
&self,
1235+
set_order: Ordering,
1236+
fetch_order: Ordering,
1237+
mut f: F,
1238+
) -> Result<*mut T, *mut T>
1239+
where
1240+
F: FnMut(*mut T) -> Option<*mut T>,
1241+
{
1242+
let mut prev = self.load(fetch_order);
1243+
while let Some(next) = f(prev) {
1244+
match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
1245+
x @ Ok(_) => return x,
1246+
Err(next_prev) => prev = next_prev,
1247+
}
1248+
}
1249+
Err(prev)
1250+
}
11261251
}
11271252

11281253
#[cfg(target_has_atomic_load_store = "8")]

0 commit comments

Comments
 (0)