Skip to content
Merged
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
06658ab
cmse: do not calculate the layout of a type with infer types
folkertdev Nov 24, 2025
67094fc
test(frontmatter): Check handling of long code fences
epage Nov 26, 2025
70b6d77
fix(parse): Limit frontmatter fences to 255 dashes
epage Nov 26, 2025
daccd99
stabilize maybe_uninit_slice
bend-n Nov 19, 2025
d67f99a
fix
bend-n Nov 19, 2025
6cdfb60
make assoc fn inherit const stability from inherent `const impl` blocks
fee1-dead Nov 29, 2025
d4af0f0
Fix indent in E0591.md
reddevilmidzy Nov 30, 2025
b111aed
fudge infer vars in cause code intentionally
adwinwhite Nov 24, 2025
ae7fa32
Implement `clamp_magnitude` for floats & signed integers
IntegralPilot Nov 8, 2025
968376d
Add label rib when visiting delegation body, add test
aerooneqq Nov 30, 2025
97f93df
Don't suggest unwrap for Result in const
lapla-cogito Dec 1, 2025
62fe6a0
Rename added test
aerooneqq Dec 1, 2025
9a967de
Rollup merge of #148690 - IntegralPilot:clamp-mag, r=joboet
matthiaskrgr Dec 1, 2025
5f3dc5d
Rollup merge of #149102 - bend-n:maybe_uninit_slice, r=joboet
matthiaskrgr Dec 1, 2025
6e5661e
Rollup merge of #149269 - folkertdev:cmse-infer, r=davidtwco
matthiaskrgr Dec 1, 2025
b8336a5
Rollup merge of #149299 - adwinwhite:next-245-ice, r=lcnr
matthiaskrgr Dec 1, 2025
c5046a6
Rollup merge of #149344 - lapla-cogito:const_unwrap_sugg, r=Kivooeo
matthiaskrgr Dec 1, 2025
af631a5
Rollup merge of #149358 - epage:fence-length, r=davidtwco
matthiaskrgr Dec 1, 2025
b0b3c92
Rollup merge of #149445 - fee1-dead-contrib:push-msxupnksrusl, r=petr…
matthiaskrgr Dec 1, 2025
6900946
Rollup merge of #149479 - reddevilmidzy:E0591, r=chenyukang
matthiaskrgr Dec 1, 2025
e0091c5
Rollup merge of #149496 - aerooneqq:ice-issue-148889, r=petrochenkov
matthiaskrgr Dec 1, 2025
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_arena/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
// tidy-alphabetical-start
#![allow(clippy::mut_from_ref)] // Arena allocators are one place where this pattern is fine.
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(maybe_uninit_slice))]
#![cfg_attr(test, feature(test))]
#![deny(unsafe_op_in_unsafe_fn)]
#![doc(test(no_crate_inject, attr(deny(warnings), allow(internal_features))))]
#![feature(core_intrinsics)]
#![feature(decl_macro)]
#![feature(dropck_eyepatch)]
#![feature(maybe_uninit_slice)]
#![feature(never_type)]
#![feature(rustc_attrs)]
#![feature(unwrap_infallible)]
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_error_codes/src/error_codes/E0591.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ This pattern should be rewritten. There are a few possible ways to do this:
and do the cast in the fn body (the preferred option)
- cast the fn item of a fn pointer before calling transmute, as shown here:

```
# extern "C" fn foo(_: Box<i32>) {}
# use std::mem::transmute;
# unsafe {
let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_));
let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too
# }
```
```
# extern "C" fn foo(_: Box<i32>) {}
# use std::mem::transmute;
# unsafe {
let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_));
let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too
# }
```

The same applies to transmutes to `*mut fn()`, which were observed in practice.
Note though that use of this type is generally incorrect.
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ fn is_valid_cmse_inputs<'tcx>(
let fn_sig = tcx.erase_and_anonymize_regions(fn_sig);

for (ty, hir_ty) in fn_sig.inputs().iter().zip(fn_decl.inputs) {
if ty.has_infer_types() {
let err = LayoutError::Unknown(*ty);
return Err((hir_ty.span, tcx.arena.alloc(err)));
}

let layout = tcx
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(*ty))
.map_err(|e| (hir_ty.span, e))?;
Expand Down Expand Up @@ -138,6 +143,11 @@ fn is_valid_cmse_output<'tcx>(
return Ok(());
}

if return_type.has_infer_types() {
let err = LayoutError::Unknown(return_type);
return Err(tcx.arena.alloc(err));
}

let typing_env = ty::TypingEnv::fully_monomorphized();
let layout = tcx.layout_of(typing_env.as_query_input(return_type))?;

Expand Down
18 changes: 10 additions & 8 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2106,14 +2106,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
)),
);

let (article, kind, variant, sugg_operator) =
if self.tcx.is_diagnostic_item(sym::Result, adt.did()) {
("a", "Result", "Err", ret_ty_matches(sym::Result))
} else if self.tcx.is_diagnostic_item(sym::Option, adt.did()) {
("an", "Option", "None", ret_ty_matches(sym::Option))
} else {
return false;
};
let (article, kind, variant, sugg_operator) = if self.tcx.is_diagnostic_item(sym::Result, adt.did())
// Do not suggest `.expect()` in const context where it's not available. rust-lang/rust#149316
&& !self.tcx.hir_is_inside_const_context(expr.hir_id)
{
("a", "Result", "Err", ret_ty_matches(sym::Result))
} else if self.tcx.is_diagnostic_item(sym::Option, adt.did()) {
("an", "Option", "None", ret_ty_matches(sym::Option))
} else {
return false;
};
if is_ctor || !self.may_coerce(args.type_at(0), expected) {
return false;
}
Expand Down
18 changes: 10 additions & 8 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3041,14 +3041,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
tcx.def_span(pick.item.def_id),
format!("the method `{item_name}` exists on the type `{self_ty}`"),
);
let (article, kind, variant, question) =
if tcx.is_diagnostic_item(sym::Result, kind.did()) {
("a", "Result", "Err", ret_ty_matches(sym::Result))
} else if tcx.is_diagnostic_item(sym::Option, kind.did()) {
("an", "Option", "None", ret_ty_matches(sym::Option))
} else {
return;
};
let (article, kind, variant, question) = if tcx.is_diagnostic_item(sym::Result, kind.did())
// Do not suggest `.expect()` in const context where it's not available. rust-lang/rust#149316
&& !tcx.hir_is_inside_const_context(expr.hir_id)
{
("a", "Result", "Err", ret_ty_matches(sym::Result))
} else if tcx.is_diagnostic_item(sym::Option, kind.did()) {
("an", "Option", "None", ret_ty_matches(sym::Option))
} else {
return;
};
if question {
err.span_suggestion_verbose(
expr.span.shrink_to_hi(),
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_infer/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ use crate::infer::InferCtxt;
#[derive(Clone, TypeFoldable, TypeVisitable)]
pub struct Obligation<'tcx, T> {
/// The reason we have to prove this thing.
/// FIXME: we shouldn't ignore the cause but instead change the affected visitors
/// to only visit predicates manually.
#[type_foldable(identity)]
#[type_visitable(ignore)]
pub cause: ObligationCause<'tcx>,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ parse_frontmatter_invalid_opening_preceding_whitespace = invalid preceding white
parse_frontmatter_length_mismatch = frontmatter close does not match the opening
.label_opening = the opening here has {$len_opening} dashes...
.label_close = ...while the close has {$len_close} dashes
parse_frontmatter_too_many_dashes = too many `-` symbols: frontmatter openings may be delimited by up to 255 `-` symbols, but found {$len_opening}
parse_frontmatter_unclosed = unclosed frontmatter
.note = frontmatter opening here was not closed
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,12 @@ pub(crate) struct FrontmatterLengthMismatch {
pub len_close: usize,
}

#[derive(Diagnostic)]
#[diag(parse_frontmatter_too_many_dashes)]
pub(crate) struct FrontmatterTooManyDashes {
pub len_opening: usize,
}

#[derive(Diagnostic)]
#[diag(parse_leading_plus_not_supported)]
pub(crate) struct LeadingPlusNotSupported {
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_parse/src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,11 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
});
}

// Only up to 255 `-`s are allowed in code fences
if u8::try_from(len_opening).is_err() {
self.dcx().emit_err(errors::FrontmatterTooManyDashes { len_opening });
}

if !rest.trim_matches(is_horizontal_whitespace).is_empty() {
let span = self.mk_sp(last_line_start_pos, self.pos);
self.dcx().emit_err(errors::FrontmatterExtraCharactersAfterClose { span });
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fn inherit_const_stability(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
match def_kind {
DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
match tcx.def_kind(tcx.local_parent(def_id)) {
DefKind::Impl { of_trait: true } => true,
DefKind::Impl { .. } => true,
_ => false,
}
}
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3689,7 +3689,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
let ident = Ident::new(kw::SelfLower, span.normalize_to_macro_rules());
let res = Res::Local(delegation.id);
this.innermost_rib_bindings(ValueNS).insert(ident, res);
this.visit_block(body);

//As we lower target_expr_template body to a body of a function we need a label rib (#148889)
this.with_label_rib(RibKind::FnOrCoroutine, |this| {
this.visit_block(body);
});
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,11 @@ fn find_best_leaf_obligation<'tcx>(
)
.break_value()
.ok_or(())
// walk around the fact that the cause in `Obligation` is ignored by folders so that
// we can properly fudge the infer vars in cause code.
.map(|o| (o.cause.clone(), o))
})
.map(|(cause, o)| PredicateObligation { cause, ..o })
.unwrap_or(obligation);
deeply_normalize_for_diagnostics(infcx, obligation.param_env, obligation)
}
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 @@ -127,7 +127,6 @@
#![feature(layout_for_ptr)]
#![feature(legacy_receiver_trait)]
#![feature(local_waker)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array_transpose)]
#![feature(panic_internals)]
#![feature(pattern)]
Expand Down
1 change: 0 additions & 1 deletion library/alloctests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#![feature(inplace_iteration)]
#![feature(iter_advance_by)]
#![feature(iter_next_chunk)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array_transpose)]
#![feature(ptr_alignment_type)]
#![feature(ptr_internals)]
Expand Down
8 changes: 1 addition & 7 deletions library/core/src/clone/uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,10 @@ impl<'a, T> InitializingSlice<'a, T> {
impl<'a, T> Drop for InitializingSlice<'a, T> {
#[cold] // will only be invoked on unwind
fn drop(&mut self) {
let initialized_slice = ptr::slice_from_raw_parts_mut(
MaybeUninit::slice_as_mut_ptr(self.data),
self.initialized_len,
);
// SAFETY:
// * the pointer is valid because it was made from a mutable reference
// * `initialized_len` counts the initialized elements as an invariant of this type,
// so each of the pointed-to elements is initialized and may be dropped.
unsafe {
ptr::drop_in_place::<[T]>(initialized_slice);
}
unsafe { self.data[..self.initialized_len].assume_init_drop() };
}
}
28 changes: 8 additions & 20 deletions library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ impl<T> MaybeUninit<T> {
/// # Examples
///
/// ```
/// #![feature(maybe_uninit_as_bytes, maybe_uninit_slice)]
/// #![feature(maybe_uninit_as_bytes)]
/// use std::mem::MaybeUninit;
///
/// let val = 0x12345678_i32;
Expand Down Expand Up @@ -1097,20 +1097,6 @@ impl<T> MaybeUninit<T> {
)
}
}

/// Gets a pointer to the first element of the array.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
pub const fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
this.as_ptr() as *const T
}

/// Gets a mutable pointer to the first element of the array.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
pub const fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
this.as_mut_ptr() as *mut T
}
}

impl<T> [MaybeUninit<T>] {
Expand Down Expand Up @@ -1410,7 +1396,7 @@ impl<T> [MaybeUninit<T>] {
/// # Examples
///
/// ```
/// #![feature(maybe_uninit_as_bytes, maybe_uninit_slice)]
/// #![feature(maybe_uninit_as_bytes)]
/// use std::mem::MaybeUninit;
///
/// let uninit = [MaybeUninit::new(0x1234u16), MaybeUninit::new(0x5678u16)];
Expand All @@ -1437,7 +1423,7 @@ impl<T> [MaybeUninit<T>] {
/// # Examples
///
/// ```
/// #![feature(maybe_uninit_as_bytes, maybe_uninit_slice)]
/// #![feature(maybe_uninit_as_bytes)]
/// use std::mem::MaybeUninit;
///
/// let mut uninit = [MaybeUninit::<u16>::uninit(), MaybeUninit::<u16>::uninit()];
Expand Down Expand Up @@ -1477,7 +1463,7 @@ impl<T> [MaybeUninit<T>] {
/// requirement the compiler knows about it is that the data pointer must be
/// non-null. Dropping such a `Vec<T>` however will cause undefined
/// behaviour.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")]
#[inline(always)]
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
pub const unsafe fn assume_init_drop(&mut self)
Expand All @@ -1499,7 +1485,8 @@ impl<T> [MaybeUninit<T>] {
/// Calling this when the content is not yet fully initialized causes undefined
/// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in
/// the slice really is in an initialized state.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")]
#[inline(always)]
pub const unsafe fn assume_init_ref(&self) -> &[T] {
// SAFETY: casting `slice` to a `*const [T]` is safe since the caller guarantees that
Expand All @@ -1517,7 +1504,8 @@ impl<T> [MaybeUninit<T>] {
/// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in the
/// slice really is in an initialized state. For instance, `.assume_init_mut()` cannot
/// be used to initialize a `MaybeUninit` slice.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")]
#[inline(always)]
pub const unsafe fn assume_init_mut(&mut self) -> &mut [T] {
// SAFETY: similar to safety notes for `slice_get_ref`, but we have a
Expand Down
32 changes: 32 additions & 0 deletions library/core/src/num/f128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,38 @@ impl f128 {
self
}

/// Clamps this number to a symmetric range centered around zero.
///
/// The method clamps the number's magnitude (absolute value) to be at most `limit`.
///
/// This is functionally equivalent to `self.clamp(-limit, limit)`, but is more
/// explicit about the intent.
///
/// # Panics
///
/// Panics if `limit` is negative or NaN, as this indicates a logic error.
///
/// # Examples
///
/// ```
/// #![feature(f128)]
/// #![feature(clamp_magnitude)]
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
/// assert_eq!(5.0f128.clamp_magnitude(3.0), 3.0);
/// assert_eq!((-5.0f128).clamp_magnitude(3.0), -3.0);
/// assert_eq!(2.0f128.clamp_magnitude(3.0), 2.0);
/// assert_eq!((-2.0f128).clamp_magnitude(3.0), -2.0);
/// # }
/// ```
#[inline]
#[unstable(feature = "clamp_magnitude", issue = "148519")]
#[must_use = "this returns the clamped value and does not modify the original"]
pub fn clamp_magnitude(self, limit: f128) -> f128 {
assert!(limit >= 0.0, "limit must be non-negative");
let limit = limit.abs(); // Canonicalises -0.0 to 0.0
self.clamp(-limit, limit)
}

/// Computes the absolute value of `self`.
///
/// This function always returns the precise result.
Expand Down
32 changes: 32 additions & 0 deletions library/core/src/num/f16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,38 @@ impl f16 {
self
}

/// Clamps this number to a symmetric range centered around zero.
///
/// The method clamps the number's magnitude (absolute value) to be at most `limit`.
///
/// This is functionally equivalent to `self.clamp(-limit, limit)`, but is more
/// explicit about the intent.
///
/// # Panics
///
/// Panics if `limit` is negative or NaN, as this indicates a logic error.
///
/// # Examples
///
/// ```
/// #![feature(f16)]
/// #![feature(clamp_magnitude)]
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
/// assert_eq!(5.0f16.clamp_magnitude(3.0), 3.0);
/// assert_eq!((-5.0f16).clamp_magnitude(3.0), -3.0);
/// assert_eq!(2.0f16.clamp_magnitude(3.0), 2.0);
/// assert_eq!((-2.0f16).clamp_magnitude(3.0), -2.0);
/// # }
/// ```
#[inline]
#[unstable(feature = "clamp_magnitude", issue = "148519")]
#[must_use = "this returns the clamped value and does not modify the original"]
pub fn clamp_magnitude(self, limit: f16) -> f16 {
assert!(limit >= 0.0, "limit must be non-negative");
let limit = limit.abs(); // Canonicalises -0.0 to 0.0
self.clamp(-limit, limit)
}

/// Computes the absolute value of `self`.
///
/// This function always returns the precise result.
Expand Down
Loading
Loading