Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
4919d55
fix location for nested bodies in promoteds
lcnr Sep 18, 2025
3b2bbcd
internal constraints are better than placeholder outlives
lcnr Sep 18, 2025
82c4018
fix ICE in rustdoc::invalid_html_tags
lolbinarycat Sep 22, 2025
60b3563
revert change removing `has_infer` check. Commit conservatively patch…
tnuha Sep 23, 2025
e8a8e06
Make missed precondition-free float intrinsics safe
clarfonthey Sep 23, 2025
c9dc0e3
temporary-lifetime-extension-tuple-ctor.rs: make usable on all editions
tshepang Sep 24, 2025
03fd823
library: std: sys: pal: uefi: Add some comments
Ayush1325 Sep 24, 2025
3378997
fix wording
lcnr Sep 24, 2025
0a41add
const-eval: improve and actually test the errors when pointers might …
RalfJung Sep 22, 2025
8328c3d
const validation: better error for maybe-null references
RalfJung Sep 24, 2025
0e7cc32
Switch next-solver related rustc dependencies of r-a to crates.io ones
ShoyuVanilla Sep 24, 2025
3150538
Rollup merge of #146711 - lcnr:fix-placeholder-ice, r=lqd
matthiaskrgr Sep 24, 2025
79bb3c4
Rollup merge of #146857 - tnuha:revert_self_has_no_region_infer, r=lcnr
matthiaskrgr Sep 24, 2025
4e225ee
Rollup merge of #146897 - lolbinarycat:rustdoc-invalid_html_tags-ice-…
matthiaskrgr Sep 24, 2025
2320fc3
Rollup merge of #146915 - clarfonthey:safe-intrinsics-2, r=RalfJung
matthiaskrgr Sep 24, 2025
4300cd6
Rollup merge of #146932 - ShoyuVanilla:ra-in-tree-hack, r=lcnr
matthiaskrgr Sep 24, 2025
af22499
Rollup merge of #146959 - tshepang:patch-2, r=nnethercote
matthiaskrgr Sep 24, 2025
24e19c9
Rollup merge of #146964 - Ayush1325:close-protocol, r=joboet
matthiaskrgr Sep 24, 2025
ec378dc
Rollup merge of #146969 - RalfJung:maybe-null-errors, r=oli-obk
matthiaskrgr Sep 24, 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
7 changes: 4 additions & 3 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1736,9 +1736,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// `BoringNoLocation` constraints can point to user-written code, but are less
// specific, and are not used for relations that would make sense to blame.
ConstraintCategory::BoringNoLocation => 6,
// Do not blame internal constraints.
ConstraintCategory::OutlivesUnnameablePlaceholder(_) => 7,
ConstraintCategory::Internal => 8,
// Do not blame internal constraints if we can avoid it. Never blame
// the `'region: 'static` constraints introduced by placeholder outlives.
ConstraintCategory::Internal => 7,
ConstraintCategory::OutlivesUnnameablePlaceholder(_) => 8,
};

debug!("constraint {constraint:?} category: {category:?}, interest: {interest:?}");
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,13 +505,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let mut constraints = Default::default();
let mut liveness_constraints =
LivenessValues::without_specific_points(Rc::new(DenseLocationMap::new(promoted_body)));
let mut deferred_closure_requirements = Default::default();

// Don't try to add borrow_region facts for the promoted MIR as they refer
// to the wrong locations.
let mut swap_constraints = |this: &mut Self| {
mem::swap(this.polonius_facts, polonius_facts);
mem::swap(&mut this.constraints.outlives_constraints, &mut constraints);
mem::swap(&mut this.constraints.liveness_constraints, &mut liveness_constraints);
mem::swap(this.deferred_closure_requirements, &mut deferred_closure_requirements);
};

swap_constraints(self);
Expand All @@ -536,6 +538,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
self.constraints.outlives_constraints.push(constraint)
}

// If there are nested bodies in promoteds, we also need to update their
// location to something in the actual body, not the promoted.
//
// We don't update the constraint categories of the resulting constraints
// as returns in nested bodies are a proper return, even if that nested body
// is in a promoted.
for (closure_def_id, args, _locations) in deferred_closure_requirements {
self.deferred_closure_requirements.push((closure_def_id, args, locations));
}

// If the region is live at least one location in the promoted MIR,
// then add a liveness constraint to the main MIR for this region
// at the location provided as an argument to this method
Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -476,14 +476,20 @@ const_eval_validation_invalid_vtable_trait = {$front_matter}: wrong trait in wid
const_eval_validation_mutable_ref_in_const = {$front_matter}: encountered mutable reference in `const` value
const_eval_validation_mutable_ref_to_immutable = {$front_matter}: encountered mutable reference or box pointing to read-only memory
const_eval_validation_never_val = {$front_matter}: encountered a value of the never type `!`
const_eval_validation_null_box = {$front_matter}: encountered a null box
const_eval_validation_null_box = {$front_matter}: encountered a {$maybe ->
[true] maybe-null
*[false] null
} box
const_eval_validation_null_fn_ptr = {$front_matter}: encountered a null function pointer
const_eval_validation_null_ref = {$front_matter}: encountered a null reference
const_eval_validation_nullable_ptr_out_of_range = {$front_matter}: encountered a potentially null pointer, but expected something that cannot possibly fail to be {$in_range}
const_eval_validation_null_ref = {$front_matter}: encountered a {$maybe ->
[true] maybe-null
*[false] null
} reference
const_eval_validation_nonnull_ptr_out_of_range = {$front_matter}: encountered a maybe-null pointer, but expected something that is definitely non-zero
const_eval_validation_out_of_range = {$front_matter}: encountered {$value}, but expected something {$in_range}
const_eval_validation_partial_pointer = {$front_matter}: encountered a partial pointer or a mix of pointers
const_eval_validation_pointer_as_int = {$front_matter}: encountered a pointer, but {$expected}
const_eval_validation_ptr_out_of_range = {$front_matter}: encountered a pointer, but expected something that cannot possibly fail to be {$in_range}
const_eval_validation_ptr_out_of_range = {$front_matter}: encountered a pointer with unknown absolute address, but expected something that is definitely {$in_range}
const_eval_validation_ref_to_uninhabited = {$front_matter}: encountered a reference pointing to uninhabited type {$ty}
const_eval_validation_unaligned_box = {$front_matter}: encountered an unaligned box (required {$required_bytes} byte alignment but found {$found_bytes})
const_eval_validation_unaligned_ref = {$front_matter}: encountered an unaligned reference (required {$required_bytes} byte alignment but found {$found_bytes})
Expand Down
17 changes: 9 additions & 8 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
MutableRefInConst => const_eval_validation_mutable_ref_in_const,
NullFnPtr => const_eval_validation_null_fn_ptr,
NeverVal => const_eval_validation_never_val,
NullablePtrOutOfRange { .. } => const_eval_validation_nullable_ptr_out_of_range,
NonnullPtrMaybeNull { .. } => const_eval_validation_nonnull_ptr_out_of_range,
PtrOutOfRange { .. } => const_eval_validation_ptr_out_of_range,
OutOfRange { .. } => const_eval_validation_out_of_range,
UnsafeCellInImmutable => const_eval_validation_unsafe_cell,
Expand Down Expand Up @@ -696,8 +696,8 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
}
UnalignedPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_unaligned_box,

NullPtr { ptr_kind: PointerKind::Box } => const_eval_validation_null_box,
NullPtr { ptr_kind: PointerKind::Ref(_) } => const_eval_validation_null_ref,
NullPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_null_box,
NullPtr { ptr_kind: PointerKind::Ref(_), .. } => const_eval_validation_null_ref,
DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => {
const_eval_validation_dangling_box_no_provenance
}
Expand Down Expand Up @@ -804,9 +804,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
| InvalidFnPtr { value } => {
err.arg("value", value);
}
NullablePtrOutOfRange { range, max_value } | PtrOutOfRange { range, max_value } => {
add_range_arg(range, max_value, err)
}
PtrOutOfRange { range, max_value } => add_range_arg(range, max_value, err),
OutOfRange { range, max_value, value } => {
err.arg("value", value);
add_range_arg(range, max_value, err);
Expand All @@ -822,10 +820,13 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
err.arg("vtable_dyn_type", vtable_dyn_type.to_string());
err.arg("expected_dyn_type", expected_dyn_type.to_string());
}
NullPtr { .. }
| MutableRefToImmutable
NullPtr { maybe, .. } => {
err.arg("maybe", maybe);
}
MutableRefToImmutable
| MutableRefInConst
| NullFnPtr
| NonnullPtrMaybeNull
| NeverVal
| UnsafeCellInImmutable
| InvalidMetaSliceTooLarge { .. }
Expand Down
18 changes: 11 additions & 7 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
CheckInAllocMsg::Dereferenceable, // will anyway be replaced by validity message
),
self.path,
Ub(DanglingIntPointer { addr: 0, .. }) => NullPtr { ptr_kind },
Ub(DanglingIntPointer { addr: 0, .. }) => NullPtr { ptr_kind, maybe: false },
Ub(DanglingIntPointer { addr: i, .. }) => DanglingPtrNoProvenance {
ptr_kind,
// FIXME this says "null pointer" when null but we need translate
Expand All @@ -538,8 +538,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
);
// Make sure this is non-null. We checked dereferenceability above, but if `size` is zero
// that does not imply non-null.
if self.ecx.scalar_may_be_null(Scalar::from_maybe_pointer(place.ptr(), self.ecx))? {
throw_validation_failure!(self.path, NullPtr { ptr_kind })
let scalar = Scalar::from_maybe_pointer(place.ptr(), self.ecx);
if self.ecx.scalar_may_be_null(scalar)? {
let maybe = !M::Provenance::OFFSET_IS_ADDR && matches!(scalar, Scalar::Ptr(..));
throw_validation_failure!(self.path, NullPtr { ptr_kind, maybe })
}
// Do not allow references to uninhabited types.
if place.layout.is_uninhabited() {
Expand Down Expand Up @@ -757,6 +759,11 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
} else {
// Otherwise (for standalone Miri), we have to still check it to be non-null.
if self.ecx.scalar_may_be_null(scalar)? {
let maybe =
!M::Provenance::OFFSET_IS_ADDR && matches!(scalar, Scalar::Ptr(..));
// This can't be a "maybe-null" pointer since the check for this being
// a fn ptr at all already ensures that the pointer is inbounds.
assert!(!maybe);
throw_validation_failure!(self.path, NullFnPtr);
}
}
Expand Down Expand Up @@ -819,10 +826,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
if start == 1 && end == max_value {
// Only null is the niche. So make sure the ptr is NOT null.
if self.ecx.scalar_may_be_null(scalar)? {
throw_validation_failure!(
self.path,
NullablePtrOutOfRange { range: valid_range, max_value }
)
throw_validation_failure!(self.path, NonnullPtrMaybeNull)
} else {
return interp_ok(());
}
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
| sym::contract_check_ensures
| sym::contract_check_requires
| sym::contract_checks
| sym::copysignf16
| sym::copysignf32
| sym::copysignf64
| sym::copysignf128
| sym::cosf16
| sym::cosf32
| sym::cosf64
Expand All @@ -106,6 +110,10 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
| sym::expf32
| sym::expf64
| sym::expf128
| sym::fabsf16
| sym::fabsf32
| sym::fabsf64
| sym::fabsf128
| sym::fadd_algebraic
| sym::fdiv_algebraic
| sym::floorf16
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,10 +499,7 @@ pub enum ValidationErrorKind<'tcx> {
MutableRefInConst,
NullFnPtr,
NeverVal,
NullablePtrOutOfRange {
range: WrappingRange,
max_value: u128,
},
NonnullPtrMaybeNull,
PtrOutOfRange {
range: WrappingRange,
max_value: u128,
Expand Down Expand Up @@ -544,6 +541,8 @@ pub enum ValidationErrorKind<'tcx> {
},
NullPtr {
ptr_kind: PointerKind,
/// Records whether this pointer is definitely null or just may be null.
maybe: bool,
},
DanglingPtrNoProvenance {
ptr_kind: PointerKind,
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1368,7 +1368,6 @@ impl<'tcx> Ty<'tcx> {
/// 2229 drop reorder migration analysis.
#[inline]
pub fn has_significant_drop(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool {
assert!(!self.has_non_region_infer());
// Avoid querying in simple cases.
match needs_drop_components(tcx, self) {
Err(AlwaysRequiresDrop) => true,
Expand All @@ -1381,6 +1380,16 @@ impl<'tcx> Ty<'tcx> {
_ => self,
};

// FIXME
// We should be canonicalizing, or else moving this to a method of inference
// context, or *something* like that,
// but for now just avoid passing inference variables
// to queries that can't cope with them.
// Instead, conservatively return "true" (may change drop order).
if query_ty.has_infer() {
return true;
}

// This doesn't depend on regions, so try to minimize distinct
// query keys used.
let erased = tcx.normalize_erasing_regions(typing_env, query_ty);
Expand Down
16 changes: 8 additions & 8 deletions library/core/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3170,7 +3170,7 @@ pub const fn maximumf128(x: f128, y: f128) -> f128 {
/// [`f16::abs`](../../std/primitive.f16.html#method.abs)
#[rustc_nounwind]
#[rustc_intrinsic]
pub const unsafe fn fabsf16(x: f16) -> f16;
pub const fn fabsf16(x: f16) -> f16;

/// Returns the absolute value of an `f32`.
///
Expand All @@ -3179,7 +3179,7 @@ pub const unsafe fn fabsf16(x: f16) -> f16;
#[rustc_nounwind]
#[rustc_intrinsic_const_stable_indirect]
#[rustc_intrinsic]
pub const unsafe fn fabsf32(x: f32) -> f32;
pub const fn fabsf32(x: f32) -> f32;

/// Returns the absolute value of an `f64`.
///
Expand All @@ -3188,23 +3188,23 @@ pub const unsafe fn fabsf32(x: f32) -> f32;
#[rustc_nounwind]
#[rustc_intrinsic_const_stable_indirect]
#[rustc_intrinsic]
pub const unsafe fn fabsf64(x: f64) -> f64;
pub const fn fabsf64(x: f64) -> f64;

/// Returns the absolute value of an `f128`.
///
/// The stabilized version of this intrinsic is
/// [`f128::abs`](../../std/primitive.f128.html#method.abs)
#[rustc_nounwind]
#[rustc_intrinsic]
pub const unsafe fn fabsf128(x: f128) -> f128;
pub const fn fabsf128(x: f128) -> f128;

/// Copies the sign from `y` to `x` for `f16` values.
///
/// The stabilized version of this intrinsic is
/// [`f16::copysign`](../../std/primitive.f16.html#method.copysign)
#[rustc_nounwind]
#[rustc_intrinsic]
pub const unsafe fn copysignf16(x: f16, y: f16) -> f16;
pub const fn copysignf16(x: f16, y: f16) -> f16;

/// Copies the sign from `y` to `x` for `f32` values.
///
Expand All @@ -3213,23 +3213,23 @@ pub const unsafe fn copysignf16(x: f16, y: f16) -> f16;
#[rustc_nounwind]
#[rustc_intrinsic_const_stable_indirect]
#[rustc_intrinsic]
pub const unsafe fn copysignf32(x: f32, y: f32) -> f32;
pub const fn copysignf32(x: f32, y: f32) -> f32;
/// Copies the sign from `y` to `x` for `f64` values.
///
/// The stabilized version of this intrinsic is
/// [`f64::copysign`](../../std/primitive.f64.html#method.copysign)
#[rustc_nounwind]
#[rustc_intrinsic_const_stable_indirect]
#[rustc_intrinsic]
pub const unsafe fn copysignf64(x: f64, y: f64) -> f64;
pub const fn copysignf64(x: f64, y: f64) -> f64;

/// Copies the sign from `y` to `x` for `f128` values.
///
/// The stabilized version of this intrinsic is
/// [`f128::copysign`](../../std/primitive.f128.html#method.copysign)
#[rustc_nounwind]
#[rustc_intrinsic]
pub const unsafe fn copysignf128(x: f128, y: f128) -> f128;
pub const fn copysignf128(x: f128, y: f128) -> f128;

/// Generates the LLVM body for the automatic differentiation of `f` using Enzyme,
/// with `df` as the derivative function and `args` as its arguments.
Expand Down
3 changes: 1 addition & 2 deletions library/core/src/num/f128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1367,8 +1367,7 @@ impl f128 {
#[rustc_const_unstable(feature = "f128", issue = "116909")]
#[must_use = "method returns a new number and does not mutate the original value"]
pub const fn copysign(self, sign: f128) -> f128 {
// SAFETY: this is actually a safe intrinsic
unsafe { intrinsics::copysignf128(self, sign) }
intrinsics::copysignf128(self, sign)
}

/// Float addition that allows optimizations based on algebraic rules.
Expand Down
3 changes: 1 addition & 2 deletions library/core/src/num/f16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1344,8 +1344,7 @@ impl f16 {
#[rustc_const_unstable(feature = "f16", issue = "116909")]
#[must_use = "method returns a new number and does not mutate the original value"]
pub const fn copysign(self, sign: f16) -> f16 {
// SAFETY: this is actually a safe intrinsic
unsafe { intrinsics::copysignf16(self, sign) }
intrinsics::copysignf16(self, sign)
}

/// Float addition that allows optimizations based on algebraic rules.
Expand Down
6 changes: 2 additions & 4 deletions library/core/src/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1450,8 +1450,7 @@ impl f32 {
#[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
#[inline]
pub const fn abs(self) -> f32 {
// SAFETY: this is actually a safe intrinsic
unsafe { intrinsics::fabsf32(self) }
intrinsics::fabsf32(self)
}

/// Returns a number that represents the sign of `self`.
Expand Down Expand Up @@ -1509,8 +1508,7 @@ impl f32 {
#[stable(feature = "copysign", since = "1.35.0")]
#[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
pub const fn copysign(self, sign: f32) -> f32 {
// SAFETY: this is actually a safe intrinsic
unsafe { intrinsics::copysignf32(self, sign) }
intrinsics::copysignf32(self, sign)
}

/// Float addition that allows optimizations based on algebraic rules.
Expand Down
6 changes: 2 additions & 4 deletions library/core/src/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1448,8 +1448,7 @@ impl f64 {
#[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
#[inline]
pub const fn abs(self) -> f64 {
// SAFETY: this is actually a safe intrinsic
unsafe { intrinsics::fabsf64(self) }
intrinsics::fabsf64(self)
}

/// Returns a number that represents the sign of `self`.
Expand Down Expand Up @@ -1507,8 +1506,7 @@ impl f64 {
#[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
#[inline]
pub const fn copysign(self, sign: f64) -> f64 {
// SAFETY: this is actually a safe intrinsic
unsafe { intrinsics::copysignf64(self, sign) }
intrinsics::copysignf64(self, sign)
}

/// Float addition that allows optimizations based on algebraic rules.
Expand Down
4 changes: 4 additions & 0 deletions library/std/src/sys/pal/uefi/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ pub(crate) fn locate_handles(mut guid: Guid) -> io::Result<Vec<NonNull<crate::ff
///
/// Queries a handle to determine if it supports a specified protocol. If the protocol is
/// supported by the handle, it opens the protocol on behalf of the calling agent.
///
/// The protocol is opened with the attribute GET_PROTOCOL, which means the caller is not required
/// to close the protocol interface with `EFI_BOOT_SERVICES.CloseProtocol()`
pub(crate) fn open_protocol<T>(
handle: NonNull<crate::ffi::c_void>,
mut protocol_guid: Guid,
Expand Down Expand Up @@ -473,6 +476,7 @@ impl<'a> crate::fmt::Debug for DevicePathNode<'a> {
}
}

/// Protocols installed by Rust side on a handle.
pub(crate) struct OwnedProtocol<T> {
guid: r_efi::efi::Guid,
handle: NonNull<crate::ffi::c_void>,
Expand Down
Loading
Loading