Skip to content

Commit

Permalink
Auto merge of rust-lang#102787 - Dylan-DPC:rollup-fvbb4t9, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 6 pull requests

Successful merges:

 - rust-lang#102300 (Use a macro to not have to copy-paste `ConstFnMutClosure::new(&mut fold, NeverShortCircuit::wrap_mut_2_imp)).0` everywhere)
 - rust-lang#102475 (unsafe keyword: trait examples and unsafe_op_in_unsafe_fn update)
 - rust-lang#102760 (Avoid repeated re-initialization of the BufReader buffer)
 - rust-lang#102764 (Check `WhereClauseReferencesSelf` after all other object safety checks)
 - rust-lang#102779 (Fix `type_of` ICE)
 - rust-lang#102780 (run Miri CI when std::sys changes)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Oct 7, 2022
2 parents 43c22af + 3800d40 commit 2d3a85b
Show file tree
Hide file tree
Showing 20 changed files with 319 additions and 164 deletions.
6 changes: 4 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
},
def_id.to_def_id(),
);
if let Some(assoc_item) = assoc_item {
tcx.type_of(tcx.generics_of(assoc_item.def_id).params[idx].def_id)
if let Some(param)
= assoc_item.map(|item| &tcx.generics_of(item.def_id).params[idx]).filter(|param| param.kind.is_ty_or_const())
{
tcx.type_of(param.def_id)
} else {
// FIXME(associated_const_equality): add a useful error message here.
tcx.ty_error_with_message(
Expand Down
28 changes: 15 additions & 13 deletions compiler/rustc_trait_selection/src/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,19 +447,6 @@ fn virtual_call_violation_for_method<'tcx>(
return Some(MethodViolationCode::Generic);
}

if tcx
.predicates_of(method.def_id)
.predicates
.iter()
// A trait object can't claim to live more than the concrete type,
// so outlives predicates will always hold.
.cloned()
.filter(|(p, _)| p.to_opt_type_outlives().is_none())
.any(|pred| contains_illegal_self_type_reference(tcx, trait_def_id, pred))
{
return Some(MethodViolationCode::WhereClauseReferencesSelf);
}

let receiver_ty = tcx.liberate_late_bound_regions(method.def_id, sig.input(0));

// Until `unsized_locals` is fully implemented, `self: Self` can't be dispatched on.
Expand Down Expand Up @@ -538,6 +525,21 @@ fn virtual_call_violation_for_method<'tcx>(
}
}

// NOTE: This check happens last, because it results in a lint, and not a
// hard error.
if tcx
.predicates_of(method.def_id)
.predicates
.iter()
// A trait object can't claim to live more than the concrete type,
// so outlives predicates will always hold.
.cloned()
.filter(|(p, _)| p.to_opt_type_outlives().is_none())
.any(|pred| contains_illegal_self_type_reference(tcx, trait_def_id, pred))
{
return Some(MethodViolationCode::WhereClauseReferencesSelf);
}

None
}

Expand Down
19 changes: 3 additions & 16 deletions library/core/src/iter/adapters/array_chunks.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::array;
use crate::const_closure::ConstFnMutClosure;
use crate::iter::{ByRefSized, FusedIterator, Iterator};
use crate::ops::{ControlFlow, NeverShortCircuit, Try};
use crate::ops::{ControlFlow, Try};

/// An iterator over `N` elements of the iterator at a time.
///
Expand Down Expand Up @@ -83,13 +82,7 @@ where
}
}

fn fold<B, F>(mut self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
self.try_fold(init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)).0
}
impl_fold_via_try_fold! { fold -> try_fold }
}

#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
Expand Down Expand Up @@ -127,13 +120,7 @@ where
try { acc }
}

fn rfold<B, F>(mut self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
self.try_rfold(init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)).0
}
impl_fold_via_try_fold! { rfold -> try_rfold }
}

impl<I, const N: usize> ArrayChunks<I, N>
Expand Down
14 changes: 1 addition & 13 deletions library/core/src/iter/adapters/map_while.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,7 @@ where
.into_try()
}

#[inline]
fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
move |acc, x| Ok(f(acc, x))
}

self.try_fold(init, ok(fold)).unwrap()
}
impl_fold_via_try_fold! { fold -> try_fold }
}

#[unstable(issue = "none", feature = "inplace_iteration")]
Expand Down
11 changes: 2 additions & 9 deletions library/core/src/iter/adapters/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::const_closure::ConstFnMutClosure;
use crate::iter::{InPlaceIterable, Iterator};
use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, NeverShortCircuit, Residual, Try};
use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try};

mod array_chunks;
mod by_ref_sized;
Expand Down Expand Up @@ -204,13 +203,7 @@ where
.into_try()
}

fn fold<B, F>(mut self, init: B, mut fold: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
self.try_fold(init, ConstFnMutClosure::new(&mut fold, NeverShortCircuit::wrap_mut_2_imp)).0
}
impl_fold_via_try_fold! { fold -> try_fold }
}

#[unstable(issue = "none", feature = "inplace_iteration")]
Expand Down
14 changes: 1 addition & 13 deletions library/core/src/iter/adapters/scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,7 @@ where
self.iter.try_fold(init, scan(state, f, fold)).into_try()
}

#[inline]
fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
move |acc, x| Ok(f(acc, x))
}

self.try_fold(init, ok(fold)).unwrap()
}
impl_fold_via_try_fold! { fold -> try_fold }
}

#[unstable(issue = "none", feature = "inplace_iteration")]
Expand Down
12 changes: 1 addition & 11 deletions library/core/src/iter/adapters/skip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,17 +206,7 @@ where
if n == 0 { try { init } } else { self.iter.try_rfold(init, check(n, fold)).into_try() }
}

fn rfold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn ok<Acc, T>(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, T) -> Result<Acc, !> {
move |acc, x| Ok(f(acc, x))
}

self.try_rfold(init, ok(fold)).unwrap()
}
impl_fold_via_try_fold! { rfold -> try_rfold }

#[inline]
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
Expand Down
14 changes: 1 addition & 13 deletions library/core/src/iter/adapters/take.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,7 @@ where
}
}

#[inline]
fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
move |acc, x| Ok(f(acc, x))
}

self.try_fold(init, ok(fold)).unwrap()
}
impl_fold_via_try_fold! { fold -> try_fold }

#[inline]
#[rustc_inherit_overflow_checks]
Expand Down
14 changes: 1 addition & 13 deletions library/core/src/iter/adapters/take_while.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,7 @@ where
}
}

#[inline]
fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
move |acc, x| Ok(f(acc, x))
}

self.try_fold(init, ok(fold)).unwrap()
}
impl_fold_via_try_fold! { fold -> try_fold }
}

#[stable(feature = "fused", since = "1.26.0")]
Expand Down
23 changes: 23 additions & 0 deletions library/core/src/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,29 @@

#![stable(feature = "rust1", since = "1.0.0")]

// This needs to be up here in order to be usable in the child modules
macro_rules! impl_fold_via_try_fold {
(fold -> try_fold) => {
impl_fold_via_try_fold! { @internal fold -> try_fold }
};
(rfold -> try_rfold) => {
impl_fold_via_try_fold! { @internal rfold -> try_rfold }
};
(@internal $fold:ident -> $try_fold:ident) => {
#[inline]
fn $fold<AAA, FFF>(mut self, init: AAA, mut fold: FFF) -> AAA
where
FFF: FnMut(AAA, Self::Item) -> AAA,
{
use crate::const_closure::ConstFnMutClosure;
use crate::ops::NeverShortCircuit;

let fold = ConstFnMutClosure::new(&mut fold, NeverShortCircuit::wrap_mut_2_imp);
self.$try_fold(init, fold).0
}
};
}

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::traits::Iterator;

Expand Down
28 changes: 2 additions & 26 deletions library/core/src/iter/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1150,19 +1150,7 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
self.spec_try_fold(init, f)
}

#[inline]
fn fold<B, F>(mut self, init: B, f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
#[inline]
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
move |acc, x| Ok(f(acc, x))
}

self.try_fold(init, ok(f)).unwrap()
}
impl_fold_via_try_fold! { fold -> try_fold }

#[inline]
fn last(mut self) -> Option<A> {
Expand Down Expand Up @@ -1230,19 +1218,7 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
self.spec_try_rfold(init, f)
}

#[inline]
fn rfold<B, F>(mut self, init: B, f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
#[inline]
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
move |acc, x| Ok(f(acc, x))
}

self.try_rfold(init, ok(f)).unwrap()
}
impl_fold_via_try_fold! { rfold -> try_rfold }
}

// Safety: See above implementation for `ops::Range<A>`
Expand Down
8 changes: 8 additions & 0 deletions library/std/src/io/buffered/bufreader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,14 @@ impl<R> BufReader<R> {
}
}

// This is only used by a test which asserts that the initialization-tracking is correct.
#[cfg(test)]
impl<R> BufReader<R> {
pub fn initialized(&self) -> usize {
self.buf.initialized()
}
}

impl<R: Seek> BufReader<R> {
/// Seeks relative to the current position. If the new position lies within the buffer,
/// the buffer will not be flushed, allowing for more efficient seeks.
Expand Down
19 changes: 16 additions & 3 deletions library/std/src/io/buffered/bufreader/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@ pub struct Buffer {
// Each call to `fill_buf` sets `filled` to indicate how many bytes at the start of `buf` are
// initialized with bytes from a read.
filled: usize,
// This is the max number of bytes returned across all `fill_buf` calls. We track this so that we
// can accurately tell `read_buf` how many bytes of buf are initialized, to bypass as much of its
// defensive initialization as possible. Note that while this often the same as `filled`, it
// doesn't need to be. Calls to `fill_buf` are not required to actually fill the buffer, and
// omitting this is a huge perf regression for `Read` impls that do not.
initialized: usize,
}

impl Buffer {
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
let buf = Box::new_uninit_slice(capacity);
Self { buf, pos: 0, filled: 0 }
Self { buf, pos: 0, filled: 0, initialized: 0 }
}

#[inline]
Expand All @@ -51,6 +57,12 @@ impl Buffer {
self.pos
}

// This is only used by a test which asserts that the initialization-tracking is correct.
#[cfg(test)]
pub fn initialized(&self) -> usize {
self.initialized
}

#[inline]
pub fn discard_buffer(&mut self) {
self.pos = 0;
Expand Down Expand Up @@ -96,13 +108,14 @@ impl Buffer {
let mut buf = BorrowedBuf::from(&mut *self.buf);
// SAFETY: `self.filled` bytes will always have been initialized.
unsafe {
buf.set_init(self.filled);
buf.set_init(self.initialized);
}

reader.read_buf(buf.unfilled())?;

self.filled = buf.len();
self.pos = 0;
self.filled = buf.len();
self.initialized = buf.init_len();
}
Ok(self.buffer())
}
Expand Down
24 changes: 24 additions & 0 deletions library/std/src/io/buffered/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1039,3 +1039,27 @@ fn single_formatted_write() {
writeln!(&mut writer, "{}, {}!", "hello", "world").unwrap();
assert_eq!(writer.get_ref().events, [RecordedEvent::Write("hello, world!\n".to_string())]);
}

#[test]
fn bufreader_full_initialize() {
struct OneByteReader;
impl Read for OneByteReader {
fn read(&mut self, buf: &mut [u8]) -> crate::io::Result<usize> {
if buf.len() > 0 {
buf[0] = 0;
Ok(1)
} else {
Ok(0)
}
}
}
let mut reader = BufReader::new(OneByteReader);
// Nothing is initialized yet.
assert_eq!(reader.initialized(), 0);

let buf = reader.fill_buf().unwrap();
// We read one byte...
assert_eq!(buf.len(), 1);
// But we initialized the whole buffer!
assert_eq!(reader.initialized(), reader.capacity());
}
Loading

0 comments on commit 2d3a85b

Please sign in to comment.