Skip to content

Commit 0072142

Browse files
authored
Merge pull request #4893 from rust-lang/rustup-2026-03-10
Automatic Rustup
2 parents d347767 + 759deb3 commit 0072142

File tree

310 files changed

+1926
-1929
lines changed

Some content is hidden

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

310 files changed

+1926
-1929
lines changed

.mailmap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ Ben Sago <ogham@users.noreply.github.com> <ogham@bsago.me>
8383
Ben Striegel <ben.striegel@gmail.com>
8484
Benjamin Jackman <ben@jackman.biz>
8585
Benoît Cortier <benoit.cortier@fried-world.eu>
86-
binarycat <binarycat@envs.net> lolbinarycat <dogedoge61+github@gmail.com> <dogedoge61@gmail.com>
86+
binarycat <binarycat@envs.net> lolbinarycat <dogedoge61+github@gmail.com>
87+
binarycat <binarycat@envs.net> lolbinarycat <dogedoge61@gmail.com>
8788
Bheesham Persaud <bheesham123@hotmail.com> Bheesham Persaud <bheesham.persaud@live.ca>
8889
bjorn3 <17426603+bjorn3@users.noreply.github.com> <bjorn3@users.noreply.github.com>
8990
bjorn3 <17426603+bjorn3@users.noreply.github.com> <bjorn3_gh@protonmail.com>

compiler/rustc_borrowck/src/diagnostics/move_errors.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -990,30 +990,25 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
990990
let bind_to = &self.body.local_decls[*local];
991991
let binding_span = bind_to.source_info.span;
992992

993-
if j == 0 {
994-
err.span_label(binding_span, "data moved here");
995-
} else {
996-
err.span_label(binding_span, "...and here");
997-
}
998-
999993
if binds_to.len() == 1 {
1000994
let place_desc = self.local_name(*local).map(|sym| format!("`{sym}`"));
1001995

996+
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::LabelMovedHere {
997+
ty: bind_to.ty,
998+
place: place_desc.as_deref().unwrap_or("the place"),
999+
span: binding_span,
1000+
});
1001+
10021002
if !desugar_spans.contains(&binding_span)
10031003
&& let Some(expr) = self.find_expr(binding_span)
10041004
{
1005-
// The binding_span doesn't correspond to a let binding desugaring
1006-
// and is an expression where calling `.clone()` would be valid.
10071005
let local_place: PlaceRef<'tcx> = (*local).into();
10081006
self.suggest_cloning(err, local_place, bind_to.ty, expr, None);
10091007
}
1010-
1011-
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
1012-
is_partial_move: false,
1013-
ty: bind_to.ty,
1014-
place: place_desc.as_deref().unwrap_or("the place"),
1015-
span: binding_span,
1016-
});
1008+
} else if j == 0 {
1009+
err.span_label(binding_span, "data moved here");
1010+
} else {
1011+
err.span_label(binding_span, "...and here");
10171012
}
10181013
}
10191014

compiler/rustc_borrowck/src/session_diagnostics.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,16 @@ pub(crate) enum TypeNoCopy<'a, 'tcx> {
570570
#[primary_span]
571571
span: Span,
572572
},
573+
#[label(
574+
"data moved here because {$place} has type `{$ty}`, which does not implement the `Copy` \
575+
trait"
576+
)]
577+
LabelMovedHere {
578+
ty: Ty<'tcx>,
579+
place: &'a str,
580+
#[primary_span]
581+
span: Span,
582+
},
573583
#[note(
574584
"{$is_partial_move ->
575585
[true] partial move

compiler/rustc_const_eval/src/interpret/call.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_hir::find_attr;
1212
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
1313
use rustc_middle::ty::{self, AdtDef, Instance, Ty, VariantDef};
1414
use rustc_middle::{bug, mir, span_bug};
15-
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
15+
use rustc_target::callconv::{ArgAbi, FnAbi};
1616
use tracing::field::Empty;
1717
use tracing::{info, instrument, trace};
1818

@@ -284,7 +284,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
284284
'tcx: 'y,
285285
{
286286
assert_eq!(callee_ty, callee_abi.layout.ty);
287-
if callee_abi.mode == PassMode::Ignore {
287+
if callee_abi.is_ignore() {
288288
// This one is skipped. Still must be made live though!
289289
if !already_live {
290290
self.storage_live(callee_arg.as_local().unwrap())?;
@@ -450,7 +450,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
450450
let mut caller_args = args
451451
.iter()
452452
.zip(caller_fn_abi.args.iter())
453-
.filter(|arg_and_abi| !matches!(arg_and_abi.1.mode, PassMode::Ignore));
453+
.filter(|arg_and_abi| !arg_and_abi.1.is_ignore());
454454

455455
// Now we have to spread them out across the callee's locals,
456456
// taking into account the `spread_arg`. If we could write
@@ -480,7 +480,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
480480

481481
// Consume the remaining arguments by putting them into the variable argument
482482
// list.
483-
let varargs = self.allocate_varargs(&mut caller_args, &mut callee_args_abis)?;
483+
let varargs = self.allocate_varargs(
484+
&mut caller_args,
485+
// "Ignored" arguments aren't actually passed, so the callee should also
486+
// ignore them. (`pass_argument` does this for regular arguments.)
487+
(&mut callee_args_abis).filter(|(_, abi)| !abi.is_ignore()),
488+
)?;
484489
// When the frame is dropped, these variable arguments are deallocated.
485490
self.frame_mut().va_list = varargs.clone();
486491
let key = self.va_list_ptr(varargs.into());

compiler/rustc_const_eval/src/interpret/stack.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,8 +631,8 @@ impl<'a, 'tcx: 'a, M: Machine<'tcx>> InterpCx<'tcx, M> {
631631
/// of variadic arguments. Return a list of the places that hold those arguments.
632632
pub(crate) fn allocate_varargs<I, J>(
633633
&mut self,
634-
caller_args: &mut I,
635-
callee_abis: &mut J,
634+
caller_args: I,
635+
mut callee_abis: J,
636636
) -> InterpResult<'tcx, Vec<MPlaceTy<'tcx, M::Provenance>>>
637637
where
638638
I: Iterator<Item = (&'a FnArg<'tcx, M::Provenance>, &'a ArgAbi<'tcx, Ty<'tcx>>)>,

compiler/rustc_const_eval/src/interpret/validity.rs

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use std::borrow::Cow;
88
use std::fmt::Write;
99
use std::hash::Hash;
10+
use std::mem;
1011
use std::num::NonZero;
1112

1213
use either::{Left, Right};
@@ -288,6 +289,8 @@ struct ValidityVisitor<'rt, 'tcx, M: Machine<'tcx>> {
288289
/// If this is `Some`, then `reset_provenance_and_padding` must be true (but not vice versa:
289290
/// we might not track data vs padding bytes if the operand isn't stored in memory anyway).
290291
data_bytes: Option<RangeSet>,
292+
/// True if we are inside of `MaybeDangling`. This disables pointer access checks.
293+
may_dangle: bool,
291294
}
292295

293296
impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
@@ -489,7 +492,8 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
489492
if place.layout.is_unsized() {
490493
self.check_wide_ptr_meta(place.meta(), place.layout)?;
491494
}
492-
// Make sure this is dereferenceable and all.
495+
496+
// Determine size and alignment of pointee.
493497
let size_and_align = try_validation!(
494498
self.ecx.size_and_align_of_val(&place),
495499
self.path,
@@ -503,27 +507,33 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
503507
// alignment and size determined by the layout (size will be 0,
504508
// alignment should take attributes into account).
505509
.unwrap_or_else(|| (place.layout.size, place.layout.align.abi));
506-
// Direct call to `check_ptr_access_align` checks alignment even on CTFE machines.
507-
try_validation!(
508-
self.ecx.check_ptr_access(
509-
place.ptr(),
510-
size,
511-
CheckInAllocMsg::Dereferenceable, // will anyway be replaced by validity message
512-
),
513-
self.path,
514-
Ub(DanglingIntPointer { addr: 0, .. }) => NullPtr { ptr_kind, maybe: false },
515-
Ub(DanglingIntPointer { addr: i, .. }) => DanglingPtrNoProvenance {
516-
ptr_kind,
517-
// FIXME this says "null pointer" when null but we need translate
518-
pointer: format!("{}", Pointer::<Option<AllocId>>::without_provenance(i))
519-
},
520-
Ub(PointerOutOfBounds { .. }) => DanglingPtrOutOfBounds {
521-
ptr_kind
522-
},
523-
Ub(PointerUseAfterFree(..)) => DanglingPtrUseAfterFree {
524-
ptr_kind,
525-
},
526-
);
510+
511+
if !self.may_dangle {
512+
// Make sure this is dereferenceable and all.
513+
514+
// Direct call to `check_ptr_access_align` checks alignment even on CTFE machines.
515+
// Call `check_ptr_access` to avoid checking alignment here.
516+
try_validation!(
517+
self.ecx.check_ptr_access(
518+
place.ptr(),
519+
size,
520+
CheckInAllocMsg::Dereferenceable, // will anyway be replaced by validity message
521+
),
522+
self.path,
523+
Ub(DanglingIntPointer { addr: 0, .. }) => NullPtr { ptr_kind, maybe: false },
524+
Ub(DanglingIntPointer { addr: i, .. }) => DanglingPtrNoProvenance {
525+
ptr_kind,
526+
pointer: format!("{}", Pointer::<Option<AllocId>>::without_provenance(i))
527+
},
528+
Ub(PointerOutOfBounds { .. }) => DanglingPtrOutOfBounds {
529+
ptr_kind
530+
},
531+
Ub(PointerUseAfterFree(..)) => DanglingPtrUseAfterFree {
532+
ptr_kind,
533+
},
534+
);
535+
}
536+
527537
try_validation!(
528538
self.ecx.check_ptr_align(
529539
place.ptr(),
@@ -536,8 +546,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
536546
found_bytes: has.bytes()
537547
},
538548
);
539-
// Make sure this is non-null. We checked dereferenceability above, but if `size` is zero
540-
// that does not imply non-null.
549+
550+
// Make sure this is non-null. This is obviously needed when `may_dangle` is set,
551+
// but even if we did check dereferenceability above that would still allow null
552+
// pointers if `size` is zero.
541553
let scalar = Scalar::from_maybe_pointer(place.ptr(), self.ecx);
542554
if self.ecx.scalar_may_be_null(scalar)? {
543555
let maybe = !M::Provenance::OFFSET_IS_ADDR && matches!(scalar, Scalar::Ptr(..));
@@ -1265,6 +1277,14 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
12651277
ty::PatternKind::Or(_patterns) => {}
12661278
}
12671279
}
1280+
ty::Adt(adt, _) if adt.is_maybe_dangling() => {
1281+
let old_may_dangle = mem::replace(&mut self.may_dangle, true);
1282+
1283+
let inner = self.ecx.project_field(val, FieldIdx::ZERO)?;
1284+
self.visit_value(&inner)?;
1285+
1286+
self.may_dangle = old_may_dangle;
1287+
}
12681288
_ => {
12691289
// default handler
12701290
try_validation!(
@@ -1350,6 +1370,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
13501370
ecx,
13511371
reset_provenance_and_padding,
13521372
data_bytes: reset_padding.then_some(RangeSet(Vec::new())),
1373+
may_dangle: false,
13531374
};
13541375
v.visit_value(val)?;
13551376
v.reset_padding(val)?;

compiler/rustc_errors/src/diagnostic.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,17 @@ impl<'a> Diagnostic<'a, ()>
127127
}
128128
}
129129

130+
/// Type used to emit diagnostic through a closure instead of implementing the `Diagnostic` trait.
131+
pub struct DiagDecorator<F: FnOnce(&mut Diag<'_, ()>)>(pub F);
132+
133+
impl<'a, F: FnOnce(&mut Diag<'_, ()>)> Diagnostic<'a, ()> for DiagDecorator<F> {
134+
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
135+
let mut diag = Diag::new(dcx, level, "");
136+
(self.0)(&mut diag);
137+
diag
138+
}
139+
}
140+
130141
/// Trait implemented by error types. This should not be implemented manually. Instead, use
131142
/// `#[derive(Subdiagnostic)]` -- see [rustc_macros::Subdiagnostic].
132143
#[rustc_diagnostic_item = "Subdiagnostic"]

compiler/rustc_errors/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ pub use anstyle::{
3636
pub use codes::*;
3737
pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer};
3838
pub use diagnostic::{
39-
BugAbort, Diag, DiagInner, DiagLocation, DiagStyledString, Diagnostic, EmissionGuarantee,
40-
FatalAbort, StringPart, Subdiag, Subdiagnostic,
39+
BugAbort, Diag, DiagDecorator, DiagInner, DiagLocation, DiagStyledString, Diagnostic,
40+
EmissionGuarantee, FatalAbort, StringPart, Subdiag, Subdiagnostic,
4141
};
4242
pub use diagnostic_impls::{
4343
DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,

compiler/rustc_feature/src/unstable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ declare_features! (
465465
/// Allows having using `suggestion` in the `#[deprecated]` attribute.
466466
(unstable, deprecated_suggestion, "1.61.0", Some(94785)),
467467
/// Allows deref patterns.
468-
(incomplete, deref_patterns, "1.79.0", Some(87121)),
468+
(unstable, deref_patterns, "1.79.0", Some(87121)),
469469
/// Allows deriving the From trait on single-field structs.
470470
(unstable, derive_from, "1.91.0", Some(144889)),
471471
/// Allows giving non-const impls custom diagnostic messages if attempted to be used as const

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,27 +1791,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17911791

17921792
fn check_expr_tuple(
17931793
&self,
1794-
elts: &'tcx [hir::Expr<'tcx>],
1794+
elements: &'tcx [hir::Expr<'tcx>],
17951795
expected: Expectation<'tcx>,
17961796
expr: &'tcx hir::Expr<'tcx>,
17971797
) -> Ty<'tcx> {
1798-
let flds = expected.only_has_type(self).and_then(|ty| {
1799-
let ty = self.try_structurally_resolve_type(expr.span, ty);
1800-
match ty.kind() {
1801-
ty::Tuple(flds) => Some(&flds[..]),
1802-
_ => None,
1803-
}
1798+
let mut expectations = expected
1799+
.only_has_type(self)
1800+
.and_then(|ty| self.try_structurally_resolve_type(expr.span, ty).opt_tuple_fields())
1801+
.unwrap_or_default()
1802+
.iter();
1803+
1804+
let elements = elements.iter().map(|e| {
1805+
let ty = expectations.next().unwrap_or_else(|| self.next_ty_var(e.span));
1806+
self.check_expr_coercible_to_type(e, ty, None);
1807+
ty
18041808
});
18051809

1806-
let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| match flds {
1807-
Some(fs) if i < fs.len() => {
1808-
let ety = fs[i];
1809-
self.check_expr_coercible_to_type(e, ety, None);
1810-
ety
1811-
}
1812-
_ => self.check_expr_with_expectation(e, NoExpectation),
1813-
});
1814-
let tuple = Ty::new_tup_from_iter(self.tcx, elt_ts_iter);
1810+
let tuple = Ty::new_tup_from_iter(self.tcx, elements);
1811+
18151812
if let Err(guar) = tuple.error_reported() {
18161813
Ty::new_error(self.tcx, guar)
18171814
} else {

0 commit comments

Comments
 (0)