Skip to content

Commit 7d289ae

Browse files
committed
Auto merge of #76376 - Dylan-DPC:rollup-8chsbw9, r=Dylan-DPC
Rollup of 11 pull requests Successful merges: - #75695 (Add a regression test for issue-72793) - #75741 (Refactor byteorder to std in rustc_middle) - #75954 (Unstable Book: add links to tracking issues for FFI features) - #75994 (`impl Rc::new_cyclic`) - #76060 (Link vec doc to & reference) - #76078 (Remove disambiguators from intra doc link text) - #76082 (Fix intra-doc links on pub re-exports) - #76254 (Fold length constant in Rvalue::Repeat) - #76258 (x.py check checks tests/examples/benches) - #76263 (inliner: Check for codegen fn attributes compatibility) - #76285 (Move jointness censoring to proc_macro) Failed merges: r? @ghost
2 parents 81a769f + 85cee57 commit 7d289ae

31 files changed

+714
-86
lines changed

Cargo.lock

-1
Original file line numberDiff line numberDiff line change
@@ -3722,7 +3722,6 @@ name = "rustc_middle"
37223722
version = "0.0.0"
37233723
dependencies = [
37243724
"bitflags",
3725-
"byteorder",
37263725
"chalk-ir",
37273726
"measureme",
37283727
"polonius-engine",

compiler/rustc_ast/src/tokenstream.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,8 @@ impl Cursor {
403403
self.index = index;
404404
}
405405

406-
pub fn look_ahead(&self, n: usize) -> Option<TokenTree> {
407-
self.stream.0[self.index..].get(n).map(|(tree, _)| tree.clone())
406+
pub fn look_ahead(&self, n: usize) -> Option<&TokenTree> {
407+
self.stream.0[self.index..].get(n).map(|(tree, _)| tree)
408408
}
409409
}
410410

compiler/rustc_expand/src/proc_macro_server.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,26 @@ impl ToInternal<token::DelimToken> for Delimiter {
4747
}
4848
}
4949

50-
impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
51-
for TokenTree<Group, Punct, Ident, Literal>
50+
impl
51+
FromInternal<(
52+
TreeAndJoint,
53+
Option<&'_ tokenstream::TokenTree>,
54+
&'_ ParseSess,
55+
&'_ mut Vec<Self>,
56+
)> for TokenTree<Group, Punct, Ident, Literal>
5257
{
5358
fn from_internal(
54-
((tree, is_joint), sess, stack): (TreeAndJoint, &ParseSess, &mut Vec<Self>),
59+
((tree, is_joint), look_ahead, sess, stack): (
60+
TreeAndJoint,
61+
Option<&tokenstream::TokenTree>,
62+
&ParseSess,
63+
&mut Vec<Self>,
64+
),
5565
) -> Self {
5666
use rustc_ast::token::*;
5767

58-
let joint = is_joint == Joint;
68+
let joint = is_joint == Joint
69+
&& matches!(look_ahead, Some(tokenstream::TokenTree::Token(t)) if t.is_op());
5970
let Token { kind, span } = match tree {
6071
tokenstream::TokenTree::Delimited(span, delim, tts) => {
6172
let delimiter = Delimiter::from_internal(delim);
@@ -445,7 +456,8 @@ impl server::TokenStreamIter for Rustc<'_> {
445456
loop {
446457
let tree = iter.stack.pop().or_else(|| {
447458
let next = iter.cursor.next_with_joint()?;
448-
Some(TokenTree::from_internal((next, self.sess, &mut iter.stack)))
459+
let lookahead = iter.cursor.look_ahead(0);
460+
Some(TokenTree::from_internal((next, lookahead, self.sess, &mut iter.stack)))
449461
})?;
450462
// A hack used to pass AST fragments to attribute and derive macros
451463
// as a single nonterminal token instead of a token stream.

compiler/rustc_middle/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ rustc_index = { path = "../rustc_index" }
2626
rustc_serialize = { path = "../rustc_serialize" }
2727
rustc_ast = { path = "../rustc_ast" }
2828
rustc_span = { path = "../rustc_span" }
29-
byteorder = { version = "1.3" }
3029
chalk-ir = "0.21.0"
3130
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
3231
measureme = "0.7.1"

compiler/rustc_middle/src/mir/interpret/allocation.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,8 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
345345

346346
/// Reads a *non-ZST* scalar.
347347
///
348-
/// ZSTs can't be read for two reasons:
349-
/// * byte-order cannot work with zero-element buffers;
350-
/// * in order to obtain a `Pointer`, we need to check for ZSTness anyway due to integer
351-
/// pointers being valid for ZSTs.
348+
/// ZSTs can't be read because in order to obtain a `Pointer`, we need to check
349+
/// for ZSTness anyway due to integer pointers being valid for ZSTs.
352350
///
353351
/// It is the caller's responsibility to check bounds and alignment beforehand.
354352
/// Most likely, you want to call `InterpCx::read_scalar` instead of this method.
@@ -397,10 +395,8 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
397395

398396
/// Writes a *non-ZST* scalar.
399397
///
400-
/// ZSTs can't be read for two reasons:
401-
/// * byte-order cannot work with zero-element buffers;
402-
/// * in order to obtain a `Pointer`, we need to check for ZSTness anyway due to integer
403-
/// pointers being valid for ZSTs.
398+
/// ZSTs can't be read because in order to obtain a `Pointer`, we need to check
399+
/// for ZSTness anyway due to integer pointers being valid for ZSTs.
404400
///
405401
/// It is the caller's responsibility to check bounds and alignment beforehand.
406402
/// Most likely, you want to call `InterpCx::write_scalar` instead of this method.

compiler/rustc_middle/src/mir/interpret/mod.rs

+23-9
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ mod value;
9898
use std::convert::TryFrom;
9999
use std::fmt;
100100
use std::io;
101+
use std::io::{Read, Write};
101102
use std::num::NonZeroU32;
102103
use std::sync::atomic::{AtomicU32, Ordering};
103104

104-
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
105105
use rustc_ast::LitKind;
106106
use rustc_data_structures::fx::FxHashMap;
107107
use rustc_data_structures::sync::{HashMapExt, Lock};
@@ -561,19 +561,33 @@ pub fn write_target_uint(
561561
mut target: &mut [u8],
562562
data: u128,
563563
) -> Result<(), io::Error> {
564-
let len = target.len();
564+
// This u128 holds an "any-size uint" (since smaller uints can fits in it)
565+
// So we do not write all bytes of the u128, just the "payload".
565566
match endianness {
566-
Endian::Little => target.write_uint128::<LittleEndian>(data, len),
567-
Endian::Big => target.write_uint128::<BigEndian>(data, len),
568-
}
567+
Endian::Little => target.write(&data.to_le_bytes())?,
568+
Endian::Big => target.write(&data.to_be_bytes()[16 - target.len()..])?,
569+
};
570+
debug_assert!(target.len() == 0); // We should have filled the target buffer.
571+
Ok(())
569572
}
570573

571574
#[inline]
572575
pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result<u128, io::Error> {
573-
match endianness {
574-
Endian::Little => source.read_uint128::<LittleEndian>(source.len()),
575-
Endian::Big => source.read_uint128::<BigEndian>(source.len()),
576-
}
576+
// This u128 holds an "any-size uint" (since smaller uints can fits in it)
577+
let mut buf = [0u8; std::mem::size_of::<u128>()];
578+
// So we do not read exactly 16 bytes into the u128, just the "payload".
579+
let uint = match endianness {
580+
Endian::Little => {
581+
source.read(&mut buf)?;
582+
Ok(u128::from_le_bytes(buf))
583+
}
584+
Endian::Big => {
585+
source.read(&mut buf[16 - source.len()..])?;
586+
Ok(u128::from_be_bytes(buf))
587+
}
588+
};
589+
debug_assert!(source.len() == 0); // We should have consumed the source buffer.
590+
uint
577591
}
578592

579593
////////////////////////////////////////////////////////////////////////////////

compiler/rustc_middle/src/mir/type_foldable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
175175
use crate::mir::Rvalue::*;
176176
match *self {
177177
Use(ref op) => Use(op.fold_with(folder)),
178-
Repeat(ref op, len) => Repeat(op.fold_with(folder), len),
178+
Repeat(ref op, len) => Repeat(op.fold_with(folder), len.fold_with(folder)),
179179
ThreadLocalRef(did) => ThreadLocalRef(did.fold_with(folder)),
180180
Ref(region, bk, ref place) => {
181181
Ref(region.fold_with(folder), bk, place.fold_with(folder))

compiler/rustc_mir/src/transform/inline.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_attr as attr;
44
use rustc_hir::def_id::DefId;
55
use rustc_index::bit_set::BitSet;
66
use rustc_index::vec::{Idx, IndexVec};
7-
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
7+
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
88
use rustc_middle::mir::visit::*;
99
use rustc_middle::mir::*;
1010
use rustc_middle::ty::subst::{Subst, SubstsRef};
@@ -45,7 +45,8 @@ impl<'tcx> MirPass<'tcx> for Inline {
4545
// based function.
4646
debug!("function inlining is disabled when compiling with `instrument_coverage`");
4747
} else {
48-
Inliner { tcx, source }.run_pass(body);
48+
Inliner { tcx, source, codegen_fn_attrs: tcx.codegen_fn_attrs(source.def_id()) }
49+
.run_pass(body);
4950
}
5051
}
5152
}
@@ -54,6 +55,7 @@ impl<'tcx> MirPass<'tcx> for Inline {
5455
struct Inliner<'tcx> {
5556
tcx: TyCtxt<'tcx>,
5657
source: MirSource<'tcx>,
58+
codegen_fn_attrs: &'tcx CodegenFnAttrs,
5759
}
5860

5961
impl Inliner<'tcx> {
@@ -242,9 +244,19 @@ impl Inliner<'tcx> {
242244
return false;
243245
}
244246

245-
// Avoid inlining functions marked as no_sanitize if sanitizer is enabled,
246-
// since instrumentation might be enabled and performed on the caller.
247-
if self.tcx.sess.opts.debugging_opts.sanitizer.intersects(codegen_fn_attrs.no_sanitize) {
247+
let self_features = &self.codegen_fn_attrs.target_features;
248+
let callee_features = &codegen_fn_attrs.target_features;
249+
if callee_features.iter().any(|feature| !self_features.contains(feature)) {
250+
debug!("`callee has extra target features - not inlining");
251+
return false;
252+
}
253+
254+
let self_no_sanitize =
255+
self.codegen_fn_attrs.no_sanitize & self.tcx.sess.opts.debugging_opts.sanitizer;
256+
let callee_no_sanitize =
257+
codegen_fn_attrs.no_sanitize & self.tcx.sess.opts.debugging_opts.sanitizer;
258+
if self_no_sanitize != callee_no_sanitize {
259+
debug!("`callee has incompatible no_sanitize attribute - not inlining");
248260
return false;
249261
}
250262

compiler/rustc_parse/src/lexer/tokentrees.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,7 @@ impl<'a> TokenTreesReader<'a> {
262262
}
263263
_ => {
264264
let tt = TokenTree::Token(self.token.take());
265-
let mut is_joint = self.bump();
266-
if !self.token.is_op() {
267-
is_joint = NonJoint;
268-
}
265+
let is_joint = self.bump();
269266
Ok((tt, is_joint))
270267
}
271268
}

compiler/rustc_parse/src/parser/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -822,15 +822,15 @@ impl<'a> Parser<'a> {
822822
}
823823

824824
let frame = &self.token_cursor.frame;
825-
looker(&match frame.tree_cursor.look_ahead(dist - 1) {
825+
match frame.tree_cursor.look_ahead(dist - 1) {
826826
Some(tree) => match tree {
827-
TokenTree::Token(token) => token,
827+
TokenTree::Token(token) => looker(token),
828828
TokenTree::Delimited(dspan, delim, _) => {
829-
Token::new(token::OpenDelim(delim), dspan.open)
829+
looker(&Token::new(token::OpenDelim(delim.clone()), dspan.open))
830830
}
831831
},
832-
None => Token::new(token::CloseDelim(frame.delim), frame.span.close),
833-
})
832+
None => looker(&Token::new(token::CloseDelim(frame.delim), frame.span.close)),
833+
}
834834
}
835835

836836
/// Returns whether any of the given keywords are `dist` tokens ahead of the current one.

library/alloc/src/rc.rs

+44
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,50 @@ impl<T> Rc<T> {
325325
)
326326
}
327327

328+
/// Constructs a new `Rc<T>` using a weak reference to itself. Attempting
329+
/// to upgrade the weak reference before this function returns will result
330+
/// in a `None` value. However, the weak reference may be cloned freely and
331+
/// stored for use at a later time.
332+
#[unstable(feature = "arc_new_cyclic", issue = "75861")]
333+
pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Rc<T> {
334+
// Construct the inner in the "uninitialized" state with a single
335+
// weak reference.
336+
let uninit_ptr: NonNull<_> = Box::leak(box RcBox {
337+
strong: Cell::new(0),
338+
weak: Cell::new(1),
339+
value: mem::MaybeUninit::<T>::uninit(),
340+
})
341+
.into();
342+
343+
let init_ptr: NonNull<RcBox<T>> = uninit_ptr.cast();
344+
345+
let weak = Weak { ptr: init_ptr };
346+
347+
// It's important we don't give up ownership of the weak pointer, or
348+
// else the memory might be freed by the time `data_fn` returns. If
349+
// we really wanted to pass ownership, we could create an additional
350+
// weak pointer for ourselves, but this would result in additional
351+
// updates to the weak reference count which might not be necessary
352+
// otherwise.
353+
let data = data_fn(&weak);
354+
355+
unsafe {
356+
let inner = init_ptr.as_ptr();
357+
ptr::write(&raw mut (*inner).value, data);
358+
359+
let prev_value = (*inner).strong.get();
360+
debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
361+
(*inner).strong.set(1);
362+
}
363+
364+
let strong = Rc::from_inner(init_ptr);
365+
366+
// Strong references should collectively own a shared weak reference,
367+
// so don't run the destructor for our old weak reference.
368+
mem::forget(weak);
369+
strong
370+
}
371+
328372
/// Constructs a new `Rc` with uninitialized contents.
329373
///
330374
/// # Examples

library/alloc/src/rc/tests.rs

+66
Original file line numberDiff line numberDiff line change
@@ -434,3 +434,69 @@ fn test_array_from_slice() {
434434
let a: Result<Rc<[u32; 2]>, _> = r.clone().try_into();
435435
assert!(a.is_err());
436436
}
437+
438+
#[test]
439+
fn test_rc_cyclic_with_zero_refs() {
440+
struct ZeroRefs {
441+
inner: Weak<ZeroRefs>,
442+
}
443+
444+
let zero_refs = Rc::new_cyclic(|inner| {
445+
assert_eq!(inner.strong_count(), 0);
446+
assert!(inner.upgrade().is_none());
447+
ZeroRefs { inner: Weak::new() }
448+
});
449+
450+
assert_eq!(Rc::strong_count(&zero_refs), 1);
451+
assert_eq!(Rc::weak_count(&zero_refs), 0);
452+
assert_eq!(zero_refs.inner.strong_count(), 0);
453+
assert_eq!(zero_refs.inner.weak_count(), 0);
454+
}
455+
456+
#[test]
457+
fn test_rc_cyclic_with_one_ref() {
458+
struct OneRef {
459+
inner: Weak<OneRef>,
460+
}
461+
462+
let one_ref = Rc::new_cyclic(|inner| {
463+
assert_eq!(inner.strong_count(), 0);
464+
assert!(inner.upgrade().is_none());
465+
OneRef { inner: inner.clone() }
466+
});
467+
468+
assert_eq!(Rc::strong_count(&one_ref), 1);
469+
assert_eq!(Rc::weak_count(&one_ref), 1);
470+
471+
let one_ref2 = Weak::upgrade(&one_ref.inner).unwrap();
472+
assert!(Rc::ptr_eq(&one_ref, &one_ref2));
473+
474+
assert_eq!(one_ref.inner.strong_count(), 2);
475+
assert_eq!(one_ref.inner.weak_count(), 1);
476+
}
477+
478+
#[test]
479+
fn test_rc_cyclic_with_two_ref() {
480+
struct TwoRefs {
481+
inner: Weak<TwoRefs>,
482+
inner1: Weak<TwoRefs>,
483+
}
484+
485+
let two_refs = Rc::new_cyclic(|inner| {
486+
assert_eq!(inner.strong_count(), 0);
487+
assert!(inner.upgrade().is_none());
488+
TwoRefs { inner: inner.clone(), inner1: inner.clone() }
489+
});
490+
491+
assert_eq!(Rc::strong_count(&two_refs), 1);
492+
assert_eq!(Rc::weak_count(&two_refs), 2);
493+
494+
let two_ref3 = Weak::upgrade(&two_refs.inner).unwrap();
495+
assert!(Rc::ptr_eq(&two_refs, &two_ref3));
496+
497+
let two_ref2 = Weak::upgrade(&two_refs.inner1).unwrap();
498+
assert!(Rc::ptr_eq(&two_refs, &two_ref2));
499+
500+
assert_eq!(Rc::strong_count(&two_refs), 3);
501+
assert_eq!(Rc::weak_count(&two_refs), 2);
502+
}

library/alloc/src/vec.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ use crate::raw_vec::RawVec;
159159
/// # Slicing
160160
///
161161
/// A `Vec` can be mutable. Slices, on the other hand, are read-only objects.
162-
/// To get a slice, use `&`. Example:
162+
/// To get a [slice], use [`&`]. Example:
163163
///
164164
/// ```
165165
/// fn read_slice(slice: &[usize]) {
@@ -287,6 +287,8 @@ use crate::raw_vec::RawVec;
287287
/// [`insert`]: Vec::insert
288288
/// [`reserve`]: Vec::reserve
289289
/// [owned slice]: Box
290+
/// [slice]: ../../std/primitive.slice.html
291+
/// [`&`]: ../../std/primitive.reference.html
290292
#[stable(feature = "rust1", since = "1.0.0")]
291293
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_type")]
292294
pub struct Vec<T> {

src/bootstrap/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ impl<'a> Builder<'a> {
382382
native::Lld
383383
),
384384
Kind::Check | Kind::Clippy | Kind::Fix | Kind::Format => {
385-
describe!(check::Std, check::Rustc, check::Rustdoc, check::Clippy)
385+
describe!(check::Std, check::Rustc, check::Rustdoc, check::Clippy, check::Bootstrap)
386386
}
387387
Kind::Test => describe!(
388388
crate::toolstate::ToolStateCheck,

0 commit comments

Comments
 (0)