Skip to content

Commit 7d6f948

Browse files
committedJan 4, 2022
Auto merge of #92556 - matthiaskrgr:rollup-s9vopuj, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #91754 (Modifications to `std::io::Stdin` on Windows so that there is no longer a 4-byte buffer minimum in read().) - #91884 (Constify `Box<T, A>` methods) - #92107 (Actually set IMAGE_SCN_LNK_REMOVE for .rmeta) - #92456 (Make the documentation of builtin macro attributes accessible) - #92507 (Suggest single quotes when char expected, str provided) - #92525 (intra-doc: Make `Receiver::into_iter` into a clickable link) - #92532 (revert #92254 "Bump gsgdt to 0.1.3") Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 2b681ac + 76c0271 commit 7d6f948

File tree

24 files changed

+458
-86
lines changed

24 files changed

+458
-86
lines changed
 

‎Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -1505,9 +1505,9 @@ dependencies = [
15051505

15061506
[[package]]
15071507
name = "gsgdt"
1508-
version = "0.1.3"
1508+
version = "0.1.2"
15091509
source = "registry+https://github.com/rust-lang/crates.io-index"
1510-
checksum = "cb958139bb971f37d2f5423436f137768f88b9c616b4c21d4f634dd129508d60"
1510+
checksum = "a0d876ce7262df96262a2a19531da6ff9a86048224d49580a585fc5c04617825"
15111511
dependencies = [
15121512
"serde",
15131513
]

‎compiler/rustc_codegen_ssa/src/back/metadata.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use std::path::Path;
66

77
use object::write::{self, StandardSegment, Symbol, SymbolSection};
88
use object::{
9-
elf, Architecture, BinaryFormat, Endianness, FileFlags, Object, ObjectSection, SectionFlags,
10-
SectionKind, SymbolFlags, SymbolKind, SymbolScope,
9+
elf, pe, Architecture, BinaryFormat, Endianness, FileFlags, Object, ObjectSection,
10+
SectionFlags, SectionKind, SymbolFlags, SymbolKind, SymbolScope,
1111
};
1212

1313
use snap::write::FrameEncoder;
@@ -216,13 +216,12 @@ pub fn create_rmeta_file(sess: &Session, metadata: &[u8]) -> Vec<u8> {
216216
);
217217
match file.format() {
218218
BinaryFormat::Coff => {
219-
const IMAGE_SCN_LNK_REMOVE: u32 = 0;
220219
file.section_mut(section).flags =
221-
SectionFlags::Coff { characteristics: IMAGE_SCN_LNK_REMOVE };
220+
SectionFlags::Coff { characteristics: pe::IMAGE_SCN_LNK_REMOVE };
222221
}
223222
BinaryFormat::Elf => {
224-
const SHF_EXCLUDE: u64 = 0x80000000;
225-
file.section_mut(section).flags = SectionFlags::Elf { sh_flags: SHF_EXCLUDE };
223+
file.section_mut(section).flags =
224+
SectionFlags::Elf { sh_flags: elf::SHF_EXCLUDE as u64 };
226225
}
227226
_ => {}
228227
};

‎compiler/rustc_infer/src/infer/error_reporting/mod.rs

+38-3
Original file line numberDiff line numberDiff line change
@@ -2041,11 +2041,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
20412041
if let ValuePairs::Types(ty::error::ExpectedFound { expected, found }) =
20422042
trace.values
20432043
{
2044-
// If a tuple of length one was expected and the found expression has
2045-
// parentheses around it, perhaps the user meant to write `(expr,)` to
2046-
// build a tuple (issue #86100)
20472044
match (expected.kind(), found.kind()) {
20482045
(ty::Tuple(_), ty::Tuple(_)) => {}
2046+
// If a tuple of length one was expected and the found expression has
2047+
// parentheses around it, perhaps the user meant to write `(expr,)` to
2048+
// build a tuple (issue #86100)
20492049
(ty::Tuple(_), _) if expected.tuple_fields().count() == 1 => {
20502050
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
20512051
if let Some(code) =
@@ -2060,6 +2060,41 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
20602060
}
20612061
}
20622062
}
2063+
// If a character was expected and the found expression is a string literal
2064+
// containing a single character, perhaps the user meant to write `'c'` to
2065+
// specify a character literal (issue #92479)
2066+
(ty::Char, ty::Ref(_, r, _)) if r.is_str() => {
2067+
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
2068+
if let Some(code) =
2069+
code.strip_prefix('"').and_then(|s| s.strip_suffix('"'))
2070+
{
2071+
if code.chars().nth(1).is_none() {
2072+
err.span_suggestion(
2073+
span,
2074+
"if you meant to write a `char` literal, use single quotes",
2075+
format!("'{}'", code),
2076+
Applicability::MachineApplicable,
2077+
);
2078+
}
2079+
}
2080+
}
2081+
}
2082+
// If a string was expected and the found expression is a character literal,
2083+
// perhaps the user meant to write `"s"` to specify a string literal.
2084+
(ty::Ref(_, r, _), ty::Char) if r.is_str() => {
2085+
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
2086+
if let Some(code) =
2087+
code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
2088+
{
2089+
err.span_suggestion(
2090+
span,
2091+
"if you meant to write a `str` literal, use double quotes",
2092+
format!("\"{}\"", code),
2093+
Applicability::MachineApplicable,
2094+
);
2095+
}
2096+
}
2097+
}
20632098
_ => {}
20642099
}
20652100
}

‎compiler/rustc_middle/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ doctest = false
1010
rustc_arena = { path = "../rustc_arena" }
1111
bitflags = "1.2.1"
1212
either = "1.5.0"
13-
gsgdt = "0.1.3"
13+
gsgdt = "0.1.2"
1414
tracing = "0.1"
1515
rustc-rayon = "0.3.1"
1616
rustc-rayon-core = "0.3.1"

‎compiler/rustc_middle/src/mir/generic_graph.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ fn bb_to_graph_node(block: BasicBlock, body: &Body<'_>, dark_mode: bool) -> Node
5555
data.terminator().kind.fmt_head(&mut terminator_head).unwrap();
5656
stmts.push(terminator_head);
5757

58-
Node::from_list(stmts, label, title, style)
58+
Node::new(stmts, label, title, style)
5959
}
6060

6161
// Must match `[0-9A-Za-z_]*`. This does not appear in the rendered graph, so

‎library/alloc/src/alloc.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -323,17 +323,21 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
323323

324324
#[cfg_attr(not(test), lang = "box_free")]
325325
#[inline]
326+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
326327
// This signature has to be the same as `Box`, otherwise an ICE will happen.
327328
// When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as
328329
// well.
329330
// For example if `Box` is changed to `struct Box<T: ?Sized, A: Allocator>(Unique<T>, A)`,
330331
// this function has to be changed to `fn box_free<T: ?Sized, A: Allocator>(Unique<T>, A)` as well.
331-
pub(crate) unsafe fn box_free<T: ?Sized, A: Allocator>(ptr: Unique<T>, alloc: A) {
332+
pub(crate) const unsafe fn box_free<T: ?Sized, A: ~const Allocator + ~const Drop>(
333+
ptr: Unique<T>,
334+
alloc: A,
335+
) {
332336
unsafe {
333337
let size = size_of_val(ptr.as_ref());
334338
let align = min_align_of_val(ptr.as_ref());
335339
let layout = Layout::from_size_align_unchecked(size, align);
336-
alloc.deallocate(ptr.cast().into(), layout)
340+
alloc.deallocate(From::from(ptr.cast()), layout)
337341
}
338342
}
339343

@@ -361,13 +365,22 @@ extern "Rust" {
361365
/// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html
362366
/// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html
363367
#[stable(feature = "global_alloc", since = "1.28.0")]
368+
#[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")]
364369
#[cfg(all(not(no_global_oom_handling), not(test)))]
365370
#[rustc_allocator_nounwind]
366371
#[cold]
367-
pub fn handle_alloc_error(layout: Layout) -> ! {
368-
unsafe {
369-
__rust_alloc_error_handler(layout.size(), layout.align());
372+
pub const fn handle_alloc_error(layout: Layout) -> ! {
373+
const fn ct_error(_: Layout) -> ! {
374+
panic!("allocation failed");
370375
}
376+
377+
fn rt_error(layout: Layout) -> ! {
378+
unsafe {
379+
__rust_alloc_error_handler(layout.size(), layout.align());
380+
}
381+
}
382+
383+
unsafe { core::intrinsics::const_eval_select((layout,), ct_error, rt_error) }
371384
}
372385

373386
// For alloc test `std::alloc::handle_alloc_error` can be used directly.

‎library/alloc/src/boxed.rs

+68-24
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,13 @@ impl<T, A: Allocator> Box<T, A> {
346346
/// ```
347347
#[cfg(not(no_global_oom_handling))]
348348
#[unstable(feature = "allocator_api", issue = "32838")]
349+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
349350
#[must_use]
350351
#[inline]
351-
pub fn new_in(x: T, alloc: A) -> Self {
352+
pub const fn new_in(x: T, alloc: A) -> Self
353+
where
354+
A: ~const Allocator + ~const Drop,
355+
{
352356
let mut boxed = Self::new_uninit_in(alloc);
353357
unsafe {
354358
boxed.as_mut_ptr().write(x);
@@ -372,8 +376,13 @@ impl<T, A: Allocator> Box<T, A> {
372376
/// # Ok::<(), std::alloc::AllocError>(())
373377
/// ```
374378
#[unstable(feature = "allocator_api", issue = "32838")]
379+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
375380
#[inline]
376-
pub fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError> {
381+
pub const fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError>
382+
where
383+
T: ~const Drop,
384+
A: ~const Allocator + ~const Drop,
385+
{
377386
let mut boxed = Self::try_new_uninit_in(alloc)?;
378387
unsafe {
379388
boxed.as_mut_ptr().write(x);
@@ -402,10 +411,14 @@ impl<T, A: Allocator> Box<T, A> {
402411
/// assert_eq!(*five, 5)
403412
/// ```
404413
#[unstable(feature = "allocator_api", issue = "32838")]
414+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
405415
#[cfg(not(no_global_oom_handling))]
406416
#[must_use]
407417
// #[unstable(feature = "new_uninit", issue = "63291")]
408-
pub fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> {
418+
pub const fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
419+
where
420+
A: ~const Allocator + ~const Drop,
421+
{
409422
let layout = Layout::new::<mem::MaybeUninit<T>>();
410423
// NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
411424
// That would make code size bigger.
@@ -439,7 +452,11 @@ impl<T, A: Allocator> Box<T, A> {
439452
/// ```
440453
#[unstable(feature = "allocator_api", issue = "32838")]
441454
// #[unstable(feature = "new_uninit", issue = "63291")]
442-
pub fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> {
455+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
456+
pub const fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
457+
where
458+
A: ~const Allocator + ~const Drop,
459+
{
443460
let layout = Layout::new::<mem::MaybeUninit<T>>();
444461
let ptr = alloc.allocate(layout)?.cast();
445462
unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
@@ -466,10 +483,14 @@ impl<T, A: Allocator> Box<T, A> {
466483
///
467484
/// [zeroed]: mem::MaybeUninit::zeroed
468485
#[unstable(feature = "allocator_api", issue = "32838")]
486+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
469487
#[cfg(not(no_global_oom_handling))]
470488
// #[unstable(feature = "new_uninit", issue = "63291")]
471489
#[must_use]
472-
pub fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> {
490+
pub const fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
491+
where
492+
A: ~const Allocator + ~const Drop,
493+
{
473494
let layout = Layout::new::<mem::MaybeUninit<T>>();
474495
// NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
475496
// That would make code size bigger.
@@ -503,7 +524,11 @@ impl<T, A: Allocator> Box<T, A> {
503524
/// [zeroed]: mem::MaybeUninit::zeroed
504525
#[unstable(feature = "allocator_api", issue = "32838")]
505526
// #[unstable(feature = "new_uninit", issue = "63291")]
506-
pub fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> {
527+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
528+
pub const fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
529+
where
530+
A: ~const Allocator + ~const Drop,
531+
{
507532
let layout = Layout::new::<mem::MaybeUninit<T>>();
508533
let ptr = alloc.allocate_zeroed(layout)?.cast();
509534
unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
@@ -513,20 +538,22 @@ impl<T, A: Allocator> Box<T, A> {
513538
/// `x` will be pinned in memory and unable to be moved.
514539
#[cfg(not(no_global_oom_handling))]
515540
#[unstable(feature = "allocator_api", issue = "32838")]
541+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
516542
#[must_use]
517543
#[inline(always)]
518-
pub fn pin_in(x: T, alloc: A) -> Pin<Self>
544+
pub const fn pin_in(x: T, alloc: A) -> Pin<Self>
519545
where
520-
A: 'static,
546+
A: 'static + ~const Allocator + ~const Drop,
521547
{
522-
Self::new_in(x, alloc).into()
548+
Self::into_pin(Self::new_in(x, alloc))
523549
}
524550

525551
/// Converts a `Box<T>` into a `Box<[T]>`
526552
///
527553
/// This conversion does not allocate on the heap and happens in place.
528554
#[unstable(feature = "box_into_boxed_slice", issue = "71582")]
529-
pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
555+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
556+
pub const fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
530557
let (raw, alloc) = Box::into_raw_with_allocator(boxed);
531558
unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) }
532559
}
@@ -543,8 +570,12 @@ impl<T, A: Allocator> Box<T, A> {
543570
/// assert_eq!(Box::into_inner(c), 5);
544571
/// ```
545572
#[unstable(feature = "box_into_inner", issue = "80437")]
573+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
546574
#[inline]
547-
pub fn into_inner(boxed: Self) -> T {
575+
pub const fn into_inner(boxed: Self) -> T
576+
where
577+
Self: ~const Drop,
578+
{
548579
*boxed
549580
}
550581
}
@@ -758,8 +789,9 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
758789
/// assert_eq!(*five, 5)
759790
/// ```
760791
#[unstable(feature = "new_uninit", issue = "63291")]
792+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
761793
#[inline]
762-
pub unsafe fn assume_init(self) -> Box<T, A> {
794+
pub const unsafe fn assume_init(self) -> Box<T, A> {
763795
let (raw, alloc) = Box::into_raw_with_allocator(self);
764796
unsafe { Box::from_raw_in(raw as *mut T, alloc) }
765797
}
@@ -792,8 +824,9 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
792824
/// }
793825
/// ```
794826
#[unstable(feature = "new_uninit", issue = "63291")]
827+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
795828
#[inline]
796-
pub fn write(mut boxed: Self, value: T) -> Box<T, A> {
829+
pub const fn write(mut boxed: Self, value: T) -> Box<T, A> {
797830
unsafe {
798831
(*boxed).write(value);
799832
boxed.assume_init()
@@ -938,8 +971,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
938971
/// [memory layout]: self#memory-layout
939972
/// [`Layout`]: crate::Layout
940973
#[unstable(feature = "allocator_api", issue = "32838")]
974+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
941975
#[inline]
942-
pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
976+
pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
943977
Box(unsafe { Unique::new_unchecked(raw) }, alloc)
944978
}
945979

@@ -1035,8 +1069,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
10351069
///
10361070
/// [memory layout]: self#memory-layout
10371071
#[unstable(feature = "allocator_api", issue = "32838")]
1072+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
10381073
#[inline]
1039-
pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
1074+
pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
10401075
let (leaked, alloc) = Box::into_unique(b);
10411076
(leaked.as_ptr(), alloc)
10421077
}
@@ -1046,9 +1081,10 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
10461081
issue = "none",
10471082
reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead"
10481083
)]
1084+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
10491085
#[inline]
10501086
#[doc(hidden)]
1051-
pub fn into_unique(b: Self) -> (Unique<T>, A) {
1087+
pub const fn into_unique(b: Self) -> (Unique<T>, A) {
10521088
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
10531089
// raw pointer for the type system. Turning it directly into a raw pointer would not be
10541090
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
@@ -1064,8 +1100,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
10641100
/// to call it as `Box::allocator(&b)` instead of `b.allocator()`. This
10651101
/// is so that there is no conflict with a method on the inner type.
10661102
#[unstable(feature = "allocator_api", issue = "32838")]
1103+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
10671104
#[inline]
1068-
pub fn allocator(b: &Self) -> &A {
1105+
pub const fn allocator(b: &Self) -> &A {
10691106
&b.1
10701107
}
10711108

@@ -1105,8 +1142,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
11051142
/// assert_eq!(*static_ref, [4, 2, 3]);
11061143
/// ```
11071144
#[stable(feature = "box_leak", since = "1.26.0")]
1145+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
11081146
#[inline]
1109-
pub fn leak<'a>(b: Self) -> &'a mut T
1147+
pub const fn leak<'a>(b: Self) -> &'a mut T
11101148
where
11111149
A: 'a,
11121150
{
@@ -1119,7 +1157,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
11191157
///
11201158
/// This is also available via [`From`].
11211159
#[unstable(feature = "box_into_pin", issue = "62370")]
1122-
pub fn into_pin(boxed: Self) -> Pin<Self>
1160+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
1161+
pub const fn into_pin(boxed: Self) -> Pin<Self>
11231162
where
11241163
A: 'static,
11251164
{
@@ -1131,7 +1170,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
11311170
}
11321171

11331172
#[stable(feature = "rust1", since = "1.0.0")]
1134-
unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box<T, A> {
1173+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
1174+
unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> const Drop for Box<T, A> {
11351175
fn drop(&mut self) {
11361176
// FIXME: Do nothing, drop is currently performed by compiler.
11371177
}
@@ -1341,7 +1381,8 @@ impl<T> From<T> for Box<T> {
13411381
}
13421382

13431383
#[stable(feature = "pin", since = "1.33.0")]
1344-
impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>>
1384+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
1385+
impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>>
13451386
where
13461387
A: 'static,
13471388
{
@@ -1720,7 +1761,8 @@ impl<T: ?Sized, A: Allocator> fmt::Pointer for Box<T, A> {
17201761
}
17211762

17221763
#[stable(feature = "rust1", since = "1.0.0")]
1723-
impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
1764+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
1765+
impl<T: ?Sized, A: Allocator> const Deref for Box<T, A> {
17241766
type Target = T;
17251767

17261768
fn deref(&self) -> &T {
@@ -1729,7 +1771,8 @@ impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
17291771
}
17301772

17311773
#[stable(feature = "rust1", since = "1.0.0")]
1732-
impl<T: ?Sized, A: Allocator> DerefMut for Box<T, A> {
1774+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
1775+
impl<T: ?Sized, A: Allocator> const DerefMut for Box<T, A> {
17331776
fn deref_mut(&mut self) -> &mut T {
17341777
&mut **self
17351778
}
@@ -1908,7 +1951,8 @@ impl<T: ?Sized, A: Allocator> AsMut<T> for Box<T, A> {
19081951
* could have a method to project a Pin<T> from it.
19091952
*/
19101953
#[stable(feature = "pin", since = "1.33.0")]
1911-
impl<T: ?Sized, A: Allocator> Unpin for Box<T, A> where A: 'static {}
1954+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
1955+
impl<T: ?Sized, A: Allocator> const Unpin for Box<T, A> where A: 'static {}
19121956

19131957
#[unstable(feature = "generator_trait", issue = "43122")]
19141958
impl<G: ?Sized + Generator<R> + Unpin, R, A: Allocator> Generator<R> for Box<G, A>

‎library/alloc/src/lib.rs

+16
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,20 @@
9696
#![feature(array_windows)]
9797
#![feature(async_stream)]
9898
#![feature(coerce_unsized)]
99+
#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
100+
#![feature(const_box)]
99101
#![cfg_attr(not(no_global_oom_handling), feature(const_btree_new))]
100102
#![feature(const_cow_is_borrowed)]
103+
#![feature(const_convert)]
104+
#![feature(const_size_of_val)]
105+
#![feature(const_align_of_val)]
106+
#![feature(const_ptr_read)]
107+
#![feature(const_maybe_uninit_write)]
108+
#![feature(const_maybe_uninit_as_mut_ptr)]
109+
#![feature(const_refs_to_cell)]
101110
#![feature(core_intrinsics)]
111+
#![feature(const_eval_select)]
112+
#![feature(const_pin)]
102113
#![feature(dispatch_from_dyn)]
103114
#![feature(exact_size_is_empty)]
104115
#![feature(extend_one)]
@@ -134,8 +145,13 @@
134145
#![feature(box_syntax)]
135146
#![feature(cfg_sanitize)]
136147
#![feature(cfg_target_has_atomic)]
148+
#![feature(const_deref)]
137149
#![feature(const_fn_trait_bound)]
150+
#![feature(const_mut_refs)]
151+
#![feature(const_ptr_write)]
152+
#![feature(const_precise_live_drops)]
138153
#![feature(const_trait_impl)]
154+
#![feature(const_try)]
139155
#![cfg_attr(bootstrap, feature(destructuring_assignment))]
140156
#![feature(dropck_eyepatch)]
141157
#![feature(exclusive_range_pattern)]

‎library/alloc/tests/boxed.rs

+111-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use std::cell::Cell;
2-
use std::mem::MaybeUninit;
3-
use std::ptr::NonNull;
1+
use core::alloc::{AllocError, Allocator, Layout};
2+
use core::cell::Cell;
3+
use core::mem::MaybeUninit;
4+
use core::ptr::NonNull;
45

56
#[test]
67
fn uninitialized_zero_size_box() {
@@ -57,3 +58,110 @@ fn box_deref_lval() {
5758
x.set(1000);
5859
assert_eq!(x.get(), 1000);
5960
}
61+
62+
pub struct ConstAllocator;
63+
64+
unsafe impl const Allocator for ConstAllocator {
65+
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
66+
match layout.size() {
67+
0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)),
68+
_ => unsafe {
69+
let ptr = core::intrinsics::const_allocate(layout.size(), layout.align());
70+
Ok(NonNull::new_unchecked(ptr as *mut [u8; 0] as *mut [u8]))
71+
},
72+
}
73+
}
74+
75+
unsafe fn deallocate(&self, _ptr: NonNull<u8>, layout: Layout) {
76+
match layout.size() {
77+
0 => { /* do nothing */ }
78+
_ => { /* do nothing too */ }
79+
}
80+
}
81+
82+
fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
83+
let ptr = self.allocate(layout)?;
84+
if layout.size() > 0 {
85+
unsafe {
86+
ptr.as_mut_ptr().write_bytes(0, layout.size());
87+
}
88+
}
89+
Ok(ptr)
90+
}
91+
92+
unsafe fn grow(
93+
&self,
94+
ptr: NonNull<u8>,
95+
old_layout: Layout,
96+
new_layout: Layout,
97+
) -> Result<NonNull<[u8]>, AllocError> {
98+
debug_assert!(
99+
new_layout.size() >= old_layout.size(),
100+
"`new_layout.size()` must be greater than or equal to `old_layout.size()`"
101+
);
102+
103+
let new_ptr = self.allocate(new_layout)?;
104+
if new_layout.size() > 0 {
105+
new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), old_layout.size());
106+
self.deallocate(ptr, old_layout);
107+
}
108+
Ok(new_ptr)
109+
}
110+
111+
unsafe fn grow_zeroed(
112+
&self,
113+
ptr: NonNull<u8>,
114+
old_layout: Layout,
115+
new_layout: Layout,
116+
) -> Result<NonNull<[u8]>, AllocError> {
117+
let new_ptr = self.grow(ptr, old_layout, new_layout)?;
118+
if new_layout.size() > 0 {
119+
let old_size = old_layout.size();
120+
let new_size = new_layout.size();
121+
let raw_ptr = new_ptr.as_mut_ptr();
122+
raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
123+
}
124+
Ok(new_ptr)
125+
}
126+
127+
unsafe fn shrink(
128+
&self,
129+
ptr: NonNull<u8>,
130+
old_layout: Layout,
131+
new_layout: Layout,
132+
) -> Result<NonNull<[u8]>, AllocError> {
133+
debug_assert!(
134+
new_layout.size() <= old_layout.size(),
135+
"`new_layout.size()` must be smaller than or equal to `old_layout.size()`"
136+
);
137+
138+
let new_ptr = self.allocate(new_layout)?;
139+
if new_layout.size() > 0 {
140+
new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), new_layout.size());
141+
self.deallocate(ptr, old_layout);
142+
}
143+
Ok(new_ptr)
144+
}
145+
146+
fn by_ref(&self) -> &Self
147+
where
148+
Self: Sized,
149+
{
150+
self
151+
}
152+
}
153+
154+
#[test]
155+
fn const_box() {
156+
const VALUE: u32 = {
157+
let mut boxed = Box::new_in(1u32, ConstAllocator);
158+
assert!(*boxed == 1);
159+
160+
*boxed = 42;
161+
assert!(*boxed == 42);
162+
163+
*boxed
164+
};
165+
166+
assert!(VALUE == 42);
167+
}

‎library/alloc/tests/lib.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
#![feature(allocator_api)]
2+
#![feature(alloc_layout_extra)]
23
#![feature(assert_matches)]
34
#![feature(box_syntax)]
45
#![feature(cow_is_borrowed)]
6+
#![feature(const_box)]
7+
#![feature(const_convert)]
58
#![feature(const_cow_is_borrowed)]
9+
#![feature(const_heap)]
10+
#![feature(const_intrinsic_copy)]
11+
#![feature(const_mut_refs)]
12+
#![feature(const_nonnull_slice_from_raw_parts)]
13+
#![feature(const_ptr_offset)]
14+
#![feature(const_ptr_write)]
15+
#![feature(const_try)]
16+
#![feature(core_intrinsics)]
617
#![feature(drain_filter)]
718
#![feature(exact_size_is_empty)]
819
#![feature(new_uninit)]
@@ -26,6 +37,7 @@
2637
#![feature(const_default_impls)]
2738
#![feature(const_trait_impl)]
2839
#![feature(const_str_from_utf8)]
40+
#![feature(nonnull_slice_from_raw_parts)]
2941

3042
use std::collections::hash_map::DefaultHasher;
3143
use std::hash::{Hash, Hasher};

‎library/core/src/macros/mod.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,6 @@ pub(crate) mod builtin {
866866
language use and is subject to change"
867867
)]
868868
#[allow_internal_unstable(fmt_internals)]
869-
#[doc(hidden)]
870869
#[rustc_builtin_macro]
871870
#[macro_export]
872871
macro_rules! format_args_nl {
@@ -1428,13 +1427,21 @@ pub(crate) mod builtin {
14281427
}
14291428

14301429
/// Attribute macro used to apply derive macros.
1430+
///
1431+
/// See [the reference] for more info.
1432+
///
1433+
/// [the reference]: ../../../reference/attributes/derive.html
14311434
#[stable(feature = "rust1", since = "1.0.0")]
14321435
#[rustc_builtin_macro]
14331436
pub macro derive($item:item) {
14341437
/* compiler built-in */
14351438
}
14361439

14371440
/// Attribute macro applied to a function to turn it into a unit test.
1441+
///
1442+
/// See [the reference] for more info.
1443+
///
1444+
/// [the reference]: ../../../reference/attributes/testing.html#the-test-attribute
14381445
#[stable(feature = "rust1", since = "1.0.0")]
14391446
#[allow_internal_unstable(test, rustc_attrs)]
14401447
#[rustc_builtin_macro]
@@ -1469,7 +1476,7 @@ pub(crate) mod builtin {
14691476

14701477
/// Attribute macro applied to a static to register it as a global allocator.
14711478
///
1472-
/// See also [`std::alloc::GlobalAlloc`](../std/alloc/trait.GlobalAlloc.html).
1479+
/// See also [`std::alloc::GlobalAlloc`](../../../std/alloc/trait.GlobalAlloc.html).
14731480
#[stable(feature = "global_allocator", since = "1.28.0")]
14741481
#[allow_internal_unstable(rustc_attrs)]
14751482
#[rustc_builtin_macro]
@@ -1507,6 +1514,7 @@ pub(crate) mod builtin {
15071514
since = "1.52.0",
15081515
reason = "rustc-serialize is deprecated and no longer supported"
15091516
)]
1517+
#[doc(hidden)] // While technically stable, using it is unstable, and deprecated. Hide it.
15101518
pub macro RustcDecodable($item:item) {
15111519
/* compiler built-in */
15121520
}
@@ -1519,6 +1527,7 @@ pub(crate) mod builtin {
15191527
since = "1.52.0",
15201528
reason = "rustc-serialize is deprecated and no longer supported"
15211529
)]
1530+
#[doc(hidden)] // While technically stable, using it is unstable, and deprecated. Hide it.
15221531
pub macro RustcEncodable($item:item) {
15231532
/* compiler built-in */
15241533
}

‎library/core/src/prelude/v1.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -69,29 +69,26 @@ pub use crate::{
6969
#[doc(no_inline)]
7070
pub use crate::concat_bytes;
7171

72+
// Do not `doc(inline)` these `doc(hidden)` items.
7273
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
73-
#[allow(deprecated, deprecated_in_future)]
74-
#[doc(no_inline)]
75-
pub use crate::macros::builtin::{
76-
bench, global_allocator, test, test_case, RustcDecodable, RustcEncodable,
77-
};
74+
#[allow(deprecated)]
75+
pub use crate::macros::builtin::{RustcDecodable, RustcEncodable};
7876

77+
// Do not `doc(no_inline)` so that they become doc items on their own
78+
// (no public module for them to be re-exported from).
7979
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
80-
#[doc(no_inline)]
81-
pub use crate::macros::builtin::derive;
80+
pub use crate::macros::builtin::{bench, derive, global_allocator, test, test_case};
8281

8382
#[unstable(
8483
feature = "cfg_accessible",
8584
issue = "64797",
8685
reason = "`cfg_accessible` is not fully implemented"
8786
)]
88-
#[doc(no_inline)]
8987
pub use crate::macros::builtin::cfg_accessible;
9088

9189
#[unstable(
9290
feature = "cfg_eval",
9391
issue = "82679",
9492
reason = "`cfg_eval` is a recently implemented feature"
9593
)]
96-
#[doc(no_inline)]
9794
pub use crate::macros::builtin::cfg_eval;

‎library/std/src/prelude/v1.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -54,33 +54,30 @@ pub use core::prelude::v1::{
5454
#[doc(no_inline)]
5555
pub use core::prelude::v1::concat_bytes;
5656

57-
// FIXME: Attribute and internal derive macros are not documented because for them rustdoc generates
58-
// dead links which fail link checker testing.
57+
// Do not `doc(inline)` these `doc(hidden)` items.
5958
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
60-
#[allow(deprecated, deprecated_in_future)]
61-
#[doc(hidden)]
62-
pub use core::prelude::v1::{
63-
bench, global_allocator, test, test_case, RustcDecodable, RustcEncodable,
64-
};
59+
#[allow(deprecated)]
60+
pub use core::prelude::v1::{RustcDecodable, RustcEncodable};
6561

62+
// Do not `doc(no_inline)` so that they become doc items on their own
63+
// (no public module for them to be re-exported from).
6664
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
67-
#[doc(hidden)]
68-
pub use core::prelude::v1::derive;
65+
pub use core::prelude::v1::{bench, derive, global_allocator, test, test_case};
6966

67+
// Do not `doc(no_inline)` either.
7068
#[unstable(
7169
feature = "cfg_accessible",
7270
issue = "64797",
7371
reason = "`cfg_accessible` is not fully implemented"
7472
)]
75-
#[doc(hidden)]
7673
pub use core::prelude::v1::cfg_accessible;
7774

75+
// Do not `doc(no_inline)` either.
7876
#[unstable(
7977
feature = "cfg_eval",
8078
issue = "82679",
8179
reason = "`cfg_eval` is a recently implemented feature"
8280
)]
83-
#[doc(hidden)]
8481
pub use core::prelude::v1::cfg_eval;
8582

8683
// The file so far is equivalent to src/libcore/prelude/v1.rs,

‎library/std/src/sync/mpsc/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -429,12 +429,13 @@ pub struct TryIter<'a, T: 'a> {
429429
}
430430

431431
/// An owning iterator over messages on a [`Receiver`],
432-
/// created by **Receiver::into_iter**.
432+
/// created by [`into_iter`].
433433
///
434434
/// This iterator will block whenever [`next`]
435435
/// is called, waiting for a new message, and [`None`] will be
436436
/// returned if the corresponding channel has hung up.
437437
///
438+
/// [`into_iter`]: Receiver::into_iter
438439
/// [`next`]: Iterator::next
439440
///
440441
/// # Examples

‎library/std/src/sys/windows/stdio.rs

+54-18
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ use core::str::utf8_char_width;
1515
// the value over time (such as if a process calls `SetStdHandle` while it's running). See #40490.
1616
pub struct Stdin {
1717
surrogate: u16,
18+
incomplete_utf8: IncompleteUtf8,
1819
}
20+
1921
pub struct Stdout {
2022
incomplete_utf8: IncompleteUtf8,
2123
}
@@ -29,6 +31,25 @@ struct IncompleteUtf8 {
2931
len: u8,
3032
}
3133

34+
impl IncompleteUtf8 {
35+
// Implemented for use in Stdin::read.
36+
fn read(&mut self, buf: &mut [u8]) -> usize {
37+
// Write to buffer until the buffer is full or we run out of bytes.
38+
let to_write = cmp::min(buf.len(), self.len as usize);
39+
buf[..to_write].copy_from_slice(&self.bytes[..to_write]);
40+
41+
// Rotate the remaining bytes if not enough remaining space in buffer.
42+
if usize::from(self.len) > buf.len() {
43+
self.bytes.copy_within(to_write.., 0);
44+
self.len -= to_write as u8;
45+
} else {
46+
self.len = 0;
47+
}
48+
49+
to_write
50+
}
51+
}
52+
3253
// Apparently Windows doesn't handle large reads on stdin or writes to stdout/stderr well (see
3354
// #13304 for details).
3455
//
@@ -205,7 +226,7 @@ fn write_u16s(handle: c::HANDLE, data: &[u16]) -> io::Result<usize> {
205226

206227
impl Stdin {
207228
pub const fn new() -> Stdin {
208-
Stdin { surrogate: 0 }
229+
Stdin { surrogate: 0, incomplete_utf8: IncompleteUtf8::new() }
209230
}
210231
}
211232

@@ -221,24 +242,39 @@ impl io::Read for Stdin {
221242
}
222243
}
223244

224-
if buf.len() == 0 {
225-
return Ok(0);
226-
} else if buf.len() < 4 {
227-
return Err(io::Error::new_const(
228-
io::ErrorKind::InvalidInput,
229-
&"Windows stdin in console mode does not support a buffer too small to \
230-
guarantee holding one arbitrary UTF-8 character (4 bytes)",
231-
));
245+
// If there are bytes in the incomplete utf-8, start with those.
246+
// (No-op if there is nothing in the buffer.)
247+
let mut bytes_copied = self.incomplete_utf8.read(buf);
248+
249+
if bytes_copied == buf.len() {
250+
return Ok(bytes_copied);
251+
} else if buf.len() - bytes_copied < 4 {
252+
// Not enough space to get a UTF-8 byte. We will use the incomplete UTF8.
253+
let mut utf16_buf = [0u16; 1];
254+
// Read one u16 character.
255+
let read = read_u16s_fixup_surrogates(handle, &mut utf16_buf, 1, &mut self.surrogate)?;
256+
// Read bytes, using the (now-empty) self.incomplete_utf8 as extra space.
257+
let read_bytes = utf16_to_utf8(&utf16_buf[..read], &mut self.incomplete_utf8.bytes)?;
258+
259+
// Read in the bytes from incomplete_utf8 until the buffer is full.
260+
self.incomplete_utf8.len = read_bytes as u8;
261+
// No-op if no bytes.
262+
bytes_copied += self.incomplete_utf8.read(&mut buf[bytes_copied..]);
263+
Ok(bytes_copied)
264+
} else {
265+
let mut utf16_buf = [0u16; MAX_BUFFER_SIZE / 2];
266+
// In the worst case, a UTF-8 string can take 3 bytes for every `u16` of a UTF-16. So
267+
// we can read at most a third of `buf.len()` chars and uphold the guarantee no data gets
268+
// lost.
269+
let amount = cmp::min(buf.len() / 3, utf16_buf.len());
270+
let read =
271+
read_u16s_fixup_surrogates(handle, &mut utf16_buf, amount, &mut self.surrogate)?;
272+
273+
match utf16_to_utf8(&utf16_buf[..read], buf) {
274+
Ok(value) => return Ok(bytes_copied + value),
275+
Err(e) => return Err(e),
276+
}
232277
}
233-
234-
let mut utf16_buf = [0u16; MAX_BUFFER_SIZE / 2];
235-
// In the worst case, a UTF-8 string can take 3 bytes for every `u16` of a UTF-16. So
236-
// we can read at most a third of `buf.len()` chars and uphold the guarantee no data gets
237-
// lost.
238-
let amount = cmp::min(buf.len() / 3, utf16_buf.len());
239-
let read = read_u16s_fixup_surrogates(handle, &mut utf16_buf, amount, &mut self.surrogate)?;
240-
241-
utf16_to_utf8(&utf16_buf[..read], buf)
242278
}
243279
}
244280

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// When a MULTI-character string literal is used where a char should be,
2+
// DO NOT suggest changing to single quotes.
3+
4+
fn main() {
5+
let _: char = "foo"; //~ ERROR mismatched types
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/char-as-str-multi.rs:5:19
3+
|
4+
LL | let _: char = "foo";
5+
| ---- ^^^^^ expected `char`, found `&str`
6+
| |
7+
| expected due to this
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// When a SINGLE-character string literal is used where a char should be,
2+
// suggest changing to single quotes.
3+
4+
// Testing both single-byte and multi-byte characters, as we should handle both.
5+
6+
// run-rustfix
7+
8+
fn main() {
9+
let _: char = 'a'; //~ ERROR mismatched types
10+
let _: char = '人'; //~ ERROR mismatched types
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// When a SINGLE-character string literal is used where a char should be,
2+
// suggest changing to single quotes.
3+
4+
// Testing both single-byte and multi-byte characters, as we should handle both.
5+
6+
// run-rustfix
7+
8+
fn main() {
9+
let _: char = "a"; //~ ERROR mismatched types
10+
let _: char = "人"; //~ ERROR mismatched types
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/char-as-str-single.rs:9:19
3+
|
4+
LL | let _: char = "a";
5+
| ---- ^^^ expected `char`, found `&str`
6+
| |
7+
| expected due to this
8+
|
9+
help: if you meant to write a `char` literal, use single quotes
10+
|
11+
LL | let _: char = 'a';
12+
| ~~~
13+
14+
error[E0308]: mismatched types
15+
--> $DIR/char-as-str-single.rs:10:19
16+
|
17+
LL | let _: char = "人";
18+
| ---- ^^^^ expected `char`, found `&str`
19+
| |
20+
| expected due to this
21+
|
22+
help: if you meant to write a `char` literal, use single quotes
23+
|
24+
LL | let _: char = '人';
25+
| ~~~~
26+
27+
error: aborting due to 2 previous errors
28+
29+
For more information about this error, try `rustc --explain E0308`.
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// When a char literal is used where a str should be,
2+
// suggest changing to double quotes.
3+
4+
// run-rustfix
5+
6+
fn main() {
7+
let _: &str = "a"; //~ ERROR mismatched types
8+
}

‎src/test/ui/inference/str-as-char.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// When a char literal is used where a str should be,
2+
// suggest changing to double quotes.
3+
4+
// run-rustfix
5+
6+
fn main() {
7+
let _: &str = 'a'; //~ ERROR mismatched types
8+
}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/str-as-char.rs:7:19
3+
|
4+
LL | let _: &str = 'a';
5+
| ---- ^^^ expected `&str`, found `char`
6+
| |
7+
| expected due to this
8+
|
9+
help: if you meant to write a `str` literal, use double quotes
10+
|
11+
LL | let _: &str = "a";
12+
| ~~~
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0308`.

‎src/test/ui/issues/issue-23589.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ error[E0308]: mismatched types
1212
|
1313
LL | let v: Vec(&str) = vec!['1', '2'];
1414
| ^^^ expected `&str`, found `char`
15+
|
16+
help: if you meant to write a `str` literal, use double quotes
17+
|
18+
LL | let v: Vec(&str) = vec!["1", '2'];
19+
| ~~~
1520

1621
error: aborting due to 2 previous errors
1722

0 commit comments

Comments
 (0)
Please sign in to comment.