Skip to content

Rollup of 6 pull requests #95500

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

Closed
wants to merge 20 commits into from
Closed
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
@@ -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.
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
@@ -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,
}

29 changes: 16 additions & 13 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
@@ -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,
@@ -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 {
@@ -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(
@@ -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(
@@ -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,
)
}
14 changes: 7 additions & 7 deletions compiler/rustc_lexer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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 {
@@ -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 },
}

@@ -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 })),
8 changes: 4 additions & 4 deletions compiler/rustc_lexer/src/tests.rs
Original file line number Diff line number Diff line change
@@ -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();
@@ -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,
4 changes: 1 addition & 3 deletions compiler/rustc_parse/src/lexer/mod.rs
Original file line number Diff line number Diff line change
@@ -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
),
)
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -272,6 +272,7 @@ symbols! {
__D,
__H,
__S,
__awaitee,
__try_var,
_d,
_e,
@@ -1018,7 +1019,6 @@ symbols! {
pattern_parentheses,
phantom_data,
pin,
pinned,
platform_intrinsics,
plugin,
plugin_registrar,
19 changes: 6 additions & 13 deletions compiler/rustc_trait_selection/src/traits/codegen.rs
Original file line number Diff line number Diff line change
@@ -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>),
@@ -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.
@@ -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))
})
}
15 changes: 9 additions & 6 deletions library/alloc/src/vec/into_iter.rs
Original file line number Diff line number Diff line change
@@ -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};

@@ -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,
}
@@ -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()
}
}

@@ -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);
}
2 changes: 1 addition & 1 deletion library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
@@ -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
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;
@@ -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];
137 changes: 73 additions & 64 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
@@ -218,111 +218,120 @@
feature(slice_index_methods, coerce_unsized, sgx_platform)
)]
#![deny(rustc::existing_doc_keyword)]
// std is implemented with unstable features, many of which are internal
// compiler details that will never be stable
// NB: the following list is sorted to minimize merge conflicts.
//
// Language features:
#![feature(alloc_error_handler)]
#![feature(alloc_layout_extra)]
#![feature(allocator_api)]
#![feature(allocator_internals)]
#![feature(allow_internal_unsafe)]
#![feature(allow_internal_unstable)]
#![feature(array_error_internals)]
#![feature(assert_matches)]
#![feature(associated_type_bounds)]
#![feature(async_iterator)]
#![feature(atomic_mut_ptr)]
#![feature(bench_black_box)]
#![feature(box_syntax)]
#![feature(c_unwind)]
#![feature(c_variadic)]
#![feature(cfg_accessible)]
#![feature(cfg_eval)]
#![feature(cfg_target_thread_local)]
#![feature(char_error_internals)]
#![feature(char_internals)]
#![feature(concat_bytes)]
#![feature(concat_idents)]
#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
#![feature(const_format_args)]
#![feature(const_io_structs)]
#![feature(const_ip)]
#![feature(const_ipv4)]
#![feature(const_ipv6)]
#![feature(const_mut_refs)]
#![feature(const_option)]
#![feature(const_socketaddr)]
#![feature(const_trait_impl)]
#![feature(c_size_t)]
#![feature(core_ffi_c)]
#![feature(core_intrinsics)]
#![feature(core_panic)]
#![feature(custom_test_frameworks)]
#![feature(decl_macro)]
#![cfg_attr(not(bootstrap), feature(deprecated_suggestion))]
#![feature(doc_cfg)]
#![feature(doc_cfg_hide)]
#![feature(rustdoc_internals)]
#![cfg_attr(not(bootstrap), feature(deprecated_suggestion))]
#![feature(doc_masked)]
#![feature(doc_notable_trait)]
#![feature(dropck_eyepatch)]
#![feature(duration_checked_float)]
#![feature(duration_constants)]
#![feature(edition_panic)]
#![feature(exact_size_is_empty)]
#![feature(exhaustive_patterns)]
#![feature(extend_one)]
#![feature(float_minimum_maximum)]
#![feature(format_args_nl)]
#![feature(strict_provenance)]
#![feature(get_mut_unchecked)]
#![feature(hashmap_internals)]
#![feature(int_error_internals)]
#![feature(intra_doc_pointers)]
#![feature(lang_items)]
#![feature(linkage)]
#![feature(log_syntax)]
#![feature(map_try_insert)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_write_slice)]
#![feature(min_specialization)]
#![feature(mixed_integer_ops)]
#![feature(must_not_suspend)]
#![feature(needs_panic_runtime)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(new_uninit)]
#![feature(nll)]
#![feature(platform_intrinsics)]
#![feature(prelude_import)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(staged_api)]
#![feature(thread_local)]
#![feature(try_blocks)]
//
// Library features (core):
#![feature(array_error_internals)]
#![feature(char_error_internals)]
#![feature(char_internals)]
#![feature(core_intrinsics)]
#![feature(duration_checked_float)]
#![feature(duration_constants)]
#![feature(exact_size_is_empty)]
#![feature(extend_one)]
#![feature(float_minimum_maximum)]
#![feature(hashmap_internals)]
#![feature(int_error_internals)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_write_slice)]
#![feature(mixed_integer_ops)]
#![feature(nonnull_slice_from_raw_parts)]
#![feature(once_cell)]
#![feature(panic_can_unwind)]
#![feature(panic_info_message)]
#![feature(panic_internals)]
#![feature(panic_can_unwind)]
#![feature(panic_unwind)]
#![feature(platform_intrinsics)]
#![feature(portable_simd)]
#![feature(prelude_import)]
#![feature(ptr_as_uninit)]
#![feature(raw_os_nonzero)]
#![feature(rustc_attrs)]
#![feature(saturating_int_impl)]
#![feature(slice_internals)]
#![feature(slice_ptr_get)]
#![feature(staged_api)]
#![feature(std_internals)]
#![feature(stdsimd)]
#![feature(str_internals)]
#![feature(test)]
#![feature(thread_local)]
#![feature(thread_local_internals)]
#![feature(toowned_clone_into)]
#![feature(strict_provenance)]
#![feature(total_cmp)]
#![feature(trace_macros)]
#![feature(try_blocks)]
//
// Library features (alloc):
#![feature(alloc_layout_extra)]
#![feature(allocator_api)]
#![feature(get_mut_unchecked)]
#![feature(map_try_insert)]
#![feature(new_uninit)]
#![feature(toowned_clone_into)]
#![feature(try_reserve_kind)]
#![feature(vec_into_raw_parts)]
// NB: the above list is sorted to minimize merge conflicts.
//
// Library features (unwind):
#![feature(panic_unwind)]
//
// Only for re-exporting:
#![feature(assert_matches)]
#![feature(async_iterator)]
#![feature(c_size_t)]
#![feature(c_variadic)]
#![feature(cfg_accessible)]
#![feature(cfg_eval)]
#![feature(concat_bytes)]
#![feature(const_format_args)]
#![feature(core_ffi_c)]
#![feature(core_panic)]
#![feature(custom_test_frameworks)]
#![feature(edition_panic)]
#![feature(format_args_nl)]
#![feature(log_syntax)]
#![feature(once_cell)]
#![feature(saturating_int_impl)]
#![feature(stdsimd)]
#![feature(test)]
#![feature(trace_macros)]
//
// Only used in tests/benchmarks:
#![feature(bench_black_box)]
//
// Only for const-ness:
#![feature(const_io_structs)]
#![feature(const_ip)]
#![feature(const_ipv4)]
#![feature(const_ipv6)]
#![feature(const_option)]
#![feature(const_socketaddr)]
#![feature(thread_local_internals)]
//
#![default_lib_allocator]

// Explicitly import the prelude. The compiler uses this same unstable attribute
8 changes: 7 additions & 1 deletion src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
@@ -117,6 +117,7 @@ use std::os::unix::fs::symlink as symlink_file;
use std::os::windows::fs::symlink_file;

use filetime::FileTime;
use once_cell::sync::OnceCell;

use crate::builder::Kind;
use crate::config::{LlvmLibunwind, TargetSelection};
@@ -904,7 +905,12 @@ impl Build {

/// Returns the sysroot of the snapshot compiler.
fn rustc_snapshot_sysroot(&self) -> &Path {
self.initial_rustc.parent().unwrap().parent().unwrap()
static SYSROOT_CACHE: OnceCell<PathBuf> = once_cell::sync::OnceCell::new();
SYSROOT_CACHE.get_or_init(|| {
let mut rustc = Command::new(&self.initial_rustc);
rustc.args(&["--print", "sysroot"]);
output(&mut rustc).trim().into()
})
}

/// Runs a command, printing out nice contextual information if it fails.
23 changes: 23 additions & 0 deletions src/test/codegen/async-fn-debug-awaitee-field.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// This test makes sure that the generator field capturing the awaitee in a `.await` expression
// is called "__awaitee" in debuginfo. This name must not be changed since debuggers and debugger
// extensions rely on the field having this name.

// ignore-tidy-linelength
// compile-flags: -C debuginfo=2 --edition=2018

async fn foo() {}

async fn async_fn_test() {
foo().await;
}

// NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}",
// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
// CHECK: [[SUSPEND_STRUCT:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend0", scope: [[GEN]],
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE:![0-9]*]],
// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<async_fn_debug_awaitee_field::foo::{async_fn_env#0}>",
// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",

fn main() {
let _fn = async_fn_test();
}
24 changes: 24 additions & 0 deletions src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#![feature(type_alias_impl_trait)]

// build-pass

trait T { type Item; }

type Alias<'a> = impl T<Item = &'a ()>;

struct S;
impl<'a> T for &'a S {
type Item = &'a ();
}

fn filter_positive<'a>() -> Alias<'a> {
&S
}

fn with_positive(fun: impl Fn(Alias<'_>)) {
fun(filter_positive());
}

fn main() {
with_positive(|_| ());
}
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/regex.rs
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for Regex {

#[allow(clippy::cast_possible_truncation)] // truncation very unlikely here
#[must_use]
fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u16) -> Span {
fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u8) -> Span {
let offset = u32::from(offset);
let end = base.lo() + BytePos(u32::try_from(c.end.offset).expect("offset too large") + offset);
let start = base.lo() + BytePos(u32::try_from(c.start.offset).expect("offset too large") + offset);