Skip to content

Commit b362939

Browse files
committed
Auto merge of #120401 - matthiaskrgr:rollup-7740vrx, r=matthiaskrgr
Rollup of 12 pull requests Successful merges: - #103522 (stabilise array methods) - #113489 (impl `From<&[T; N]>` for `Cow<[T]>`) - #119342 (Emit suggestion when trying to write exclusive ranges as `..<`) - #119562 (Rename `pointer` field on `Pin`) - #119800 (Document `rustc_index::vec::IndexVec`) - #120205 (std: make `HEAP` initializer never inline) - #120277 (Normalize field types before checking validity) - #120311 (core: add `From<core::ascii::Char>` implementations) - #120366 (mark a doctest with UB as no_run) - #120378 (always normalize `LoweredTy` in the new solver) - #120382 (Classify closure arguments in refutable pattern in argument error) - #120389 (Add fmease to the compiler review rotation) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c073f56 + 6ce96c0 commit b362939

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+324
-106
lines changed

compiler/rustc_const_eval/src/transform/validate.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -810,13 +810,18 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
810810
let adt_def = self.tcx.adt_def(def_id);
811811
assert!(adt_def.is_union());
812812
assert_eq!(idx, FIRST_VARIANT);
813-
let dest = adt_def.non_enum_variant().fields[field].ty(self.tcx, args);
814-
if fields.len() != 1 {
813+
let dest_ty = self.tcx.normalize_erasing_regions(
814+
self.param_env,
815+
adt_def.non_enum_variant().fields[field].ty(self.tcx, args),
816+
);
817+
if fields.len() == 1 {
818+
let src_ty = fields.raw[0].ty(self.body, self.tcx);
819+
if !self.mir_assign_valid_types(src_ty, dest_ty) {
820+
self.fail(location, "union field has the wrong type");
821+
}
822+
} else {
815823
self.fail(location, "unions should have one initialized field");
816824
}
817-
if !self.mir_assign_valid_types(fields.raw[0].ty(self.body, self.tcx), dest) {
818-
self.fail(location, "union field has the wrong type");
819-
}
820825
}
821826
AggregateKind::Adt(def_id, idx, args, _, None) => {
822827
let adt_def = self.tcx.adt_def(def_id);
@@ -826,10 +831,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
826831
self.fail(location, "adt has the wrong number of initialized fields");
827832
}
828833
for (src, dest) in std::iter::zip(fields, &variant.fields) {
829-
if !self.mir_assign_valid_types(
830-
src.ty(self.body, self.tcx),
831-
dest.ty(self.tcx, args),
832-
) {
834+
let dest_ty = self
835+
.tcx
836+
.normalize_erasing_regions(self.param_env, dest.ty(self.tcx, args));
837+
if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest_ty) {
833838
self.fail(location, "adt field has the wrong type");
834839
}
835840
}

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,14 @@ pub struct LoweredTy<'tcx> {
369369

370370
impl<'tcx> LoweredTy<'tcx> {
371371
pub fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx> {
372-
LoweredTy { raw, normalized: fcx.normalize(span, raw) }
372+
// FIXME(-Znext-solver): We're still figuring out how to best handle
373+
// normalization and this doesn't feel too great. We should look at this
374+
// code again before stabilizing it.
375+
let normalized = if fcx.next_trait_solver() {
376+
fcx.try_structurally_resolve_type(span, raw)
377+
} else {
378+
fcx.normalize(span, raw)
379+
};
380+
LoweredTy { raw, normalized }
373381
}
374382
}

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2040,7 +2040,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20402040
let field_is_local = sole_field.did.is_local();
20412041
let field_is_accessible =
20422042
sole_field.vis.is_accessible_from(expr.hir_id.owner.def_id, self.tcx)
2043-
// Skip suggestions for unstable public fields (for example `Pin::pointer`)
2043+
// Skip suggestions for unstable public fields (for example `Pin::__pointer`)
20442044
&& matches!(self.tcx.eval_stability(sole_field.did, None, expr.span, None), EvalResult::Allow | EvalResult::Unmarked);
20452045

20462046
if !field_is_local && !field_is_accessible {

compiler/rustc_index/src/vec.rs

+7
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ use std::vec;
1212
use crate::{Idx, IndexSlice};
1313

1414
/// An owned contiguous collection of `T`s, indexed by `I` rather than by `usize`.
15+
/// Its purpose is to avoid mixing indexes.
1516
///
1617
/// While it's possible to use `u32` or `usize` directly for `I`,
1718
/// you almost certainly want to use a [`newtype_index!`]-generated type instead.
1819
///
20+
/// This allows to index the IndexVec with the new index type.
21+
///
1922
/// [`newtype_index!`]: ../macro.newtype_index.html
2023
#[derive(Clone, PartialEq, Eq, Hash)]
2124
#[repr(transparent)]
@@ -25,11 +28,13 @@ pub struct IndexVec<I: Idx, T> {
2528
}
2629

2730
impl<I: Idx, T> IndexVec<I, T> {
31+
/// Constructs a new, empty `IndexVec<I, T>`.
2832
#[inline]
2933
pub const fn new() -> Self {
3034
IndexVec::from_raw(Vec::new())
3135
}
3236

37+
/// Constructs a new `IndexVec<I, T>` from a `Vec<T>`.
3338
#[inline]
3439
pub const fn from_raw(raw: Vec<T>) -> Self {
3540
IndexVec { raw, _marker: PhantomData }
@@ -59,6 +64,7 @@ impl<I: Idx, T> IndexVec<I, T> {
5964
IndexVec::from_raw(vec![elem; universe.len()])
6065
}
6166

67+
/// Creates a new IndexVec with n copies of the `elem`.
6268
#[inline]
6369
pub fn from_elem_n(elem: T, n: usize) -> Self
6470
where
@@ -85,6 +91,7 @@ impl<I: Idx, T> IndexVec<I, T> {
8591
IndexSlice::from_raw_mut(&mut self.raw)
8692
}
8793

94+
/// Pushes an element to the array returning the index where it was pushed to.
8895
#[inline]
8996
pub fn push(&mut self, d: T) -> I {
9097
let idx = self.next_index();

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,18 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err
4747
};
4848
visitor.visit_expr(&thir[expr]);
4949

50+
let origin = match tcx.def_kind(def_id) {
51+
DefKind::AssocFn | DefKind::Fn => "function argument",
52+
DefKind::Closure => "closure argument",
53+
// other types of MIR don't have function parameters, and we don't need to
54+
// categorize those for the irrefutable check.
55+
_ if thir.params.is_empty() => "",
56+
kind => bug!("unexpected function parameters in THIR: {kind:?} {def_id:?}"),
57+
};
58+
5059
for param in thir.params.iter() {
5160
if let Some(box ref pattern) = param.pat {
52-
visitor.check_binding_is_irrefutable(pattern, "function argument", None, None);
61+
visitor.check_binding_is_irrefutable(pattern, origin, None, None);
5362
}
5463
}
5564
visitor.error

compiler/rustc_parse/src/parser/diagnostics.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::parser;
2323
use crate::parser::attr::InnerAttrPolicy;
2424
use rustc_ast as ast;
2525
use rustc_ast::ptr::P;
26-
use rustc_ast::token::{self, Delimiter, Lit, LitKind, TokenKind};
26+
use rustc_ast::token::{self, Delimiter, Lit, LitKind, Token, TokenKind};
2727
use rustc_ast::tokenstream::AttrTokenTree;
2828
use rustc_ast::util::parser::AssocOp;
2929
use rustc_ast::{
@@ -448,12 +448,11 @@ impl<'a> Parser<'a> {
448448
})
449449
}
450450

451-
let mut expected = edible
451+
self.expected_tokens.extend(edible.iter().chain(inedible).cloned().map(TokenType::Token));
452+
let mut expected = self
453+
.expected_tokens
452454
.iter()
453-
.chain(inedible)
454455
.cloned()
455-
.map(TokenType::Token)
456-
.chain(self.expected_tokens.iter().cloned())
457456
.filter(|token| {
458457
// Filter out suggestions that suggest the same token which was found and deemed incorrect.
459458
fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
@@ -2927,6 +2926,22 @@ impl<'a> Parser<'a> {
29272926
Ok(())
29282927
}
29292928

2929+
/// Check for exclusive ranges written as `..<`
2930+
pub(crate) fn maybe_err_dotdotlt_syntax(&self, maybe_lt: Token, mut err: PErr<'a>) -> PErr<'a> {
2931+
if maybe_lt == token::Lt
2932+
&& (self.expected_tokens.contains(&TokenType::Token(token::Gt))
2933+
|| matches!(self.token.kind, token::Literal(..)))
2934+
{
2935+
err.span_suggestion(
2936+
maybe_lt.span,
2937+
"remove the `<` to write an exclusive range",
2938+
"",
2939+
Applicability::MachineApplicable,
2940+
);
2941+
}
2942+
err
2943+
}
2944+
29302945
pub fn is_diff_marker(&mut self, long_kind: &TokenKind, short_kind: &TokenKind) -> bool {
29312946
(0..3).all(|i| self.look_ahead(i, |tok| tok == long_kind))
29322947
&& self.look_ahead(3, |tok| tok == short_kind)

compiler/rustc_parse/src/parser/expr.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,11 @@ impl<'a> Parser<'a> {
482482
cur_op_span: Span,
483483
) -> PResult<'a, P<Expr>> {
484484
let rhs = if self.is_at_start_of_range_notation_rhs() {
485-
Some(self.parse_expr_assoc_with(prec + 1, LhsExpr::NotYetParsed)?)
485+
let maybe_lt = self.token.clone();
486+
Some(
487+
self.parse_expr_assoc_with(prec + 1, LhsExpr::NotYetParsed)
488+
.map_err(|err| self.maybe_err_dotdotlt_syntax(maybe_lt, err))?,
489+
)
486490
} else {
487491
None
488492
};
@@ -531,11 +535,13 @@ impl<'a> Parser<'a> {
531535
let attrs = self.parse_or_use_outer_attributes(attrs)?;
532536
self.collect_tokens_for_expr(attrs, |this, attrs| {
533537
let lo = this.token.span;
538+
let maybe_lt = this.look_ahead(1, |t| t.clone());
534539
this.bump();
535540
let (span, opt_end) = if this.is_at_start_of_range_notation_rhs() {
536541
// RHS must be parsed with more associativity than the dots.
537542
this.parse_expr_assoc_with(op.unwrap().precedence() + 1, LhsExpr::NotYetParsed)
538-
.map(|x| (lo.to(x.span), Some(x)))?
543+
.map(|x| (lo.to(x.span), Some(x)))
544+
.map_err(|err| this.maybe_err_dotdotlt_syntax(maybe_lt, err))?
539545
} else {
540546
(lo, None)
541547
};

library/alloc/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@
103103
#![feature(allocator_api)]
104104
#![feature(array_chunks)]
105105
#![feature(array_into_iter_constructors)]
106-
#![feature(array_methods)]
107106
#![feature(array_windows)]
108107
#![feature(ascii_char)]
109108
#![feature(assert_matches)]

library/alloc/src/vec/cow.rs

+13
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ impl<'a, T: Clone> From<&'a [T]> for Cow<'a, [T]> {
1515
}
1616
}
1717

18+
#[stable(feature = "cow_from_array_ref", since = "CURRENT_RUSTC_VERSION")]
19+
impl<'a, T: Clone, const N: usize> From<&'a [T; N]> for Cow<'a, [T]> {
20+
/// Creates a [`Borrowed`] variant of [`Cow`]
21+
/// from a reference to an array.
22+
///
23+
/// This conversion does not allocate or clone the data.
24+
///
25+
/// [`Borrowed`]: crate::borrow::Cow::Borrowed
26+
fn from(s: &'a [T; N]) -> Cow<'a, [T]> {
27+
Cow::Borrowed(s as &[_])
28+
}
29+
}
30+
1831
#[stable(feature = "cow_from_vec", since = "1.8.0")]
1932
impl<'a, T: Clone> From<Vec<T>> for Cow<'a, [T]> {
2033
/// Creates an [`Owned`] variant of [`Cow`]

library/core/src/array/mod.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -559,8 +559,6 @@ impl<T, const N: usize> [T; N] {
559559
/// # Example
560560
///
561561
/// ```
562-
/// #![feature(array_methods)]
563-
///
564562
/// let floats = [3.1, 2.7, -1.0];
565563
/// let float_refs: [&f64; 3] = floats.each_ref();
566564
/// assert_eq!(float_refs, [&3.1, &2.7, &-1.0]);
@@ -571,16 +569,14 @@ impl<T, const N: usize> [T; N] {
571569
/// array if its elements are not [`Copy`].
572570
///
573571
/// ```
574-
/// #![feature(array_methods)]
575-
///
576572
/// let strings = ["Ferris".to_string(), "♥".to_string(), "Rust".to_string()];
577573
/// let is_ascii = strings.each_ref().map(|s| s.is_ascii());
578574
/// assert_eq!(is_ascii, [true, false, true]);
579575
///
580576
/// // We can still access the original array: it has not been moved.
581577
/// assert_eq!(strings.len(), 3);
582578
/// ```
583-
#[unstable(feature = "array_methods", issue = "76118")]
579+
#[stable(feature = "array_methods", since = "CURRENT_RUSTC_VERSION")]
584580
pub fn each_ref(&self) -> [&T; N] {
585581
from_trusted_iterator(self.iter())
586582
}
@@ -592,15 +588,14 @@ impl<T, const N: usize> [T; N] {
592588
/// # Example
593589
///
594590
/// ```
595-
/// #![feature(array_methods)]
596591
///
597592
/// let mut floats = [3.1, 2.7, -1.0];
598593
/// let float_refs: [&mut f64; 3] = floats.each_mut();
599594
/// *float_refs[0] = 0.0;
600595
/// assert_eq!(float_refs, [&mut 0.0, &mut 2.7, &mut -1.0]);
601596
/// assert_eq!(floats, [0.0, 2.7, -1.0]);
602597
/// ```
603-
#[unstable(feature = "array_methods", issue = "76118")]
598+
#[stable(feature = "array_methods", since = "CURRENT_RUSTC_VERSION")]
604599
pub fn each_mut(&mut self) -> [&mut T; N] {
605600
from_trusted_iterator(self.iter_mut())
606601
}

library/core/src/ascii/ascii_char.rs

+16
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,22 @@ impl AsciiChar {
537537
}
538538
}
539539

540+
macro_rules! into_int_impl {
541+
($($ty:ty)*) => {
542+
$(
543+
#[unstable(feature = "ascii_char", issue = "110998")]
544+
impl From<AsciiChar> for $ty {
545+
#[inline]
546+
fn from(chr: AsciiChar) -> $ty {
547+
chr as u8 as $ty
548+
}
549+
}
550+
)*
551+
}
552+
}
553+
554+
into_int_impl!(u8 u16 u32 u64 u128 char);
555+
540556
impl [AsciiChar] {
541557
/// Views this slice of ASCII characters as a UTF-8 `str`.
542558
#[unstable(feature = "ascii_char", issue = "110998")]

library/core/src/intrinsics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2531,7 +2531,7 @@ extern "rust-intrinsic" {
25312531
/// or `false`, and the caller has to ensure sound behavior for both cases.
25322532
/// In other words, the following code has *Undefined Behavior*:
25332533
///
2534-
/// ```
2534+
/// ```no_run
25352535
/// #![feature(is_val_statically_known)]
25362536
/// #![feature(core_intrinsics)]
25372537
/// # #![allow(internal_features)]

0 commit comments

Comments
 (0)