diff --git a/.mailmap b/.mailmap index fa30f07ad7310..4a3e39831e8a2 100644 --- a/.mailmap +++ b/.mailmap @@ -259,11 +259,9 @@ Gregor Peach Grzegorz Bartoszek Guanqun Lu Guillaume Gomez -Guillaume Gomez Guillaume Gomez -Guillaume Gomez ggomez -Guillaume Gomez ggomez -Guillaume Gomez Guillaume Gomez -Guillaume Gomez Guillaume Gomez +Guillaume Gomez +Guillaume Gomez +Guillaume Gomez gnzlbg hamidreza kalbasi Hanna Kruppe diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 75dab290d6031..0c0763aeb59fd 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -562,7 +562,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { // Don't hash unless necessary, because it's expensive. let opt_hir_hash = - if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None }; + if tcx.needs_hir_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None }; let delayed_resolver = Steal::new((resolver, krate)); mid_hir::Crate::new(owners, delayed_ids, delayed_resolver, opt_hir_hash) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 81160b6c3fed5..dd9ebf298b229 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -3,8 +3,8 @@ use std::ffi::c_uint; use std::{assert_matches, iter, ptr}; use rustc_abi::{ - AddressSpace, Align, BackendRepr, Float, HasDataLayout, Integer, NumScalableVectors, Primitive, - Size, WrappingRange, + AddressSpace, Align, BackendRepr, CVariadicStatus, Float, HasDataLayout, Integer, + NumScalableVectors, Primitive, Size, WrappingRange, }; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; @@ -23,6 +23,7 @@ use rustc_middle::ty::{ }; use rustc_middle::{bug, span_bug}; use rustc_session::config::CrateType; +use rustc_session::errors::feature_err; use rustc_session::lint::builtin::DEPRECATED_LLVM_INTRINSIC; use rustc_span::{Span, Symbol, sym}; use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate}; @@ -288,6 +289,16 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } sym::breakpoint => self.call_intrinsic("llvm.debugtrap", &[], &[]), sym::va_arg => { + let target = &self.cx.tcx.sess.target; + let stability = target.supports_c_variadic_definitions(); + if let CVariadicStatus::Unstable { feature } = stability + && !self.tcx.features().enabled(feature) + { + let msg = + format!("C-variadic function definitions on this target are unstable"); + feature_err(&*self.sess(), feature, span, msg).emit(); + } + let BackendRepr::Scalar(scalar) = result.layout.backend_repr else { bug!("the va_arg intrinsic does not support non-scalar types") }; diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 65bb487c7b8eb..5af522486b1f6 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -563,8 +563,9 @@ declare_features! ( /// Allows defining gen blocks and `gen fn`. (unstable, gen_blocks, "1.75.0", Some(117078)), /// Allows using generics in more complex const expressions, based on definitional equality. - (unstable, generic_const_args, "1.95.0", Some(151972)), - /// Allows non-trivial generic constants which have to have wfness manually propagated to callers + (incomplete, generic_const_args, "1.95.0", Some(151972)), + /// Allows non-trivial generic constants which have to be shown to successfully evaluate + /// to a value by being part of an item signature. (incomplete, generic_const_exprs, "1.56.0", Some(76560)), /// Allows generic parameters and where-clauses on free & associated const items. (incomplete, generic_const_items, "1.73.0", Some(113521)), @@ -626,7 +627,8 @@ declare_features! ( /// Allows additional const parameter types, such as [u8; 10] or user defined types. /// User defined types must not have fields more private than the type itself. (unstable, min_adt_const_params, "1.96.0", Some(154042)), - /// Enables the generic const args MVP (only bare paths, not arbitrary computation). + /// Enables the generic const args MVP (paths to type const items and constructors + /// for ADTs and primitives). (incomplete, min_generic_const_args, "1.84.0", Some(132980)), /// A minimal, sound subset of specialization intended to be used by the /// standard library until the soundness issues with specialization diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 170393f3b8179..63c7332893b81 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -36,7 +36,7 @@ impl Linker { Linker { dep_graph: tcx.dep_graph.clone(), output_filenames: Arc::clone(tcx.output_filenames(())), - crate_hash: if tcx.needs_crate_hash() { + crate_hash: if tcx.sess.opts.incremental.is_some() { Some(tcx.crate_hash(LOCAL_CRATE)) } else { None diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 492d21b3169a8..2d55078bc4d3e 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -237,7 +237,7 @@ impl<'tcx> TyCtxt<'tcx> { attrs: &SortedMap, define_opaque: Option<&[(Span, LocalDefId)]>, ) -> Hashes { - if !self.needs_crate_hash() { + if !self.needs_hir_hash() { return Hashes { opt_hash_including_bodies: None, attrs_hash: None }; } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index d1048a65a7be0..c25f5b402eb0d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1127,12 +1127,12 @@ impl<'tcx> TyCtxt<'tcx> { }) } - pub fn needs_crate_hash(self) -> bool { - // Why is the crate hash needed for these configurations? + pub fn needs_hir_hash(self) -> bool { + // Why is the hir hash needed for these configurations? // - debug_assertions: for the "fingerprint the result" check in // `rustc_query_impl::execution::execute_job`. // - incremental: for query lookups. - // - needs_metadata: for putting into crate metadata. + // - needs_metadata: it is included in the crate metadata through the crate_hash query // - instrument_coverage: for putting into coverage data (see // `hash_mir_source`). // - metrics_dir: metrics use the strict version hash in the filenames diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 53c5e28c0be27..7d820403ccb7d 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -1007,18 +1007,23 @@ pub const fn type_name_of_val(_val: &T) -> &'static str { #[must_use] #[unstable(feature = "try_as_dyn", issue = "144361")] pub const fn try_as_dyn< - T: Any + 'static, + T: Any + ?Sized + 'static, U: ptr::Pointee> + ?Sized + 'static, >( t: &T, ) -> Option<&U> { + // For unsized `T`, `trait_info_of` always returns `None` (vtable lookup is + // only supported for sized types). The function therefore unconditionally + // returns `None` in that case. let vtable: Option> = const { TypeId::of::().trait_info_of::().as_ref().map(TraitImpl::get_vtable) }; match vtable { Some(dyn_metadata) => { - let pointer = ptr::from_raw_parts(t, dyn_metadata); + let pointer = ptr::from_raw_parts(t as *const T as *const (), dyn_metadata); // SAFETY: `t` is a reference to a type, so we know it is valid. // `dyn_metadata` is a vtable for T, implementing the trait of `U`. + // `T` is sized here because `trait_info_of` only returns `Some` for sized types, + // so the thin data pointer fully describes the value. Some(unsafe { &*pointer }) } None => None, @@ -1061,18 +1066,23 @@ pub const fn try_as_dyn< #[must_use] #[unstable(feature = "try_as_dyn", issue = "144361")] pub const fn try_as_dyn_mut< - T: Any + 'static, + T: Any + ?Sized + 'static, U: ptr::Pointee> + ?Sized + 'static, >( t: &mut T, ) -> Option<&mut U> { + // For unsized `T`, `trait_info_of` always returns `None` (vtable lookup is + // only supported for sized types). The function therefore unconditionally + // returns `None` in that case. let vtable: Option> = const { TypeId::of::().trait_info_of::().as_ref().map(TraitImpl::get_vtable) }; match vtable { Some(dyn_metadata) => { - let pointer = ptr::from_raw_parts_mut(t, dyn_metadata); + let pointer = ptr::from_raw_parts_mut(t as *mut T as *mut (), dyn_metadata); // SAFETY: `t` is a reference to a type, so we know it is valid. // `dyn_metadata` is a vtable for T, implementing the trait of `U`. + // `T` is sized here because `trait_info_of` only returns `Some` for sized types, + // so the thin data pointer fully describes the value. Some(unsafe { &mut *pointer }) } None => None, diff --git a/src/doc/unstable-book/src/language-features/generic-const-args.md b/src/doc/unstable-book/src/language-features/generic-const-args.md new file mode 100644 index 0000000000000..b9870e60d0f91 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/generic-const-args.md @@ -0,0 +1,37 @@ +# generic_const_args + +Allows using generics in more complex const expressions, based on definitional equality. + +The tracking issue for this feature is: [#151972] + +[#151972]: https://github.com/rust-lang/rust/issues/151972 + +------------------------ + +Warning: This feature is incomplete; its design and syntax may change. + +This feature enables many of the same use cases supported by [generic_const_exprs], +but based on the machinery developed for [min_generic_const_args]. In a way, it is +meant to be an interim successor for GCE (though it might not currently support all +the valid cases that supported by GCE). + +See also: [generic_const_items] + +[min_generic_const_args]: min-generic-const-args.md +[generic_const_exprs]: generic-const-exprs.md +[generic_const_items]: generic-const-items.md + +## Examples + +```rust +#![feature(generic_const_items)] +#![feature(min_generic_const_args)] +#![feature(generic_const_args)] +#![expect(incomplete_features)] + +type const ADD1: usize = const { N + 1 }; + +type const INC: usize = ADD1::; + +const ARR: [(); ADD1::<0>] = [(); INC::<0>]; +``` diff --git a/src/doc/unstable-book/src/language-features/generic-const-exprs.md b/src/doc/unstable-book/src/language-features/generic-const-exprs.md new file mode 100644 index 0000000000000..2085ed8fed0cc --- /dev/null +++ b/src/doc/unstable-book/src/language-features/generic-const-exprs.md @@ -0,0 +1,73 @@ +# generic_const_exprs + +Allows non-trivial generic constants which have to be shown to successfully evaluate +to a value by being part of an item signature. + +The tracking issue for this feature is: [#76560] + + +[#76560]: https://github.com/rust-lang/rust/issues/76560 + +------------------------ + +Warning: This feature is incomplete; its design and syntax may change. + +See also: [min_generic_const_args], [generic_const_args] + +[min_generic_const_args]: min-generic-const-args.md +[generic_const_args]: generic-const-args.md + +## Examples + +```rust +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +// Use parameters that depend on a generic argument. +struct Foo +where + [(); N + 1]:, +{ + array: [usize; N + 1], +} + +// Use generic parameters in const operations. +trait Bar { + const X: usize; + const Y: usize; +} + +// Note `B::X * B::Y`. +const fn baz(x: [usize; B::X], y: [usize; B::Y]) -> [usize; B::X * B::Y] { + let mut out = [0; B::X * B::Y]; + let mut i = 0; + while i < B::Y { + let mut j = 0; + while j < B::X { + out[i * B::X + j] = y[i].saturating_mul(x[j]); + j += 1; + } + i += 1; + } + out +} + + +// Create a new type based on a generic argument. +pub struct Grow { + arr: [usize; N], +} + +impl Grow { + pub const fn grow(self, val: usize) -> Grow<{ N + 1 }> { + let mut new_arr = [0; { N + 1 }]; + let mut idx = 0; + while idx < N { + new_arr[idx] = self.arr[idx]; + idx += 1; + } + new_arr[N] = val; + Grow { arr: new_arr } + } +} +``` diff --git a/src/doc/unstable-book/src/language-features/generic-const-items.md b/src/doc/unstable-book/src/language-features/generic-const-items.md new file mode 100644 index 0000000000000..c856c9f135aff --- /dev/null +++ b/src/doc/unstable-book/src/language-features/generic-const-items.md @@ -0,0 +1,53 @@ +# generic_const_items + +Allows generic parameters and where-clauses on free & associated const items. + +The tracking issue for this feature is: [#113521] + +[#113521]: https://github.com/rust-lang/rust/issues/113521 + +------------------------ + +Warning: This feature is an [experiment] and lacks an RFC. +There are no guarantees that it will ever be stabilized. + +See also: [generic_const_exprs], [min_generic_const_args]. + +[experiment]: https://lang-team.rust-lang.org/how_to/experiment.html +[generic_const_exprs]: generic-const-exprs.md +[min_generic_const_args]: min-generic-const-args.md + +## Examples + +### Generic constant values + +```rust +#![allow(incomplete_features)] +#![feature(generic_const_items)] + +const GENERIC_VAL: usize = ARG + 1; + +#[test] +fn generic_const_arg() { + assert_eq!(GENERIC_VAL::<1>, 2); + assert_eq!(GENERIC_VAL::<2>, 3); +} +``` + +### Conditional constants + +```rust +#![allow(incomplete_features)] +#![feature(generic_const_items)] + +// `GENERIC_VAL::<0>` will fail to compile +const GENERIC_VAL: usize = if ARG > 0 { ARG + 1 } else { panic!("0 value") }; + +// Will fail to compile if the `Copy` derive is removed. +const COPY_MARKER: () = (); + +#[derive(Clone, Copy)] +struct Foo; + +const FOO_IS_COPY: () = COPY_MARKER::; +``` diff --git a/src/doc/unstable-book/src/language-features/min-generic-const-args.md b/src/doc/unstable-book/src/language-features/min-generic-const-args.md new file mode 100644 index 0000000000000..336b6a420c2d6 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/min-generic-const-args.md @@ -0,0 +1,110 @@ +# min_generic_const_args + +Enables the generic const args MVP (paths to type const items and constructors for ADTs and primitives). + +The tracking issue for this feature is: [#132980] + +[#132980]: https://github.com/rust-lang/rust/issues/132980 + +------------------------ + +Warning: This feature is incomplete; its design and syntax may change. + +This feature acts as a minimal alternative to [generic_const_exprs] that allows a smaller subset of functionality, +and uses a different approach for implementation. It is intentionally more restrictive, which helps with avoiding edge +cases that make the `generic_const_exprs` hard to implement properly. See [Feature background][feature_background] +for more details. + +Related features: [generic_const_args], [generic_const_items]. + +[feature_background]: https://github.com/rust-lang/project-const-generics/blob/main/documents/min_const_generics_plan.md +[generic_const_exprs]: generic-const-exprs.md +[generic_const_args]: generic-const-args.md +[generic_const_items]: generic-const-items.md + +## `type const` syntax + +This feature introduces new syntax: `type const`. +Constants marked as `type const` are allowed to be used in type contexts, e.g.: + +```compile_fail +#![allow(incomplete_features)] +#![feature(min_generic_const_args)] + +type const X: usize = 1; +const Y: usize = 1; + +struct Foo { + good_arr: [(); X], // Allowed + bad_arr: [(); Y], // Will not compile, `Y` must be `type const`. +} +``` + +## Examples + +```rust +#![allow(incomplete_features)] +#![feature(min_generic_const_args)] + +trait Bar { + type const VAL: usize; + type const VAL2: usize; +} + +struct Baz; + +impl Bar for Baz { + type const VAL: usize = 2; + type const VAL2: usize = const { Self::VAL * 2 }; +} + +struct Foo { + arr1: [usize; B::VAL], + arr2: [usize; B::VAL2], +} +``` + +Note that with [generic_const_exprs] the same example would look as follows: + +```rust +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +trait Bar { + const VAL: usize; + const VAL2: usize; +} + +struct Baz; + +impl Bar for Baz { + const VAL: usize = 2; + const VAL2: usize = const { Self::VAL * 2 }; +} + +struct Foo +where + [(); B::VAL]:, + [(); B::VAL2]:, +{ + arr1: [usize; B::VAL], + arr2: [usize; B::VAL2], +} +``` + +Use of const functions is allowed: + +```rust +#![allow(incomplete_features)] +#![feature(min_generic_const_args)] + +const VAL: usize = 1; + +const fn inc(val: usize) -> usize { + val + 1 +} + +type const INC: usize = const { inc(VAL) }; + +const ARR: [usize; INC] = [0; INC]; +``` diff --git a/tests/assembly-llvm/c-variadic/avr.rs b/tests/assembly-llvm/c-variadic/avr.rs new file mode 100644 index 0000000000000..a5f48a2d0533e --- /dev/null +++ b/tests/assembly-llvm/c-variadic/avr.rs @@ -0,0 +1,220 @@ +//@ add-minicore +//@ assembly-output: emit-asm +// +//@ revisions: AVR +//@ [AVR] compile-flags: -Copt-level=3 --target=avr-none -Ctarget-cpu=atmega328p +//@ [AVR] needs-llvm-components: avr +#![feature(c_variadic, c_variadic_experimental_arch, no_core, lang_items, intrinsics, rustc_attrs)] +#![no_core] +#![crate_type = "lib"] + +// Check that rustc and clang output match, see https://godbolt.org/z/1MvxoceeT. + +extern crate minicore; +use minicore::*; + +#[lang = "va_arg_safe"] +pub unsafe trait VaArgSafe {} + +unsafe impl VaArgSafe for i16 {} +unsafe impl VaArgSafe for i32 {} +unsafe impl VaArgSafe for i64 {} +unsafe impl VaArgSafe for f32 {} +unsafe impl VaArgSafe for f64 {} +unsafe impl VaArgSafe for *const T {} + +#[repr(transparent)] +struct VaListInner { + ptr: *const c_void, +} + +#[repr(transparent)] +#[lang = "va_list"] +pub struct VaList<'a> { + inner: VaListInner, + _marker: PhantomData<&'a mut ()>, +} + +#[rustc_intrinsic] +#[rustc_nounwind] +pub const unsafe fn va_arg(ap: &mut VaList<'_>) -> T; + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_f32(ap: &mut VaList<'_>) -> f32 { + // CHECK-LABEL: read_f32 + // + // AVR: movw r30, r24 + // AVR-NEXT: ld r24, Z + // AVR-NEXT: ldd r25, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 2 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r20, r30 + // AVR-NEXT: movw r18, r24 + // AVR-NEXT: movw r30, r18 + // AVR-NEXT: ld r22, Z + // AVR-NEXT: ldd r23, Z+1 + // AVR-NEXT: adiw r24, 4 + // AVR-NEXT: movw r30, r20 + // AVR-NEXT: std Z+1, r25 + // AVR-NEXT: st Z, r24 + // AVR-NEXT: movw r30, r18 + // AVR-NEXT: ldd r24, Z+2 + // AVR-NEXT: ldd r25, Z+3 + // AVR-NEXT: ret + va_arg(ap) +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_f64(ap: &mut VaList<'_>) -> f64 { + // CHECK-LABEL: read_f64 + // + // AVR: push r14 + // AVR-NEXT: push r15 + // AVR-NEXT: push r16 + // AVR-NEXT: push r17 + // AVR-NEXT: movw r30, r24 + // AVR-NEXT: ld r24, Z + // AVR-NEXT: ldd r25, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 2 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r14, r30 + // AVR-NEXT: movw r16, r24 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ld r18, Z + // AVR-NEXT: ldd r19, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 4 + // AVR-NEXT: movw r30, r14 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ldd r20, Z+2 + // AVR-NEXT: ldd r21, Z+3 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 6 + // AVR-NEXT: movw r30, r14 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ldd r22, Z+4 + // AVR-NEXT: ldd r23, Z+5 + // AVR-NEXT: adiw r24, 8 + // AVR-NEXT: movw r30, r14 + // AVR-NEXT: std Z+1, r25 + // AVR-NEXT: st Z, r24 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ldd r24, Z+6 + // AVR-NEXT: ldd r25, Z+7 + // AVR-NEXT: pop r17 + // AVR-NEXT: pop r16 + // AVR-NEXT: pop r15 + // AVR-NEXT: pop r14 + // AVR-NEXT: ret + va_arg(ap) +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_i16(ap: &mut VaList<'_>) -> i16 { + // CHECK-LABEL: read_i16 + // + // AVR: movw r30, r24 + // AVR-NEXT: ld r24, Z + // AVR-NEXT: ldd r25, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 2 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r30, r24 + // AVR-NEXT: ld r24, Z + // AVR-NEXT: ldd r25, Z+1 + // AVR-NEXT: ret + va_arg(ap) +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { + // CHECK-LABEL: read_i32 + // + // AVR: movw r30, r24 + // AVR-NEXT: ld r24, Z + // AVR-NEXT: ldd r25, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 2 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r20, r30 + // AVR-NEXT: movw r18, r24 + // AVR-NEXT: movw r30, r18 + // AVR-NEXT: ld r22, Z + // AVR-NEXT: ldd r23, Z+1 + // AVR-NEXT: adiw r24, 4 + // AVR-NEXT: movw r30, r20 + // AVR-NEXT: std Z+1, r25 + // AVR-NEXT: st Z, r24 + // AVR-NEXT: movw r30, r18 + // AVR-NEXT: ldd r24, Z+2 + // AVR-NEXT: ldd r25, Z+3 + // AVR-NEXT: ret + va_arg(ap) +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 { + // CHECK-LABEL: read_i64 + // + // AVR: push r14 + // AVR-NEXT: push r15 + // AVR-NEXT: push r16 + // AVR-NEXT: push r17 + // AVR-NEXT: movw r30, r24 + // AVR-NEXT: ld r24, Z + // AVR-NEXT: ldd r25, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 2 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r14, r30 + // AVR-NEXT: movw r16, r24 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ld r18, Z + // AVR-NEXT: ldd r19, Z+1 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 4 + // AVR-NEXT: movw r30, r14 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ldd r20, Z+2 + // AVR-NEXT: ldd r21, Z+3 + // AVR-NEXT: movw r26, r24 + // AVR-NEXT: adiw r26, 6 + // AVR-NEXT: movw r30, r14 + // AVR-NEXT: std Z+1, r27 + // AVR-NEXT: st Z, r26 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ldd r22, Z+4 + // AVR-NEXT: ldd r23, Z+5 + // AVR-NEXT: adiw r24, 8 + // AVR-NEXT: movw r30, r14 + // AVR-NEXT: std Z+1, r25 + // AVR-NEXT: st Z, r24 + // AVR-NEXT: movw r30, r16 + // AVR-NEXT: ldd r24, Z+6 + // AVR-NEXT: ldd r25, Z+7 + // AVR-NEXT: pop r17 + // AVR-NEXT: pop r16 + // AVR-NEXT: pop r15 + // AVR-NEXT: pop r14 + // AVR-NEXT: ret + va_arg(ap) +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_ptr(ap: &mut VaList<'_>) -> *const u8 { + // AVR: read_ptr = pm(read_i16) + va_arg(ap) +} diff --git a/tests/assembly-llvm/c-variadic/sparc.rs b/tests/assembly-llvm/c-variadic/sparc.rs index 59f039e7df28b..6ce25119a135c 100644 --- a/tests/assembly-llvm/c-variadic/sparc.rs +++ b/tests/assembly-llvm/c-variadic/sparc.rs @@ -7,6 +7,7 @@ //@ [SPARC64] compile-flags: -Copt-level=3 --target sparc64-unknown-linux-gnu //@ [SPARC64] needs-llvm-components: sparc #![feature(c_variadic, no_core, lang_items, intrinsics, rustc_attrs, asm_experimental_arch)] +#![cfg_attr(target_arch = "sparc", feature(c_variadic_experimental_arch))] #![no_core] #![crate_type = "lib"] diff --git a/tests/ui/any/try_as_dyn_unsized.rs b/tests/ui/any/try_as_dyn_unsized.rs new file mode 100644 index 0000000000000..83bf1e2863c43 --- /dev/null +++ b/tests/ui/any/try_as_dyn_unsized.rs @@ -0,0 +1,34 @@ +//@ run-pass +#![feature(try_as_dyn)] + +use std::fmt::Debug; + +// Generic over `?Sized` T: relies on the relaxed bound on `try_as_dyn`. +fn try_debug(t: &T) -> Option { + std::any::try_as_dyn::(t).map(|d| format!("{d:?}")) +} + +fn try_debug_mut(t: &mut T) -> Option { + std::any::try_as_dyn_mut::(t).map(|d| format!("{d:?}")) +} + +fn main() { + // Sized case still works through a `?Sized` generic context. + let x: i32 = 7; + assert_eq!(try_debug(&x).as_deref(), Some("7")); + + let mut y: i32 = 8; + assert_eq!(try_debug_mut(&mut y).as_deref(), Some("8")); + + // Unsized `T` always returns `None`, even though `str: Debug` and + // `[T]: Debug` hold — vtable lookup for unsized impl types is not + // currently supported by `TypeId::trait_info_of`. + let s: &str = "hello"; + assert!(try_debug::(s).is_none()); + + let slice: &[i32] = &[1, 2, 3]; + assert!(try_debug::<[i32]>(slice).is_none()); + + let dyn_any: &dyn std::any::Any = &0i32; + assert!(try_debug::(dyn_any).is_none()); +} diff --git a/tests/ui/issues/issue-23073.rs b/tests/ui/associated-types/ambiguous-associated-type-default.rs similarity index 71% rename from tests/ui/issues/issue-23073.rs rename to tests/ui/associated-types/ambiguous-associated-type-default.rs index a0ca91336c365..31d1355d41cee 100644 --- a/tests/ui/issues/issue-23073.rs +++ b/tests/ui/associated-types/ambiguous-associated-type-default.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/23073 + #![feature(associated_type_defaults)] trait Foo { type T; } diff --git a/tests/ui/issues/issue-23073.stderr b/tests/ui/associated-types/ambiguous-associated-type-default.stderr similarity index 90% rename from tests/ui/issues/issue-23073.stderr rename to tests/ui/associated-types/ambiguous-associated-type-default.stderr index 87dcf3b328923..38484756fa94a 100644 --- a/tests/ui/issues/issue-23073.stderr +++ b/tests/ui/associated-types/ambiguous-associated-type-default.stderr @@ -1,5 +1,5 @@ error[E0223]: ambiguous associated type - --> $DIR/issue-23073.rs:6:17 + --> $DIR/ambiguous-associated-type-default.rs:8:17 | LL | type FooT = <::Foo>::T; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-20803.rs b/tests/ui/associated-types/assoc-type-add-output-via-operator-syntax.rs similarity index 68% rename from tests/ui/issues/issue-20803.rs rename to tests/ui/associated-types/assoc-type-add-output-via-operator-syntax.rs index 47bf52b31a026..180c3576595de 100644 --- a/tests/ui/issues/issue-20803.rs +++ b/tests/ui/associated-types/assoc-type-add-output-via-operator-syntax.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/20803 + //@ run-pass use std::ops::Add; diff --git a/tests/ui/issues/issue-37051.rs b/tests/ui/associated-types/assoc-type-default-without-override-in-impl.rs similarity index 81% rename from tests/ui/issues/issue-37051.rs rename to tests/ui/associated-types/assoc-type-default-without-override-in-impl.rs index fa9cc5964fe1f..c9f1760787102 100644 --- a/tests/ui/issues/issue-37051.rs +++ b/tests/ui/associated-types/assoc-type-default-without-override-in-impl.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/37051 + //@ check-pass #![feature(associated_type_defaults)] diff --git a/tests/ui/issues/issue-39970.rs b/tests/ui/associated-types/assoc-type-element-mismatch-in-hrtb.rs similarity index 84% rename from tests/ui/issues/issue-39970.rs rename to tests/ui/associated-types/assoc-type-element-mismatch-in-hrtb.rs index 40d3ae30a87c6..254fb0051ed30 100644 --- a/tests/ui/issues/issue-39970.rs +++ b/tests/ui/associated-types/assoc-type-element-mismatch-in-hrtb.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/39970 + trait Array<'a> { type Element: 'a; } diff --git a/tests/ui/issues/issue-39970.stderr b/tests/ui/associated-types/assoc-type-element-mismatch-in-hrtb.stderr similarity index 80% rename from tests/ui/issues/issue-39970.stderr rename to tests/ui/associated-types/assoc-type-element-mismatch-in-hrtb.stderr index 0fe73574bad6f..eff0a5b53ae06 100644 --- a/tests/ui/issues/issue-39970.stderr +++ b/tests/ui/associated-types/assoc-type-element-mismatch-in-hrtb.stderr @@ -1,16 +1,16 @@ error[E0271]: type mismatch resolving `<() as Array<'a>>::Element == ()` - --> $DIR/issue-39970.rs:19:6 + --> $DIR/assoc-type-element-mismatch-in-hrtb.rs:21:6 | LL | <() as Visit>::visit(); | ^^ type mismatch resolving `<() as Array<'a>>::Element == ()` | note: expected this to be `()` - --> $DIR/issue-39970.rs:10:20 + --> $DIR/assoc-type-element-mismatch-in-hrtb.rs:12:20 | LL | type Element = &'a (); | ^^^^^^ note: required for `()` to implement `Visit` - --> $DIR/issue-39970.rs:13:6 + --> $DIR/assoc-type-element-mismatch-in-hrtb.rs:15:6 | LL | impl Visit for () where | ^^^^^ ^^ diff --git a/tests/ui/issues/issue-28983.rs b/tests/ui/associated-types/assoc-type-in-extern-fn-signature.rs similarity index 86% rename from tests/ui/issues/issue-28983.rs rename to tests/ui/associated-types/assoc-type-in-extern-fn-signature.rs index 90a4793787d4e..ffd26ad8462f5 100644 --- a/tests/ui/issues/issue-28983.rs +++ b/tests/ui/associated-types/assoc-type-in-extern-fn-signature.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/28983 + //@ run-pass pub trait Test { type T; } diff --git a/tests/ui/issues/issue-19632.rs b/tests/ui/associated-types/assoc-type-in-generic-struct-bound.rs similarity index 69% rename from tests/ui/issues/issue-19632.rs rename to tests/ui/associated-types/assoc-type-in-generic-struct-bound.rs index a99ab5f5ebe1d..4aa4b5f3caa10 100644 --- a/tests/ui/issues/issue-19632.rs +++ b/tests/ui/associated-types/assoc-type-in-generic-struct-bound.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/19632 + //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/issues/issue-20797.rs b/tests/ui/associated-types/assoc-type-in-strategy-pattern-iterator.rs similarity index 97% rename from tests/ui/issues/issue-20797.rs rename to tests/ui/associated-types/assoc-type-in-strategy-pattern-iterator.rs index 3d3160c6e85d6..0291b225f6955 100644 --- a/tests/ui/issues/issue-20797.rs +++ b/tests/ui/associated-types/assoc-type-in-strategy-pattern-iterator.rs @@ -1,6 +1,6 @@ //@ build-pass -// Regression test for #20797. +// Regression test for https://github.com/rust-lang/rust/issues/20797 use std::default::Default; use std::io; diff --git a/tests/ui/issues/issue-26127.rs b/tests/ui/associated-types/assoc-type-in-struct-constructor.rs similarity index 71% rename from tests/ui/issues/issue-26127.rs rename to tests/ui/associated-types/assoc-type-in-struct-constructor.rs index 45f50efdccbdb..b041260cfb356 100644 --- a/tests/ui/issues/issue-26127.rs +++ b/tests/ui/associated-types/assoc-type-in-struct-constructor.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/26127 + //@ run-pass trait Tr { type T; } impl Tr for u8 { type T=(); } diff --git a/tests/ui/issues/issue-19631.rs b/tests/ui/associated-types/assoc-type-in-unused-where-clause.rs similarity index 73% rename from tests/ui/issues/issue-19631.rs rename to tests/ui/associated-types/assoc-type-in-unused-where-clause.rs index d13ac216e36ea..7f570015fc752 100644 --- a/tests/ui/issues/issue-19631.rs +++ b/tests/ui/associated-types/assoc-type-in-unused-where-clause.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/19631 + //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/issues/issue-36036-associated-type-layout.rs b/tests/ui/associated-types/assoc-type-layout-unsized-allowed-sized-used.rs similarity index 79% rename from tests/ui/issues/issue-36036-associated-type-layout.rs rename to tests/ui/associated-types/assoc-type-layout-unsized-allowed-sized-used.rs index 63f9927c67826..1e6fc4ebbb38f 100644 --- a/tests/ui/issues/issue-36036-associated-type-layout.rs +++ b/tests/ui/associated-types/assoc-type-layout-unsized-allowed-sized-used.rs @@ -1,5 +1,6 @@ //@ run-pass -// Issue 36036: computing the layout of a type composed from another +// Regression test for https://github.com/rust-lang/rust/issues/36036 +// computing the layout of a type composed from another // trait's associated type caused compiler to ICE when the associated // type was allowed to be unsized, even though the known instantiated // type is itself sized. diff --git a/tests/ui/issues/issue-23336.rs b/tests/ui/associated-types/assoc-type-method-call-via-blanket-impl.rs similarity index 77% rename from tests/ui/issues/issue-23336.rs rename to tests/ui/associated-types/assoc-type-method-call-via-blanket-impl.rs index e71c2af0c85d6..d4fa38124a77c 100644 --- a/tests/ui/issues/issue-23336.rs +++ b/tests/ui/associated-types/assoc-type-method-call-via-blanket-impl.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/23336 + //@ run-pass pub trait Data { fn doit(&self) {} } impl Data for T {} diff --git a/tests/ui/issues/issue-17732.rs b/tests/ui/associated-types/assoc-type-named-string.rs similarity index 73% rename from tests/ui/issues/issue-17732.rs rename to tests/ui/associated-types/assoc-type-named-string.rs index e093ed7f41fb0..03449e2cdabe5 100644 --- a/tests/ui/issues/issue-17732.rs +++ b/tests/ui/associated-types/assoc-type-named-string.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/17732 + //@ check-pass #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/tests/ui/issues/issue-20009.rs b/tests/ui/associated-types/assoc-type-output-is-sized.rs similarity index 73% rename from tests/ui/issues/issue-20009.rs rename to tests/ui/associated-types/assoc-type-output-is-sized.rs index 4d091f3a962c6..8ef4595843df2 100644 --- a/tests/ui/issues/issue-20009.rs +++ b/tests/ui/associated-types/assoc-type-output-is-sized.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/20009 + //@ check-pass // Check that associated types are `Sized` diff --git a/tests/ui/issues/issue-20971.rs b/tests/ui/associated-types/assoc-type-projection-in-box-return.rs similarity index 83% rename from tests/ui/issues/issue-20971.rs rename to tests/ui/associated-types/assoc-type-projection-in-box-return.rs index 31dd910191935..6c95467d141aa 100644 --- a/tests/ui/issues/issue-20971.rs +++ b/tests/ui/associated-types/assoc-type-projection-in-box-return.rs @@ -1,4 +1,4 @@ -// Regression test for Issue #20971. +// Regression test for Issue https://github.com/rust-lang/rust/issues/20971 //@ run-fail //@ error-pattern:Hello, world! diff --git a/tests/ui/issues/issue-19850.rs b/tests/ui/associated-types/assoc-type-projection-in-let-binding.rs similarity index 84% rename from tests/ui/issues/issue-19850.rs rename to tests/ui/associated-types/assoc-type-projection-in-let-binding.rs index 485b1a763900b..0438bcd96e1f5 100644 --- a/tests/ui/issues/issue-19850.rs +++ b/tests/ui/associated-types/assoc-type-projection-in-let-binding.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/19850 + //@ check-pass #![allow(unused_variables)] // Test that `::Output` and `Self::Output` are accepted as type annotations in let diff --git a/tests/ui/issues/issue-23406.rs b/tests/ui/associated-types/assoc-type-projection-on-ref-lifetime.rs similarity index 72% rename from tests/ui/issues/issue-23406.rs rename to tests/ui/associated-types/assoc-type-projection-on-ref-lifetime.rs index 819f0feb6147a..b70d0a7468ff1 100644 --- a/tests/ui/issues/issue-23406.rs +++ b/tests/ui/associated-types/assoc-type-projection-on-ref-lifetime.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/23406 + //@ build-pass #![allow(dead_code)] trait Inner { diff --git a/tests/ui/issues/issue-37109.rs b/tests/ui/associated-types/assoc-type-ref-in-tuple-return.rs similarity index 75% rename from tests/ui/issues/issue-37109.rs rename to tests/ui/associated-types/assoc-type-ref-in-tuple-return.rs index 5276266523d8d..a587affb52ef8 100644 --- a/tests/ui/issues/issue-37109.rs +++ b/tests/ui/associated-types/assoc-type-ref-in-tuple-return.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/37109 + //@ run-pass trait ToRef<'a> { type Ref: 'a; diff --git a/tests/ui/issues/issue-23992.rs b/tests/ui/associated-types/assoc-type-returns-outer-wrapping-self.rs similarity index 84% rename from tests/ui/issues/issue-23992.rs rename to tests/ui/associated-types/assoc-type-returns-outer-wrapping-self.rs index 08a99d357bc43..74e941962a16b 100644 --- a/tests/ui/issues/issue-23992.rs +++ b/tests/ui/associated-types/assoc-type-returns-outer-wrapping-self.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/23992 + //@ run-pass pub struct Outer(T); pub struct Inner<'a> { value: &'a bool } diff --git a/tests/ui/issues/issue-21909.rs b/tests/ui/associated-types/bound-references-sibling-assoc-type.rs similarity index 67% rename from tests/ui/issues/issue-21909.rs rename to tests/ui/associated-types/bound-references-sibling-assoc-type.rs index ffc75f1f08cdd..18709cec121aa 100644 --- a/tests/ui/issues/issue-21909.rs +++ b/tests/ui/associated-types/bound-references-sibling-assoc-type.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/21909 + //@ check-pass trait A { diff --git a/tests/ui/issues/issue-34839.rs b/tests/ui/associated-types/enum-variant-with-assoc-type-and-lifetimes.rs similarity index 83% rename from tests/ui/issues/issue-34839.rs rename to tests/ui/associated-types/enum-variant-with-assoc-type-and-lifetimes.rs index 73edba5817af3..64de3df1e7c92 100644 --- a/tests/ui/issues/issue-34839.rs +++ b/tests/ui/associated-types/enum-variant-with-assoc-type-and-lifetimes.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/34839 + //@ check-pass trait RegularExpression: Sized { diff --git a/tests/ui/issues/issue-25679.rs b/tests/ui/associated-types/method-on-impl-with-assoc-type-projection.rs similarity index 100% rename from tests/ui/issues/issue-25679.rs rename to tests/ui/associated-types/method-on-impl-with-assoc-type-projection.rs diff --git a/tests/ui/issues/issue-25693.rs b/tests/ui/associated-types/recursive-enum-with-assoc-type-selfref.rs similarity index 100% rename from tests/ui/issues/issue-25693.rs rename to tests/ui/associated-types/recursive-enum-with-assoc-type-selfref.rs diff --git a/tests/ui/issues/issue-35600.rs b/tests/ui/associated-types/same-name-assoc-type-and-method.rs similarity index 76% rename from tests/ui/issues/issue-35600.rs rename to tests/ui/associated-types/same-name-assoc-type-and-method.rs index 40df0b6dfd890..21990ee150ab6 100644 --- a/tests/ui/issues/issue-35600.rs +++ b/tests/ui/associated-types/same-name-assoc-type-and-method.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/35600 + //@ run-pass #![allow(non_camel_case_types)] #![allow(unused_variables)] diff --git a/tests/ui/issues/issue-27281.rs b/tests/ui/associated-types/self-type-alias-for-assoc-type.rs similarity index 78% rename from tests/ui/issues/issue-27281.rs rename to tests/ui/associated-types/self-type-alias-for-assoc-type.rs index e76fd135dcd23..14864ede2a8be 100644 --- a/tests/ui/issues/issue-27281.rs +++ b/tests/ui/associated-types/self-type-alias-for-assoc-type.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/27281 + //@ check-pass pub trait Trait<'a> { type T; diff --git a/tests/ui/issues/issue-18809.rs b/tests/ui/associated-types/simple-associated-type-impl.rs similarity index 64% rename from tests/ui/issues/issue-18809.rs rename to tests/ui/associated-types/simple-associated-type-impl.rs index d3ef6abc8bdc8..1ebaf3b281786 100644 --- a/tests/ui/issues/issue-18809.rs +++ b/tests/ui/associated-types/simple-associated-type-impl.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/18809 + //@ check-pass trait Tup { type T0; diff --git a/tests/ui/issues/issue-43357.rs b/tests/ui/associated-types/size-of-assoc-type-output.rs similarity index 66% rename from tests/ui/issues/issue-43357.rs rename to tests/ui/associated-types/size-of-assoc-type-output.rs index fd20bac804074..c8f1865a3a5c1 100644 --- a/tests/ui/issues/issue-43357.rs +++ b/tests/ui/associated-types/size-of-assoc-type-output.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/43357 + //@ check-pass #![allow(dead_code)] trait Trait { diff --git a/tests/ui/issues/issue-19482.rs b/tests/ui/associated-types/unspecified-assoc-type-in-trait-object.rs similarity index 78% rename from tests/ui/issues/issue-19482.rs rename to tests/ui/associated-types/unspecified-assoc-type-in-trait-object.rs index 9d0c8d96d29a6..45b0171bccba0 100644 --- a/tests/ui/issues/issue-19482.rs +++ b/tests/ui/associated-types/unspecified-assoc-type-in-trait-object.rs @@ -1,3 +1,4 @@ +// Regression test for https://github.com/rust-lang/rust/issues/19842 // Test that a partially specified trait object with unspecified associated // type does not type-check. diff --git a/tests/ui/issues/issue-19482.stderr b/tests/ui/associated-types/unspecified-assoc-type-in-trait-object.stderr similarity index 87% rename from tests/ui/issues/issue-19482.stderr rename to tests/ui/associated-types/unspecified-assoc-type-in-trait-object.stderr index 5ac5130b2cd6c..0bcd91e31c2c4 100644 --- a/tests/ui/issues/issue-19482.stderr +++ b/tests/ui/associated-types/unspecified-assoc-type-in-trait-object.stderr @@ -1,5 +1,5 @@ error[E0191]: the value of the associated type `A` in `Foo` must be specified - --> $DIR/issue-19482.rs:10:16 + --> $DIR/unspecified-assoc-type-in-trait-object.rs:11:16 | LL | type A; | ------ `A` defined here