Skip to content
Closed
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
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
d338aca
unstably constify float mul_add methods
Qelxiros Sep 18, 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
1ff5e53
Rollup merge of #146711 - lcnr:fix-placeholder-ice, r=lqd
matthiaskrgr Sep 24, 2025
76719ac
Rollup merge of #146735 - Qelxiros:const_mul_add, r=tgross35,RalfJung
matthiaskrgr Sep 24, 2025
707fad6
Rollup merge of #146857 - tnuha:revert_self_has_no_region_infer, r=lcnr
matthiaskrgr Sep 24, 2025
6d7eeca
Rollup merge of #146897 - lolbinarycat:rustdoc-invalid_html_tags-ice-…
matthiaskrgr Sep 24, 2025
2ed8c82
Rollup merge of #146915 - clarfonthey:safe-intrinsics-2, r=RalfJung
matthiaskrgr Sep 24, 2025
c138dea
Rollup merge of #146932 - ShoyuVanilla:ra-in-tree-hack, r=lcnr
matthiaskrgr Sep 24, 2025
1ad2f61
Rollup merge of #146959 - tshepang:patch-2, r=nnethercote
matthiaskrgr Sep 24, 2025
7a407b2
Rollup merge of #146964 - Ayush1325:close-protocol, r=joboet
matthiaskrgr Sep 24, 2025
947400c
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
46 changes: 46 additions & 0 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
dest,
rustc_apfloat::Round::NearestTiesToEven,
)?,
sym::fmaf16 => self.fma_intrinsic::<Half>(args, dest)?,
sym::fmaf32 => self.fma_intrinsic::<Single>(args, dest)?,
sym::fmaf64 => self.fma_intrinsic::<Double>(args, dest)?,
sym::fmaf128 => self.fma_intrinsic::<Quad>(args, dest)?,
sym::fmuladdf16 => self.float_muladd_intrinsic::<Half>(args, dest)?,
sym::fmuladdf32 => self.float_muladd_intrinsic::<Single>(args, dest)?,
sym::fmuladdf64 => self.float_muladd_intrinsic::<Double>(args, dest)?,
sym::fmuladdf128 => self.float_muladd_intrinsic::<Quad>(args, dest)?,

// Unsupported intrinsic: skip the return_to_block below.
_ => return interp_ok(false),
Expand Down Expand Up @@ -1035,4 +1043,42 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_scalar(res, dest)?;
interp_ok(())
}

fn fma_intrinsic<F>(
&mut self,
args: &[OpTy<'tcx, M::Provenance>],
dest: &PlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, ()>
where
F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
{
let a: F = self.read_scalar(&args[0])?.to_float()?;
let b: F = self.read_scalar(&args[1])?.to_float()?;
let c: F = self.read_scalar(&args[2])?.to_float()?;

let res = a.mul_add(b, c).value;
let res = self.adjust_nan(res, &[a, b, c]);
self.write_scalar(res, dest)?;
interp_ok(())
}

fn float_muladd_intrinsic<F>(
&mut self,
args: &[OpTy<'tcx, M::Provenance>],
dest: &PlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, ()>
where
F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
{
let a: F = self.read_scalar(&args[0])?.to_float()?;
let b: F = self.read_scalar(&args[1])?.to_float()?;
let c: F = self.read_scalar(&args[2])?.to_float()?;

let fuse = M::float_fuse_mul_add(self);

let res = if fuse { a.mul_add(b, c).value } else { ((a * b).value + c).value };
let res = self.adjust_nan(res, &[a, b, c]);
self.write_scalar(res, dest)?;
interp_ok(())
}
}
8 changes: 8 additions & 0 deletions compiler/rustc_const_eval/src/interpret/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,9 @@ pub trait Machine<'tcx>: Sized {
a
}

/// Determines whether the `fmuladd` intrinsics fuse the multiply-add or use separate operations.
fn float_fuse_mul_add(_ecx: &mut InterpCx<'tcx, Self>) -> bool;

/// Called before a basic block terminator is executed.
#[inline]
fn before_terminator(_ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {
Expand Down Expand Up @@ -672,6 +675,11 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
match fn_val {}
}

#[inline(always)]
fn float_fuse_mul_add(_ecx: &mut InterpCx<$tcx, Self>) -> bool {
true
}

#[inline(always)]
fn ub_checks(_ecx: &InterpCx<$tcx, Self>) -> InterpResult<$tcx, bool> {
// We can't look at `tcx.sess` here as that can differ across crates, which can lead to
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
Loading
Loading