Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #130755

Merged
merged 18 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
de4c897
bootstrap: Set the dylib path when building books with rustdoc
cuviper Sep 18, 2024
019435b
Remove x86_64-fuchsia and aarch64-fuchsia target aliases
arttet Sep 21, 2024
8d28099
Add more test cases for block-no-opening-brace
GrigorenkoPV Sep 22, 2024
73cc575
Fix `break_last_token`.
nnethercote Sep 19, 2024
f7735f9
Add rustfmt 2024 reformatting to git blame ignore
Kobzol Sep 23, 2024
5c1c725
std: implement the `random` feature
joboet Aug 15, 2024
b9d47cf
std: switch to faster random sources on macOS and most BSDs
joboet Aug 17, 2024
a21ff01
miri: shim `CCRandomGenerateBytes`
joboet Aug 18, 2024
e94dd9b
random: add tracking issue, address other comments
joboet Sep 22, 2024
3ff09a0
update miri test
joboet Sep 22, 2024
b0c2c93
readd @tgross35 and @joboet to the review rotation
joboet Sep 23, 2024
1d36931
Rollup merge of #129201 - joboet:random_faster_sources, r=joshtriplett
workingjubilee Sep 23, 2024
c58e3cb
Rollup merge of #130536 - cuviper:rustbook-dylib-path, r=Mark-Simulacrum
workingjubilee Sep 23, 2024
515bdcd
Rollup merge of #130551 - nnethercote:fix-break-last-token, r=petroch…
workingjubilee Sep 23, 2024
021ae2c
Rollup merge of #130657 - arttet:fix/fuchsia, r=jieyouxu
workingjubilee Sep 23, 2024
6feefdb
Rollup merge of #130721 - GrigorenkoPV:block-no-opening-brace, r=jiey…
workingjubilee Sep 23, 2024
7ea3919
Rollup merge of #130736 - Kobzol:rustfmt-2024-git-blame, r=compiler-e…
workingjubilee Sep 23, 2024
c7abc85
Rollup merge of #130746 - joboet:hello_again, r=joboet
workingjubilee Sep 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ ec2cc761bc7067712ecc7734502f703fe3b024c8
84ac80f1921afc243d71fd0caaa4f2838c294102
# bless mir-opt tests to add `copy`
99cb0c6bc399fb94a0ddde7e9b38e9c00d523bad
# reformat with rustfmt edition 2024
c682aa162b0d41e21cc6748f4fecfe01efb69d1f
64 changes: 35 additions & 29 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,35 +385,41 @@ impl TokenKind {
Literal(Lit::new(kind, symbol, suffix))
}

/// An approximation to proc-macro-style single-character operators used by rustc parser.
/// If the operator token can be broken into two tokens, the first of which is single-character,
/// then this function performs that operation, otherwise it returns `None`.
pub fn break_two_token_op(&self) -> Option<(TokenKind, TokenKind)> {
Some(match *self {
Le => (Lt, Eq),
EqEq => (Eq, Eq),
Ne => (Not, Eq),
Ge => (Gt, Eq),
AndAnd => (BinOp(And), BinOp(And)),
OrOr => (BinOp(Or), BinOp(Or)),
BinOp(Shl) => (Lt, Lt),
BinOp(Shr) => (Gt, Gt),
BinOpEq(Plus) => (BinOp(Plus), Eq),
BinOpEq(Minus) => (BinOp(Minus), Eq),
BinOpEq(Star) => (BinOp(Star), Eq),
BinOpEq(Slash) => (BinOp(Slash), Eq),
BinOpEq(Percent) => (BinOp(Percent), Eq),
BinOpEq(Caret) => (BinOp(Caret), Eq),
BinOpEq(And) => (BinOp(And), Eq),
BinOpEq(Or) => (BinOp(Or), Eq),
BinOpEq(Shl) => (Lt, Le),
BinOpEq(Shr) => (Gt, Ge),
DotDot => (Dot, Dot),
DotDotDot => (Dot, DotDot),
PathSep => (Colon, Colon),
RArrow => (BinOp(Minus), Gt),
LArrow => (Lt, BinOp(Minus)),
FatArrow => (Eq, Gt),
/// An approximation to proc-macro-style single-character operators used by
/// rustc parser. If the operator token can be broken into two tokens, the
/// first of which has `n` (1 or 2) chars, then this function performs that
/// operation, otherwise it returns `None`.
pub fn break_two_token_op(&self, n: u32) -> Option<(TokenKind, TokenKind)> {
assert!(n == 1 || n == 2);
Some(match (self, n) {
(Le, 1) => (Lt, Eq),
(EqEq, 1) => (Eq, Eq),
(Ne, 1) => (Not, Eq),
(Ge, 1) => (Gt, Eq),
(AndAnd, 1) => (BinOp(And), BinOp(And)),
(OrOr, 1) => (BinOp(Or), BinOp(Or)),
(BinOp(Shl), 1) => (Lt, Lt),
(BinOp(Shr), 1) => (Gt, Gt),
(BinOpEq(Plus), 1) => (BinOp(Plus), Eq),
(BinOpEq(Minus), 1) => (BinOp(Minus), Eq),
(BinOpEq(Star), 1) => (BinOp(Star), Eq),
(BinOpEq(Slash), 1) => (BinOp(Slash), Eq),
(BinOpEq(Percent), 1) => (BinOp(Percent), Eq),
(BinOpEq(Caret), 1) => (BinOp(Caret), Eq),
(BinOpEq(And), 1) => (BinOp(And), Eq),
(BinOpEq(Or), 1) => (BinOp(Or), Eq),
(BinOpEq(Shl), 1) => (Lt, Le), // `<` + `<=`
(BinOpEq(Shl), 2) => (BinOp(Shl), Eq), // `<<` + `=`
(BinOpEq(Shr), 1) => (Gt, Ge), // `>` + `>=`
(BinOpEq(Shr), 2) => (BinOp(Shr), Eq), // `>>` + `=`
(DotDot, 1) => (Dot, Dot),
(DotDotDot, 1) => (Dot, DotDot), // `.` + `..`
(DotDotDot, 2) => (DotDot, Dot), // `..` + `.`
(DotDotEq, 2) => (DotDot, Eq),
(PathSep, 1) => (Colon, Colon),
(RArrow, 1) => (BinOp(Minus), Gt),
(LArrow, 1) => (Lt, BinOp(Minus)),
(FatArrow, 1) => (Eq, Gt),
_ => return None,
})
}
Expand Down
36 changes: 19 additions & 17 deletions compiler/rustc_parse/src/parser/attr_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ struct LazyAttrTokenStreamImpl {
start_token: (Token, Spacing),
cursor_snapshot: TokenCursor,
num_calls: u32,
break_last_token: bool,
break_last_token: u32,
node_replacements: Box<[NodeReplacement]>,
}

Expand Down Expand Up @@ -339,17 +339,20 @@ impl<'a> Parser<'a> {
let parser_replacements_end = self.capture_state.parser_replacements.len();

assert!(
!(self.break_last_token && matches!(capture_trailing, Trailing::Yes)),
"Cannot set break_last_token and have trailing token"
!(self.break_last_token > 0 && matches!(capture_trailing, Trailing::Yes)),
"Cannot have break_last_token > 0 and have trailing token"
);
assert!(self.break_last_token <= 2, "cannot break token more than twice");

let end_pos = self.num_bump_calls
+ capture_trailing as u32
// If we 'broke' the last token (e.g. breaking a '>>' token to two '>' tokens), then
// extend the range of captured tokens to include it, since the parser was not actually
// bumped past it. When the `LazyAttrTokenStream` gets converted into an
// `AttrTokenStream`, we will create the proper token.
+ self.break_last_token as u32;
// If we "broke" the last token (e.g. breaking a `>>` token once into `>` + `>`, or
// breaking a `>>=` token twice into `>` + `>` + `=`), then extend the range of
// captured tokens to include it, because the parser was not actually bumped past it.
// (Even if we broke twice, it was still just one token originally, hence the `1`.)
// When the `LazyAttrTokenStream` gets converted into an `AttrTokenStream`, we will
// rebreak that final token once or twice.
+ if self.break_last_token == 0 { 0 } else { 1 };

let num_calls = end_pos - collect_pos.start_pos;

Expand Down Expand Up @@ -425,7 +428,7 @@ impl<'a> Parser<'a> {
// for the `#[cfg]` and/or `#[cfg_attr]` attrs. This allows us to run
// eager cfg-expansion on the captured token stream.
if definite_capture_mode {
assert!(!self.break_last_token, "Should not have unglued last token with cfg attr");
assert!(self.break_last_token == 0, "Should not have unglued last token with cfg attr");

// What is the status here when parsing the example code at the top of this method?
//
Expand Down Expand Up @@ -471,7 +474,7 @@ impl<'a> Parser<'a> {
/// close delims.
fn make_attr_token_stream(
iter: impl Iterator<Item = FlatToken>,
break_last_token: bool,
break_last_token: u32,
) -> AttrTokenStream {
#[derive(Debug)]
struct FrameData {
Expand Down Expand Up @@ -513,18 +516,17 @@ fn make_attr_token_stream(
}
}

if break_last_token {
if break_last_token > 0 {
let last_token = stack_top.inner.pop().unwrap();
if let AttrTokenTree::Token(last_token, spacing) = last_token {
let unglued_first = last_token.kind.break_two_token_op().unwrap().0;
let (unglued, _) = last_token.kind.break_two_token_op(break_last_token).unwrap();

// An 'unglued' token is always two ASCII characters
// Tokens are always ASCII chars, so we can use byte arithmetic here.
let mut first_span = last_token.span.shrink_to_lo();
first_span = first_span.with_hi(first_span.lo() + rustc_span::BytePos(1));
first_span =
first_span.with_hi(first_span.lo() + rustc_span::BytePos(break_last_token));

stack_top
.inner
.push(AttrTokenTree::Token(Token::new(unglued_first, first_span), spacing));
stack_top.inner.push(AttrTokenTree::Token(Token::new(unglued, first_span), spacing));
} else {
panic!("Unexpected last token {last_token:?}")
}
Expand Down
39 changes: 21 additions & 18 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,21 +146,25 @@ pub struct Parser<'a> {
token_cursor: TokenCursor,
// The number of calls to `bump`, i.e. the position in the token stream.
num_bump_calls: u32,
// During parsing we may sometimes need to 'unglue' a glued token into two
// component tokens (e.g. '>>' into '>' and '>), so the parser can consume
// them one at a time. This process bypasses the normal capturing mechanism
// (e.g. `num_bump_calls` will not be incremented), since the 'unglued'
// tokens due not exist in the original `TokenStream`.
// During parsing we may sometimes need to "unglue" a glued token into two
// or three component tokens (e.g. `>>` into `>` and `>`, or `>>=` into `>`
// and `>` and `=`), so the parser can consume them one at a time. This
// process bypasses the normal capturing mechanism (e.g. `num_bump_calls`
// will not be incremented), since the "unglued" tokens due not exist in
// the original `TokenStream`.
//
// If we end up consuming both unglued tokens, this is not an issue. We'll
// end up capturing the single 'glued' token.
// If we end up consuming all the component tokens, this is not an issue,
// because we'll end up capturing the single "glued" token.
//
// However, sometimes we may want to capture just the first 'unglued'
// However, sometimes we may want to capture not all of the original
// token. For example, capturing the `Vec<u8>` in `Option<Vec<u8>>`
// requires us to unglue the trailing `>>` token. The `break_last_token`
// field is used to track this token. It gets appended to the captured
// field is used to track these tokens. They get appended to the captured
// stream when we evaluate a `LazyAttrTokenStream`.
break_last_token: bool,
//
// This value is always 0, 1, or 2. It can only reach 2 when splitting
// `>>=` or `<<=`.
break_last_token: u32,
/// This field is used to keep track of how many left angle brackets we have seen. This is
/// required in order to detect extra leading left angle brackets (`<` characters) and error
/// appropriately.
Expand Down Expand Up @@ -453,7 +457,7 @@ impl<'a> Parser<'a> {
expected_tokens: Vec::new(),
token_cursor: TokenCursor { tree_cursor: stream.into_trees(), stack: Vec::new() },
num_bump_calls: 0,
break_last_token: false,
break_last_token: 0,
unmatched_angle_bracket_count: 0,
angle_bracket_nesting: 0,
last_unexpected_token_span: None,
Expand Down Expand Up @@ -773,7 +777,7 @@ impl<'a> Parser<'a> {
self.bump();
return true;
}
match self.token.kind.break_two_token_op() {
match self.token.kind.break_two_token_op(1) {
Some((first, second)) if first == expected => {
let first_span = self.psess.source_map().start_point(self.token.span);
let second_span = self.token.span.with_lo(first_span.hi());
Expand All @@ -783,8 +787,8 @@ impl<'a> Parser<'a> {
//
// If we consume any additional tokens, then this token
// is not needed (we'll capture the entire 'glued' token),
// and `bump` will set this field to `None`
self.break_last_token = true;
// and `bump` will set this field to 0.
self.break_last_token += 1;
// Use the spacing of the glued token as the spacing of the
// unglued second token.
self.bump_with((Token::new(second, second_span), self.token_spacing));
Expand Down Expand Up @@ -1148,10 +1152,9 @@ impl<'a> Parser<'a> {
// than `.0`/`.1` access.
let mut next = self.token_cursor.inlined_next();
self.num_bump_calls += 1;
// We've retrieved an token from the underlying
// cursor, so we no longer need to worry about
// an unglued token. See `break_and_eat` for more details
self.break_last_token = false;
// We got a token from the underlying cursor and no longer need to
// worry about an unglued token. See `break_and_eat` for more details.
self.break_last_token = 0;
if next.0.span.is_dummy() {
// Tweak the location for better diagnostics, but keep syntactic context intact.
let fallback_span = self.token.span;
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1690,12 +1690,8 @@ supported_targets! {
("x86_64h-apple-darwin", x86_64h_apple_darwin),
("i686-apple-darwin", i686_apple_darwin),

// FIXME(#106649): Remove aarch64-fuchsia in favor of aarch64-unknown-fuchsia
("aarch64-fuchsia", aarch64_fuchsia),
("aarch64-unknown-fuchsia", aarch64_unknown_fuchsia),
("riscv64gc-unknown-fuchsia", riscv64gc_unknown_fuchsia),
// FIXME(#106649): Remove x86_64-fuchsia in favor of x86_64-unknown-fuchsia
("x86_64-fuchsia", x86_64_fuchsia),
("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia),

("avr-unknown-gnu-atmega328", avr_unknown_gnu_atmega328),
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_target/src/spec/targets/aarch64_fuchsia.rs

This file was deleted.

1 change: 0 additions & 1 deletion compiler/rustc_target/src/spec/targets/x86_64_fuchsia.rs

This file was deleted.

2 changes: 2 additions & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,8 @@ pub mod panicking;
#[unstable(feature = "core_pattern_types", issue = "123646")]
pub mod pat;
pub mod pin;
#[unstable(feature = "random", issue = "130703")]
pub mod random;
#[unstable(feature = "new_range_api", issue = "125687")]
pub mod range;
pub mod result;
Expand Down
62 changes: 62 additions & 0 deletions library/core/src/random.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//! Random value generation.
//!
//! The [`Random`] trait allows generating a random value for a type using a
//! given [`RandomSource`].

/// A source of randomness.
#[unstable(feature = "random", issue = "130703")]
pub trait RandomSource {
/// Fills `bytes` with random bytes.
fn fill_bytes(&mut self, bytes: &mut [u8]);
}

/// A trait for getting a random value for a type.
///
/// **Warning:** Be careful when manipulating random values! The
/// [`random`](Random::random) method on integers samples them with a uniform
/// distribution, so a value of 1 is just as likely as [`i32::MAX`]. By using
/// modulo operations, some of the resulting values can become more likely than
/// others. Use audited crates when in doubt.
#[unstable(feature = "random", issue = "130703")]
pub trait Random: Sized {
/// Generates a random value.
fn random(source: &mut (impl RandomSource + ?Sized)) -> Self;
}

impl Random for bool {
fn random(source: &mut (impl RandomSource + ?Sized)) -> Self {
u8::random(source) & 1 == 1
}
}

macro_rules! impl_primitive {
($t:ty) => {
impl Random for $t {
/// Generates a random value.
///
/// **Warning:** Be careful when manipulating the resulting value! This
/// method samples according to a uniform distribution, so a value of 1 is
/// just as likely as [`MAX`](Self::MAX). By using modulo operations, some
/// values can become more likely than others. Use audited crates when in
/// doubt.
fn random(source: &mut (impl RandomSource + ?Sized)) -> Self {
let mut bytes = (0 as Self).to_ne_bytes();
source.fill_bytes(&mut bytes);
Self::from_ne_bytes(bytes)
}
}
};
}

impl_primitive!(u8);
impl_primitive!(i8);
impl_primitive!(u16);
impl_primitive!(i16);
impl_primitive!(u32);
impl_primitive!(i32);
impl_primitive!(u64);
impl_primitive!(i64);
impl_primitive!(u128);
impl_primitive!(i128);
impl_primitive!(usize);
impl_primitive!(isize);
5 changes: 3 additions & 2 deletions library/std/src/hash/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
#[allow(deprecated)]
use super::{BuildHasher, Hasher, SipHasher13};
use crate::cell::Cell;
use crate::{fmt, sys};
use crate::fmt;
use crate::sys::random::hashmap_random_keys;

/// `RandomState` is the default state for [`HashMap`] types.
///
Expand Down Expand Up @@ -65,7 +66,7 @@ impl RandomState {
// increment one of the seeds on every RandomState creation, giving
// every corresponding HashMap a different iteration order.
thread_local!(static KEYS: Cell<(u64, u64)> = {
Cell::new(sys::hashmap_random_keys())
Cell::new(hashmap_random_keys())
});

KEYS.with(|keys| {
Expand Down
4 changes: 4 additions & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@
//
// Library features (core):
// tidy-alphabetical-start
#![feature(array_chunks)]
#![feature(c_str_module)]
#![feature(char_internals)]
#![feature(clone_to_uninit)]
Expand Down Expand Up @@ -348,6 +349,7 @@
#![feature(prelude_2024)]
#![feature(ptr_as_uninit)]
#![feature(ptr_mask)]
#![feature(random)]
#![feature(slice_internals)]
#![feature(slice_ptr_get)]
#![feature(slice_range)]
Expand Down Expand Up @@ -595,6 +597,8 @@ pub mod path;
#[unstable(feature = "anonymous_pipe", issue = "127154")]
pub mod pipe;
pub mod process;
#[unstable(feature = "random", issue = "130703")]
pub mod random;
pub mod sync;
pub mod time;

Expand Down
Loading
Loading