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 #120364

Closed
wants to merge 21 commits into from
Closed
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
cce93f0
Add `str::Lines::remainder`
WaffleLapkin Jan 30, 2023
ac39d3c
Stabilize `slice_group_by`
niklasf Nov 7, 2023
c3a8237
Improve slice_group_by doc wording
niklasf Nov 17, 2023
42afefa
Initial implementation of `str::from_raw_parts[_mut]`
Sky9x Dec 31, 2023
c824399
Fix broken markdown in csky-unknown-linux-gnuabiv2.md
mbrubeck Jan 4, 2024
1b9a013
specialize `Bytes` on `StdinLock<'_>` by using the underlying `BufRea…
AldanTanneo Jan 17, 2024
8c2ae80
Don't manually resolve async closures in rustc_resolve
compiler-errors Jan 24, 2024
886108b
Add feature gate
Nadrieril Jan 8, 2024
95a14d4
Implement feature gate logic
Nadrieril Jan 18, 2024
8866449
Split assembly tests for ELF and MachO
nikic Jan 19, 2024
27717db
Builtin macros effectively have implicit #[collapse_debuginfo(yes)] a…
azhogin Jan 21, 2024
f94a942
Export core::str::from_raw_parts{,_mut} into alloc::str and std::str
dtolnay Jan 26, 2024
9450e2f
Rollup merge of #107464 - WaffleLapkin:all_that_remains_of_lines, r=d…
matthiaskrgr Jan 26, 2024
7749e49
Rollup merge of #117678 - niklasf:stabilize-slice_group_by, r=dtolnay
matthiaskrgr Jan 26, 2024
2a41d8b
Rollup merge of #118803 - Nadrieril:min-exhaustive-patterns, r=compil…
matthiaskrgr Jan 26, 2024
93d27fa
Rollup merge of #119466 - Sky9x:str_from_raw_parts, r=dtolnay
matthiaskrgr Jan 26, 2024
d894ea1
Rollup merge of #120053 - AldanTanneo:specialize-stdinlock-bytes, r=t…
matthiaskrgr Jan 26, 2024
86031a0
Rollup merge of #120124 - nikic:fix-assembly-test, r=davidtwco
matthiaskrgr Jan 26, 2024
5fbd7fa
Rollup merge of #120204 - azhogin:azhogin/collapse_debuginfo_for_buil…
matthiaskrgr Jan 26, 2024
0e1097e
Rollup merge of #120322 - compiler-errors:higher-ranked-async-closure…
matthiaskrgr Jan 26, 2024
451d588
Rollup merge of #120356 - mbrubeck:patch-2, r=ehuss
matthiaskrgr Jan 26, 2024
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
8 changes: 7 additions & 1 deletion compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,9 +796,15 @@ impl SyntaxExtension {
/// | external | no | if-ext | if-ext | yes |
/// | yes | yes | yes | yes | yes |
fn get_collapse_debuginfo(sess: &Session, attrs: &[ast::Attribute], is_local: bool) -> bool {
let collapse_debuginfo_attr = attr::find_by_name(attrs, sym::collapse_debuginfo)
let mut collapse_debuginfo_attr = attr::find_by_name(attrs, sym::collapse_debuginfo)
.map(|v| Self::collapse_debuginfo_by_name(sess, v))
.unwrap_or(CollapseMacroDebuginfo::Unspecified);
if collapse_debuginfo_attr == CollapseMacroDebuginfo::Unspecified
&& attr::contains_name(attrs, sym::rustc_builtin_macro)
{
collapse_debuginfo_attr = CollapseMacroDebuginfo::Yes;
}

let flag = sess.opts.unstable_opts.collapse_macro_debuginfo;
let attr = collapse_debuginfo_attr;
let ext = !is_local;
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,9 @@ declare_features! (
(unstable, macro_metavar_expr, "1.61.0", Some(83527)),
/// Allows `#[marker]` on certain traits allowing overlapping implementations.
(unstable, marker_trait_attr, "1.30.0", Some(29864)),
/// Allows exhaustive pattern matching on types that contain uninhabited types in cases that are
/// unambiguously sound.
(incomplete, min_exhaustive_patterns, "CURRENT_RUSTC_VERSION", Some(119612)),
/// A minimal, sound subset of specialization intended to be used by the
/// standard library until the soundness issues with specialization
/// are fixed.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_pattern_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ pub trait TypeCx: Sized + fmt::Debug {
type PatData: Clone;

fn is_exhaustive_patterns_feature_on(&self) -> bool;
fn is_min_exhaustive_patterns_feature_on(&self) -> bool;

/// The number of fields for this constructor.
fn ctor_arity(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> usize;
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_pattern_analysis/src/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
// `field.ty()` doesn't normalize after substituting.
let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
let is_uninhabited = cx.tcx.features().exhaustive_patterns && cx.is_uninhabited(ty);
let is_uninhabited = (cx.tcx.features().exhaustive_patterns
|| cx.tcx.features().min_exhaustive_patterns)
&& cx.is_uninhabited(ty);

if is_uninhabited && (!is_visible || is_non_exhaustive) {
None
Expand Down Expand Up @@ -863,6 +865,9 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
fn is_exhaustive_patterns_feature_on(&self) -> bool {
self.tcx.features().exhaustive_patterns
}
fn is_min_exhaustive_patterns_feature_on(&self) -> bool {
self.tcx.features().min_exhaustive_patterns
}

fn ctor_arity(&self, ctor: &crate::constructor::Constructor<Self>, ty: &Self::Ty) -> usize {
self.ctor_arity(ctor, *ty)
Expand Down
26 changes: 17 additions & 9 deletions compiler/rustc_pattern_analysis/src/usefulness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,11 +548,12 @@
//! [`ValidityConstraint::specialize`].
//!
//! Having said all that, in practice we don't fully follow what's been presented in this section.
//! Under `exhaustive_patterns`, we allow omitting empty arms even in `!known_valid` places, for
//! backwards-compatibility until we have a better alternative. Without `exhaustive_patterns`, we
//! mostly treat empty types as inhabited, except specifically a non-nested `!` or empty enum. In
//! this specific case we also allow the empty match regardless of place validity, for
//! backwards-compatibility. Hopefully we can eventually deprecate this.
//! Let's call "toplevel exception" the case where the match scrutinee itself has type `!` or
//! `EmptyEnum`. First, on stable rust, we require `_` patterns for empty types in all cases apart
//! from the toplevel exception. The `exhaustive_patterns` and `min_exaustive_patterns` allow
//! omitting patterns in the cases described above. There's a final detail: in the toplevel
//! exception or with the `exhaustive_patterns` feature, we ignore place validity when checking
//! whether a pattern is required for exhaustiveness. I (Nadrieril) hope to deprecate this behavior.
//!
//!
//!
Expand Down Expand Up @@ -1442,10 +1443,17 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
// We treat match scrutinees of type `!` or `EmptyEnum` differently.
let is_toplevel_exception =
is_top_level && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
// Whether empty patterns can be omitted for exhaustiveness.
let can_omit_empty_arms = is_toplevel_exception || mcx.tycx.is_exhaustive_patterns_feature_on();
// Whether empty patterns are counted as useful or not.
let empty_arms_are_unreachable = place_validity.is_known_valid() && can_omit_empty_arms;
// Whether empty patterns are counted as useful or not. We only warn an empty arm unreachable if
// it is guaranteed unreachable by the opsem (i.e. if the place is `known_valid`).
let empty_arms_are_unreachable = place_validity.is_known_valid()
&& (is_toplevel_exception
|| mcx.tycx.is_exhaustive_patterns_feature_on()
|| mcx.tycx.is_min_exhaustive_patterns_feature_on());
// Whether empty patterns can be omitted for exhaustiveness. We ignore place validity in the
// toplevel exception and `exhaustive_patterns` cases for backwards compatibility.
let can_omit_empty_arms = empty_arms_are_unreachable
|| is_toplevel_exception
|| mcx.tycx.is_exhaustive_patterns_feature_on();

// Analyze the constructors present in this column.
let ctors = matrix.heads().map(|p| p.ctor());
Expand Down
29 changes: 0 additions & 29 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4424,35 +4424,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
ExprKind::Type(ref _type_expr, ref _ty) => {
visit::walk_expr(self, expr);
}
// `async |x| ...` gets desugared to `|x| async {...}`, so we need to
// resolve the arguments within the proper scopes so that usages of them inside the
// closure are detected as upvars rather than normal closure arg usages.
//
// Similarly, `gen |x| ...` gets desugared to `|x| gen {...}`, so we handle that too.
ExprKind::Closure(box ast::Closure {
coroutine_kind: Some(_),
ref fn_decl,
ref body,
..
}) => {
self.with_rib(ValueNS, RibKind::Normal, |this| {
this.with_label_rib(RibKind::FnOrCoroutine, |this| {
// Resolve arguments:
this.resolve_params(&fn_decl.inputs);
// No need to resolve return type --
// the outer closure return type is `FnRetTy::Default`.

// Now resolve the inner closure
{
// No need to resolve arguments: the inner closure has none.
// Resolve the return type:
visit::walk_fn_ret_ty(this, &fn_decl.output);
// Resolve the body
this.visit_expr(body);
}
})
});
}
// For closures, RibKind::FnOrCoroutine is added in visit_fn
ExprKind::Closure(box ast::Closure {
binder: ClosureBinder::For { ref generic_params, span },
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,7 @@ symbols! {
min_const_fn,
min_const_generics,
min_const_unsafe_fn,
min_exhaustive_patterns,
min_specialization,
min_type_alias_impl_trait,
minnumf32,
Expand Down
1 change: 0 additions & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@
#![feature(set_ptr_value)]
#![feature(sized_type_properties)]
#![feature(slice_from_ptr_range)]
#![feature(slice_group_by)]
#![feature(slice_ptr_get)]
#![feature(slice_ptr_len)]
#![feature(slice_range)]
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ pub use core::slice::{from_mut, from_ref};
pub use core::slice::{from_mut_ptr_range, from_ptr_range};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
pub use core::slice::{ChunkBy, ChunkByMut};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{Chunks, Windows};
#[stable(feature = "chunks_exact", since = "1.31.0")]
pub use core::slice::{ChunksExact, ChunksExactMut};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{ChunksMut, Split, SplitMut};
#[unstable(feature = "slice_group_by", issue = "80552")]
pub use core::slice::{GroupBy, GroupByMut};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{Iter, IterMut};
#[stable(feature = "rchunks", since = "1.31.0")]
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub use core::str::SplitAsciiWhitespace;
pub use core::str::SplitInclusive;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::SplitWhitespace;
#[unstable(feature = "str_from_raw_parts", issue = "119206")]
pub use core::str::{from_raw_parts, from_raw_parts_mut};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{from_utf8, from_utf8_mut, Bytes, CharIndices, Chars};
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
1 change: 0 additions & 1 deletion library/alloc/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#![feature(iter_advance_by)]
#![feature(iter_next_chunk)]
#![feature(round_char_boundary)]
#![feature(slice_group_by)]
#![feature(slice_partition_dedup)]
#![feature(string_remove_matches)]
#![feature(const_btree_len)]
Expand Down
16 changes: 8 additions & 8 deletions library/alloc/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1614,26 +1614,26 @@ fn subslice_patterns() {
}

#[test]
fn test_group_by() {
fn test_chunk_by() {
let slice = &[1, 1, 1, 3, 3, 2, 2, 2, 1, 0];

let mut iter = slice.group_by(|a, b| a == b);
let mut iter = slice.chunk_by(|a, b| a == b);
assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next(), Some(&[3, 3][..]));
assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
assert_eq!(iter.next(), Some(&[1][..]));
assert_eq!(iter.next(), Some(&[0][..]));
assert_eq!(iter.next(), None);

let mut iter = slice.group_by(|a, b| a == b);
let mut iter = slice.chunk_by(|a, b| a == b);
assert_eq!(iter.next_back(), Some(&[0][..]));
assert_eq!(iter.next_back(), Some(&[1][..]));
assert_eq!(iter.next_back(), Some(&[2, 2, 2][..]));
assert_eq!(iter.next_back(), Some(&[3, 3][..]));
assert_eq!(iter.next_back(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next_back(), None);

let mut iter = slice.group_by(|a, b| a == b);
let mut iter = slice.chunk_by(|a, b| a == b);
assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next_back(), Some(&[0][..]));
assert_eq!(iter.next(), Some(&[3, 3][..]));
Expand All @@ -1643,26 +1643,26 @@ fn test_group_by() {
}

#[test]
fn test_group_by_mut() {
fn test_chunk_by_mut() {
let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2, 1, 0];

let mut iter = slice.group_by_mut(|a, b| a == b);
let mut iter = slice.chunk_by_mut(|a, b| a == b);
assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
assert_eq!(iter.next(), Some(&mut [3, 3][..]));
assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
assert_eq!(iter.next(), Some(&mut [1][..]));
assert_eq!(iter.next(), Some(&mut [0][..]));
assert_eq!(iter.next(), None);

let mut iter = slice.group_by_mut(|a, b| a == b);
let mut iter = slice.chunk_by_mut(|a, b| a == b);
assert_eq!(iter.next_back(), Some(&mut [0][..]));
assert_eq!(iter.next_back(), Some(&mut [1][..]));
assert_eq!(iter.next_back(), Some(&mut [2, 2, 2][..]));
assert_eq!(iter.next_back(), Some(&mut [3, 3][..]));
assert_eq!(iter.next_back(), Some(&mut [1, 1, 1][..]));
assert_eq!(iter.next_back(), None);

let mut iter = slice.group_by_mut(|a, b| a == b);
let mut iter = slice.chunk_by_mut(|a, b| a == b);
assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
assert_eq!(iter.next_back(), Some(&mut [0][..]));
assert_eq!(iter.next(), Some(&mut [3, 3][..]));
Expand Down
64 changes: 32 additions & 32 deletions library/core/src/slice/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3248,26 +3248,26 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for IterMut<'a, T> {

/// An iterator over slice in (non-overlapping) chunks separated by a predicate.
///
/// This struct is created by the [`group_by`] method on [slices].
/// This struct is created by the [`chunk_by`] method on [slices].
///
/// [`group_by`]: slice::group_by
/// [`chunk_by`]: slice::chunk_by
/// [slices]: slice
#[unstable(feature = "slice_group_by", issue = "80552")]
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct GroupBy<'a, T: 'a, P> {
pub struct ChunkBy<'a, T: 'a, P> {
slice: &'a [T],
predicate: P,
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> GroupBy<'a, T, P> {
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> ChunkBy<'a, T, P> {
pub(super) fn new(slice: &'a [T], predicate: P) -> Self {
GroupBy { slice, predicate }
ChunkBy { slice, predicate }
}
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> Iterator for GroupBy<'a, T, P>
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> Iterator for ChunkBy<'a, T, P>
where
P: FnMut(&T, &T) -> bool,
{
Expand Down Expand Up @@ -3300,8 +3300,8 @@ where
}
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> DoubleEndedIterator for GroupBy<'a, T, P>
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> DoubleEndedIterator for ChunkBy<'a, T, P>
where
P: FnMut(&T, &T) -> bool,
{
Expand All @@ -3322,39 +3322,39 @@ where
}
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> FusedIterator for GroupBy<'a, T, P> where P: FnMut(&T, &T) -> bool {}
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> FusedIterator for ChunkBy<'a, T, P> where P: FnMut(&T, &T) -> bool {}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for GroupBy<'a, T, P> {
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkBy<'a, T, P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("GroupBy").field("slice", &self.slice).finish()
f.debug_struct("ChunkBy").field("slice", &self.slice).finish()
}
}

/// An iterator over slice in (non-overlapping) mutable chunks separated
/// by a predicate.
///
/// This struct is created by the [`group_by_mut`] method on [slices].
/// This struct is created by the [`chunk_by_mut`] method on [slices].
///
/// [`group_by_mut`]: slice::group_by_mut
/// [`chunk_by_mut`]: slice::chunk_by_mut
/// [slices]: slice
#[unstable(feature = "slice_group_by", issue = "80552")]
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct GroupByMut<'a, T: 'a, P> {
pub struct ChunkByMut<'a, T: 'a, P> {
slice: &'a mut [T],
predicate: P,
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> GroupByMut<'a, T, P> {
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> ChunkByMut<'a, T, P> {
pub(super) fn new(slice: &'a mut [T], predicate: P) -> Self {
GroupByMut { slice, predicate }
ChunkByMut { slice, predicate }
}
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> Iterator for GroupByMut<'a, T, P>
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> Iterator for ChunkByMut<'a, T, P>
where
P: FnMut(&T, &T) -> bool,
{
Expand Down Expand Up @@ -3388,8 +3388,8 @@ where
}
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> DoubleEndedIterator for GroupByMut<'a, T, P>
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> DoubleEndedIterator for ChunkByMut<'a, T, P>
where
P: FnMut(&T, &T) -> bool,
{
Expand All @@ -3411,12 +3411,12 @@ where
}
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> FusedIterator for GroupByMut<'a, T, P> where P: FnMut(&T, &T) -> bool {}
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> FusedIterator for ChunkByMut<'a, T, P> where P: FnMut(&T, &T) -> bool {}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for GroupByMut<'a, T, P> {
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkByMut<'a, T, P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("GroupByMut").field("slice", &self.slice).finish()
f.debug_struct("ChunkByMut").field("slice", &self.slice).finish()
}
}
Loading
Loading