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 6 pull requests #95500

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
25a7d2d
Fix `cargo run tidy`
jyn514 Mar 10, 2022
38e0ae5
Reduce max hash in raw strings from u16 to u8
GrishaVar Mar 23, 2022
b51f20e
Update syntax tree definition
GrishaVar Mar 23, 2022
0cf6061
Fix double drop of allocator in IntoIter impl of Vec
jhorstmann Mar 25, 2022
d14c0d2
Use ManuallyDrop::take instead of into_inner
jhorstmann Mar 25, 2022
4b53f56
Add a test verifying the number of drop calls
jhorstmann Mar 25, 2022
c3840c9
Update clippy helper function types
GrishaVar Mar 25, 2022
d9a438d
Add another assertion without into_iter
jhorstmann Mar 25, 2022
78e27e2
async: Give predictable, reserved name to binding generated from .awa…
michaelwoerister Mar 16, 2022
1144677
Don't ICE when opaque types get their hidden type constrained again.
oli-obk Mar 30, 2022
f0b12f4
Remove unused #![feature]s from std.
m-ou-se Mar 17, 2022
e4248fe
Categorize and sort unstable features in std.
m-ou-se Mar 17, 2022
39a8442
Put back std #![feature]s that were not unused.
m-ou-se Mar 30, 2022
759d1e6
Update error message & remove outdated test comment
GrishaVar Mar 30, 2022
4842f4f
Rollup merge of #94806 - jyn514:cargo-run-tidy, r=Mark-Simulacrum
Dylan-DPC Mar 30, 2022
e6ff7b1
Rollup merge of #95011 - michaelwoerister:awaitee_field, r=tmandry
Dylan-DPC Mar 30, 2022
e0719bd
Rollup merge of #95032 - m-ou-se:std-features, r=yaahc
Dylan-DPC Mar 30, 2022
957dc51
Rollup merge of #95251 - GrishaVar:hashes-u16-to-u8, r=dtolnay
Dylan-DPC Mar 30, 2022
d7b0032
Rollup merge of #95298 - jhorstmann:fix-double-drop-of-allocator-in-v…
Dylan-DPC Mar 30, 2022
e5d022f
Rollup merge of #95471 - oli-obk:tait_ice, r=estebank
Dylan-DPC Mar 30, 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
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1616,7 +1616,7 @@ pub enum StrStyle {
/// A raw string, like `r##"foo"##`.
///
/// The value is the number of `#` symbols used.
Raw(u16),
Raw(u8),
}

/// An AST literal.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ pub enum LitKind {
Integer,
Float,
Str,
StrRaw(u16), // raw string delimited by `n` hash symbols
StrRaw(u8), // raw string delimited by `n` hash symbols
ByteStr,
ByteStrRaw(u16), // raw byte string delimited by `n` hash symbols
ByteStrRaw(u8), // raw byte string delimited by `n` hash symbols
Err,
}

Expand Down
29 changes: 16 additions & 13 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,9 +618,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
/// Desugar `<expr>.await` into:
/// ```rust
/// match ::std::future::IntoFuture::into_future(<expr>) {
/// mut pinned => loop {
/// mut __awaitee => loop {
/// match unsafe { ::std::future::Future::poll(
/// <::std::pin::Pin>::new_unchecked(&mut pinned),
/// <::std::pin::Pin>::new_unchecked(&mut __awaitee),
/// ::std::future::get_context(task_context),
/// ) } {
/// ::std::task::Poll::Ready(result) => break result,
Expand Down Expand Up @@ -657,21 +657,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
let expr = self.lower_expr_mut(expr);
let expr_hir_id = expr.hir_id;

let pinned_ident = Ident::with_dummy_span(sym::pinned);
let (pinned_pat, pinned_pat_hid) =
self.pat_ident_binding_mode(span, pinned_ident, hir::BindingAnnotation::Mutable);
// Note that the name of this binding must not be changed to something else because
// debuggers and debugger extensions expect it to be called `__awaitee`. They use
// this name to identify what is being awaited by a suspended async functions.
let awaitee_ident = Ident::with_dummy_span(sym::__awaitee);
let (awaitee_pat, awaitee_pat_hid) =
self.pat_ident_binding_mode(span, awaitee_ident, hir::BindingAnnotation::Mutable);

let task_context_ident = Ident::with_dummy_span(sym::_task_context);

// unsafe {
// ::std::future::Future::poll(
// ::std::pin::Pin::new_unchecked(&mut pinned),
// ::std::pin::Pin::new_unchecked(&mut __awaitee),
// ::std::future::get_context(task_context),
// )
// }
let poll_expr = {
let pinned = self.expr_ident(span, pinned_ident, pinned_pat_hid);
let ref_mut_pinned = self.expr_mut_addr_of(span, pinned);
let awaitee = self.expr_ident(span, awaitee_ident, awaitee_pat_hid);
let ref_mut_awaitee = self.expr_mut_addr_of(span, awaitee);
let task_context = if let Some(task_context_hid) = self.task_context {
self.expr_ident_mut(span, task_context_ident, task_context_hid)
} else {
Expand All @@ -681,7 +684,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let new_unchecked = self.expr_call_lang_item_fn_mut(
span,
hir::LangItem::PinNewUnchecked,
arena_vec![self; ref_mut_pinned],
arena_vec![self; ref_mut_awaitee],
Some(expr_hir_id),
);
let get_context = self.expr_call_lang_item_fn_mut(
Expand Down Expand Up @@ -782,8 +785,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: self.lower_span(span),
});

// mut pinned => loop { ... }
let pinned_arm = self.arm(pinned_pat, loop_expr);
// mut __awaitee => loop { ... }
let awaitee_arm = self.arm(awaitee_pat, loop_expr);

// `match ::std::future::IntoFuture::into_future(<expr>) { ... }`
let into_future_span = self.mark_span_with_reason(
Expand All @@ -799,11 +802,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
);

// match <into_future_expr> {
// mut pinned => loop { .. }
// mut __awaitee => loop { .. }
// }
hir::ExprKind::Match(
into_future_expr,
arena_vec![self; pinned_arm],
arena_vec![self; awaitee_arm],
hir::MatchSource::AwaitDesugar,
)
}
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_lexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,15 @@ pub enum LiteralKind {
/// "b"abc"", "b"abc"
ByteStr { terminated: bool },
/// "r"abc"", "r#"abc"#", "r####"ab"###"c"####", "r#"a"
RawStr { n_hashes: u16, err: Option<RawStrError> },
RawStr { n_hashes: u8, err: Option<RawStrError> },
/// "br"abc"", "br#"abc"#", "br####"ab"###"c"####", "br#"a"
RawByteStr { n_hashes: u16, err: Option<RawStrError> },
RawByteStr { n_hashes: u8, err: Option<RawStrError> },
}

/// Error produced validating a raw string. Represents cases like:
/// - `r##~"abcde"##`: `InvalidStarter`
/// - `r###"abcde"##`: `NoTerminator { expected: 3, found: 2, possible_terminator_offset: Some(11)`
/// - Too many `#`s (>65535): `TooManyDelimiters`
/// - Too many `#`s (>255): `TooManyDelimiters`
// perf note: It doesn't matter that this makes `Token` 36 bytes bigger. See #77629
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum RawStrError {
Expand All @@ -178,7 +178,7 @@ pub enum RawStrError {
/// The string was never terminated. `possible_terminator_offset` is the number of characters after `r` or `br` where they
/// may have intended to terminate it.
NoTerminator { expected: usize, found: usize, possible_terminator_offset: Option<usize> },
/// More than 65535 `#`s exist.
/// More than 255 `#`s exist.
TooManyDelimiters { found: usize },
}

Expand Down Expand Up @@ -698,12 +698,12 @@ impl Cursor<'_> {
}

/// Eats the double-quoted string and returns `n_hashes` and an error if encountered.
fn raw_double_quoted_string(&mut self, prefix_len: usize) -> (u16, Option<RawStrError>) {
fn raw_double_quoted_string(&mut self, prefix_len: usize) -> (u8, Option<RawStrError>) {
// Wrap the actual function to handle the error with too many hashes.
// This way, it eats the whole raw string.
let (n_hashes, err) = self.raw_string_unvalidated(prefix_len);
// Only up to 65535 `#`s are allowed in raw strings
match u16::try_from(n_hashes) {
// Only up to 255 `#`s are allowed in raw strings
match u8::try_from(n_hashes) {
Ok(num) => (num, err),
// We lie about the number of hashes here :P
Err(_) => (0, Some(RawStrError::TooManyDelimiters { found: n_hashes })),
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_lexer/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::*;

use expect_test::{expect, Expect};

fn check_raw_str(s: &str, expected_hashes: u16, expected_err: Option<RawStrError>) {
fn check_raw_str(s: &str, expected_hashes: u8, expected_err: Option<RawStrError>) {
let s = &format!("r{}", s);
let mut cursor = Cursor::new(s);
cursor.bump();
Expand Down Expand Up @@ -68,13 +68,13 @@ fn test_unterminated_no_pound() {

#[test]
fn test_too_many_hashes() {
let max_count = u16::MAX;
let max_count = u8::MAX;
let mut hashes: String = "#".repeat(max_count.into());

// Valid number of hashes (65535 = 2^16 - 1), but invalid string.
// Valid number of hashes (255 = 2^8 - 1 = u8::MAX), but invalid string.
check_raw_str(&hashes, max_count, Some(RawStrError::InvalidStarter { bad_char: '\u{0}' }));

// One more hash sign (65536 = 2^16) becomes too many.
// One more hash sign (256 = 2^8) becomes too many.
hashes.push('#');
check_raw_str(
&hashes,
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_parse/src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,15 +597,13 @@ impl<'a> StringReader<'a> {
}
}

/// Note: It was decided to not add a test case, because it would be too big.
/// <https://github.com/rust-lang/rust/pull/50296#issuecomment-392135180>
fn report_too_many_hashes(&self, start: BytePos, found: usize) -> ! {
self.fatal_span_(
start,
self.pos,
&format!(
"too many `#` symbols: raw strings may be delimited \
by up to 65535 `#` symbols, but found {}",
by up to 255 `#` symbols, but found {}",
found
),
)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ symbols! {
__D,
__H,
__S,
__awaitee,
__try_var,
_d,
_e,
Expand Down Expand Up @@ -1018,7 +1019,6 @@ symbols! {
pattern_parentheses,
phantom_data,
pin,
pinned,
platform_intrinsics,
plugin,
plugin_registrar,
Expand Down
19 changes: 6 additions & 13 deletions compiler/rustc_trait_selection/src/traits/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use rustc_middle::ty::{self, TyCtxt};
/// obligations *could be* resolved if we wanted to.
///
/// This also expects that `trait_ref` is fully normalized.
#[instrument(level = "debug", skip(tcx))]
pub fn codegen_fulfill_obligation<'tcx>(
tcx: TyCtxt<'tcx>,
(param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
Expand All @@ -27,11 +28,6 @@ pub fn codegen_fulfill_obligation<'tcx>(
let trait_ref = tcx.erase_regions(trait_ref);
// We expect the input to be fully normalized.
debug_assert_eq!(trait_ref, tcx.normalize_erasing_regions(param_env, trait_ref));
debug!(
"codegen_fulfill_obligation(trait_ref={:?}, def_id={:?})",
(param_env, trait_ref),
trait_ref.def_id()
);

// Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl.
Expand Down Expand Up @@ -80,25 +76,22 @@ pub fn codegen_fulfill_obligation<'tcx>(
}
};

debug!("fulfill_obligation: selection={:?}", selection);
debug!(?selection);

// Currently, we use a fulfillment context to completely resolve
// all nested obligations. This is because they can inform the
// inference of the impl's type parameters.
let mut fulfill_cx = FulfillmentContext::new();
let impl_source = selection.map(|predicate| {
debug!("fulfill_obligation: register_predicate_obligation {:?}", predicate);
fulfill_cx.register_predicate_obligation(&infcx, predicate);
});
let impl_source = drain_fulfillment_cx_or_panic(&infcx, &mut fulfill_cx, impl_source);

// There should be no opaque types during codegen, they all get revealed.
let opaque_types = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
if !opaque_types.is_empty() {
bug!("{:#?}", opaque_types);
}
// Opaque types may have gotten their hidden types constrained, but we can ignore them safely
// as they will get constrained elsewhere, too.
let _opaque_types = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();

debug!("Cache miss: {:?} => {:?}", trait_ref, impl_source);
debug!("Cache miss: {trait_ref:?} => {impl_source:?}");
Ok(&*tcx.arena.alloc(impl_source))
})
}
Expand Down
15 changes: 9 additions & 6 deletions library/alloc/src/vec/into_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use core::iter::{
FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccessNoCoerce,
};
use core::marker::PhantomData;
use core::mem::{self};
use core::mem::{self, ManuallyDrop};
use core::ops::Deref;
use core::ptr::{self, NonNull};
use core::slice::{self};

Expand All @@ -32,7 +33,9 @@ pub struct IntoIter<
pub(super) buf: NonNull<T>,
pub(super) phantom: PhantomData<T>,
pub(super) cap: usize,
pub(super) alloc: A,
// the drop impl reconstructs a RawVec from buf, cap and alloc
// to avoid dropping the allocator twice we need to wrap it into ManuallyDrop
pub(super) alloc: ManuallyDrop<A>,
pub(super) ptr: *const T,
pub(super) end: *const T,
}
Expand Down Expand Up @@ -295,11 +298,11 @@ where
impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> {
#[cfg(not(test))]
fn clone(&self) -> Self {
self.as_slice().to_vec_in(self.alloc.clone()).into_iter()
self.as_slice().to_vec_in(self.alloc.deref().clone()).into_iter()
}
#[cfg(test)]
fn clone(&self) -> Self {
crate::slice::to_vec(self.as_slice(), self.alloc.clone()).into_iter()
crate::slice::to_vec(self.as_slice(), self.alloc.deref().clone()).into_iter()
}
}

Expand All @@ -311,8 +314,8 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter<T, A> {
impl<T, A: Allocator> Drop for DropGuard<'_, T, A> {
fn drop(&mut self) {
unsafe {
// `IntoIter::alloc` is not used anymore after this
let alloc = ptr::read(&self.0.alloc);
// `IntoIter::alloc` is not used anymore after this and will be dropped by RawVec
let alloc = ManuallyDrop::take(&mut self.0.alloc);
// RawVec handles deallocation
let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc);
}
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2579,7 +2579,7 @@ impl<T, A: Allocator> IntoIterator for Vec<T, A> {
fn into_iter(self) -> IntoIter<T, A> {
unsafe {
let mut me = ManuallyDrop::new(self);
let alloc = ptr::read(me.allocator());
let alloc = ManuallyDrop::new(ptr::read(me.allocator()));
let begin = me.as_mut_ptr();
let end = if mem::size_of::<T>() == 0 {
arith_offset(begin as *const i8, me.len() as isize) as *const T
Expand Down
28 changes: 28 additions & 0 deletions library/alloc/tests/vec.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use core::alloc::{Allocator, Layout};
use core::ptr::NonNull;
use std::alloc::System;
use std::assert_matches::assert_matches;
use std::borrow::Cow;
use std::cell::Cell;
Expand Down Expand Up @@ -991,6 +994,31 @@ fn test_into_iter_advance_by() {
assert_eq!(i.len(), 0);
}

#[test]
fn test_into_iter_drop_allocator() {
struct ReferenceCountedAllocator<'a>(DropCounter<'a>);

unsafe impl Allocator for ReferenceCountedAllocator<'_> {
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, core::alloc::AllocError> {
System.allocate(layout)
}

unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
System.deallocate(ptr, layout)
}
}

let mut drop_count = 0;

let allocator = ReferenceCountedAllocator(DropCounter { count: &mut drop_count });
let _ = Vec::<u32, _>::new_in(allocator);
assert_eq!(drop_count, 1);

let allocator = ReferenceCountedAllocator(DropCounter { count: &mut drop_count });
let _ = Vec::<u32, _>::new_in(allocator).into_iter();
assert_eq!(drop_count, 2);
}

#[test]
fn test_from_iter_specialization() {
let src: Vec<usize> = vec![0usize; 1];
Expand Down
Loading