diff options
| author | bors <bors@rust-lang.org> | 2025-09-24 18:35:58 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-09-24 18:35:58 +0000 |
| commit | caccb4d0368bd918ef6668af8e13834d07040417 (patch) | |
| tree | a0d193440aa5f0f1781db2028555338c0f7cf475 | |
| parent | 15283f6fe95e5b604273d13a428bab5fc0788f5a (diff) | |
| parent | ec378dc7732e7a2657539072cfd25c68f8802509 (diff) | |
| download | rust-caccb4d0368bd918ef6668af8e13834d07040417.tar.gz rust-caccb4d0368bd918ef6668af8e13834d07040417.zip | |
Auto merge of #146999 - matthiaskrgr:rollup-0gbkm82, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang/rust#146711 (fix 2 borrowck issues) - rust-lang/rust#146857 (revert change removing `has_infer` check. Commit conservatively patch…) - rust-lang/rust#146897 (fix ICE in rustdoc::invalid_html_tags) - rust-lang/rust#146915 (Make missed precondition-free float intrinsics safe) - rust-lang/rust#146932 (Switch next-solver related rustc dependencies of r-a to crates.io ones) - rust-lang/rust#146959 (temporary-lifetime-extension-tuple-ctor.rs: make usable on all editions) - rust-lang/rust#146964 (library: std: sys: pal: uefi: Add some comments) - rust-lang/rust#146969 (const-eval: better wording for errors involving maybe-null pointers) r? `@ghost` `@rustbot` modify labels: rollup
38 files changed, 385 insertions, 114 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 5f4bfd9df48..0910e8ef4b3 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 19cbcd139aa..606d3d95d9e 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 700d7c26752..010ffa60c7a 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 2d412ee5ec2..d352a638424 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/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 9adc3fa4631..5f088fe37e8 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 6faa67f6a90..bc3448be582 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 7c72a8ec243..951aac503fe 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 4f039381e50..a4422abc688 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 a174ced5a2a..eaf2738d8b7 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -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 b0c9e9ef05e..3b03cde0372 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. diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 56db92f91fc..a027d63005b 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. diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 57be4d8d30a..bfc091c54b2 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. diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 748956ae980..21cd77d8014 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. diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index b50574de937..c0d69c3e002 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<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, @@ -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>, diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index da09117b1bb..136ff258048 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 29578acb404..bd32bec383f 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]+)?(<imm>)?( \([0-9]+ ptr bytes\))?─*╼" + r"╾─*a(lloc)?([0-9]+)(\+0x[0-9a-f]+)?(<imm>)?( \([0-9]+ ptr bytes\))?─*╼" ) .replace_all(&normalized, |caps: &Captures<'_>| { // Renumber the captured index. 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 301d4cca066..e5c213ca937 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 451622ef747..2e59a488e67 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 7ebefa76ed0..0b3582051bc 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 86545415009..99b1354b633 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 c7a747ade3e..70139e86669 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 f8dacf0fb86..027a386abe8 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 00000000000..d7efc201e7e --- /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)] + +/// <TABLE +/// BORDER> +/// <TR +/// > +/// <TH +//~^ ERROR: unclosed HTML tag `TH` +/// >key +/// </TD +//~^ ERROR: unopened HTML tag `TD` +/// > +/// <TH +//~^ ERROR: unclosed HTML tag `TH` +/// >value +/// </TD +//~^ ERROR: unopened HTML tag `TD` +/// > +/// </TR +/// > +/// </TABLE +/// > +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 00000000000..64a82b3a952 --- /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 | /// </TD + | _____^ +LL | | +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 | /// </TD + | _____^ +LL | | +LL | | /// > + | |_____^ + +error: unclosed HTML tag `TH` + --> $DIR/invalid-html-tags-ice-146890.rs:9:5 + | +LL | /// <TH + | ^^^ + +error: unclosed HTML tag `TH` + --> $DIR/invalid-html-tags-ice-146890.rs:15:5 + | +LL | /// <TH + | ^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs new file mode 100644 index 00000000000..e5c1f47b9e0 --- /dev/null +++ b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Zdeduplicate-diagnostics=yes + +// Regression test for #146467. +#![feature(inherent_associated_types)] +//~^ WARN the feature `inherent_associated_types` is incomplete + +struct Foo<T>(T); + +impl<'a> Foo<fn(&())> { + //~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait + type Assoc = &'a (); +} + +fn foo(_: for<'a> fn(Foo<fn(&'a ())>::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 00000000000..4c0726d4ddc --- /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 <https://github.com/rust-lang/rust/issues/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<fn(&())> { + | ^^ 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<fn(&'a ())>::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected struct `Foo<for<'a> fn(&'a ())>` + found struct `Foo<for<'a> 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<fn(&'a ())>::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 91646842624..851f3996cd1 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<dyn Send> = 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 91c82efbc5e..e4486e3c500 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<u8> = 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<usize> = 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<u8> = unsafe { MaybeUninit { uninit: () }.init }; @@ -80,6 +80,17 @@ LL | const NULL_FAT_PTR: NonNull<dyn Send> = 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 d8e5102fcbe..a5fdde1f9a4 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]+)?(<imm>)?─*╼ )+ *│.*" -> "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<u16> = 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 c45f66c2925..349a98f11be 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<u16> = 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<u8> = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -103,8 +114,8 @@ LL | const USIZE_AS_BOX: Box<u8> = 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<imm>, but expected a function pointer - --> $DIR/ub-ref-ptr.rs:58:1 +error[E0080]: constructing invalid value: encountered ALLOC3<imm>, 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 00000000000..73b8187a800 --- /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 <https://github.com/rust-lang/rust/issues/146748>) + +// 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]+)?(<imm>)?─*╼ )+ *│.*" -> "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::<i32>()) }; +//~^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 00000000000..664975831f4 --- /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::<i32>()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 00000000000..dfdb816652c --- /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(<fn(&'a ()) as Trait>::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 00000000000..c75a063e45f --- /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(<fn(&'a ()) as Trait>::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(<fn(&'a ()) as Trait>::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 bb537f855a4..7de786dff3b 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 00000000000..3e801197a78 --- /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 00000000000..b61b6322c10 --- /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 index c3d835cfe16..c3d835cfe16 100644 --- a/tests/ui/type-inference/has_sigdrop.rs +++ b/tests/ui/type-inference/dropper_has_sigdrop.rs |
