Skip to content

Commit a867059

Browse files
committedJul 25, 2022
Auto merge of rust-lang#99735 - JohnTitor:rollup-d93jyr2, r=JohnTitor
Rollup of 9 pull requests Successful merges: - rust-lang#92390 (Constify a few `(Partial)Ord` impls) - rust-lang#97077 (Simplify some code that depend on Deref) - rust-lang#98710 (correct the output of a `capacity` method example) - rust-lang#99084 (clarify how write_bytes can lead to UB due to invalid values) - rust-lang#99178 (Lighten up const_prop_lint, reusing const_prop) - rust-lang#99673 (don't ICE on invalid dyn calls) - rust-lang#99703 (Expose size_hint() for TokenStream's iterator) - rust-lang#99709 (`Inherited` always has `TypeckResults` available) - rust-lang#99713 (Fix sidebar background) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6dbae3a + e58bfac commit a867059

File tree

15 files changed

+157
-471
lines changed

15 files changed

+157
-471
lines changed
 

Diff for: ‎compiler/rustc_codegen_ssa/src/mir/place.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -435,18 +435,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
435435
LocalRef::Place(place) => place,
436436
LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
437437
LocalRef::Operand(..) => {
438-
if let Some(elem) = place_ref
439-
.projection
440-
.iter()
441-
.enumerate()
442-
.find(|elem| matches!(elem.1, mir::ProjectionElem::Deref))
443-
{
444-
base = elem.0 + 1;
438+
if place_ref.has_deref() {
439+
base = 1;
445440
let cg_base = self.codegen_consume(
446441
bx,
447-
mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref },
442+
mir::PlaceRef { projection: &place_ref.projection[..0], ..place_ref },
448443
);
449-
450444
cg_base.deref(bx.cx())
451445
} else {
452446
bug!("using operand local {:?} as place", place_ref);

Diff for: ‎compiler/rustc_const_eval/src/interpret/terminator.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -571,8 +571,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
571571

572572
// Now determine the actual method to call. We can do that in two different ways and
573573
// compare them to ensure everything fits.
574-
let ty::VtblEntry::Method(fn_inst) = self.get_vtable_entries(vptr)?[idx] else {
575-
span_bug!(self.cur_span(), "dyn call index points at something that is not a method")
574+
let Some(ty::VtblEntry::Method(fn_inst)) = self.get_vtable_entries(vptr)?.get(idx).copied() else {
575+
throw_ub_format!("`dyn` call trying to call something that is not a method")
576576
};
577577
if cfg!(debug_assertions) {
578578
let tcx = *self.tcx;

Diff for: ‎compiler/rustc_middle/src/mir/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1461,6 +1461,14 @@ impl<'tcx> Place<'tcx> {
14611461
self.projection.iter().any(|elem| elem.is_indirect())
14621462
}
14631463

1464+
/// If MirPhase >= Derefered and if projection contains Deref,
1465+
/// It's guaranteed to be in the first place
1466+
pub fn has_deref(&self) -> bool {
1467+
// To make sure this is not accidently used in wrong mir phase
1468+
debug_assert!(!self.projection[1..].contains(&PlaceElem::Deref));
1469+
self.projection.first() == Some(&PlaceElem::Deref)
1470+
}
1471+
14641472
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
14651473
/// a single deref of a local.
14661474
#[inline(always)]
@@ -1533,6 +1541,12 @@ impl<'tcx> PlaceRef<'tcx> {
15331541
}
15341542
}
15351543

1544+
/// If MirPhase >= Derefered and if projection contains Deref,
1545+
/// It's guaranteed to be in the first place
1546+
pub fn has_deref(&self) -> bool {
1547+
self.projection.first() == Some(&PlaceElem::Deref)
1548+
}
1549+
15361550
/// If this place represents a local variable like `_X` with no
15371551
/// projections, return `Some(_X)`.
15381552
#[inline]

Diff for: ‎compiler/rustc_mir_transform/src/add_retag.rs

+5-21
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,9 @@ pub struct AddRetag;
1515
/// (Concurrent accesses by other threads are no problem as these are anyway non-atomic
1616
/// copies. Data races are UB.)
1717
fn is_stable(place: PlaceRef<'_>) -> bool {
18-
place.projection.iter().all(|elem| {
19-
match elem {
20-
// Which place this evaluates to can change with any memory write,
21-
// so cannot assume this to be stable.
22-
ProjectionElem::Deref => false,
23-
// Array indices are interesting, but MIR building generates a *fresh*
24-
// temporary for every array access, so the index cannot be changed as
25-
// a side-effect.
26-
ProjectionElem::Index { .. } |
27-
// The rest is completely boring, they just offset by a constant.
28-
ProjectionElem::Field { .. } |
29-
ProjectionElem::ConstantIndex { .. } |
30-
ProjectionElem::Subslice { .. } |
31-
ProjectionElem::Downcast { .. } => true,
32-
}
33-
})
18+
// Which place this evaluates to can change with any memory write,
19+
// so cannot assume deref to be stable.
20+
!place.has_deref()
3421
}
3522

3623
/// Determine whether this type may contain a reference (or box), and thus needs retagging.
@@ -91,11 +78,8 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
9178
};
9279
let place_base_raw = |place: &Place<'tcx>| {
9380
// If this is a `Deref`, get the type of what we are deref'ing.
94-
let deref_base =
95-
place.projection.iter().rposition(|p| matches!(p, ProjectionElem::Deref));
96-
if let Some(deref_base) = deref_base {
97-
let base_proj = &place.projection[..deref_base];
98-
let ty = Place::ty_from(place.local, base_proj, &*local_decls, tcx).ty;
81+
if place.has_deref() {
82+
let ty = &local_decls[place.local].ty;
9983
ty.is_unsafe_ptr()
10084
} else {
10185
// Not a deref, and thus not raw.

Diff for: ‎compiler/rustc_mir_transform/src/const_prop.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -155,18 +155,18 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
155155
}
156156
}
157157

158-
struct ConstPropMachine<'mir, 'tcx> {
158+
pub struct ConstPropMachine<'mir, 'tcx> {
159159
/// The virtual call stack.
160160
stack: Vec<Frame<'mir, 'tcx>>,
161161
/// `OnlyInsideOwnBlock` locals that were written in the current block get erased at the end.
162-
written_only_inside_own_block_locals: FxHashSet<Local>,
162+
pub written_only_inside_own_block_locals: FxHashSet<Local>,
163163
/// Locals that need to be cleared after every block terminates.
164-
only_propagate_inside_block_locals: BitSet<Local>,
165-
can_const_prop: IndexVec<Local, ConstPropMode>,
164+
pub only_propagate_inside_block_locals: BitSet<Local>,
165+
pub can_const_prop: IndexVec<Local, ConstPropMode>,
166166
}
167167

168168
impl ConstPropMachine<'_, '_> {
169-
fn new(
169+
pub fn new(
170170
only_propagate_inside_block_locals: BitSet<Local>,
171171
can_const_prop: IndexVec<Local, ConstPropMode>,
172172
) -> Self {
@@ -816,7 +816,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
816816

817817
/// The mode that `ConstProp` is allowed to run in for a given `Local`.
818818
#[derive(Clone, Copy, Debug, PartialEq)]
819-
enum ConstPropMode {
819+
pub enum ConstPropMode {
820820
/// The `Local` can be propagated into and reads of this `Local` can also be propagated.
821821
FullConstProp,
822822
/// The `Local` can only be propagated into and from its own block.
@@ -828,7 +828,7 @@ enum ConstPropMode {
828828
NoPropagation,
829829
}
830830

831-
struct CanConstProp {
831+
pub struct CanConstProp {
832832
can_const_prop: IndexVec<Local, ConstPropMode>,
833833
// False at the beginning. Once set, no more assignments are allowed to that local.
834834
found_assignment: BitSet<Local>,
@@ -838,7 +838,7 @@ struct CanConstProp {
838838

839839
impl CanConstProp {
840840
/// Returns true if `local` can be propagated
841-
fn check<'tcx>(
841+
pub fn check<'tcx>(
842842
tcx: TyCtxt<'tcx>,
843843
param_env: ParamEnv<'tcx>,
844844
body: &Body<'tcx>,

Diff for: ‎compiler/rustc_mir_transform/src/const_prop_lint.rs

+15-336
Large diffs are not rendered by default.

Diff for: ‎compiler/rustc_typeck/src/check/inherited.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use super::callee::DeferredCallResolution;
2-
use super::MaybeInProgressTables;
32

43
use rustc_data_structures::fx::FxHashSet;
54
use rustc_hir as hir;
@@ -29,7 +28,7 @@ use std::ops::Deref;
2928
pub struct Inherited<'a, 'tcx> {
3029
pub(super) infcx: InferCtxt<'a, 'tcx>,
3130

32-
pub(super) typeck_results: super::MaybeInProgressTables<'a, 'tcx>,
31+
pub(super) typeck_results: &'a RefCell<ty::TypeckResults<'tcx>>,
3332

3433
pub(super) locals: RefCell<HirIdMap<super::LocalTy<'tcx>>>,
3534

@@ -110,11 +109,11 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
110109
let tcx = infcx.tcx;
111110
let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
112111
let body_id = tcx.hir().maybe_body_owned_by(item_id);
112+
let typeck_results =
113+
infcx.in_progress_typeck_results.expect("building `FnCtxt` without typeck results");
113114

114115
Inherited {
115-
typeck_results: MaybeInProgressTables {
116-
maybe_typeck_results: infcx.in_progress_typeck_results,
117-
},
116+
typeck_results,
118117
infcx,
119118
fulfillment_cx: RefCell::new(<dyn TraitEngine<'_>>::new(tcx)),
120119
locals: RefCell::new(Default::default()),

Diff for: ‎compiler/rustc_typeck/src/check/mod.rs

+1-28
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,7 @@ use rustc_target::spec::abi::Abi;
128128
use rustc_trait_selection::traits;
129129
use rustc_trait_selection::traits::error_reporting::recursive_type_with_infinite_size_error;
130130
use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
131-
132-
use std::cell::{Ref, RefCell, RefMut};
131+
use std::cell::RefCell;
133132

134133
use crate::require_c_abi_if_c_variadic;
135134
use crate::util::common::indenter;
@@ -900,32 +899,6 @@ enum TupleArgumentsFlag {
900899
TupleArguments,
901900
}
902901

903-
/// A wrapper for `InferCtxt`'s `in_progress_typeck_results` field.
904-
#[derive(Copy, Clone)]
905-
struct MaybeInProgressTables<'a, 'tcx> {
906-
maybe_typeck_results: Option<&'a RefCell<ty::TypeckResults<'tcx>>>,
907-
}
908-
909-
impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
910-
fn borrow(self) -> Ref<'a, ty::TypeckResults<'tcx>> {
911-
match self.maybe_typeck_results {
912-
Some(typeck_results) => typeck_results.borrow(),
913-
None => bug!(
914-
"MaybeInProgressTables: inh/fcx.typeck_results.borrow() with no typeck results"
915-
),
916-
}
917-
}
918-
919-
fn borrow_mut(self) -> RefMut<'a, ty::TypeckResults<'tcx>> {
920-
match self.maybe_typeck_results {
921-
Some(typeck_results) => typeck_results.borrow_mut(),
922-
None => bug!(
923-
"MaybeInProgressTables: inh/fcx.typeck_results.borrow_mut() with no typeck results"
924-
),
925-
}
926-
}
927-
}
928-
929902
fn typeck_item_bodies(tcx: TyCtxt<'_>, (): ()) {
930903
tcx.hir().par_body_owners(|body_owner_def_id| tcx.ensure().typeck(body_owner_def_id));
931904
}

Diff for: ‎library/alloc/src/string.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -317,11 +317,11 @@ use crate::vec::Vec;
317317
///
318318
/// ```text
319319
/// 0
320-
/// 5
321-
/// 10
322-
/// 20
323-
/// 20
324-
/// 40
320+
/// 8
321+
/// 16
322+
/// 16
323+
/// 32
324+
/// 32
325325
/// ```
326326
///
327327
/// At first, we have no memory allocated at all, but as we append to the

Diff for: ‎library/core/src/cmp.rs

+55-19
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
2323
#![stable(feature = "rust1", since = "1.0.0")]
2424

25+
use crate::marker::Destruct;
26+
2527
use self::Ordering::*;
2628

2729
/// Trait for equality comparisons which are [partial equivalence
@@ -603,7 +605,8 @@ impl Ordering {
603605
pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T);
604606

605607
#[stable(feature = "reverse_cmp_key", since = "1.19.0")]
606-
impl<T: PartialOrd> PartialOrd for Reverse<T> {
608+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
609+
impl<T: ~const PartialOrd> const PartialOrd for Reverse<T> {
607610
#[inline]
608611
fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
609612
other.0.partial_cmp(&self.0)
@@ -761,6 +764,7 @@ impl<T: Clone> Clone for Reverse<T> {
761764
#[doc(alias = ">=")]
762765
#[stable(feature = "rust1", since = "1.0.0")]
763766
#[rustc_diagnostic_item = "Ord"]
767+
#[const_trait]
764768
pub trait Ord: Eq + PartialOrd<Self> {
765769
/// This method returns an [`Ordering`] between `self` and `other`.
766770
///
@@ -796,8 +800,15 @@ pub trait Ord: Eq + PartialOrd<Self> {
796800
fn max(self, other: Self) -> Self
797801
where
798802
Self: Sized,
803+
Self: ~const Destruct,
799804
{
800-
max_by(self, other, Ord::cmp)
805+
// HACK(fee1-dead): go back to using `self.max_by(other, Ord::cmp)`
806+
// when trait methods are allowed to be used when a const closure is
807+
// expected.
808+
match self.cmp(&other) {
809+
Ordering::Less | Ordering::Equal => other,
810+
Ordering::Greater => self,
811+
}
801812
}
802813

803814
/// Compares and returns the minimum of two values.
@@ -816,8 +827,15 @@ pub trait Ord: Eq + PartialOrd<Self> {
816827
fn min(self, other: Self) -> Self
817828
where
818829
Self: Sized,
830+
Self: ~const Destruct,
819831
{
820-
min_by(self, other, Ord::cmp)
832+
// HACK(fee1-dead): go back to using `self.min_by(other, Ord::cmp)`
833+
// when trait methods are allowed to be used when a const closure is
834+
// expected.
835+
match self.cmp(&other) {
836+
Ordering::Less | Ordering::Equal => self,
837+
Ordering::Greater => other,
838+
}
821839
}
822840

823841
/// Restrict a value to a certain interval.
@@ -841,6 +859,8 @@ pub trait Ord: Eq + PartialOrd<Self> {
841859
fn clamp(self, min: Self, max: Self) -> Self
842860
where
843861
Self: Sized,
862+
Self: ~const Destruct,
863+
Self: ~const PartialOrd,
844864
{
845865
assert!(min <= max);
846866
if self < min {
@@ -862,15 +882,17 @@ pub macro Ord($item:item) {
862882
}
863883

864884
#[stable(feature = "rust1", since = "1.0.0")]
865-
impl Ord for Ordering {
885+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
886+
impl const Ord for Ordering {
866887
#[inline]
867888
fn cmp(&self, other: &Ordering) -> Ordering {
868889
(*self as i32).cmp(&(*other as i32))
869890
}
870891
}
871892

872893
#[stable(feature = "rust1", since = "1.0.0")]
873-
impl PartialOrd for Ordering {
894+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
895+
impl const PartialOrd for Ordering {
874896
#[inline]
875897
fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
876898
(*self as i32).partial_cmp(&(*other as i32))
@@ -1187,8 +1209,9 @@ pub macro PartialOrd($item:item) {
11871209
#[inline]
11881210
#[must_use]
11891211
#[stable(feature = "rust1", since = "1.0.0")]
1212+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
11901213
#[cfg_attr(not(test), rustc_diagnostic_item = "cmp_min")]
1191-
pub fn min<T: Ord>(v1: T, v2: T) -> T {
1214+
pub const fn min<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T {
11921215
v1.min(v2)
11931216
}
11941217

@@ -1250,8 +1273,9 @@ pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
12501273
#[inline]
12511274
#[must_use]
12521275
#[stable(feature = "rust1", since = "1.0.0")]
1276+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
12531277
#[cfg_attr(not(test), rustc_diagnostic_item = "cmp_max")]
1254-
pub fn max<T: Ord>(v1: T, v2: T) -> T {
1278+
pub const fn max<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T {
12551279
v1.max(v2)
12561280
}
12571281

@@ -1304,7 +1328,8 @@ mod impls {
13041328
macro_rules! partial_eq_impl {
13051329
($($t:ty)*) => ($(
13061330
#[stable(feature = "rust1", since = "1.0.0")]
1307-
impl PartialEq for $t {
1331+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1332+
impl const PartialEq for $t {
13081333
#[inline]
13091334
fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
13101335
#[inline]
@@ -1314,7 +1339,8 @@ mod impls {
13141339
}
13151340

13161341
#[stable(feature = "rust1", since = "1.0.0")]
1317-
impl PartialEq for () {
1342+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1343+
impl const PartialEq for () {
13181344
#[inline]
13191345
fn eq(&self, _other: &()) -> bool {
13201346
true
@@ -1341,7 +1367,8 @@ mod impls {
13411367
macro_rules! partial_ord_impl {
13421368
($($t:ty)*) => ($(
13431369
#[stable(feature = "rust1", since = "1.0.0")]
1344-
impl PartialOrd for $t {
1370+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1371+
impl const PartialOrd for $t {
13451372
#[inline]
13461373
fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
13471374
match (*self <= *other, *self >= *other) {
@@ -1364,15 +1391,17 @@ mod impls {
13641391
}
13651392

13661393
#[stable(feature = "rust1", since = "1.0.0")]
1367-
impl PartialOrd for () {
1394+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1395+
impl const PartialOrd for () {
13681396
#[inline]
13691397
fn partial_cmp(&self, _: &()) -> Option<Ordering> {
13701398
Some(Equal)
13711399
}
13721400
}
13731401

13741402
#[stable(feature = "rust1", since = "1.0.0")]
1375-
impl PartialOrd for bool {
1403+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1404+
impl const PartialOrd for bool {
13761405
#[inline]
13771406
fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
13781407
Some(self.cmp(other))
@@ -1384,7 +1413,8 @@ mod impls {
13841413
macro_rules! ord_impl {
13851414
($($t:ty)*) => ($(
13861415
#[stable(feature = "rust1", since = "1.0.0")]
1387-
impl PartialOrd for $t {
1416+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1417+
impl const PartialOrd for $t {
13881418
#[inline]
13891419
fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
13901420
Some(self.cmp(other))
@@ -1400,7 +1430,8 @@ mod impls {
14001430
}
14011431

14021432
#[stable(feature = "rust1", since = "1.0.0")]
1403-
impl Ord for $t {
1433+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1434+
impl const Ord for $t {
14041435
#[inline]
14051436
fn cmp(&self, other: &$t) -> Ordering {
14061437
// The order here is important to generate more optimal assembly.
@@ -1414,15 +1445,17 @@ mod impls {
14141445
}
14151446

14161447
#[stable(feature = "rust1", since = "1.0.0")]
1417-
impl Ord for () {
1448+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1449+
impl const Ord for () {
14181450
#[inline]
14191451
fn cmp(&self, _other: &()) -> Ordering {
14201452
Equal
14211453
}
14221454
}
14231455

14241456
#[stable(feature = "rust1", since = "1.0.0")]
1425-
impl Ord for bool {
1457+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1458+
impl const Ord for bool {
14261459
#[inline]
14271460
fn cmp(&self, other: &bool) -> Ordering {
14281461
// Casting to i8's and converting the difference to an Ordering generates
@@ -1441,7 +1474,8 @@ mod impls {
14411474
ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
14421475

14431476
#[unstable(feature = "never_type", issue = "35121")]
1444-
impl PartialEq for ! {
1477+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1478+
impl const PartialEq for ! {
14451479
fn eq(&self, _: &!) -> bool {
14461480
*self
14471481
}
@@ -1451,14 +1485,16 @@ mod impls {
14511485
impl Eq for ! {}
14521486

14531487
#[unstable(feature = "never_type", issue = "35121")]
1454-
impl PartialOrd for ! {
1488+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1489+
impl const PartialOrd for ! {
14551490
fn partial_cmp(&self, _: &!) -> Option<Ordering> {
14561491
*self
14571492
}
14581493
}
14591494

14601495
#[unstable(feature = "never_type", issue = "35121")]
1461-
impl Ord for ! {
1496+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1497+
impl const Ord for ! {
14621498
fn cmp(&self, _: &!) -> Ordering {
14631499
*self
14641500
}

Diff for: ‎library/core/src/intrinsics.rs

+14-37
Original file line numberDiff line numberDiff line change
@@ -2566,14 +2566,23 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
25662566
///
25672567
/// * `dst` must be properly aligned.
25682568
///
2569-
/// Additionally, the caller must ensure that writing `count *
2570-
/// size_of::<T>()` bytes to the given region of memory results in a valid
2571-
/// value of `T`. Using a region of memory typed as a `T` that contains an
2572-
/// invalid value of `T` is undefined behavior.
2573-
///
25742569
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
25752570
/// `0`, the pointer must be non-null and properly aligned.
25762571
///
2572+
/// Additionally, note that changing `*dst` in this way can easily lead to undefined behavior (UB)
2573+
/// later if the written bytes are not a valid representation of some `T`. For instance, the
2574+
/// following is an **incorrect** use of this function:
2575+
///
2576+
/// ```rust,no_run
2577+
/// unsafe {
2578+
/// let mut value: u8 = 0;
2579+
/// let ptr: *mut bool = &mut value as *mut u8 as *mut bool;
2580+
/// let _bool = ptr.read(); // This is fine, `ptr` points to a valid `bool`.
2581+
/// ptr.write_bytes(42u8, 1); // This function itself does not cause UB...
2582+
/// let _bool = ptr.read(); // ...but it makes this operation UB! ⚠️
2583+
/// }
2584+
/// ```
2585+
///
25772586
/// [valid]: crate::ptr#safety
25782587
///
25792588
/// # Examples
@@ -2590,38 +2599,6 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
25902599
/// }
25912600
/// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);
25922601
/// ```
2593-
///
2594-
/// Creating an invalid value:
2595-
///
2596-
/// ```
2597-
/// use std::ptr;
2598-
///
2599-
/// let mut v = Box::new(0i32);
2600-
///
2601-
/// unsafe {
2602-
/// // Leaks the previously held value by overwriting the `Box<T>` with
2603-
/// // a null pointer.
2604-
/// ptr::write_bytes(&mut v as *mut Box<i32>, 0, 1);
2605-
/// }
2606-
///
2607-
/// // At this point, using or dropping `v` results in undefined behavior.
2608-
/// // drop(v); // ERROR
2609-
///
2610-
/// // Even leaking `v` "uses" it, and hence is undefined behavior.
2611-
/// // mem::forget(v); // ERROR
2612-
///
2613-
/// // In fact, `v` is invalid according to basic type layout invariants, so *any*
2614-
/// // operation touching it is undefined behavior.
2615-
/// // let v2 = v; // ERROR
2616-
///
2617-
/// unsafe {
2618-
/// // Let us instead put in a valid value
2619-
/// ptr::write(&mut v as *mut Box<i32>, Box::new(42i32));
2620-
/// }
2621-
///
2622-
/// // Now the box is fine
2623-
/// assert_eq!(*v, 42);
2624-
/// ```
26252602
#[doc(alias = "memset")]
26262603
#[stable(feature = "rust1", since = "1.0.0")]
26272604
#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]

Diff for: ‎library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
#![feature(const_cell_into_inner)]
106106
#![feature(const_char_convert)]
107107
#![feature(const_clone)]
108+
#![feature(const_cmp)]
108109
#![feature(const_discriminant)]
109110
#![feature(const_eval_select)]
110111
#![feature(const_float_bits_conv)]

Diff for: ‎library/proc_macro/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,14 @@ pub mod token_stream {
382382
bridge::TokenTree::Literal(tt) => TokenTree::Literal(Literal(tt)),
383383
})
384384
}
385+
386+
fn size_hint(&self) -> (usize, Option<usize>) {
387+
self.0.size_hint()
388+
}
389+
390+
fn count(self) -> usize {
391+
self.0.count()
392+
}
385393
}
386394

387395
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]

Diff for: ‎src/librustdoc/html/static/css/rustdoc.css

-1
Original file line numberDiff line numberDiff line change
@@ -1855,7 +1855,6 @@ in storage.js plus the media query with (min-width: 701px)
18551855
the sidebar stays visible for screen readers, which is useful for navigation. */
18561856
left: -1000px;
18571857
margin-left: 0;
1858-
background-color: rgba(0,0,0,0);
18591858
margin: 0;
18601859
padding: 0;
18611860
z-index: 11;

Diff for: ‎src/test/rustdoc-gui/sidebar-mobile.goml

+22
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,25 @@ assert-position: ("#method\.must_use", {"y": 45})
4040
click: ".sidebar-menu-toggle"
4141
scroll-to: ".block.keyword li:nth-child(1)"
4242
compare-elements-position-near: (".block.keyword li:nth-child(1)", ".mobile-topbar", {"y": 543})
43+
44+
// Now checking the background color of the sidebar.
45+
local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"}
46+
reload:
47+
48+
// Open the sidebar menu.
49+
click: ".sidebar-menu-toggle"
50+
assert-css: (".sidebar", {"background-color": "rgb(80, 80, 80)"})
51+
52+
local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "ayu"}
53+
reload:
54+
55+
// Open the sidebar menu.
56+
click: ".sidebar-menu-toggle"
57+
assert-css: (".sidebar", {"background-color": "rgb(20, 25, 31)"})
58+
59+
local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "light"}
60+
reload:
61+
62+
// Open the sidebar menu.
63+
click: ".sidebar-menu-toggle"
64+
assert-css: (".sidebar", {"background-color": "rgb(245, 245, 245)"})

0 commit comments

Comments
 (0)
Please sign in to comment.