Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #105512

Merged
merged 21 commits into from
Dec 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4ced370
Make `missing_copy_implementations` more cautious
Sep 28, 2022
b209ff2
Update trait check
Nov 19, 2022
34277fc
Rebase
Nov 29, 2022
17766c1
Skip test on s390x as LLD does not support the platform
uweigand Dec 6, 2022
58e60ac
Make `VecDeque::from_iter` O(1) from `vec(_deque)::IntoIter`
scottmcm Dec 8, 2022
98ae83d
Mangle "main" as "__main_void" on wasm32-wasi
sunfishcode Dec 8, 2022
5626df9
Add `rustc_on_unimplemented` to `Sum` and `Product` trait.
aDotInTheVoid Dec 4, 2022
90da11d
rustdoc: remove no-op mobile CSS `#sidebar-toggle { text-align }`
notriddle Dec 9, 2022
6648134
Apply review feedback; Fix no_global_oom_handling build
scottmcm Dec 9, 2022
f41576b
Fix typo in apple_base.rs
eltociear Dec 9, 2022
d60967b
rustdoc: make stability badge CSS more consistent
notriddle Dec 9, 2022
b3b17bd
Tweak `rustc_must_implement_one_of` diagnostic output
estebank Dec 9, 2022
4fae589
Rollup merge of #102406 - mejrs:missing_copy, r=wesleywiser
matthiaskrgr Dec 9, 2022
856027a
Rollup merge of #105265 - aDotInTheVoid:sum-product-on-unimplemented,…
matthiaskrgr Dec 9, 2022
c44326e
Rollup merge of #105385 - uweigand:s390x-test-lld, r=Mark-Simulacrum
matthiaskrgr Dec 9, 2022
5156fbd
Rollup merge of #105453 - scottmcm:vecdeque_from_iter, r=the8472
matthiaskrgr Dec 9, 2022
320d018
Rollup merge of #105468 - sunfishcode:sunfishcode/main-void-wasi, r=e…
matthiaskrgr Dec 9, 2022
d477386
Rollup merge of #105480 - notriddle:notriddle/sidebar-toggle-mobile-c…
matthiaskrgr Dec 9, 2022
f78babd
Rollup merge of #105489 - eltociear:patch-17, r=Dylan-DPC
matthiaskrgr Dec 9, 2022
d0563c6
Rollup merge of #105504 - notriddle:notriddle/stab-css, r=GuillaumeGomez
matthiaskrgr Dec 9, 2022
376b0bc
Rollup merge of #105506 - estebank:rustc_must_implement_one_of, r=com…
matthiaskrgr Dec 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
.struct_span_err(
attr.span,
"the `#[rustc_must_implement_one_of]` attribute must be \
used with at least 2 args",
used with at least 2 args",
)
.emit();

Expand Down Expand Up @@ -987,7 +987,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
tcx.sess
.struct_span_err(
item.span,
"This function doesn't have a default implementation",
"function doesn't have a default implementation",
)
.span_note(attr_span, "required by this annotation")
.emit();
Expand All @@ -999,17 +999,17 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
}
Some(item) => {
tcx.sess
.struct_span_err(item.span, "Not a function")
.struct_span_err(item.span, "not a function")
.span_note(attr_span, "required by this annotation")
.note(
"All `#[rustc_must_implement_one_of]` arguments \
must be associated function names",
"all `#[rustc_must_implement_one_of]` arguments must be associated \
function names",
)
.emit();
}
None => {
tcx.sess
.struct_span_err(ident.span, "Function not found in this trait")
.struct_span_err(ident.span, "function not found in this trait")
.emit();
}
}
Expand All @@ -1027,11 +1027,8 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
for ident in &*list {
if let Some(dup) = set.insert(ident.name, ident.span) {
tcx.sess
.struct_span_err(vec![dup, ident.span], "Functions names are duplicated")
.note(
"All `#[rustc_must_implement_one_of]` arguments \
must be unique",
)
.struct_span_err(vec![dup, ident.span], "functions names are duplicated")
.note("all `#[rustc_must_implement_one_of]` arguments must be unique")
.emit();

no_dups = false;
Expand Down
32 changes: 31 additions & 1 deletion compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, InnerSpan, Span};
use rustc_target::abi::{Abi, VariantIdx};
use rustc_trait_selection::traits::{self, misc::can_type_implement_copy};
use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt};
use rustc_trait_selection::traits::{self, misc::can_type_implement_copy, EvaluationResult};

use crate::nonstandard_style::{method_context, MethodLateContext};

Expand Down Expand Up @@ -750,10 +751,39 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
if def.has_dtor(cx.tcx) {
return;
}

// If the type contains a raw pointer, it may represent something like a handle,
// and recommending Copy might be a bad idea.
for field in def.all_fields() {
let did = field.did;
if cx.tcx.type_of(did).is_unsafe_ptr() {
return;
}
}
let param_env = ty::ParamEnv::empty();
if ty.is_copy_modulo_regions(cx.tcx, param_env) {
return;
}

// We shouldn't recommend implementing `Copy` on stateful things,
// such as iterators.
if let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator) {
if cx.tcx.infer_ctxt().build().type_implements_trait(iter_trait, [ty], param_env)
== EvaluationResult::EvaluatedToOk
{
return;
}
}

// Default value of clippy::trivially_copy_pass_by_ref
const MAX_SIZE: u64 = 256;

if let Some(size) = cx.layout_of(ty).ok().map(|l| l.size.bytes()) {
if size > MAX_SIZE {
return;
}
}

if can_type_implement_copy(
cx.tcx,
param_env,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/spec/apple_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ pub fn macos_llvm_target(arch: Arch) -> String {
fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow<str>]> {
// Apple platforms only officially support macOS as a host for any compilation.
//
// If building for macOS, we go ahead and remove any erronous environment state
// If building for macOS, we go ahead and remove any erroneous environment state
// that's only applicable to cross-OS compilation. Always leave anything for the
// host OS alone though.
if os == "macos" {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_target/src/spec/wasm32_wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ pub fn target() -> Target {
// `args::args()` makes the WASI API calls itself.
options.main_needs_argc_argv = false;

// And, WASI mangles the name of "main" to distinguish between different
// signatures.
options.entry_name = "__main_void".into();

Target {
llvm_target: "wasm32-wasi".into(),
pointer_width: 32,
Expand Down
4 changes: 4 additions & 0 deletions library/alloc/src/collections/vec_deque/into_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ impl<T, A: Allocator> IntoIter<T, A> {
pub(super) fn new(inner: VecDeque<T, A>) -> Self {
IntoIter { inner }
}

pub(super) fn into_vecdeque(self) -> VecDeque<T, A> {
self.inner
}
}

#[stable(feature = "collection_debug", since = "1.17.0")]
Expand Down
48 changes: 37 additions & 11 deletions library/alloc/src/collections/vec_deque/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ use self::spec_extend::SpecExtend;

mod spec_extend;

use self::spec_from_iter::SpecFromIter;

mod spec_from_iter;

#[cfg(test)]
mod tests;

Expand Down Expand Up @@ -586,6 +590,38 @@ impl<T, A: Allocator> VecDeque<T, A> {
VecDeque { head: 0, len: 0, buf: RawVec::with_capacity_in(capacity, alloc) }
}

/// Creates a `VecDeque` from a raw allocation, when the initialized
/// part of that allocation forms a *contiguous* subslice thereof.
///
/// For use by `vec::IntoIter::into_vecdeque`
///
/// # Safety
///
/// All the usual requirements on the allocated memory like in
/// `Vec::from_raw_parts_in`, but takes a *range* of elements that are
/// initialized rather than only supporting `0..len`. Requires that
/// `initialized.start` ≤ `initialized.end` ≤ `capacity`.
#[inline]
pub(crate) unsafe fn from_contiguous_raw_parts_in(
ptr: *mut T,
initialized: Range<usize>,
capacity: usize,
alloc: A,
) -> Self {
debug_assert!(initialized.start <= initialized.end);
debug_assert!(initialized.end <= capacity);

// SAFETY: Our safety precondition guarantees the range length won't wrap,
// and that the allocation is valid for use in `RawVec`.
unsafe {
VecDeque {
head: initialized.start,
len: initialized.end.unchecked_sub(initialized.start),
buf: RawVec::from_raw_parts_in(ptr, capacity, alloc),
}
}
}

/// Provides a reference to the element at the given index.
///
/// Element at index 0 is the front of the queue.
Expand Down Expand Up @@ -2699,18 +2735,8 @@ impl<T, A: Allocator> IndexMut<usize> for VecDeque<T, A> {

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> FromIterator<T> for VecDeque<T> {
#[inline]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> VecDeque<T> {
// Since converting is O(1) now, might as well re-use that logic
// (including things like the `vec::IntoIter`→`Vec` specialization)
// especially as that could save us some monomorphiziation work
// if one uses the same iterators (like slice ones) with both.
return from_iter_via_vec(iter.into_iter());

#[inline]
fn from_iter_via_vec<U>(iter: impl Iterator<Item = U>) -> VecDeque<U> {
Vec::from_iter(iter).into()
}
SpecFromIter::spec_from_iter(iter.into_iter())
}
}

Expand Down
33 changes: 33 additions & 0 deletions library/alloc/src/collections/vec_deque/spec_from_iter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use super::{IntoIter, VecDeque};

/// Specialization trait used for `VecDeque::from_iter`
pub(super) trait SpecFromIter<T, I> {
fn spec_from_iter(iter: I) -> Self;
}

impl<T, I> SpecFromIter<T, I> for VecDeque<T>
where
I: Iterator<Item = T>,
{
default fn spec_from_iter(iterator: I) -> Self {
// Since converting is O(1) now, just re-use the `Vec` logic for
// anything where we can't do something extra-special for `VecDeque`,
// especially as that could save us some monomorphiziation work
// if one uses the same iterators (like slice ones) with both.
crate::vec::Vec::from_iter(iterator).into()
}
}

impl<T> SpecFromIter<T, crate::vec::IntoIter<T>> for VecDeque<T> {
#[inline]
fn spec_from_iter(iterator: crate::vec::IntoIter<T>) -> Self {
iterator.into_vecdeque()
}
}

impl<T> SpecFromIter<T, IntoIter<T>> for VecDeque<T> {
#[inline]
fn spec_from_iter(iterator: IntoIter<T>) -> Self {
iterator.into_vecdeque()
}
}
29 changes: 29 additions & 0 deletions library/alloc/src/vec/into_iter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#[cfg(not(no_global_oom_handling))]
use super::AsVecIntoIter;
use crate::alloc::{Allocator, Global};
#[cfg(not(no_global_oom_handling))]
use crate::collections::VecDeque;
use crate::raw_vec::RawVec;
use core::array;
use core::fmt;
Expand Down Expand Up @@ -132,6 +134,33 @@ impl<T, A: Allocator> IntoIter<T, A> {
pub(crate) fn forget_remaining_elements(&mut self) {
self.ptr = self.end;
}

#[cfg(not(no_global_oom_handling))]
#[inline]
pub(crate) fn into_vecdeque(self) -> VecDeque<T, A> {
// Keep our `Drop` impl from dropping the elements and the allocator
let mut this = ManuallyDrop::new(self);

// SAFETY: This allocation originally came from a `Vec`, so it passes
// all those checks. We have `this.buf` ≤ `this.ptr` ≤ `this.end`,
// so the `sub_ptr`s below cannot wrap, and will produce a well-formed
// range. `end` ≤ `buf + cap`, so the range will be in-bounds.
// Taking `alloc` is ok because nothing else is going to look at it,
// since our `Drop` impl isn't going to run so there's no more code.
unsafe {
let buf = this.buf.as_ptr();
let initialized = if T::IS_ZST {
// All the pointers are the same for ZSTs, so it's fine to
// say that they're all at the beginning of the "allocation".
0..this.len()
} else {
this.ptr.sub_ptr(buf)..this.end.sub_ptr(buf)
};
let cap = this.cap;
let alloc = ManuallyDrop::take(&mut this.alloc);
VecDeque::from_contiguous_raw_parts_in(buf, initialized, cap, alloc)
}
}
}

#[stable(feature = "vec_intoiter_as_ref", since = "1.46.0")]
Expand Down
36 changes: 36 additions & 0 deletions library/alloc/tests/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1736,3 +1736,39 @@ fn test_resize_keeps_reserved_space_from_item() {
d.resize(1, v);
assert_eq!(d[0].capacity(), 1234);
}

#[test]
fn test_collect_from_into_iter_keeps_allocation() {
let mut v = Vec::with_capacity(13);
v.extend(0..7);
check(v.as_ptr(), v.last().unwrap(), v.into_iter());

let mut v = VecDeque::with_capacity(13);
v.extend(0..7);
check(&v[0], &v[v.len() - 1], v.into_iter());

fn check(buf: *const i32, last: *const i32, mut it: impl Iterator<Item = i32>) {
assert_eq!(it.next(), Some(0));
assert_eq!(it.next(), Some(1));

let mut v: VecDeque<i32> = it.collect();
assert_eq!(v.capacity(), 13);
assert_eq!(v.as_slices().0.as_ptr(), buf.wrapping_add(2));
assert_eq!(&v[v.len() - 1] as *const _, last);

assert_eq!(v.as_slices(), ([2, 3, 4, 5, 6].as_slice(), [].as_slice()));
v.push_front(7);
assert_eq!(v.as_slices(), ([7, 2, 3, 4, 5, 6].as_slice(), [].as_slice()));
v.push_front(8);
assert_eq!(v.as_slices(), ([8, 7, 2, 3, 4, 5, 6].as_slice(), [].as_slice()));

// Now that we've adding thing in place of the two that we removed from
// the front of the iterator, we're back to matching the buffer pointer.
assert_eq!(v.as_slices().0.as_ptr(), buf);
assert_eq!(&v[v.len() - 1] as *const _, last);

v.push_front(9);
assert_eq!(v.as_slices(), ([9].as_slice(), [8, 7, 2, 3, 4, 5, 6].as_slice()));
assert_eq!(v.capacity(), 13);
}
}
8 changes: 8 additions & 0 deletions library/core/src/iter/traits/accum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ use crate::num::Wrapping;
/// [`sum()`]: Iterator::sum
/// [`FromIterator`]: iter::FromIterator
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
#[rustc_on_unimplemented(
message = "a value of type `{Self}` cannot be made by summing an iterator over elements of type `{A}`",
label = "value of type `{Self}` cannot be made by summing a `std::iter::Iterator<Item={A}>`"
)]
pub trait Sum<A = Self>: Sized {
/// Method which takes an iterator and generates `Self` from the elements by
/// "summing up" the items.
Expand All @@ -27,6 +31,10 @@ pub trait Sum<A = Self>: Sized {
/// [`product()`]: Iterator::product
/// [`FromIterator`]: iter::FromIterator
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
#[rustc_on_unimplemented(
message = "a value of type `{Self}` cannot be made by multiplying all elements of type `{A}` from an iterator",
label = "value of type `{Self}` cannot be made by multiplying all elements from a `std::iter::Iterator<Item={A}>`"
)]
pub trait Product<A = Self>: Sized {
/// Method which takes an iterator and generates `Self` from the elements by
/// multiplying the items.
Expand Down
Loading