diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 5f4bfd9df48e5..0910e8ef4b37b 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -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:?}"); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 19cbcd139aa56..606d3d95d9e65 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -505,6 +505,7 @@ 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. @@ -512,6 +513,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { 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); @@ -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 diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 700d7c26752b6..010ffa60c7a53 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -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}) diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 2d412ee5ec26e..d352a6384245f 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -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, @@ -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 } @@ -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); @@ -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 { .. } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 418dd658121db..785978b4d7111 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -636,6 +636,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { dest, rustc_apfloat::Round::NearestTiesToEven, )?, + sym::fmaf16 => self.fma_intrinsic::(args, dest)?, + sym::fmaf32 => self.fma_intrinsic::(args, dest)?, + sym::fmaf64 => self.fma_intrinsic::(args, dest)?, + sym::fmaf128 => self.fma_intrinsic::(args, dest)?, + sym::fmuladdf16 => self.float_muladd_intrinsic::(args, dest)?, + sym::fmuladdf32 => self.float_muladd_intrinsic::(args, dest)?, + sym::fmuladdf64 => self.float_muladd_intrinsic::(args, dest)?, + sym::fmuladdf128 => self.float_muladd_intrinsic::(args, dest)?, // Unsupported intrinsic: skip the return_to_block below. _ => return interp_ok(false), @@ -1035,4 +1043,42 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(res, dest)?; interp_ok(()) } + + fn fma_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &PlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + 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( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &PlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + 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(()) + } } diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index e22629993fba7..1725635e0b479 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -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> { @@ -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 diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 9adc3fa463180..5f088fe37e80b 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -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 @@ -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() { @@ -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); } } @@ -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(()); } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 6faa67f6a904a..bc3448be5823e 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -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 @@ -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 diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 7c72a8ec243a8..951aac503fee8 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -499,10 +499,7 @@ pub enum ValidationErrorKind<'tcx> { MutableRefInConst, NullFnPtr, NeverVal, - NullablePtrOutOfRange { - range: WrappingRange, - max_value: u128, - }, + NonnullPtrMaybeNull, PtrOutOfRange { range: WrappingRange, max_value: u128, @@ -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, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 4f039381e500d..a4422abc6883a 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -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, @@ -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); diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index a174ced5a2a63..cef700be9ea1f 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1312,28 +1312,28 @@ pub fn log2f128(x: f128) -> f128; /// [`f16::mul_add`](../../std/primitive.f16.html#method.mul_add) #[rustc_intrinsic] #[rustc_nounwind] -pub fn fmaf16(a: f16, b: f16, c: f16) -> f16; +pub const fn fmaf16(a: f16, b: f16, c: f16) -> f16; /// Returns `a * b + c` for `f32` values. /// /// The stabilized version of this intrinsic is /// [`f32::mul_add`](../../std/primitive.f32.html#method.mul_add) #[rustc_intrinsic] #[rustc_nounwind] -pub fn fmaf32(a: f32, b: f32, c: f32) -> f32; +pub const fn fmaf32(a: f32, b: f32, c: f32) -> f32; /// Returns `a * b + c` for `f64` values. /// /// The stabilized version of this intrinsic is /// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add) #[rustc_intrinsic] #[rustc_nounwind] -pub fn fmaf64(a: f64, b: f64, c: f64) -> f64; +pub const fn fmaf64(a: f64, b: f64, c: f64) -> f64; /// Returns `a * b + c` for `f128` values. /// /// The stabilized version of this intrinsic is /// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add) #[rustc_intrinsic] #[rustc_nounwind] -pub fn fmaf128(a: f128, b: f128, c: f128) -> f128; +pub const fn fmaf128(a: f128, b: f128, c: f128) -> f128; /// Returns `a * b + c` for `f16` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the @@ -1347,7 +1347,7 @@ pub fn fmaf128(a: f128, b: f128, c: f128) -> f128; /// example. #[rustc_intrinsic] #[rustc_nounwind] -pub fn fmuladdf16(a: f16, b: f16, c: f16) -> f16; +pub const fn fmuladdf16(a: f16, b: f16, c: f16) -> f16; /// Returns `a * b + c` for `f32` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the /// intermediate result. @@ -1360,7 +1360,7 @@ pub fn fmuladdf16(a: f16, b: f16, c: f16) -> f16; /// example. #[rustc_intrinsic] #[rustc_nounwind] -pub fn fmuladdf32(a: f32, b: f32, c: f32) -> f32; +pub const fn fmuladdf32(a: f32, b: f32, c: f32) -> f32; /// Returns `a * b + c` for `f64` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the /// intermediate result. @@ -1373,7 +1373,7 @@ pub fn fmuladdf32(a: f32, b: f32, c: f32) -> f32; /// example. #[rustc_intrinsic] #[rustc_nounwind] -pub fn fmuladdf64(a: f64, b: f64, c: f64) -> f64; +pub const fn fmuladdf64(a: f64, b: f64, c: f64) -> f64; /// Returns `a * b + c` for `f128` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the /// intermediate result. @@ -1386,7 +1386,7 @@ pub fn fmuladdf64(a: f64, b: f64, c: f64) -> f64; /// example. #[rustc_intrinsic] #[rustc_nounwind] -pub fn fmuladdf128(a: f128, b: f128, c: f128) -> f128; +pub const fn fmuladdf128(a: f128, b: f128, c: f128) -> f128; /// Returns the largest integer less than or equal to an `f16`. /// @@ -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`. /// @@ -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`. /// @@ -3188,7 +3188,7 @@ 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`. /// @@ -3196,7 +3196,7 @@ pub const unsafe fn fabsf64(x: f64) -> f64; /// [`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. /// @@ -3204,7 +3204,7 @@ pub const unsafe fn fabsf128(x: f128) -> f128; /// [`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. /// @@ -3213,7 +3213,7 @@ 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 @@ -3221,7 +3221,7 @@ pub const unsafe fn copysignf32(x: f32, y: f32) -> f32; #[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. /// @@ -3229,7 +3229,7 @@ pub const unsafe fn copysignf64(x: f64, y: f64) -> f64; /// [`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. diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index b0c9e9ef05e76..73ca3fbb142c8 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -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. @@ -1660,7 +1659,8 @@ impl f128 { #[doc(alias = "fmaf128", alias = "fusedMultiplyAdd")] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn mul_add(self, a: f128, b: f128) -> f128 { + #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] + pub const fn mul_add(self, a: f128, b: f128) -> f128 { intrinsics::fmaf128(self, a, b) } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 56db92f91fcf1..a9dbade0e6599 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -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. @@ -1635,7 +1634,8 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[doc(alias = "fmaf16", alias = "fusedMultiplyAdd")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn mul_add(self, a: f16, b: f16) -> f16 { + #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] + pub const fn mul_add(self, a: f16, b: f16) -> f16 { intrinsics::fmaf16(self, a, b) } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 57be4d8d30ad1..53474cd3e9058 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -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`. @@ -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. @@ -1800,7 +1798,8 @@ pub mod math { #[doc(alias = "fmaf", alias = "fusedMultiplyAdd")] #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "core_float_math", issue = "137578")] - pub fn mul_add(x: f32, y: f32, z: f32) -> f32 { + #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] + pub const fn mul_add(x: f32, y: f32, z: f32) -> f32 { intrinsics::fmaf32(x, y, z) } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 748956ae980d6..78113a60bbc28 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -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`. @@ -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. @@ -1798,7 +1796,8 @@ pub mod math { #[doc(alias = "fma", alias = "fusedMultiplyAdd")] #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn mul_add(x: f64, a: f64, b: f64) -> f64 { + #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] + pub const fn mul_add(x: f64, a: f64, b: f64) -> f64 { intrinsics::fmaf64(x, a, b) } diff --git a/library/coretests/tests/floats/f128.rs b/library/coretests/tests/floats/f128.rs index d31eba863f5fe..62278bf96c3c1 100644 --- a/library/coretests/tests/floats/f128.rs +++ b/library/coretests/tests/floats/f128.rs @@ -20,24 +20,6 @@ const TOL_PRECISE: f128 = 1e-28; // FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support // the intrinsics. -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_mul_add() { - let nan: f128 = f128::NAN; - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - assert_biteq!(12.3f128.mul_add(4.5, 6.7), 62.0500000000000000000000000000000037); - assert_biteq!((-12.3f128).mul_add(-4.5, -6.7), 48.6500000000000000000000000000000049); - assert_biteq!(0.0f128.mul_add(8.9, 1.2), 1.2); - assert_biteq!(3.4f128.mul_add(-0.0, 5.6), 5.6); - assert!(nan.mul_add(7.8, 9.0).is_nan()); - assert_biteq!(inf.mul_add(7.8, 9.0), inf); - assert_biteq!(neg_inf.mul_add(7.8, 9.0), neg_inf); - assert_biteq!(8.9f128.mul_add(inf, 3.2), inf); - assert_biteq!((-3.2f128).mul_add(2.4, neg_inf), neg_inf); -} - #[test] #[cfg(any(miri, target_has_reliable_f128_math))] fn test_max_recip() { diff --git a/library/coretests/tests/floats/f16.rs b/library/coretests/tests/floats/f16.rs index 302fd0861d75d..7ffafd467a519 100644 --- a/library/coretests/tests/floats/f16.rs +++ b/library/coretests/tests/floats/f16.rs @@ -22,24 +22,6 @@ const TOL_P4: f16 = 10.0; // FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support // the intrinsics. -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_mul_add() { - let nan: f16 = f16::NAN; - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - assert_biteq!(12.3f16.mul_add(4.5, 6.7), 62.031); - assert_biteq!((-12.3f16).mul_add(-4.5, -6.7), 48.625); - assert_biteq!(0.0f16.mul_add(8.9, 1.2), 1.2); - assert_biteq!(3.4f16.mul_add(-0.0, 5.6), 5.6); - assert!(nan.mul_add(7.8, 9.0).is_nan()); - assert_biteq!(inf.mul_add(7.8, 9.0), inf); - assert_biteq!(neg_inf.mul_add(7.8, 9.0), neg_inf); - assert_biteq!(8.9f16.mul_add(inf, 3.2), inf); - assert_biteq!((-3.2f16).mul_add(2.4, neg_inf), neg_inf); -} - #[test] #[cfg(any(miri, target_has_reliable_f16_math))] fn test_max_recip() { diff --git a/library/coretests/tests/floats/f32.rs b/library/coretests/tests/floats/f32.rs deleted file mode 100644 index a1fe8b076501d..0000000000000 --- a/library/coretests/tests/floats/f32.rs +++ /dev/null @@ -1,21 +0,0 @@ -use core::f32; - -use super::assert_biteq; - -// FIXME(#140515): mingw has an incorrect fma https://sourceforge.net/p/mingw-w64/bugs/848/ -#[cfg_attr(all(target_os = "windows", target_env = "gnu", not(target_abi = "llvm")), ignore)] -#[test] -fn test_mul_add() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_biteq!(f32::math::mul_add(12.3f32, 4.5, 6.7), 62.05); - assert_biteq!(f32::math::mul_add(-12.3f32, -4.5, -6.7), 48.65); - assert_biteq!(f32::math::mul_add(0.0f32, 8.9, 1.2), 1.2); - assert_biteq!(f32::math::mul_add(3.4f32, -0.0, 5.6), 5.6); - assert!(f32::math::mul_add(nan, 7.8, 9.0).is_nan()); - assert_biteq!(f32::math::mul_add(inf, 7.8, 9.0), inf); - assert_biteq!(f32::math::mul_add(neg_inf, 7.8, 9.0), neg_inf); - assert_biteq!(f32::math::mul_add(8.9f32, inf, 3.2), inf); - assert_biteq!(f32::math::mul_add(-3.2f32, 2.4, neg_inf), neg_inf); -} diff --git a/library/coretests/tests/floats/f64.rs b/library/coretests/tests/floats/f64.rs deleted file mode 100644 index 4c5a3d68d1fd6..0000000000000 --- a/library/coretests/tests/floats/f64.rs +++ /dev/null @@ -1,21 +0,0 @@ -use core::f64; - -use super::assert_biteq; - -// FIXME(#140515): mingw has an incorrect fma https://sourceforge.net/p/mingw-w64/bugs/848/ -#[cfg_attr(all(target_os = "windows", target_env = "gnu", not(target_abi = "llvm")), ignore)] -#[test] -fn test_mul_add() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_biteq!(12.3f64.mul_add(4.5, 6.7), 62.050000000000004); - assert_biteq!((-12.3f64).mul_add(-4.5, -6.7), 48.650000000000006); - assert_biteq!(0.0f64.mul_add(8.9, 1.2), 1.2); - assert_biteq!(3.4f64.mul_add(-0.0, 5.6), 5.6); - assert!(nan.mul_add(7.8, 9.0).is_nan()); - assert_biteq!(inf.mul_add(7.8, 9.0), inf); - assert_biteq!(neg_inf.mul_add(7.8, 9.0), neg_inf); - assert_biteq!(8.9f64.mul_add(inf, 3.2), inf); - assert_biteq!((-3.2f64).mul_add(2.4, neg_inf), neg_inf); -} diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs index d2b5722309445..cc32bfa4a7db0 100644 --- a/library/coretests/tests/floats/mod.rs +++ b/library/coretests/tests/floats/mod.rs @@ -34,6 +34,10 @@ trait TestableFloat: Sized { const RAW_12_DOT_5: Self; const RAW_1337: Self; const RAW_MINUS_14_DOT_25: Self; + /// The result of 12.3.mul_add(4.5, 6.7) + const MUL_ADD_RESULT: Self; + /// The result of (-12.3).mul_add(-4.5, -6.7) + const NEG_MUL_ADD_RESULT: Self; } impl TestableFloat for f16 { @@ -58,6 +62,8 @@ impl TestableFloat for f16 { const RAW_12_DOT_5: Self = Self::from_bits(0x4a40); const RAW_1337: Self = Self::from_bits(0x6539); const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xcb20); + const MUL_ADD_RESULT: Self = 62.031; + const NEG_MUL_ADD_RESULT: Self = 48.625; } impl TestableFloat for f32 { @@ -84,6 +90,8 @@ impl TestableFloat for f32 { const RAW_12_DOT_5: Self = Self::from_bits(0x41480000); const RAW_1337: Self = Self::from_bits(0x44a72000); const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xc1640000); + const MUL_ADD_RESULT: Self = 62.05; + const NEG_MUL_ADD_RESULT: Self = 48.65; } impl TestableFloat for f64 { @@ -106,6 +114,8 @@ impl TestableFloat for f64 { const RAW_12_DOT_5: Self = Self::from_bits(0x4029000000000000); const RAW_1337: Self = Self::from_bits(0x4094e40000000000); const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xc02c800000000000); + const MUL_ADD_RESULT: Self = 62.050000000000004; + const NEG_MUL_ADD_RESULT: Self = 48.650000000000006; } impl TestableFloat for f128 { @@ -128,6 +138,8 @@ impl TestableFloat for f128 { const RAW_12_DOT_5: Self = Self::from_bits(0x40029000000000000000000000000000); const RAW_1337: Self = Self::from_bits(0x40094e40000000000000000000000000); const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xc002c800000000000000000000000000); + const MUL_ADD_RESULT: Self = 62.0500000000000000000000000000000037; + const NEG_MUL_ADD_RESULT: Self = 48.6500000000000000000000000000000049; } /// Determine the tolerance for values of the argument type. @@ -359,8 +371,6 @@ macro_rules! float_test { mod f128; mod f16; -mod f32; -mod f64; float_test! { name: num, @@ -1541,3 +1551,25 @@ float_test! { assert_biteq!(Float::from_bits(masked_nan2), Float::from_bits(masked_nan2)); } } + +float_test! { + name: mul_add, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + f128: #[cfg(any(miri, target_has_reliable_f128))], + }, + test { + let nan: Float = Float::NAN; + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + assert_biteq!(flt(12.3).mul_add(4.5, 6.7), Float::MUL_ADD_RESULT); + assert_biteq!((flt(-12.3)).mul_add(-4.5, -6.7), Float::NEG_MUL_ADD_RESULT); + assert_biteq!(flt(0.0).mul_add(8.9, 1.2), 1.2); + assert_biteq!(flt(3.4).mul_add(-0.0, 5.6), 5.6); + assert!(nan.mul_add(7.8, 9.0).is_nan()); + assert_biteq!(inf.mul_add(7.8, 9.0), inf); + assert_biteq!(neg_inf.mul_add(7.8, 9.0), neg_inf); + assert_biteq!(flt(8.9).mul_add(inf, 3.2), inf); + assert_biteq!((flt(-3.2)).mul_add(2.4, neg_inf), neg_inf); + } +} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 5c519f3a499d2..a80d7f8b44d7d 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -20,6 +20,7 @@ #![feature(const_convert)] #![feature(const_destruct)] #![feature(const_eval_select)] +#![feature(const_mul_add)] #![feature(const_ops)] #![feature(const_option_ops)] #![feature(const_ref_cell)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 45abd6bca8a5b..233e41aa34535 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -332,6 +332,7 @@ #![feature(char_internals)] #![feature(clone_to_uninit)] #![feature(const_convert)] +#![feature(const_mul_add)] #![feature(core_intrinsics)] #![feature(core_io_borrowed_buf)] #![feature(drop_guard)] diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs index ac1d889cc3731..e7810e77e76f0 100644 --- a/library/std/src/num/f32.rs +++ b/library/std/src/num/f32.rs @@ -217,7 +217,8 @@ impl f32 { #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn mul_add(self, a: f32, b: f32) -> f32 { + #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] + pub const fn mul_add(self, a: f32, b: f32) -> f32 { core::f32::math::mul_add(self, a, b) } diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs index 55c8593a0c0b1..cbebbfb1be166 100644 --- a/library/std/src/num/f64.rs +++ b/library/std/src/num/f64.rs @@ -217,7 +217,8 @@ impl f64 { #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn mul_add(self, a: f64, b: f64) -> f64 { + #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] + pub const fn mul_add(self, a: f64, b: f64) -> f64 { core::f64::math::mul_add(self, a, b) } diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index b50574de937aa..c0d69c3e0029a 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -92,6 +92,9 @@ pub(crate) fn locate_handles(mut guid: Guid) -> io::Result( handle: NonNull, mut protocol_guid: Guid, @@ -473,6 +476,7 @@ impl<'a> crate::fmt::Debug for DevicePathNode<'a> { } } +/// Protocols installed by Rust side on a handle. pub(crate) struct OwnedProtocol { guid: r_efi::efi::Guid, handle: NonNull, diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index da09117b1bba7..136ff258048bf 100644 --- a/src/librustdoc/passes/lint/html_tags.rs +++ b/src/librustdoc/passes/lint/html_tags.rs @@ -364,6 +364,7 @@ impl TagParser { } else { if !self.tag_name.is_empty() { self.in_attrs = true; + // range of the entire tag within dox let mut r = Range { start: range.start + start_pos, end: range.start + pos }; if c == '>' { // In case we have a tag without attribute, we can consider the span to @@ -381,7 +382,7 @@ impl TagParser { for (new_pos, c) in text[pos..].char_indices() { if !c.is_whitespace() { if c == '>' { - r.end = range.start + new_pos + 1; + r.end = range.start + pos + new_pos + 1; found = true; } else if c == '<' { self.handle_lt_in_tag(range.clone(), pos + new_pos, f); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 29578acb40400..bd32bec383fa3 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2663,7 +2663,7 @@ impl<'test> TestCx<'test> { // The alloc-id appears in pretty-printed allocations. normalized = static_regex!( - r"╾─*a(lloc)?([0-9]+)(\+0x[0-9]+)?()?( \([0-9]+ ptr bytes\))?─*╼" + r"╾─*a(lloc)?([0-9]+)(\+0x[0-9a-f]+)?()?( \([0-9]+ ptr bytes\))?─*╼" ) .replace_all(&normalized, |caps: &Captures<'_>| { // Renumber the captured index. diff --git a/src/tools/miri/src/intrinsics/math.rs b/src/tools/miri/src/intrinsics/math.rs index b9c99f2859468..0cc4342f0d55d 100644 --- a/src/tools/miri/src/intrinsics/math.rs +++ b/src/tools/miri/src/intrinsics/math.rs @@ -1,4 +1,3 @@ -use rand::Rng; use rustc_apfloat::{self, Float, FloatConvert, Round}; use rustc_middle::mir; use rustc_middle::ty::{self, FloatTy}; @@ -39,46 +38,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "sqrtf64" => sqrt::(this, args, dest)?, "sqrtf128" => sqrt::(this, args, dest)?, - "fmaf32" => { - let [a, b, c] = check_intrinsic_arg_count(args)?; - let a = this.read_scalar(a)?.to_f32()?; - let b = this.read_scalar(b)?.to_f32()?; - let c = this.read_scalar(c)?.to_f32()?; - let res = a.mul_add(b, c).value; - let res = this.adjust_nan(res, &[a, b, c]); - this.write_scalar(res, dest)?; - } - "fmaf64" => { - let [a, b, c] = check_intrinsic_arg_count(args)?; - let a = this.read_scalar(a)?.to_f64()?; - let b = this.read_scalar(b)?.to_f64()?; - let c = this.read_scalar(c)?.to_f64()?; - let res = a.mul_add(b, c).value; - let res = this.adjust_nan(res, &[a, b, c]); - this.write_scalar(res, dest)?; - } - - "fmuladdf32" => { - let [a, b, c] = check_intrinsic_arg_count(args)?; - let a = this.read_scalar(a)?.to_f32()?; - let b = this.read_scalar(b)?.to_f32()?; - let c = this.read_scalar(c)?.to_f32()?; - let fuse: bool = this.machine.float_nondet && this.machine.rng.get_mut().random(); - let res = if fuse { a.mul_add(b, c).value } else { ((a * b).value + c).value }; - let res = this.adjust_nan(res, &[a, b, c]); - this.write_scalar(res, dest)?; - } - "fmuladdf64" => { - let [a, b, c] = check_intrinsic_arg_count(args)?; - let a = this.read_scalar(a)?.to_f64()?; - let b = this.read_scalar(b)?.to_f64()?; - let c = this.read_scalar(c)?.to_f64()?; - let fuse: bool = this.machine.float_nondet && this.machine.rng.get_mut().random(); - let res = if fuse { a.mul_add(b, c).value } else { ((a * b).value + c).value }; - let res = this.adjust_nan(res, &[a, b, c]); - this.write_scalar(res, dest)?; - } - #[rustfmt::skip] | "fadd_fast" | "fsub_fast" diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 04c8bee72c038..d307636e782fc 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1293,6 +1293,11 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { ecx.equal_float_min_max(a, b) } + #[inline(always)] + fn float_fuse_mul_add(ecx: &mut InterpCx<'tcx, Self>) -> bool { + ecx.machine.float_nondet && ecx.machine.rng.get_mut().random() + } + #[inline(always)] fn ub_checks(ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool> { interp_ok(ecx.tcx.sess.ub_checks()) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index 301d4cca0666c..e5c213ca937c8 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -15,10 +15,6 @@ extern crate rustc_parse_format; #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_parse_format as rustc_parse_format; -#[cfg(feature = "in-rust-tree")] -extern crate rustc_abi; - -#[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_abi as rustc_abi; pub mod db; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 451622ef7472b..2e59a488e6734 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -3,45 +3,24 @@ #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] -#[cfg(feature = "in-rust-tree")] -extern crate rustc_index; +// FIXME: We used to import `rustc_*` deps from `rustc_private` with `feature = "in-rust-tree" but +// temporarily switched to crates.io versions due to hardships that working on them from rustc +// demands corresponding changes on rust-analyzer at the same time. +// For details, see the zulip discussion below: +// https://rust-lang.zulipchat.com/#narrow/channel/185405-t-compiler.2Frust-analyzer/topic/relying.20on.20in-tree.20.60rustc_type_ir.60.2F.60rustc_next_trait_solver.60/with/541055689 -#[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_index as rustc_index; -#[cfg(feature = "in-rust-tree")] -extern crate rustc_abi; - -#[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_abi as rustc_abi; -#[cfg(feature = "in-rust-tree")] -extern crate rustc_pattern_analysis; - -#[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_pattern_analysis as rustc_pattern_analysis; -#[cfg(feature = "in-rust-tree")] -extern crate rustc_ast_ir; - -#[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_ast_ir as rustc_ast_ir; -#[cfg(feature = "in-rust-tree")] -extern crate rustc_type_ir; - -#[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_type_ir as rustc_type_ir; -#[cfg(feature = "in-rust-tree")] -extern crate rustc_next_trait_solver; - -#[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_next_trait_solver as rustc_next_trait_solver; -#[cfg(feature = "in-rust-tree")] -extern crate rustc_data_structures as ena; - mod builder; mod chalk_db; mod chalk_ext; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs index 7ebefa76ed029..0b3582051bc07 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs @@ -36,8 +36,6 @@ impl<'db> Const<'db> { internee: kind, flags: flags.flags, outer_exclusive_binder: flags.outer_exclusive_binder, - #[cfg(feature = "in-rust-tree")] - stable_hash: ena::fingerprint::Fingerprint::ZERO, }; Const::new_(interner.db(), InternedWrapperNoDebug(cached)) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs index 86545415009a0..99b1354b6335f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs @@ -227,8 +227,6 @@ impl<'db> Predicate<'db> { internee: kind, flags: flags.flags, outer_exclusive_binder: flags.outer_exclusive_binder, - #[cfg(feature = "in-rust-tree")] - stable_hash: ena::fingerprint::Fingerprint::ZERO, }; Predicate::new_(interner.db(), InternedWrapperNoDebug(cached)) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs index c7a747ade3e76..70139e8666948 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs @@ -60,8 +60,6 @@ impl<'db> Ty<'db> { internee: kind, flags: flags.flags, outer_exclusive_binder: flags.outer_exclusive_binder, - #[cfg(feature = "in-rust-tree")] - stable_hash: ena::fingerprint::Fingerprint::ZERO, }; Ty::new_(interner.db(), InternedWrapperNoDebug(cached)) } diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index f8dacf0fb863d..027a386abe8ce 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -20,10 +20,6 @@ #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] #![recursion_limit = "512"] -#[cfg(feature = "in-rust-tree")] -extern crate rustc_type_ir; - -#[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_type_ir as rustc_type_ir; mod attrs; diff --git a/tests/rustdoc-ui/lints/invalid-html-tags-ice-146890.rs b/tests/rustdoc-ui/lints/invalid-html-tags-ice-146890.rs new file mode 100644 index 0000000000000..d7efc201e7e39 --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-html-tags-ice-146890.rs @@ -0,0 +1,25 @@ +// this test ensures that bad HTML with multiline tags doesn't cause an ICE +// regression test for https://github.com/rust-lang/rust/issues/146890 +#[deny(rustdoc::invalid_html_tags)] + +/// +/// +/// +///
key +/// +/// value +/// +///
+pub fn foo() {} diff --git a/tests/rustdoc-ui/lints/invalid-html-tags-ice-146890.stderr b/tests/rustdoc-ui/lints/invalid-html-tags-ice-146890.stderr new file mode 100644 index 0000000000000..64a82b3a952aa --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-html-tags-ice-146890.stderr @@ -0,0 +1,38 @@ +error: unopened HTML tag `TD` + --> $DIR/invalid-html-tags-ice-146890.rs:12:5 + | +LL | /// + | |_____^ + | +note: the lint level is defined here + --> $DIR/invalid-html-tags-ice-146890.rs:3:8 + | +LL | #[deny(rustdoc::invalid_html_tags)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unopened HTML tag `TD` + --> $DIR/invalid-html-tags-ice-146890.rs:18:5 + | +LL | /// + | |_____^ + +error: unclosed HTML tag `TH` + --> $DIR/invalid-html-tags-ice-146890.rs:9:5 + | +LL | /// $DIR/invalid-html-tags-ice-146890.rs:15:5 + | +LL | /// (T); + +impl<'a> Foo { + //~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait + type Assoc = &'a (); +} + +fn foo(_: for<'a> fn(Foo::Assoc)) {} +//~^ ERROR mismatched types +//~| ERROR higher-ranked subtype error +fn main() {} diff --git a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr new file mode 100644 index 0000000000000..4c0726d4ddca9 --- /dev/null +++ b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr @@ -0,0 +1,34 @@ +warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:4:12 + | +LL | #![feature(inherent_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #8995 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:9:6 + | +LL | impl<'a> Foo { + | ^^ unconstrained lifetime parameter + +error[E0308]: mismatched types + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:11 + | +LL | fn foo(_: for<'a> fn(Foo::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected struct `Foo fn(&'a ())>` + found struct `Foo fn(&'a ())>` + +error: higher-ranked subtype error + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:1 + | +LL | fn foo(_: for<'a> fn(Foo::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0207, E0308. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/consts/const-eval/ub-nonnull.rs b/tests/ui/consts/const-eval/ub-nonnull.rs index 9164684262480..851f3996cd104 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.rs +++ b/tests/ui/consts/const-eval/ub-nonnull.rs @@ -57,4 +57,8 @@ const NULL_FAT_PTR: NonNull = unsafe { mem::transmute((0_usize, meta)) }; +static S: u32 = 0; // just a static to construct a maybe-null pointer off of +const MAYBE_NULL_PTR: NonNull<()> = unsafe { mem::transmute((&raw const S).wrapping_add(4)) }; +//~^ ERROR invalid value + fn main() {} diff --git a/tests/ui/consts/const-eval/ub-nonnull.stderr b/tests/ui/consts/const-eval/ub-nonnull.stderr index 91c82efbc5ed1..e4486e3c500b9 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.stderr +++ b/tests/ui/consts/const-eval/ub-nonnull.stderr @@ -9,7 +9,7 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; HEX_DUMP } -error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by 255 bytes, but got ALLOC1 which is only 1 byte from the end of the allocation +error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by 255 bytes, but got ALLOC2 which is only 1 byte from the end of the allocation --> $DIR/ub-nonnull.rs:22:29 | LL | let out_of_bounds_ptr = &ptr[255]; @@ -37,7 +37,7 @@ LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; HEX_DUMP } -error[E0080]: reading memory at ALLOC2[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory +error[E0080]: reading memory at ALLOC3[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory --> $DIR/ub-nonnull.rs:36:38 | LL | const UNINIT: NonZero = unsafe { MaybeUninit { uninit: () }.init }; @@ -80,6 +80,17 @@ LL | const NULL_FAT_PTR: NonNull = unsafe { HEX_DUMP } -error: aborting due to 8 previous errors +error[E0080]: constructing invalid value: encountered a maybe-null pointer, but expected something that is definitely non-zero + --> $DIR/ub-nonnull.rs:61:1 + | +LL | const MAYBE_NULL_PTR: NonNull<()> = unsafe { mem::transmute((&raw const S).wrapping_add(4)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value + | + = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.rs b/tests/ui/consts/const-eval/ub-ref-ptr.rs index d8e5102fcbe78..a5fdde1f9a4e9 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.rs +++ b/tests/ui/consts/const-eval/ub-ref-ptr.rs @@ -4,7 +4,7 @@ //@ normalize-stderr: "([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" //@ dont-require-annotations: NOTE //@ normalize-stderr: "0x[0-9](\.\.|\])" -> "0x%$1" - +#![feature(rustc_attrs)] #![allow(invalid_value)] use std::mem; @@ -27,6 +27,11 @@ const NULL: &u16 = unsafe { mem::transmute(0usize) }; const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; //~^ ERROR invalid value +const MAYBE_NULL_BOX: Box<()> = unsafe { mem::transmute({ +//~^ ERROR maybe-null + let ref_ = &0u8; + (ref_ as *const u8).wrapping_add(10) +}) }; // It is very important that we reject this: We do promote `&(4 * REF_AS_USIZE)`, // but that would fail to compile; so we ended up breaking user code that would @@ -57,7 +62,12 @@ const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; //~^ ERROR invalid value const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; //~^ ERROR invalid value - +const MAYBE_NULL_FN_PTR: fn() = unsafe { mem::transmute({ +//~^ ERROR invalid value + fn fun() {} + let ptr = fun as fn(); + (ptr as *const u8).wrapping_add(10) +}) }; const UNALIGNED_READ: () = unsafe { let x = &[0u8; 4]; @@ -65,5 +75,14 @@ const UNALIGNED_READ: () = unsafe { ptr.read(); //~ ERROR accessing memory }; +// Check the general case of a pointer value not falling into the scalar valid range. +#[rustc_layout_scalar_valid_range_start(1000)] +pub struct High { + pointer: *const (), +} +static S: u32 = 0; // just a static to construct a pointer with unknown absolute address +const INVALID_VALUE_PTR: High = unsafe { mem::transmute(&S) }; +//~^ ERROR invalid value + fn main() {} diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr index c45f66c29259c..349a98f11be42 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr @@ -42,8 +42,19 @@ LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; HEX_DUMP } +error[E0080]: constructing invalid value: encountered a maybe-null box + --> $DIR/ub-ref-ptr.rs:30:1 + | +LL | const MAYBE_NULL_BOX: Box<()> = unsafe { mem::transmute({ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value + | + = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + error[E0080]: unable to turn pointer into integer - --> $DIR/ub-ref-ptr.rs:34:1 + --> $DIR/ub-ref-ptr.rs:39:1 | LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `REF_AS_USIZE` failed here @@ -52,7 +63,7 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: unable to turn pointer into integer - --> $DIR/ub-ref-ptr.rs:37:39 + --> $DIR/ub-ref-ptr.rs:42:39 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `REF_AS_USIZE_SLICE` failed here @@ -61,13 +72,13 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant encountered - --> $DIR/ub-ref-ptr.rs:37:38 + --> $DIR/ub-ref-ptr.rs:42:38 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: unable to turn pointer into integer - --> $DIR/ub-ref-ptr.rs:40:86 + --> $DIR/ub-ref-ptr.rs:45:86 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^ evaluation of `REF_AS_USIZE_BOX_SLICE` failed here @@ -76,13 +87,13 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant encountered - --> $DIR/ub-ref-ptr.rs:40:85 + --> $DIR/ub-ref-ptr.rs:45:85 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^^ error[E0080]: constructing invalid value: encountered a dangling reference (0x539[noalloc] has no provenance) - --> $DIR/ub-ref-ptr.rs:43:1 + --> $DIR/ub-ref-ptr.rs:48:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -93,7 +104,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; } error[E0080]: constructing invalid value: encountered a dangling box (0x539[noalloc] has no provenance) - --> $DIR/ub-ref-ptr.rs:46:1 + --> $DIR/ub-ref-ptr.rs:51:1 | LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -103,8 +114,8 @@ LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; HEX_DUMP } -error[E0080]: reading memory at ALLOC3[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory - --> $DIR/ub-ref-ptr.rs:49:41 +error[E0080]: reading memory at ALLOC6[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory + --> $DIR/ub-ref-ptr.rs:54:41 | LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT_PTR` failed here @@ -114,7 +125,7 @@ LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; } error[E0080]: constructing invalid value: encountered null pointer, but expected a function pointer - --> $DIR/ub-ref-ptr.rs:52:1 + --> $DIR/ub-ref-ptr.rs:57:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -124,8 +135,8 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; HEX_DUMP } -error[E0080]: reading memory at ALLOC4[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory - --> $DIR/ub-ref-ptr.rs:54:38 +error[E0080]: reading memory at ALLOC7[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory + --> $DIR/ub-ref-ptr.rs:59:38 | LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT_FN_PTR` failed here @@ -135,7 +146,7 @@ LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; } error[E0080]: constructing invalid value: encountered 0xd[noalloc], but expected a function pointer - --> $DIR/ub-ref-ptr.rs:56:1 + --> $DIR/ub-ref-ptr.rs:61:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -145,8 +156,8 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; HEX_DUMP } -error[E0080]: constructing invalid value: encountered ALLOC2, but expected a function pointer - --> $DIR/ub-ref-ptr.rs:58:1 +error[E0080]: constructing invalid value: encountered ALLOC3, but expected a function pointer + --> $DIR/ub-ref-ptr.rs:63:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -156,12 +167,34 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; HEX_DUMP } +error[E0080]: constructing invalid value: encountered ALLOC4+0xa, but expected a function pointer + --> $DIR/ub-ref-ptr.rs:65:1 + | +LL | const MAYBE_NULL_FN_PTR: fn() = unsafe { mem::transmute({ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value + | + = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + error[E0080]: accessing memory based on pointer with alignment 1, but alignment 4 is required - --> $DIR/ub-ref-ptr.rs:65:5 + --> $DIR/ub-ref-ptr.rs:75:5 | LL | ptr.read(); | ^^^^^^^^^^ evaluation of `UNALIGNED_READ` failed here -error: aborting due to 15 previous errors +error[E0080]: constructing invalid value: encountered a pointer with unknown absolute address, but expected something that is definitely greater or equal to 1000 + --> $DIR/ub-ref-ptr.rs:84:1 + | +LL | const INVALID_VALUE_PTR: High = unsafe { mem::transmute(&S) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value + | + = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + +error: aborting due to 18 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const_transmute_type_id7.rs b/tests/ui/consts/const_transmute_type_id7.rs new file mode 100644 index 0000000000000..73b8187a8007a --- /dev/null +++ b/tests/ui/consts/const_transmute_type_id7.rs @@ -0,0 +1,16 @@ +//! Ensure a decent error message for maybe-null references. +//! (see ) + +// Strip out raw byte dumps to make comparison platform-independent: +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" + +#![feature(const_trait_impl, const_cmp)] + +use std::any::TypeId; +use std::mem::transmute; + +const A: [&(); 16 / size_of::<*const ()>()] = unsafe { transmute(TypeId::of::()) }; +//~^ERROR: maybe-null + +fn main() {} diff --git a/tests/ui/consts/const_transmute_type_id7.stderr b/tests/ui/consts/const_transmute_type_id7.stderr new file mode 100644 index 0000000000000..664975831f402 --- /dev/null +++ b/tests/ui/consts/const_transmute_type_id7.stderr @@ -0,0 +1,14 @@ +error[E0080]: constructing invalid value at [0]: encountered a maybe-null reference + --> $DIR/const_transmute_type_id7.rs:13:1 + | +LL | const A: [&(); 16 / size_of::<*const ()>()] = unsafe { transmute(TypeId::of::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value + | + = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/higher-ranked/do-not-blame-outlives-static-ice.rs b/tests/ui/higher-ranked/do-not-blame-outlives-static-ice.rs new file mode 100644 index 0000000000000..dfdb816652c44 --- /dev/null +++ b/tests/ui/higher-ranked/do-not-blame-outlives-static-ice.rs @@ -0,0 +1,12 @@ +//@ compile-flags: -Zdeduplicate-diagnostics=yes + +// Regression test for #146467. +trait Trait { type Assoc; } + +impl Trait for fn(&()) { type Assoc = (); } + +fn f(_: for<'a> fn(::Assoc)) {} +//~^ ERROR implementation of `Trait` is not general enough +//~| ERROR higher-ranked subtype error + +fn main() {} diff --git a/tests/ui/higher-ranked/do-not-blame-outlives-static-ice.stderr b/tests/ui/higher-ranked/do-not-blame-outlives-static-ice.stderr new file mode 100644 index 0000000000000..c75a063e45fa0 --- /dev/null +++ b/tests/ui/higher-ranked/do-not-blame-outlives-static-ice.stderr @@ -0,0 +1,17 @@ +error: implementation of `Trait` is not general enough + --> $DIR/do-not-blame-outlives-static-ice.rs:8:9 + | +LL | fn f(_: for<'a> fn(::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough + | + = note: `for<'a> fn(&'a ())` must implement `Trait`, for any lifetime `'0`... + = note: ...but `Trait` is actually implemented for the type `for<'a> fn(&'a ())` + +error: higher-ranked subtype error + --> $DIR/do-not-blame-outlives-static-ice.rs:8:1 + | +LL | fn f(_: for<'a> fn(::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lifetimes/temporary-lifetime-extension-tuple-ctor.rs b/tests/ui/lifetimes/temporary-lifetime-extension-tuple-ctor.rs index bb537f855a4ab..7de786dff3b77 100644 --- a/tests/ui/lifetimes/temporary-lifetime-extension-tuple-ctor.rs +++ b/tests/ui/lifetimes/temporary-lifetime-extension-tuple-ctor.rs @@ -1,4 +1,4 @@ -//@ edition:2024 +//@ reference: destructors.scope.lifetime-extension.exprs fn temp() -> String { String::from("Hello") @@ -22,7 +22,7 @@ fn main() { let a = &temp(); let b = Some(&temp()); let c = Option::Some::<&String>(&temp()); - use Option::Some as S; + use std::option::Option::Some as S; let d = S(&temp()); let e = X(&temp()); let f = Some(Ok::<_, ()>(std::borrow::Cow::Borrowed(if true { @@ -31,6 +31,6 @@ fn main() { panic!() }))); let some = Some; // Turn the ctor into a regular function. - let g = some(&temp()); //~ERROR temporary value dropped while borrowe + let g = some(&temp()); //~ERROR temporary value dropped while borrowed println!("{a:?} {b:?} {c:?} {d:?} {e:?} {f:?} {g:?}"); } diff --git a/tests/ui/type-inference/box_has_sigdrop.rs b/tests/ui/type-inference/box_has_sigdrop.rs new file mode 100644 index 0000000000000..3e801197a78e6 --- /dev/null +++ b/tests/ui/type-inference/box_has_sigdrop.rs @@ -0,0 +1,9 @@ +//@ should-fail +//@ compile-flags: -Wrust-2021-incompatible-closure-captures +// Inference, canonicalization, and significant drops should work nicely together. +// Related issue: #86868 + +fn main() { + let mut state = 0; + Box::new(move || state) +} diff --git a/tests/ui/type-inference/box_has_sigdrop.stderr b/tests/ui/type-inference/box_has_sigdrop.stderr new file mode 100644 index 0000000000000..b61b6322c107f --- /dev/null +++ b/tests/ui/type-inference/box_has_sigdrop.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/box_has_sigdrop.rs:8:5 + | +LL | fn main() { + | - expected `()` because of default return type +LL | let mut state = 0; +LL | Box::new(move || state) + | ^^^^^^^^^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `Box<{closure@box_has_sigdrop.rs:8:14}>` + | + = note: expected unit type `()` + found struct `Box<{closure@$DIR/box_has_sigdrop.rs:8:14: 8:21}>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-inference/has_sigdrop.rs b/tests/ui/type-inference/dropper_has_sigdrop.rs similarity index 100% rename from tests/ui/type-inference/has_sigdrop.rs rename to tests/ui/type-inference/dropper_has_sigdrop.rs