mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #148573 - matthiaskrgr:rollup-cn5viia, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang/rust#146861 (add extend_front to VecDeque with specialization like extend) - rust-lang/rust#148213 (Fix invalid tag closing when leaving expansion "original code") - rust-lang/rust#148292 (Un-shadow object bound candidate in `NormalizesTo` goal if self_ty is trait object) - rust-lang/rust#148528 (run-make tests: use edition 2024) - rust-lang/rust#148554 (Add regression test for issue 148542) - rust-lang/rust#148561 (Fix ICE from async closure variance) - rust-lang/rust#148563 (rustdoc-search: remove broken index special case) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
@@ -698,6 +698,7 @@ fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
}
|
||||
|
||||
Closure(..)
|
||||
| CoroutineClosure(..)
|
||||
| FnDef(..)
|
||||
| Infer(..)
|
||||
| Coroutine(..)
|
||||
|
||||
@@ -454,7 +454,16 @@ pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<D>>(
|
||||
self.assemble_object_bound_candidates(goal, &mut candidates);
|
||||
}
|
||||
}
|
||||
AssembleCandidatesFrom::EnvAndBounds => {}
|
||||
AssembleCandidatesFrom::EnvAndBounds => {
|
||||
// This is somewhat inconsistent and may make #57893 slightly easier to exploit.
|
||||
// However, it matches the behavior of the old solver. See
|
||||
// `tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs`.
|
||||
if matches!(normalized_self_ty.kind(), ty::Dynamic(..))
|
||||
&& !candidates.iter().any(|c| matches!(c.source, CandidateSource::ParamEnv(_)))
|
||||
{
|
||||
self.assemble_object_bound_candidates(goal, &mut candidates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(candidates, failed_candidate_info)
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
mod iter;
|
||||
|
||||
use self::spec_extend::SpecExtend;
|
||||
use self::spec_extend::{SpecExtend, SpecExtendFront};
|
||||
|
||||
mod spec_extend;
|
||||
|
||||
@@ -179,6 +179,21 @@ unsafe fn push_unchecked(&mut self, element: T) {
|
||||
self.len += 1;
|
||||
}
|
||||
|
||||
/// Prepends an element to the buffer.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// May only be called if `deque.len() < deque.capacity()`
|
||||
#[inline]
|
||||
unsafe fn push_front_unchecked(&mut self, element: T) {
|
||||
self.head = self.wrap_sub(self.head, 1);
|
||||
// SAFETY: Because of the precondition, it's guaranteed that there is space
|
||||
// in the logical array before the first element (where self.head is now).
|
||||
unsafe { self.buffer_write(self.head, element) };
|
||||
// This can't overflow because `deque.len() < deque.capacity() <= usize::MAX`.
|
||||
self.len += 1;
|
||||
}
|
||||
|
||||
/// Moves an element out of the buffer
|
||||
#[inline]
|
||||
unsafe fn buffer_read(&mut self, off: usize) -> T {
|
||||
@@ -505,6 +520,35 @@ unsafe fn copy_slice(&mut self, dst: usize, src: &[T]) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Copies all values from `src` to `dst` in reversed order, wrapping around if needed.
|
||||
/// Assumes capacity is sufficient.
|
||||
/// Equivalent to calling [`VecDeque::copy_slice`] with a [reversed](https://doc.rust-lang.org/std/primitive.slice.html#method.reverse) slice.
|
||||
#[inline]
|
||||
unsafe fn copy_slice_reversed(&mut self, dst: usize, src: &[T]) {
|
||||
/// # Safety
|
||||
///
|
||||
/// See [`ptr::copy_nonoverlapping`].
|
||||
unsafe fn copy_nonoverlapping_reversed<T>(src: *const T, dst: *mut T, count: usize) {
|
||||
for i in 0..count {
|
||||
unsafe { ptr::copy_nonoverlapping(src.add(count - 1 - i), dst.add(i), 1) };
|
||||
}
|
||||
}
|
||||
|
||||
debug_assert!(src.len() <= self.capacity());
|
||||
let head_room = self.capacity() - dst;
|
||||
if src.len() <= head_room {
|
||||
unsafe {
|
||||
copy_nonoverlapping_reversed(src.as_ptr(), self.ptr().add(dst), src.len());
|
||||
}
|
||||
} else {
|
||||
let (left, right) = src.split_at(src.len() - head_room);
|
||||
unsafe {
|
||||
copy_nonoverlapping_reversed(right.as_ptr(), self.ptr().add(dst), right.len());
|
||||
copy_nonoverlapping_reversed(left.as_ptr(), self.ptr(), left.len());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes all values from `iter` to `dst`.
|
||||
///
|
||||
/// # Safety
|
||||
@@ -2122,6 +2166,73 @@ pub fn push_back_mut(&mut self, value: T) -> &mut T {
|
||||
unsafe { self.buffer_write(self.to_physical_idx(len), value) }
|
||||
}
|
||||
|
||||
/// Prepends all contents of the iterator to the front of the deque.
|
||||
/// The order of the contents is preserved.
|
||||
///
|
||||
/// To get behavior like [`append`][VecDeque::append] where elements are moved
|
||||
/// from the other collection to this one, use `self.prepend(other.drain(..))`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(deque_extend_front)]
|
||||
/// use std::collections::VecDeque;
|
||||
///
|
||||
/// let mut deque = VecDeque::from([4, 5, 6]);
|
||||
/// deque.prepend([1, 2, 3]);
|
||||
/// assert_eq!(deque, [1, 2, 3, 4, 5, 6]);
|
||||
/// ```
|
||||
///
|
||||
/// Move values between collections like [`append`][VecDeque::append] does but prepend to the front:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(deque_extend_front)]
|
||||
/// use std::collections::VecDeque;
|
||||
///
|
||||
/// let mut deque1 = VecDeque::from([4, 5, 6]);
|
||||
/// let mut deque2 = VecDeque::from([1, 2, 3]);
|
||||
/// deque1.prepend(deque2.drain(..));
|
||||
/// assert_eq!(deque1, [1, 2, 3, 4, 5, 6]);
|
||||
/// assert!(deque2.is_empty());
|
||||
/// ```
|
||||
#[unstable(feature = "deque_extend_front", issue = "146975")]
|
||||
#[track_caller]
|
||||
pub fn prepend<I: IntoIterator<Item = T, IntoIter: DoubleEndedIterator>>(&mut self, other: I) {
|
||||
self.extend_front(other.into_iter().rev())
|
||||
}
|
||||
|
||||
/// Prepends all contents of the iterator to the front of the deque,
|
||||
/// as if [`push_front`][VecDeque::push_front] was called repeatedly with
|
||||
/// the values yielded by the iterator.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(deque_extend_front)]
|
||||
/// use std::collections::VecDeque;
|
||||
///
|
||||
/// let mut deque = VecDeque::from([4, 5, 6]);
|
||||
/// deque.extend_front([3, 2, 1]);
|
||||
/// assert_eq!(deque, [1, 2, 3, 4, 5, 6]);
|
||||
/// ```
|
||||
///
|
||||
/// This behaves like [`push_front`][VecDeque::push_front] was called repeatedly:
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::VecDeque;
|
||||
///
|
||||
/// let mut deque = VecDeque::from([4, 5, 6]);
|
||||
/// for v in [3, 2, 1] {
|
||||
/// deque.push_front(v);
|
||||
/// }
|
||||
/// assert_eq!(deque, [1, 2, 3, 4, 5, 6]);
|
||||
/// ```
|
||||
#[unstable(feature = "deque_extend_front", issue = "146975")]
|
||||
#[track_caller]
|
||||
pub fn extend_front<I: IntoIterator<Item = T>>(&mut self, iter: I) {
|
||||
<Self as SpecExtendFront<T, I::IntoIter>>::spec_extend_front(self, iter.into_iter());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_contiguous(&self) -> bool {
|
||||
// Do the calculation like this to avoid overflowing if len + head > usize::MAX
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use core::iter::TrustedLen;
|
||||
use core::iter::{Copied, Rev, TrustedLen};
|
||||
use core::slice;
|
||||
|
||||
use super::VecDeque;
|
||||
@@ -114,3 +114,113 @@ fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Specialization trait used for VecDeque::extend_front
|
||||
pub(super) trait SpecExtendFront<T, I> {
|
||||
#[track_caller]
|
||||
fn spec_extend_front(&mut self, iter: I);
|
||||
}
|
||||
|
||||
impl<T, I, A: Allocator> SpecExtendFront<T, I> for VecDeque<T, A>
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
{
|
||||
#[track_caller]
|
||||
default fn spec_extend_front(&mut self, mut iter: I) {
|
||||
// This function should be the moral equivalent of:
|
||||
//
|
||||
// for item in iter {
|
||||
// self.push_front(item);
|
||||
// }
|
||||
|
||||
while let Some(element) = iter.next() {
|
||||
let (lower, _) = iter.size_hint();
|
||||
self.reserve(lower.saturating_add(1));
|
||||
|
||||
// SAFETY: We just reserved space for at least one element.
|
||||
unsafe { self.push_front_unchecked(element) };
|
||||
|
||||
// Inner loop to avoid repeatedly calling `reserve`.
|
||||
while self.len < self.capacity() {
|
||||
let Some(element) = iter.next() else {
|
||||
return;
|
||||
};
|
||||
// SAFETY: The loop condition guarantees that `self.len() < self.capacity()`.
|
||||
unsafe { self.push_front_unchecked(element) };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<T, A: Allocator> SpecExtendFront<T, vec::IntoIter<T>> for VecDeque<T, A> {
|
||||
#[track_caller]
|
||||
fn spec_extend_front(&mut self, mut iterator: vec::IntoIter<T>) {
|
||||
let slice = iterator.as_slice();
|
||||
// SAFETY: elements in the slice are forgotten after this call
|
||||
unsafe { prepend_reversed(self, slice) };
|
||||
iterator.forget_remaining_elements();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<T, A: Allocator> SpecExtendFront<T, Rev<vec::IntoIter<T>>> for VecDeque<T, A> {
|
||||
#[track_caller]
|
||||
fn spec_extend_front(&mut self, iterator: Rev<vec::IntoIter<T>>) {
|
||||
let mut iterator = iterator.into_inner();
|
||||
let slice = iterator.as_slice();
|
||||
// SAFETY: elements in the slice are forgotten after this call
|
||||
unsafe { prepend(self, slice) };
|
||||
iterator.forget_remaining_elements();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, A: Allocator> SpecExtendFront<T, Copied<slice::Iter<'a, T>>> for VecDeque<T, A>
|
||||
where
|
||||
Copied<slice::Iter<'a, T>>: Iterator<Item = T>,
|
||||
{
|
||||
#[track_caller]
|
||||
fn spec_extend_front(&mut self, iter: Copied<slice::Iter<'a, T>>) {
|
||||
let slice = iter.into_inner().as_slice();
|
||||
// SAFETY: T is Copy because Copied<slice::Iter<'a, T>> is Iterator
|
||||
unsafe { prepend_reversed(self, slice) };
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, A: Allocator> SpecExtendFront<T, Rev<Copied<slice::Iter<'a, T>>>> for VecDeque<T, A>
|
||||
where
|
||||
Rev<Copied<slice::Iter<'a, T>>>: Iterator<Item = T>,
|
||||
{
|
||||
#[track_caller]
|
||||
fn spec_extend_front(&mut self, iter: Rev<Copied<slice::Iter<'a, T>>>) {
|
||||
let slice = iter.into_inner().into_inner().as_slice();
|
||||
// SAFETY: T is Copy because Rev<Copied<slice::Iter<'a, T>>> is Iterator
|
||||
unsafe { prepend(self, slice) };
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Elements of `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`.
|
||||
unsafe fn prepend<T, A: Allocator>(deque: &mut VecDeque<T, A>, slice: &[T]) {
|
||||
deque.reserve(slice.len());
|
||||
|
||||
unsafe {
|
||||
deque.head = deque.wrap_sub(deque.head, slice.len());
|
||||
deque.copy_slice(deque.head, slice);
|
||||
deque.len += slice.len();
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Elements of `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`.
|
||||
unsafe fn prepend_reversed<T, A: Allocator>(deque: &mut VecDeque<T, A>, slice: &[T]) {
|
||||
deque.reserve(slice.len());
|
||||
|
||||
unsafe {
|
||||
deque.head = deque.wrap_sub(deque.head, slice.len());
|
||||
deque.copy_slice_reversed(deque.head, slice);
|
||||
deque.len += slice.len();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
#![feature(const_default)]
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(const_heap)]
|
||||
#![feature(copied_into_inner)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(deprecated_suggestion)]
|
||||
#![feature(deref_pure_trait)]
|
||||
@@ -134,6 +135,7 @@
|
||||
#![feature(ptr_alignment_type)]
|
||||
#![feature(ptr_internals)]
|
||||
#![feature(ptr_metadata)]
|
||||
#![feature(rev_into_inner)]
|
||||
#![feature(set_ptr_value)]
|
||||
#![feature(sized_type_properties)]
|
||||
#![feature(slice_from_ptr_range)]
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#![feature(assert_matches)]
|
||||
#![feature(char_internals)]
|
||||
#![feature(char_max_len)]
|
||||
#![feature(copied_into_inner)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
#![feature(extend_one)]
|
||||
@@ -32,6 +33,7 @@
|
||||
#![feature(maybe_uninit_uninit_array_transpose)]
|
||||
#![feature(ptr_alignment_type)]
|
||||
#![feature(ptr_internals)]
|
||||
#![feature(rev_into_inner)]
|
||||
#![feature(sized_type_properties)]
|
||||
#![feature(slice_iter_mut_as_mut_slice)]
|
||||
#![feature(slice_ptr_get)]
|
||||
|
||||
@@ -2081,3 +2081,77 @@ fn test_extend_and_prepend_from_within() {
|
||||
v.extend_from_within(..);
|
||||
assert_eq!(v.iter().map(|s| &**s).collect::<String>(), "123123123123");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extend_front() {
|
||||
let mut v = VecDeque::new();
|
||||
v.extend_front(0..3);
|
||||
assert_eq!(v, [2, 1, 0]);
|
||||
v.extend_front(3..6);
|
||||
assert_eq!(v, [5, 4, 3, 2, 1, 0]);
|
||||
v.prepend([1; 4]);
|
||||
assert_eq!(v, [1, 1, 1, 1, 5, 4, 3, 2, 1, 0]);
|
||||
|
||||
let mut v = VecDeque::with_capacity(8);
|
||||
let cap = v.capacity();
|
||||
v.extend(0..4);
|
||||
v.truncate_front(2);
|
||||
v.extend_front(4..8);
|
||||
assert_eq!(v.as_slices(), ([7, 6].as_slice(), [5, 4, 2, 3].as_slice()));
|
||||
assert_eq!(v.capacity(), cap);
|
||||
|
||||
let mut v = VecDeque::new();
|
||||
v.extend_front([]);
|
||||
v.extend_front(None);
|
||||
v.extend_front(vec![]);
|
||||
v.prepend([]);
|
||||
v.prepend(None);
|
||||
v.prepend(vec![]);
|
||||
assert_eq!(v.capacity(), 0);
|
||||
v.extend_front(Some(123));
|
||||
assert_eq!(v, [123]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extend_front_specialization_vec_into_iter() {
|
||||
// trigger 4 code paths: all combinations of prepend and extend_front, wrap and no wrap
|
||||
let mut v = VecDeque::with_capacity(4);
|
||||
v.prepend(vec![1, 2, 3]);
|
||||
assert_eq!(v, [1, 2, 3]);
|
||||
v.pop_back();
|
||||
// this should wrap around the physical buffer
|
||||
v.prepend(vec![-1, 0]);
|
||||
// check it really wrapped
|
||||
assert_eq!(v.as_slices(), ([-1].as_slice(), [0, 1, 2].as_slice()));
|
||||
|
||||
let mut v = VecDeque::with_capacity(4);
|
||||
v.extend_front(vec![1, 2, 3]);
|
||||
assert_eq!(v, [3, 2, 1]);
|
||||
v.pop_back();
|
||||
// this should wrap around the physical buffer
|
||||
v.extend_front(vec![4, 5]);
|
||||
// check it really wrapped
|
||||
assert_eq!(v.as_slices(), ([5].as_slice(), [4, 3, 2].as_slice()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extend_front_specialization_copy_slice() {
|
||||
// trigger 4 code paths: all combinations of prepend and extend_front, wrap and no wrap
|
||||
let mut v = VecDeque::with_capacity(4);
|
||||
v.prepend([1, 2, 3].as_slice().iter().copied());
|
||||
assert_eq!(v, [1, 2, 3]);
|
||||
v.pop_back();
|
||||
// this should wrap around the physical buffer
|
||||
v.prepend([-1, 0].as_slice().iter().copied());
|
||||
// check it really wrapped
|
||||
assert_eq!(v.as_slices(), ([-1].as_slice(), [0, 1, 2].as_slice()));
|
||||
|
||||
let mut v = VecDeque::with_capacity(4);
|
||||
v.extend_front([1, 2, 3].as_slice().iter().copied());
|
||||
assert_eq!(v, [3, 2, 1]);
|
||||
v.pop_back();
|
||||
// this should wrap around the physical buffer
|
||||
v.extend_front([4, 5].as_slice().iter().copied());
|
||||
// check it really wrapped
|
||||
assert_eq!(v.as_slices(), ([5].as_slice(), [4, 3, 2].as_slice()));
|
||||
}
|
||||
|
||||
@@ -24,6 +24,12 @@ impl<I> Copied<I> {
|
||||
pub(in crate::iter) fn new(it: I) -> Copied<I> {
|
||||
Copied { it }
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "copied_into_inner", issue = "none")]
|
||||
pub fn into_inner(self) -> I {
|
||||
self.it
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_fold<T: Copy, Acc>(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, &T) -> Acc {
|
||||
|
||||
@@ -427,6 +427,27 @@ fn close_expansion(&mut self) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Used when we're done with the current expansion "original code" (ie code before expansion).
|
||||
/// We close all tags inside `Class::Original` and only keep the ones that were not closed yet.
|
||||
fn close_original_tag(&mut self) {
|
||||
let mut classes_to_reopen = Vec::new();
|
||||
while let Some(mut class_info) = self.class_stack.open_classes.pop() {
|
||||
if class_info.class == Class::Original {
|
||||
while let Some(class_info) = classes_to_reopen.pop() {
|
||||
self.class_stack.open_classes.push(class_info);
|
||||
}
|
||||
class_info.close_tag(self.out);
|
||||
return;
|
||||
}
|
||||
class_info.close_tag(self.out);
|
||||
if !class_info.pending_exit {
|
||||
class_info.closing_tag = None;
|
||||
classes_to_reopen.push(class_info);
|
||||
}
|
||||
}
|
||||
panic!("Didn't find `Class::Original` to close");
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Write> Drop for TokenHandler<'_, '_, F> {
|
||||
@@ -484,7 +505,9 @@ fn end_expansion<'a, W: Write>(
|
||||
expanded_codes: &'a [ExpandedCode],
|
||||
span: Span,
|
||||
) -> Option<&'a ExpandedCode> {
|
||||
token_handler.class_stack.exit_elem();
|
||||
// We close `Class::Original` and everything open inside it.
|
||||
token_handler.close_original_tag();
|
||||
// Then we check if we have another macro expansion on the same line.
|
||||
let expansion = get_next_expansion(expanded_codes, token_handler.line, span);
|
||||
if expansion.is_none() {
|
||||
token_handler.close_expansion();
|
||||
|
||||
@@ -1051,28 +1051,21 @@ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
if self.search_unbox
|
||||
|| !self.inverted_function_inputs_index.is_empty()
|
||||
|| !self.inverted_function_output_index.is_empty()
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(None)?;
|
||||
let mut buf = Vec::new();
|
||||
encode::write_postings_to_string(&self.inverted_function_inputs_index, &mut buf);
|
||||
let mut serialized_result = Vec::new();
|
||||
stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result);
|
||||
seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?;
|
||||
buf.clear();
|
||||
serialized_result.clear();
|
||||
encode::write_postings_to_string(&self.inverted_function_output_index, &mut buf);
|
||||
stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result);
|
||||
seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?;
|
||||
if self.search_unbox {
|
||||
seq.serialize_element(&1)?;
|
||||
}
|
||||
seq.end()
|
||||
} else {
|
||||
None::<()>.serialize(serializer)
|
||||
let mut seq = serializer.serialize_seq(None)?;
|
||||
let mut buf = Vec::new();
|
||||
encode::write_postings_to_string(&self.inverted_function_inputs_index, &mut buf);
|
||||
let mut serialized_result = Vec::new();
|
||||
stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result);
|
||||
seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?;
|
||||
buf.clear();
|
||||
serialized_result.clear();
|
||||
encode::write_postings_to_string(&self.inverted_function_output_index, &mut buf);
|
||||
stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result);
|
||||
seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?;
|
||||
if self.search_unbox {
|
||||
seq.serialize_element(&1)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
fn main() {
|
||||
rustc()
|
||||
.edition("2021")
|
||||
.edition("2024")
|
||||
.arg("-Dwarnings")
|
||||
.crate_type("rlib")
|
||||
.input(source_root().join("library/alloc/src/lib.rs"))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
fn main() {
|
||||
rustc()
|
||||
.edition("2021")
|
||||
.edition("2024")
|
||||
.arg("-Dwarnings")
|
||||
.crate_type("rlib")
|
||||
.input(source_root().join("library/alloc/src/lib.rs"))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
fn main() {
|
||||
rustc()
|
||||
.edition("2021")
|
||||
.edition("2024")
|
||||
.arg("-Dwarnings")
|
||||
.crate_type("rlib")
|
||||
.input(source_root().join("library/alloc/src/lib.rs"))
|
||||
|
||||
@@ -49,21 +49,21 @@ fn main() {
|
||||
rustc()
|
||||
.input("proc.rs")
|
||||
.crate_type("proc-macro")
|
||||
.edition("2021")
|
||||
.edition("2024")
|
||||
.arg("-Cdebuginfo=line-tables-only")
|
||||
.run();
|
||||
rustc()
|
||||
.extern_("proc", dynamic_lib_name("proc"))
|
||||
.input("other.rs")
|
||||
.crate_type("rlib")
|
||||
.edition("2021")
|
||||
.edition("2024")
|
||||
.opt_level("3")
|
||||
.arg("-Cdebuginfo=line-tables-only")
|
||||
.run();
|
||||
rustc()
|
||||
.extern_("other", rust_lib_name("other"))
|
||||
.input("main.rs")
|
||||
.edition("2021")
|
||||
.edition("2024")
|
||||
.opt_level("3")
|
||||
.arg("-Cdebuginfo=line-tables-only")
|
||||
.arg("-Clto=fat")
|
||||
|
||||
@@ -19,7 +19,7 @@ fn main() {
|
||||
.crate_type("lib")
|
||||
.emit("obj=foo.o")
|
||||
.panic("abort")
|
||||
.edition("2021")
|
||||
.edition("2024")
|
||||
.arg("-Zvalidate-mir")
|
||||
.arg("-Cforce-unwind-tables=no")
|
||||
.run();
|
||||
|
||||
@@ -19,14 +19,14 @@ fn main() {
|
||||
rustc()
|
||||
.input("src/proc.rs")
|
||||
.crate_name(proc_crate_name)
|
||||
.edition("2021")
|
||||
.edition("2024")
|
||||
.crate_type("proc-macro")
|
||||
.emit("dep-info,link")
|
||||
.run();
|
||||
rustc()
|
||||
.input("src/lib.rs")
|
||||
.crate_name(crate_name)
|
||||
.edition("2021")
|
||||
.edition("2024")
|
||||
.crate_type("lib")
|
||||
.emit("dep-info,link")
|
||||
.run();
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// https://github.com/rust-lang/rust/issues/148431
|
||||
|
||||
// This test is designed to hit a case where, thanks to the
|
||||
// recursion limit, the where clause gets generated, but not
|
||||
// used, because we run out of fuel.
|
||||
//
|
||||
// This results in a reverse index with nothing in it, which
|
||||
// used to crash when we parsed it.
|
||||
pub fn foobar1<A: T1<B>, B: T2<C>, C: T3<D>, D: T4<A>>(a: A) {}
|
||||
|
||||
pub trait T1<T: ?Sized> {}
|
||||
pub trait T2<T: ?Sized> {}
|
||||
pub trait T3<T: ?Sized> {}
|
||||
pub trait T4<T: ?Sized> {}
|
||||
|
||||
// foobar1 is the version that worked at the time this test was written
|
||||
// the rest are here to try to make the test at least a little more
|
||||
// robust, in the sense that it actually tests the code and isn't magically
|
||||
// fixed by the recursion limit changing
|
||||
pub fn foobar2<A: U1<B>, B: U2<C>, C: U3<D>, D: U4<E>, E: U5<A>>(a: A) {}
|
||||
|
||||
pub trait U1<T: ?Sized> {}
|
||||
pub trait U2<T: ?Sized> {}
|
||||
pub trait U3<T: ?Sized> {}
|
||||
pub trait U4<T: ?Sized> {}
|
||||
pub trait U5<T: ?Sized> {}
|
||||
|
||||
pub fn foobar3<A: V1<B>, B: V2<C>, C: V3<D>, D: V4<E>, E: V5<F>, F: V6<A>>(a: A) {}
|
||||
|
||||
pub trait V1<T: ?Sized> {}
|
||||
pub trait V2<T: ?Sized> {}
|
||||
pub trait V3<T: ?Sized> {}
|
||||
pub trait V4<T: ?Sized> {}
|
||||
pub trait V5<T: ?Sized> {}
|
||||
pub trait V6<T: ?Sized> {}
|
||||
|
||||
pub fn foobar4<A: W1<B>, B: W2<C>, C: W3<A>>(a: A) {}
|
||||
|
||||
pub trait W1<T: ?Sized> {}
|
||||
pub trait W2<T: ?Sized> {}
|
||||
pub trait W3<T: ?Sized> {}
|
||||
@@ -0,0 +1,8 @@
|
||||
const EXPECTED = [
|
||||
{
|
||||
query: 'baz',
|
||||
others: [
|
||||
{ name: 'baz' }
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,8 @@
|
||||
//@ aux-crate:emptytype=emptytype.rs
|
||||
//@ compile-flags: --extern emptytype
|
||||
//@ aux-build:emptytype.rs
|
||||
//@ build-aux-docs
|
||||
|
||||
extern crate emptytype;
|
||||
|
||||
pub fn baz() {}
|
||||
@@ -0,0 +1,15 @@
|
||||
//@ force-host
|
||||
//@ no-prefer-dynamic
|
||||
//@ compile-flags: --crate-type proc-macro
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![crate_name = "just_some_proc"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn repro(_args: TokenStream, _input: TokenStream) -> TokenStream {
|
||||
"struct Repro;".parse().unwrap()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Regression test for <https://github.com/rust-lang/rust/issues/148184>.
|
||||
// It ensures that the macro expansion correctly handles its "class stack".
|
||||
|
||||
//@ compile-flags: -Zunstable-options --generate-macro-expansion
|
||||
//@ aux-build:one-line-expand.rs
|
||||
|
||||
#![crate_name = "foo"]
|
||||
|
||||
extern crate just_some_proc;
|
||||
|
||||
//@ has 'src/foo/one-line-expand.rs.html'
|
||||
//@ has - '//*[@class="comment"]' '//'
|
||||
//@ has - '//*[@class="original"]' '#[just_some_proc::repro]'
|
||||
//@ has - '//*[@class="original"]/*[@class="attr"]' '#[just_some_proc::repro]'
|
||||
//@ has - '//code/*[@class="kw"]' 'struct '
|
||||
|
||||
//
|
||||
#[just_some_proc::repro]
|
||||
struct Repro;
|
||||
@@ -0,0 +1,12 @@
|
||||
//@ edition: 2024
|
||||
|
||||
struct T<'g>();
|
||||
//~^ ERROR lifetime parameter `'g` is never used
|
||||
|
||||
fn ord<a>() -> _ {
|
||||
//~^ WARN type parameter `a` should have an upper camel case name
|
||||
//~| ERROR the placeholder `_` is not allowed within types on item signatures for return types
|
||||
async || {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,26 @@
|
||||
warning: type parameter `a` should have an upper camel case name
|
||||
--> $DIR/ice-async-closure-variance-issue-148488.rs:6:8
|
||||
|
|
||||
LL | fn ord<a>() -> _ {
|
||||
| ^ help: convert the identifier to upper camel case: `A`
|
||||
|
|
||||
= note: `#[warn(non_camel_case_types)]` (part of `#[warn(nonstandard_style)]`) on by default
|
||||
|
||||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
|
||||
--> $DIR/ice-async-closure-variance-issue-148488.rs:6:16
|
||||
|
|
||||
LL | fn ord<a>() -> _ {
|
||||
| ^ not allowed in type signatures
|
||||
|
||||
error[E0392]: lifetime parameter `'g` is never used
|
||||
--> $DIR/ice-async-closure-variance-issue-148488.rs:3:10
|
||||
|
|
||||
LL | struct T<'g>();
|
||||
| ^^ unused lifetime parameter
|
||||
|
|
||||
= help: consider removing `'g`, referring to it in a field, or using a marker such as `PhantomData`
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0121, E0392.
|
||||
For more information about an error, try `rustc --explain E0121`.
|
||||
@@ -0,0 +1,13 @@
|
||||
//@ edition: 2021
|
||||
|
||||
// Regression test for #148542
|
||||
// Ensure we don't ICE with "Invalid `ConstKind` for `const_to_pat`: {const error}"
|
||||
|
||||
fn foo() where &str:, {
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
match 42_u8 {
|
||||
-10.. => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,14 @@
|
||||
error[E0637]: `&` without an explicit lifetime name cannot be used here
|
||||
--> $DIR/const-error-ice-issue-148542.rs:6:16
|
||||
|
|
||||
LL | fn foo() where &str:, {
|
||||
| ^ explicit lifetime name needed here
|
||||
|
|
||||
help: consider introducing a higher-ranked lifetime here
|
||||
|
|
||||
LL | fn foo() where for<'a> &'a str:, {
|
||||
| +++++++ ++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0637`.
|
||||
@@ -0,0 +1,36 @@
|
||||
//@ compile-flags: -Znext-solver
|
||||
//@ check-pass
|
||||
|
||||
// Regression test for trait-system-refactor-initiative#244
|
||||
|
||||
trait Trait {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
// We have param env candidate for the trait goal but not the projection.
|
||||
// Under such circumstance, consider object candidate if the self_ty is trait object.
|
||||
fn foo<T>(x: <dyn Trait<Assoc = T> as Trait>::Assoc) -> T
|
||||
where
|
||||
dyn Trait<Assoc = T>: Trait,
|
||||
{
|
||||
x
|
||||
}
|
||||
|
||||
trait Id<'a> {
|
||||
type This: ?Sized;
|
||||
}
|
||||
impl<T: ?Sized> Id<'_> for T {
|
||||
type This = T;
|
||||
}
|
||||
|
||||
// Ensure that we properly normalize alias self_ty before evaluating the goal.
|
||||
fn alias_foo<T>(x: for<'a> fn(
|
||||
<<dyn Trait<Assoc = T> as Id<'a>>::This as Trait>::Assoc
|
||||
)) -> fn(T)
|
||||
where
|
||||
dyn Trait<Assoc = T>: Trait,
|
||||
{
|
||||
x
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Reference in New Issue
Block a user