Skip to content

Commit 288931b

Browse files
authored
Merge pull request #4288 from rust-lang/rustup-2025-04-23
Automatic Rustup
2 parents 5d6c6e0 + f356f2f commit 288931b

File tree

84 files changed

+853
-271
lines changed

Some content is hidden

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

84 files changed

+853
-271
lines changed

compiler/rustc_builtin_macros/src/autodiff.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,14 +217,12 @@ mod llvm_enzyme {
217217
ast::StmtKind::Item(iitem) => extract_item_info(iitem),
218218
_ => None,
219219
},
220-
Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => {
221-
match &assoc_item.kind {
222-
ast::AssocItemKind::Fn(box ast::Fn { sig, ident, .. }) => {
223-
Some((assoc_item.vis.clone(), sig.clone(), ident.clone()))
224-
}
225-
_ => None,
220+
Annotatable::AssocItem(assoc_item, Impl { .. }) => match &assoc_item.kind {
221+
ast::AssocItemKind::Fn(box ast::Fn { sig, ident, .. }) => {
222+
Some((assoc_item.vis.clone(), sig.clone(), ident.clone()))
226223
}
227-
}
224+
_ => None,
225+
},
228226
_ => None,
229227
}) else {
230228
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
@@ -365,7 +363,7 @@ mod llvm_enzyme {
365363
}
366364
Annotatable::Item(iitem.clone())
367365
}
368-
Annotatable::AssocItem(ref mut assoc_item, i @ Impl { of_trait: false }) => {
366+
Annotatable::AssocItem(ref mut assoc_item, i @ Impl { .. }) => {
369367
if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) {
370368
assoc_item.attrs.push(attr);
371369
}

compiler/rustc_const_eval/src/interpret/memory.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -872,8 +872,21 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
872872

873873
// # Function pointers
874874
// (both global from `alloc_map` and local from `extra_fn_ptr_map`)
875-
if self.get_fn_alloc(id).is_some() {
876-
return AllocInfo::new(Size::ZERO, Align::ONE, AllocKind::Function, Mutability::Not);
875+
if let Some(fn_val) = self.get_fn_alloc(id) {
876+
let align = match fn_val {
877+
FnVal::Instance(instance) => {
878+
// Function alignment can be set globally with the `-Zmin-function-alignment=<n>` flag;
879+
// the alignment from a `#[repr(align(<n>))]` is used if it specifies a higher alignment.
880+
let fn_align = self.tcx.codegen_fn_attrs(instance.def_id()).alignment;
881+
let global_align = self.tcx.sess.opts.unstable_opts.min_function_alignment;
882+
883+
Ord::max(global_align, fn_align).unwrap_or(Align::ONE)
884+
}
885+
// Machine-specific extra functions currently do not support alignment restrictions.
886+
FnVal::Other(_) => Align::ONE,
887+
};
888+
889+
return AllocInfo::new(Size::ZERO, align, AllocKind::Function, Mutability::Not);
877890
}
878891

879892
// # Global allocations

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3289,8 +3289,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32893289
err.multipart_suggestion(
32903290
format!("{val} is a raw pointer; try dereferencing it"),
32913291
vec![
3292-
(base.span.shrink_to_lo(), "(*".to_string()),
3293-
(base.span.shrink_to_hi(), ")".to_string()),
3292+
(base.span.shrink_to_lo(), "(*".into()),
3293+
(base.span.between(field.span), format!(").")),
32943294
],
32953295
Applicability::MaybeIncorrect,
32963296
);

compiler/rustc_parse/messages.ftl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,9 @@ parse_expected_struct_field = expected one of `,`, `:`, or `{"}"}`, found `{$tok
246246
247247
parse_expected_trait_in_trait_impl_found_type = expected a trait, found type
248248
249-
parse_expr_rarrow_call = `->` used for field access or method call
249+
parse_expr_rarrow_call = `->` is not valid syntax for field accesses and method calls
250250
.suggestion = try using `.` instead
251-
.help = the `.` operator will dereference the value if needed
251+
.help = the `.` operator will automatically dereference the value, except if the value is a raw pointer
252252
253253
parse_extern_crate_name_with_dashes = crate name using dashes are not valid in `extern crate` statements
254254
.label = dash-separated idents are not valid

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 67 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use rustc_macros::Subdiagnostic;
2626
use rustc_session::errors::{ExprParenthesesNeeded, report_lit_error};
2727
use rustc_session::lint::BuiltinLintDiag;
2828
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
29+
use rustc_span::edition::Edition;
2930
use rustc_span::source_map::{self, Spanned};
3031
use rustc_span::{BytePos, ErrorGuaranteed, Ident, Pos, Span, Symbol, kw, sym};
3132
use thin_vec::{ThinVec, thin_vec};
@@ -2145,6 +2146,17 @@ impl<'a> Parser<'a> {
21452146
/// Keep this in sync with `Token::can_begin_literal_maybe_minus` and
21462147
/// `Lit::from_token` (excluding unary negation).
21472148
fn eat_token_lit(&mut self) -> Option<token::Lit> {
2149+
let check_expr = |expr: P<Expr>| {
2150+
if let ast::ExprKind::Lit(token_lit) = expr.kind {
2151+
Some(token_lit)
2152+
} else if let ast::ExprKind::Unary(UnOp::Neg, inner) = &expr.kind
2153+
&& let ast::Expr { kind: ast::ExprKind::Lit(_), .. } = **inner
2154+
{
2155+
None
2156+
} else {
2157+
panic!("unexpected reparsed expr/literal: {:?}", expr.kind);
2158+
}
2159+
};
21482160
match self.token.uninterpolate().kind {
21492161
token::Ident(name, IdentIsRaw::No) if name.is_bool_lit() => {
21502162
self.bump();
@@ -2158,26 +2170,15 @@ impl<'a> Parser<'a> {
21582170
let lit = self
21592171
.eat_metavar_seq(MetaVarKind::Literal, |this| this.parse_literal_maybe_minus())
21602172
.expect("metavar seq literal");
2161-
let ast::ExprKind::Lit(token_lit) = lit.kind else {
2162-
panic!("didn't reparse a literal");
2163-
};
2164-
Some(token_lit)
2173+
check_expr(lit)
21652174
}
21662175
token::OpenInvisible(InvisibleOrigin::MetaVar(
21672176
mv_kind @ MetaVarKind::Expr { can_begin_literal_maybe_minus: true, .. },
21682177
)) => {
21692178
let expr = self
21702179
.eat_metavar_seq(mv_kind, |this| this.parse_expr())
21712180
.expect("metavar seq expr");
2172-
if let ast::ExprKind::Lit(token_lit) = expr.kind {
2173-
Some(token_lit)
2174-
} else if let ast::ExprKind::Unary(UnOp::Neg, inner) = &expr.kind
2175-
&& let ast::Expr { kind: ast::ExprKind::Lit(_), .. } = **inner
2176-
{
2177-
None
2178-
} else {
2179-
panic!("unexpected reparsed expr: {:?}", expr.kind);
2180-
}
2181+
check_expr(expr)
21812182
}
21822183
_ => None,
21832184
}
@@ -2602,7 +2603,10 @@ impl<'a> Parser<'a> {
26022603
/// Parses an `if` expression (`if` token already eaten).
26032604
fn parse_expr_if(&mut self) -> PResult<'a, P<Expr>> {
26042605
let lo = self.prev_token.span;
2605-
let cond = self.parse_expr_cond()?;
2606+
// Scoping code checks the top level edition of the `if`; let's match it here.
2607+
// The `CondChecker` also checks the edition of the `let` itself, just to make sure.
2608+
let let_chains_policy = LetChainsPolicy::EditionDependent { current_edition: lo.edition() };
2609+
let cond = self.parse_expr_cond(let_chains_policy)?;
26062610
self.parse_if_after_cond(lo, cond)
26072611
}
26082612

@@ -2711,18 +2715,17 @@ impl<'a> Parser<'a> {
27112715
}
27122716

27132717
/// Parses the condition of a `if` or `while` expression.
2718+
///
2719+
/// The specified `edition` in `let_chains_policy` should be that of the whole `if` construct,
2720+
/// i.e. the same span we use to later decide whether the drop behaviour should be that of
2721+
/// edition `..=2021` or that of `2024..`.
27142722
// Public because it is used in rustfmt forks such as https://github.com/tucant/rustfmt/blob/30c83df9e1db10007bdd16dafce8a86b404329b2/src/parse/macros/html.rs#L57 for custom if expressions.
2715-
pub fn parse_expr_cond(&mut self) -> PResult<'a, P<Expr>> {
2723+
pub fn parse_expr_cond(&mut self, let_chains_policy: LetChainsPolicy) -> PResult<'a, P<Expr>> {
27162724
let attrs = self.parse_outer_attributes()?;
27172725
let (mut cond, _) =
27182726
self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL | Restrictions::ALLOW_LET, attrs)?;
27192727

2720-
CondChecker::new(self).visit_expr(&mut cond);
2721-
2722-
if let ExprKind::Let(_, _, _, Recovered::No) = cond.kind {
2723-
// Remove the last feature gating of a `let` expression since it's stable.
2724-
self.psess.gated_spans.ungate_last(sym::let_chains, cond.span);
2725-
}
2728+
CondChecker::new(self, let_chains_policy).visit_expr(&mut cond);
27262729

27272730
Ok(cond)
27282731
}
@@ -3017,7 +3020,8 @@ impl<'a> Parser<'a> {
30173020

30183021
/// Parses a `while` or `while let` expression (`while` token already eaten).
30193022
fn parse_expr_while(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
3020-
let cond = self.parse_expr_cond().map_err(|mut err| {
3023+
let policy = LetChainsPolicy::EditionDependent { current_edition: lo.edition() };
3024+
let cond = self.parse_expr_cond(policy).map_err(|mut err| {
30213025
err.span_label(lo, "while parsing the condition of this `while` expression");
30223026
err
30233027
})?;
@@ -3401,17 +3405,17 @@ impl<'a> Parser<'a> {
34013405
}
34023406

34033407
fn parse_match_arm_guard(&mut self) -> PResult<'a, Option<P<Expr>>> {
3404-
// Used to check the `let_chains` and `if_let_guard` features mostly by scanning
3408+
// Used to check the `if_let_guard` feature mostly by scanning
34053409
// `&&` tokens.
3406-
fn check_let_expr(expr: &Expr) -> (bool, bool) {
3410+
fn has_let_expr(expr: &Expr) -> bool {
34073411
match &expr.kind {
34083412
ExprKind::Binary(BinOp { node: BinOpKind::And, .. }, lhs, rhs) => {
3409-
let lhs_rslt = check_let_expr(lhs);
3410-
let rhs_rslt = check_let_expr(rhs);
3411-
(lhs_rslt.0 || rhs_rslt.0, false)
3413+
let lhs_rslt = has_let_expr(lhs);
3414+
let rhs_rslt = has_let_expr(rhs);
3415+
lhs_rslt || rhs_rslt
34123416
}
3413-
ExprKind::Let(..) => (true, true),
3414-
_ => (false, true),
3417+
ExprKind::Let(..) => true,
3418+
_ => false,
34153419
}
34163420
}
34173421
if !self.eat_keyword(exp!(If)) {
@@ -3422,14 +3426,9 @@ impl<'a> Parser<'a> {
34223426
let if_span = self.prev_token.span;
34233427
let mut cond = self.parse_match_guard_condition()?;
34243428

3425-
CondChecker::new(self).visit_expr(&mut cond);
3429+
CondChecker::new(self, LetChainsPolicy::AlwaysAllowed).visit_expr(&mut cond);
34263430

3427-
let (has_let_expr, does_not_have_bin_op) = check_let_expr(&cond);
3428-
if has_let_expr {
3429-
if does_not_have_bin_op {
3430-
// Remove the last feature gating of a `let` expression since it's stable.
3431-
self.psess.gated_spans.ungate_last(sym::let_chains, cond.span);
3432-
}
3431+
if has_let_expr(&cond) {
34333432
let span = if_span.to(cond.span);
34343433
self.psess.gated_spans.gate(sym::if_let_guard, span);
34353434
}
@@ -3456,7 +3455,7 @@ impl<'a> Parser<'a> {
34563455
unreachable!()
34573456
};
34583457
self.psess.gated_spans.ungate_last(sym::guard_patterns, cond.span);
3459-
CondChecker::new(self).visit_expr(&mut cond);
3458+
CondChecker::new(self, LetChainsPolicy::AlwaysAllowed).visit_expr(&mut cond);
34603459
let right = self.prev_token.span;
34613460
self.dcx().emit_err(errors::ParenthesesInMatchPat {
34623461
span: vec![left, right],
@@ -4027,7 +4026,14 @@ pub(crate) enum ForbiddenLetReason {
40274026
NotSupportedParentheses(#[primary_span] Span),
40284027
}
40294028

4030-
/// Visitor to check for invalid/unstable use of `ExprKind::Let` that can't
4029+
/// Whether let chains are allowed on all editions, or it's edition dependent (allowed only on
4030+
/// 2024 and later). In case of edition dependence, specify the currently present edition.
4031+
pub enum LetChainsPolicy {
4032+
AlwaysAllowed,
4033+
EditionDependent { current_edition: Edition },
4034+
}
4035+
4036+
/// Visitor to check for invalid use of `ExprKind::Let` that can't
40314037
/// easily be caught in parsing. For example:
40324038
///
40334039
/// ```rust,ignore (example)
@@ -4038,19 +4044,29 @@ pub(crate) enum ForbiddenLetReason {
40384044
/// ```
40394045
struct CondChecker<'a> {
40404046
parser: &'a Parser<'a>,
4047+
let_chains_policy: LetChainsPolicy,
4048+
depth: u32,
40414049
forbid_let_reason: Option<ForbiddenLetReason>,
40424050
missing_let: Option<errors::MaybeMissingLet>,
40434051
comparison: Option<errors::MaybeComparison>,
40444052
}
40454053

40464054
impl<'a> CondChecker<'a> {
4047-
fn new(parser: &'a Parser<'a>) -> Self {
4048-
CondChecker { parser, forbid_let_reason: None, missing_let: None, comparison: None }
4055+
fn new(parser: &'a Parser<'a>, let_chains_policy: LetChainsPolicy) -> Self {
4056+
CondChecker {
4057+
parser,
4058+
forbid_let_reason: None,
4059+
missing_let: None,
4060+
comparison: None,
4061+
let_chains_policy,
4062+
depth: 0,
4063+
}
40494064
}
40504065
}
40514066

40524067
impl MutVisitor for CondChecker<'_> {
40534068
fn visit_expr(&mut self, e: &mut P<Expr>) {
4069+
self.depth += 1;
40544070
use ForbiddenLetReason::*;
40554071

40564072
let span = e.span;
@@ -4065,8 +4081,16 @@ impl MutVisitor for CondChecker<'_> {
40654081
comparison: self.comparison,
40664082
},
40674083
));
4068-
} else {
4069-
self.parser.psess.gated_spans.gate(sym::let_chains, span);
4084+
} else if self.depth > 1 {
4085+
// Top level `let` is always allowed; only gate chains
4086+
match self.let_chains_policy {
4087+
LetChainsPolicy::AlwaysAllowed => (),
4088+
LetChainsPolicy::EditionDependent { current_edition } => {
4089+
if !current_edition.at_least_rust_2024() || !span.at_least_rust_2024() {
4090+
self.parser.psess.gated_spans.gate(sym::let_chains, span);
4091+
}
4092+
}
4093+
}
40704094
}
40714095
}
40724096
ExprKind::Binary(Spanned { node: BinOpKind::And, .. }, _, _) => {
@@ -4168,5 +4192,6 @@ impl MutVisitor for CondChecker<'_> {
41684192
// These would forbid any let expressions they contain already.
41694193
}
41704194
}
4195+
self.depth -= 1;
41714196
}
41724197
}

library/core/src/num/f128.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ impl f128 {
145145
pub const RADIX: u32 = 2;
146146

147147
/// Number of significant digits in base 2.
148+
///
149+
/// Note that the size of the mantissa in the bitwise representation is one
150+
/// smaller than this since the leading 1 is not stored explicitly.
148151
#[unstable(feature = "f128", issue = "116909")]
149152
pub const MANTISSA_DIGITS: u32 = 113;
150153

library/core/src/num/f16.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ impl f16 {
140140
pub const RADIX: u32 = 2;
141141

142142
/// Number of significant digits in base 2.
143+
///
144+
/// Note that the size of the mantissa in the bitwise representation is one
145+
/// smaller than this since the leading 1 is not stored explicitly.
143146
#[unstable(feature = "f16", issue = "116909")]
144147
pub const MANTISSA_DIGITS: u32 = 11;
145148

library/core/src/num/f32.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,9 @@ impl f32 {
390390
pub const RADIX: u32 = 2;
391391

392392
/// Number of significant digits in base 2.
393+
///
394+
/// Note that the size of the mantissa in the bitwise representation is one
395+
/// smaller than this since the leading 1 is not stored explicitly.
393396
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
394397
pub const MANTISSA_DIGITS: u32 = 24;
395398

library/core/src/num/f64.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,9 @@ impl f64 {
390390
pub const RADIX: u32 = 2;
391391

392392
/// Number of significant digits in base 2.
393+
///
394+
/// Note that the size of the mantissa in the bitwise representation is one
395+
/// smaller than this since the leading 1 is not stored explicitly.
393396
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
394397
pub const MANTISSA_DIGITS: u32 = 53;
395398
/// Approximate number of significant digits in base 10.

library/std/src/sys/process/unix/unix.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ impl Command {
415415
all(target_os = "linux", target_env = "musl"),
416416
target_os = "nto",
417417
target_vendor = "apple",
418+
target_os = "cygwin",
418419
)))]
419420
fn posix_spawn(
420421
&mut self,
@@ -433,6 +434,7 @@ impl Command {
433434
all(target_os = "linux", target_env = "musl"),
434435
target_os = "nto",
435436
target_vendor = "apple",
437+
target_os = "cygwin",
436438
))]
437439
fn posix_spawn(
438440
&mut self,
@@ -584,7 +586,7 @@ impl Command {
584586
/// Some platforms can set a new working directory for a spawned process in the
585587
/// `posix_spawn` path. This function looks up the function pointer for adding
586588
/// such an action to a `posix_spawn_file_actions_t` struct.
587-
#[cfg(not(all(target_os = "linux", target_env = "musl")))]
589+
#[cfg(not(any(all(target_os = "linux", target_env = "musl"), target_os = "cygwin")))]
588590
fn get_posix_spawn_addchdir() -> Option<PosixSpawnAddChdirFn> {
589591
use crate::sys::weak::weak;
590592

@@ -618,7 +620,9 @@ impl Command {
618620
/// Weak symbol lookup doesn't work with statically linked libcs, so in cases
619621
/// where static linking is possible we need to either check for the presence
620622
/// of the symbol at compile time or know about it upfront.
621-
#[cfg(all(target_os = "linux", target_env = "musl"))]
623+
///
624+
/// Cygwin doesn't support weak symbol, so just link it.
625+
#[cfg(any(all(target_os = "linux", target_env = "musl"), target_os = "cygwin"))]
622626
fn get_posix_spawn_addchdir() -> Option<PosixSpawnAddChdirFn> {
623627
// Our minimum required musl supports this function, so we can just use it.
624628
Some(libc::posix_spawn_file_actions_addchdir_np)

library/std/tests/floats/f128.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ fn test_nan() {
112112
assert!(!nan.is_sign_negative());
113113
assert!(!nan.is_normal());
114114
assert_eq!(Fp::Nan, nan.classify());
115+
// Ensure the quiet bit is set.
116+
assert!(nan.to_bits() & (1 << (f128::MANTISSA_DIGITS - 2)) != 0);
115117
}
116118

117119
#[test]

library/std/tests/floats/f16.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ fn test_nan() {
9595
assert!(!nan.is_sign_negative());
9696
assert!(!nan.is_normal());
9797
assert_eq!(Fp::Nan, nan.classify());
98+
// Ensure the quiet bit is set.
99+
assert!(nan.to_bits() & (1 << (f16::MANTISSA_DIGITS - 2)) != 0);
98100
}
99101

100102
#[test]

0 commit comments

Comments
 (0)