Skip to content

Commit f40aaa6

Browse files
committed
Auto merge of #58016 - Centril:rollup, r=Centril
Rollup of 12 pull requests Successful merges: - #57008 (suggest `|` when `,` founds in invalid match value) - #57106 (Mark str::trim.* functions as #[must_use].) - #57920 (use `SOURCE_DATE_EPOCH` for man page time if set) - #57934 (Introduce into_raw_non_null on Rc and Arc) - #57971 (SGX target: improve panic & exit handling) - #57980 (Add the edition guide to the bookshelf) - #57984 (Improve bug message in check_ty) - #57999 (Add MOVBE x86 CPU feature) - #58000 (Fixes and cleanups) - #58005 (update docs for fix_start/end_matches) - #58007 (Don't panic when accessing enum variant ctor using `Self` in match) - #58008 (Pass correct arguments to places_conflict) Failed merges: r? @ghost
2 parents 147311c + 877dee7 commit f40aaa6

File tree

29 files changed

+319
-89
lines changed

29 files changed

+319
-89
lines changed

src/bootstrap/dist.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::builder::{Builder, RunConfig, ShouldRun, Step};
2323
use crate::compile;
2424
use crate::tool::{self, Tool};
2525
use crate::cache::{INTERNER, Interned};
26-
use time;
26+
use time::{self, Timespec};
2727

2828
pub fn pkgname(builder: &Builder, component: &str) -> String {
2929
if component == "cargo" {
@@ -528,7 +528,19 @@ impl Step for Rustc {
528528
t!(fs::create_dir_all(image.join("share/man/man1")));
529529
let man_src = builder.src.join("src/doc/man");
530530
let man_dst = image.join("share/man/man1");
531-
let month_year = t!(time::strftime("%B %Y", &time::now()));
531+
532+
// Reproducible builds: If SOURCE_DATE_EPOCH is set, use that as the time.
533+
let time = env::var("SOURCE_DATE_EPOCH")
534+
.map(|timestamp| {
535+
let epoch = timestamp.parse().map_err(|err| {
536+
format!("could not parse SOURCE_DATE_EPOCH: {}", err)
537+
}).unwrap();
538+
539+
time::at(Timespec::new(epoch, 0))
540+
})
541+
.unwrap_or_else(|_| time::now());
542+
543+
let month_year = t!(time::strftime("%B %Y", &time));
532544
// don't use our `bootstrap::util::{copy, cp_r}`, because those try
533545
// to hardlink, and we don't want to edit the source templates
534546
for file_entry in builder.read_dir(&man_src) {

src/doc/index.md

+4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ accomplishing various tasks.
7171
</form>
7272
</div>
7373

74+
## The Edition Guide
75+
76+
[The Edition Guide](edition-guide/index.html) describes the Rust editions.
77+
7478
## The Rustc Book
7579

7680
[The Rustc Book](rustc/index.html) describes the Rust compiler, `rustc`.

src/liballoc/rc.rs

+21
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,27 @@ impl<T: ?Sized> Rc<T> {
433433
}
434434
}
435435

436+
/// Consumes the `Rc`, returning the wrapped pointer as `NonNull<T>`.
437+
///
438+
/// # Examples
439+
///
440+
/// ```
441+
/// #![feature(rc_into_raw_non_null)]
442+
///
443+
/// use std::rc::Rc;
444+
///
445+
/// let x = Rc::new(10);
446+
/// let ptr = Rc::into_raw_non_null(x);
447+
/// let deref = unsafe { *ptr.as_ref() };
448+
/// assert_eq!(deref, 10);
449+
/// ```
450+
#[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
451+
#[inline]
452+
pub fn into_raw_non_null(this: Self) -> NonNull<T> {
453+
// safe because Rc guarantees its pointer is non-null
454+
unsafe { NonNull::new_unchecked(Rc::into_raw(this) as *mut _) }
455+
}
456+
436457
/// Creates a new [`Weak`][weak] pointer to this value.
437458
///
438459
/// [weak]: struct.Weak.html

src/liballoc/sync.rs

+21
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,27 @@ impl<T: ?Sized> Arc<T> {
413413
}
414414
}
415415

416+
/// Consumes the `Arc`, returning the wrapped pointer as `NonNull<T>`.
417+
///
418+
/// # Examples
419+
///
420+
/// ```
421+
/// #![feature(rc_into_raw_non_null)]
422+
///
423+
/// use std::sync::Arc;
424+
///
425+
/// let x = Arc::new(10);
426+
/// let ptr = Arc::into_raw_non_null(x);
427+
/// let deref = unsafe { *ptr.as_ref() };
428+
/// assert_eq!(deref, 10);
429+
/// ```
430+
#[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
431+
#[inline]
432+
pub fn into_raw_non_null(this: Self) -> NonNull<T> {
433+
// safe because Arc guarantees its pointer is non-null
434+
unsafe { NonNull::new_unchecked(Arc::into_raw(this) as *mut _) }
435+
}
436+
416437
/// Creates a new [`Weak`][weak] pointer to this value.
417438
///
418439
/// [weak]: struct.Weak.html

src/libcore/str/mod.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -3489,6 +3489,8 @@ impl str {
34893489
///
34903490
/// assert_eq!("Hello\tworld", s.trim());
34913491
/// ```
3492+
#[must_use = "this returns the trimmed string as a slice, \
3493+
without modifying the original"]
34923494
#[stable(feature = "rust1", since = "1.0.0")]
34933495
pub fn trim(&self) -> &str {
34943496
self.trim_matches(|c: char| c.is_whitespace())
@@ -3524,6 +3526,8 @@ impl str {
35243526
/// let s = " עברית ";
35253527
/// assert!(Some('ע') == s.trim_start().chars().next());
35263528
/// ```
3529+
#[must_use = "this returns the trimmed string as a new slice, \
3530+
without modifying the original"]
35273531
#[stable(feature = "trim_direction", since = "1.30.0")]
35283532
pub fn trim_start(&self) -> &str {
35293533
self.trim_start_matches(|c: char| c.is_whitespace())
@@ -3559,6 +3563,8 @@ impl str {
35593563
/// let s = " עברית ";
35603564
/// assert!(Some('ת') == s.trim_end().chars().rev().next());
35613565
/// ```
3566+
#[must_use = "this returns the trimmed string as a new slice, \
3567+
without modifying the original"]
35623568
#[stable(feature = "trim_direction", since = "1.30.0")]
35633569
pub fn trim_end(&self) -> &str {
35643570
self.trim_end_matches(|c: char| c.is_whitespace())
@@ -3661,6 +3667,8 @@ impl str {
36613667
/// ```
36623668
/// assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar");
36633669
/// ```
3670+
#[must_use = "this returns the trimmed string as a new slice, \
3671+
without modifying the original"]
36643672
#[stable(feature = "rust1", since = "1.0.0")]
36653673
pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
36663674
where P::Searcher: DoubleEndedSearcher<'a>
@@ -3706,6 +3714,8 @@ impl str {
37063714
/// let x: &[_] = &['1', '2'];
37073715
/// assert_eq!("12foo1bar12".trim_start_matches(x), "foo1bar12");
37083716
/// ```
3717+
#[must_use = "this returns the trimmed string as a new slice, \
3718+
without modifying the original"]
37093719
#[stable(feature = "trim_direction", since = "1.30.0")]
37103720
pub fn trim_start_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
37113721
let mut i = self.len();
@@ -3749,6 +3759,8 @@ impl str {
37493759
/// ```
37503760
/// assert_eq!("1fooX".trim_end_matches(|c| c == '1' || c == 'X'), "1foo");
37513761
/// ```
3762+
#[must_use = "this returns the trimmed string as a new slice, \
3763+
without modifying the original"]
37523764
#[stable(feature = "trim_direction", since = "1.30.0")]
37533765
pub fn trim_end_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
37543766
where P::Searcher: ReverseSearcher<'a>
@@ -3774,10 +3786,10 @@ impl str {
37743786
///
37753787
/// # Text directionality
37763788
///
3777-
/// A string is a sequence of bytes. 'Left' in this context means the first
3778-
/// position of that byte string; for a language like Arabic or Hebrew
3779-
/// which are 'right to left' rather than 'left to right', this will be
3780-
/// the _right_ side, not the left.
3789+
/// A string is a sequence of bytes. `start` in this context means the first
3790+
/// position of that byte string; for a left-to-right language like English or
3791+
/// Russian, this will be left side; and for right-to-left languages like
3792+
/// like Arabic or Hebrew, this will be the right side.
37813793
///
37823794
/// # Examples
37833795
///
@@ -3806,10 +3818,10 @@ impl str {
38063818
///
38073819
/// # Text directionality
38083820
///
3809-
/// A string is a sequence of bytes. 'Right' in this context means the last
3810-
/// position of that byte string; for a language like Arabic or Hebrew
3811-
/// which are 'right to left' rather than 'left to right', this will be
3812-
/// the _left_ side, not the right.
3821+
/// A string is a sequence of bytes. `end` in this context means the last
3822+
/// position of that byte string; for a left-to-right language like English or
3823+
/// Russian, this will be right side; and for right-to-left languages like
3824+
/// like Arabic or Hebrew, this will be the left side.
38133825
///
38143826
/// # Examples
38153827
///

src/librustc/mir/interpret/value.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub struct RawConst<'tcx> {
1414
}
1515

1616
/// Represents a constant value in Rust. Scalar and ScalarPair are optimizations which
17-
/// matches the LocalValue optimizations for easy conversions between Value and ConstValue.
17+
/// matches the LocalState optimizations for easy conversions between Value and ConstValue.
1818
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
1919
pub enum ConstValue<'tcx> {
2020
/// Used only for types with layout::abi::Scalar ABI and ZSTs

src/librustc_codegen_llvm/llvm_util.rs

+1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ const X86_WHITELIST: &[(&str, Option<&str>)] = &[
147147
("fxsr", None),
148148
("lzcnt", None),
149149
("mmx", Some("mmx_target_feature")),
150+
("movbe", Some("movbe_target_feature")),
150151
("pclmulqdq", None),
151152
("popcnt", None),
152153
("rdrand", None),

src/librustc_mir/dataflow/impls/borrows.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
215215
if places_conflict::places_conflict(
216216
self.tcx,
217217
self.mir,
218-
place,
219218
&borrow_data.borrowed_place,
219+
place,
220220
places_conflict::PlaceConflictBias::NoOverlap,
221221
) {
222222
debug!(

src/librustc_mir/interpret/eval_context.rs

+44-28
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ pub struct Frame<'mir, 'tcx: 'mir, Tag=(), Extra=()> {
7676
/// The locals are stored as `Option<Value>`s.
7777
/// `None` represents a local that is currently dead, while a live local
7878
/// can either directly contain `Scalar` or refer to some part of an `Allocation`.
79-
pub locals: IndexVec<mir::Local, LocalValue<Tag>>,
80-
pub local_layouts: IndexVec<mir::Local, Cell<Option<TyLayout<'tcx>>>>,
79+
pub locals: IndexVec<mir::Local, LocalState<'tcx, Tag>>,
8180

8281
////////////////////////////////////////////////////////////////////////////////
8382
// Current position within the function
@@ -106,7 +105,15 @@ pub enum StackPopCleanup {
106105
None { cleanup: bool },
107106
}
108107

109-
// State of a local variable
108+
/// State of a local variable including a memoized layout
109+
#[derive(Clone, PartialEq, Eq)]
110+
pub struct LocalState<'tcx, Tag=(), Id=AllocId> {
111+
pub state: LocalValue<Tag, Id>,
112+
/// Don't modify if `Some`, this is only used to prevent computing the layout twice
113+
pub layout: Cell<Option<TyLayout<'tcx>>>,
114+
}
115+
116+
/// State of a local variable
110117
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
111118
pub enum LocalValue<Tag=(), Id=AllocId> {
112119
Dead,
@@ -117,16 +124,16 @@ pub enum LocalValue<Tag=(), Id=AllocId> {
117124
Live(Operand<Tag, Id>),
118125
}
119126

120-
impl<'tcx, Tag> LocalValue<Tag> {
127+
impl<'tcx, Tag> LocalState<'tcx, Tag> {
121128
pub fn access(&self) -> EvalResult<'tcx, &Operand<Tag>> {
122-
match self {
129+
match self.state {
123130
LocalValue::Dead => err!(DeadLocal),
124131
LocalValue::Live(ref val) => Ok(val),
125132
}
126133
}
127134

128135
pub fn access_mut(&mut self) -> EvalResult<'tcx, &mut Operand<Tag>> {
129-
match self {
136+
match self.state {
130137
LocalValue::Dead => err!(DeadLocal),
131138
LocalValue::Live(ref mut val) => Ok(val),
132139
}
@@ -310,17 +317,21 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
310317
pub fn layout_of_local(
311318
&self,
312319
frame: &Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>,
313-
local: mir::Local
320+
local: mir::Local,
321+
layout: Option<TyLayout<'tcx>>,
314322
) -> EvalResult<'tcx, TyLayout<'tcx>> {
315-
let cell = &frame.local_layouts[local];
316-
if cell.get().is_none() {
317-
let local_ty = frame.mir.local_decls[local].ty;
318-
let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs);
319-
let layout = self.layout_of(local_ty)?;
320-
cell.set(Some(layout));
323+
match frame.locals[local].layout.get() {
324+
None => {
325+
let layout = ::interpret::operand::from_known_layout(layout, || {
326+
let local_ty = frame.mir.local_decls[local].ty;
327+
let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs);
328+
self.layout_of(local_ty)
329+
})?;
330+
frame.locals[local].layout.set(Some(layout));
331+
Ok(layout)
332+
}
333+
Some(layout) => Ok(layout),
321334
}
322-
323-
Ok(cell.get().unwrap())
324335
}
325336

326337
pub fn str_to_immediate(&mut self, s: &str) -> EvalResult<'tcx, Immediate<M::PointerTag>> {
@@ -454,7 +465,6 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
454465
// empty local array, we fill it in below, after we are inside the stack frame and
455466
// all methods actually know about the frame
456467
locals: IndexVec::new(),
457-
local_layouts: IndexVec::from_elem_n(Default::default(), mir.local_decls.len()),
458468
span,
459469
instance,
460470
stmt: 0,
@@ -466,12 +476,16 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
466476
// We put some marker immediate into the locals that we later want to initialize.
467477
// This can be anything except for LocalValue::Dead -- because *that* is the
468478
// value we use for things that we know are initially dead.
469-
let dummy =
470-
LocalValue::Live(Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Undef)));
479+
let dummy = LocalState {
480+
state: LocalValue::Live(Operand::Immediate(Immediate::Scalar(
481+
ScalarMaybeUndef::Undef,
482+
))),
483+
layout: Cell::new(None),
484+
};
471485
let mut locals = IndexVec::from_elem(dummy, &mir.local_decls);
472486
// Return place is handled specially by the `eval_place` functions, and the
473487
// entry in `locals` should never be used. Make it dead, to be sure.
474-
locals[mir::RETURN_PLACE] = LocalValue::Dead;
488+
locals[mir::RETURN_PLACE].state = LocalValue::Dead;
475489
// Now mark those locals as dead that we do not want to initialize
476490
match self.tcx.describe_def(instance.def_id()) {
477491
// statics and constants don't have `Storage*` statements, no need to look for them
@@ -484,7 +498,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
484498
match stmt.kind {
485499
StorageLive(local) |
486500
StorageDead(local) => {
487-
locals[local] = LocalValue::Dead;
501+
locals[local].state = LocalValue::Dead;
488502
}
489503
_ => {}
490504
}
@@ -494,11 +508,13 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
494508
}
495509
// Finally, properly initialize all those that still have the dummy value
496510
for (idx, local) in locals.iter_enumerated_mut() {
497-
match *local {
511+
match local.state {
498512
LocalValue::Live(_) => {
499-
// This needs to be peoperly initialized.
500-
let layout = self.layout_of_local(self.frame(), idx)?;
501-
*local = LocalValue::Live(self.uninit_operand(layout)?);
513+
// This needs to be properly initialized.
514+
let ty = self.monomorphize(mir.local_decls[idx].ty)?;
515+
let layout = self.layout_of(ty)?;
516+
local.state = LocalValue::Live(self.uninit_operand(layout)?);
517+
local.layout = Cell::new(Some(layout));
502518
}
503519
LocalValue::Dead => {
504520
// Nothing to do
@@ -543,7 +559,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
543559
}
544560
// Deallocate all locals that are backed by an allocation.
545561
for local in frame.locals {
546-
self.deallocate_local(local)?;
562+
self.deallocate_local(local.state)?;
547563
}
548564
// Validate the return value. Do this after deallocating so that we catch dangling
549565
// references.
@@ -591,10 +607,10 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
591607
assert!(local != mir::RETURN_PLACE, "Cannot make return place live");
592608
trace!("{:?} is now live", local);
593609

594-
let layout = self.layout_of_local(self.frame(), local)?;
610+
let layout = self.layout_of_local(self.frame(), local, None)?;
595611
let init = LocalValue::Live(self.uninit_operand(layout)?);
596612
// StorageLive *always* kills the value that's currently stored
597-
Ok(mem::replace(&mut self.frame_mut().locals[local], init))
613+
Ok(mem::replace(&mut self.frame_mut().locals[local].state, init))
598614
}
599615

600616
/// Returns the old value of the local.
@@ -603,7 +619,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
603619
assert!(local != mir::RETURN_PLACE, "Cannot make return place dead");
604620
trace!("{:?} is now dead", local);
605621

606-
mem::replace(&mut self.frame_mut().locals[local], LocalValue::Dead)
622+
mem::replace(&mut self.frame_mut().locals[local].state, LocalValue::Dead)
607623
}
608624

609625
pub(super) fn deallocate_local(

src/librustc_mir/interpret/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ mod visitor;
1818
pub use rustc::mir::interpret::*; // have all the `interpret` symbols in one place: here
1919

2020
pub use self::eval_context::{
21-
EvalContext, Frame, StackPopCleanup, LocalValue,
21+
EvalContext, Frame, StackPopCleanup, LocalState, LocalValue,
2222
};
2323

2424
pub use self::place::{Place, PlaceTy, MemPlace, MPlaceTy};

0 commit comments

Comments
 (0)