diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index ca6128b6f1be4..cca1d499088f4 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -10,8 +10,8 @@ use tracing::{debug, trace}; use crate::{ AbiAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer, - LayoutData, Niche, NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, - TargetDataLayout, Variants, WrappingRange, + LayoutData, Niche, NonZeroUsize, NumScalableVectors, Primitive, ReprOptions, Scalar, Size, + StructKind, TagEncoding, TargetDataLayout, Variants, WrappingRange, }; mod coroutine; @@ -204,13 +204,19 @@ impl LayoutCalculator { &self, element: F, count: u64, + number_of_vectors: NumScalableVectors, ) -> LayoutCalculatorResult where FieldIdx: Idx, VariantIdx: Idx, F: AsRef> + fmt::Debug, { - vector_type_layout(SimdVectorKind::Scalable, self.cx.data_layout(), element, count) + vector_type_layout( + SimdVectorKind::Scalable(number_of_vectors), + self.cx.data_layout(), + element, + count, + ) } pub fn simd_type( @@ -1526,7 +1532,7 @@ impl LayoutCalculator { enum SimdVectorKind { /// `#[rustc_scalable_vector]` - Scalable, + Scalable(NumScalableVectors), /// `#[repr(simd, packed)]` PackedFixed, /// `#[repr(simd)]` @@ -1559,9 +1565,10 @@ where let size = elt.size.checked_mul(count, dl).ok_or_else(|| LayoutCalculatorError::SizeOverflow)?; let (repr, align) = match kind { - SimdVectorKind::Scalable => { - (BackendRepr::SimdScalableVector { element, count }, dl.llvmlike_vector_align(size)) - } + SimdVectorKind::Scalable(number_of_vectors) => ( + BackendRepr::SimdScalableVector { element, count, number_of_vectors }, + dl.llvmlike_vector_align(size), + ), // Non-power-of-two vectors have padding up to the next power-of-two. // If we're a packed repr, remove the padding while keeping the alignment as close // to a vector as possible. diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 253dff6f8e75c..4f3bd6ef208da 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1702,6 +1702,28 @@ impl AddressSpace { pub const ZERO: Self = AddressSpace(0); } +/// How many scalable vectors are in a `BackendRepr::ScalableVector`? +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +#[cfg_attr(feature = "nightly", derive(HashStable_Generic))] +pub struct NumScalableVectors(pub u8); + +impl NumScalableVectors { + /// Returns a `NumScalableVector` for a non-tuple scalable vector (e.g. a single vector). + pub fn for_non_tuple() -> Self { + NumScalableVectors(1) + } + + // Returns `NumScalableVectors` for values of two through eight, which are a valid number of + // fields for a tuple of scalable vectors to have. `1` is a valid value of `NumScalableVectors` + // but not for a tuple which would have a field count. + pub fn from_field_count(count: usize) -> Option { + match count { + 2..8 => Some(NumScalableVectors(count as u8)), + _ => None, + } + } +} + /// The way we represent values to the backend /// /// Previously this was conflated with the "ABI" a type is given, as in the platform-specific ABI. @@ -1720,6 +1742,7 @@ pub enum BackendRepr { SimdScalableVector { element: Scalar, count: u64, + number_of_vectors: NumScalableVectors, }, SimdVector { element: Scalar, @@ -1826,8 +1849,12 @@ impl BackendRepr { BackendRepr::SimdVector { element: element.to_union(), count } } BackendRepr::Memory { .. } => BackendRepr::Memory { sized: true }, - BackendRepr::SimdScalableVector { element, count } => { - BackendRepr::SimdScalableVector { element: element.to_union(), count } + BackendRepr::SimdScalableVector { element, count, number_of_vectors } => { + BackendRepr::SimdScalableVector { + element: element.to_union(), + count, + number_of_vectors, + } } } } @@ -2167,7 +2194,7 @@ impl LayoutData { } /// Returns `true` if the size of the type is only known at runtime. - pub fn is_runtime_sized(&self) -> bool { + pub fn is_scalable_vector(&self) -> bool { matches!(self.backend_repr, BackendRepr::SimdScalableVector { .. }) } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5fcc8f0161194..6d9fe9870c42e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2683,7 +2683,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { overly_complex_const(self) } ExprKind::Lit(literal) => { - let span = expr.span; + let span = self.lower_span(expr.span); let literal = self.lower_lit(literal, span); ConstArg { @@ -2695,7 +2695,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { ExprKind::Unary(UnOp::Neg, inner_expr) if let ExprKind::Lit(literal) = &inner_expr.kind => { - let span = expr.span; + let span = self.lower_span(expr.span); let literal = self.lower_lit(literal, span); if !matches!(literal.node, LitKind::Int(..)) { diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 1d6d77604411c..3cffd862b9b98 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -24,7 +24,8 @@ use rustc_data_structures::fx::FxHashSet; use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{ - FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers, + FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, + LayoutOfHelpers, TyAndLayout, }; use rustc_middle::ty::{self, AtomicOrdering, Instance, Ty, TyCtxt}; use rustc_span::Span; @@ -943,8 +944,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { .get_address(self.location) } - fn scalable_alloca(&mut self, _elt: u64, _align: Align, _element_ty: Ty<'_>) -> RValue<'gcc> { - todo!() + fn alloca_with_ty(&mut self, ty: TyAndLayout<'tcx>) -> RValue<'gcc> { + self.alloca(ty.layout.size, ty.layout.align.abi) } fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> { diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 9e548ac0a8b01..dd0064d34bc4a 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -145,6 +145,10 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> { self.const_int(self.type_i32(), i as i64) } + fn const_i64(&self, i: i64) -> RValue<'gcc> { + self.const_int(self.type_i64(), i) + } + fn const_int(&self, typ: Type<'gcc>, int: i64) -> RValue<'gcc> { self.gcc_int(typ, int) } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 4e79e4fafac52..056a0763087a2 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -7,8 +7,7 @@ pub(crate) mod autodiff; pub(crate) mod gpu_offload; use libc::{c_char, c_uint}; -use rustc_abi as abi; -use rustc_abi::{Align, Size, WrappingRange}; +use rustc_abi::{self as abi, Align, Size, WrappingRange}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, SynchronizationScope, TypeKind}; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; @@ -616,21 +615,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn scalable_alloca(&mut self, elt: u64, align: Align, element_ty: Ty<'_>) -> Self::Value { + fn alloca_with_ty(&mut self, layout: TyAndLayout<'tcx>) -> Self::Value { let mut bx = Builder::with_cx(self.cx); bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) }); - let llvm_ty = match element_ty.kind() { - ty::Bool => bx.type_i1(), - ty::Int(int_ty) => self.cx.type_int_from_ty(*int_ty), - ty::Uint(uint_ty) => self.cx.type_uint_from_ty(*uint_ty), - ty::Float(float_ty) => self.cx.type_float_from_ty(*float_ty), - _ => unreachable!("scalable vectors can only contain a bool, int, uint or float"), - }; + let scalable_vector_ty = layout.llvm_type(self.cx); unsafe { - let ty = llvm::LLVMScalableVectorType(llvm_ty, elt.try_into().unwrap()); - let alloca = llvm::LLVMBuildAlloca(&bx.llbuilder, ty, UNNAMED); - llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); + let alloca = llvm::LLVMBuildAlloca(&bx.llbuilder, scalable_vector_ty, UNNAMED); + llvm::LLVMSetAlignment(alloca, layout.align.abi.bytes() as c_uint); alloca } } diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index a134e97cc8915..dadf8e9e7d5fa 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -159,6 +159,10 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> { self.const_int(self.type_i32(), i as i64) } + fn const_i64(&self, i: i64) -> &'ll Value { + self.const_int(self.type_i64(), i as i64) + } + fn const_int(&self, t: &'ll Type, i: i64) -> &'ll Value { debug_assert!( self.type_kind(t) == TypeKind::Integer, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs b/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs index 52d04625749b9..1172660af4a29 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs @@ -35,6 +35,14 @@ declare_constant!(DW_OP_plus_uconst: u64); /// Double-checked by a static assertion in `RustWrapper.cpp`. #[allow(non_upper_case_globals)] pub(crate) const DW_OP_LLVM_fragment: u64 = 0x1000; +#[allow(non_upper_case_globals)] +pub(crate) const DW_OP_constu: u64 = 0x10; +#[allow(non_upper_case_globals)] +pub(crate) const DW_OP_minus: u64 = 0x1c; +#[allow(non_upper_case_globals)] +pub(crate) const DW_OP_mul: u64 = 0x1e; +#[allow(non_upper_case_globals)] +pub(crate) const DW_OP_bregx: u64 = 0x92; // It describes the actual value of a source variable which might not exist in registers or in memory. #[allow(non_upper_case_globals)] pub(crate) const DW_OP_stack_value: u64 = 0x9f; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 04c0b6953290c..c91d3ec63a028 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -3,10 +3,10 @@ use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; use std::path::PathBuf; use std::sync::Arc; -use std::{iter, ptr}; +use std::{assert_matches, iter, ptr}; use libc::{c_longlong, c_uint}; -use rustc_abi::{Align, Size}; +use rustc_abi::{Align, Layout, NumScalableVectors, Size}; use rustc_codegen_ssa::debuginfo::type_names::{VTableNameKind, cpp_like_debuginfo}; use rustc_codegen_ssa::traits::*; use rustc_hir::def::{CtorKind, DefKind}; @@ -16,12 +16,12 @@ use rustc_middle::ty::layout::{ HasTypingEnv, LayoutOf, TyAndLayout, WIDE_PTR_ADDR, WIDE_PTR_EXTRA, }; use rustc_middle::ty::{ - self, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility, + self, AdtDef, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility, }; use rustc_session::config::{self, DebugInfo, Lto}; use rustc_span::{DUMMY_SP, FileName, RemapPathScopeComponents, SourceFile, Span, Symbol, hygiene}; use rustc_symbol_mangling::typeid_for_trait_ref; -use rustc_target::spec::DebuginfoKind; +use rustc_target::spec::{Arch, DebuginfoKind}; use smallvec::smallvec; use tracing::{debug, instrument}; @@ -33,7 +33,7 @@ use super::type_names::{compute_debuginfo_type_name, compute_debuginfo_vtable_na use super::utils::{DIB, debug_context, get_namespace_for_item, is_node_local_to_unit}; use crate::common::{AsCCharPtr, CodegenCx}; use crate::debuginfo::metadata::type_map::build_type_with_children; -use crate::debuginfo::utils::{WidePtrKind, wide_pointer_kind}; +use crate::debuginfo::utils::{WidePtrKind, create_DIArray, wide_pointer_kind}; use crate::debuginfo::{DIBuilderExt, dwarf_const}; use crate::llvm::debuginfo::{ DIBasicType, DIBuilder, DICompositeType, DIDescriptor, DIFile, DIFlags, DILexicalBlock, @@ -1039,6 +1039,7 @@ fn build_struct_type_di_node<'ll, 'tcx>( span: Span, ) -> DINodeCreationResult<'ll> { let struct_type = unique_type_id.expect_ty(); + let ty::Adt(adt_def, _) = struct_type.kind() else { bug!("build_struct_type_di_node() called with non-struct-type: {:?}", struct_type); }; @@ -1051,6 +1052,21 @@ fn build_struct_type_di_node<'ll, 'tcx>( } else { None }; + let name = compute_debuginfo_type_name(cx.tcx, struct_type, false); + + if struct_type.is_scalable_vector() { + let parts = struct_type.scalable_vector_parts(cx.tcx).unwrap(); + return build_scalable_vector_di_node( + cx, + unique_type_id, + name, + *adt_def, + parts, + struct_type_and_layout.layout, + def_location, + containing_scope, + ); + } type_map::build_type_with_children( cx, @@ -1058,7 +1074,7 @@ fn build_struct_type_di_node<'ll, 'tcx>( cx, Stub::Struct, unique_type_id, - &compute_debuginfo_type_name(cx.tcx, struct_type, false), + &name, def_location, size_and_align_of(struct_type_and_layout), Some(containing_scope), @@ -1101,6 +1117,100 @@ fn build_struct_type_di_node<'ll, 'tcx>( ) } +/// Generate debuginfo for a `#[rustc_scalable_vector]` type. +/// +/// Debuginfo for a scalable vector uses a derived type based on a composite type. The composite +/// type has the `DIFlagVector` flag set and is based on the element type of the scalable vector. +/// The composite type has a subrange from 0 to an expression that calculates the number of +/// elements in the vector. +/// +/// ```text,ignore +/// !1 = !DIDerivedType(tag: DW_TAG_typedef, name: "svint16_t", ..., baseType: !2, ...) +/// !2 = !DICompositeType(tag: DW_TAG_array_type, baseType: !3, ..., flags: DIFlagVector, elements: !4) +/// !3 = !DIBasicType(name: "i16", size: 16, encoding: DW_ATE_signed) +/// !4 = !{!5} +/// !5 = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 4, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) +/// ``` +/// +/// See the `CodegenType::CreateType(const BuiltinType *BT)` implementation in Clang for how this +/// is generated for C and C++. +fn build_scalable_vector_di_node<'ll, 'tcx>( + cx: &CodegenCx<'ll, 'tcx>, + unique_type_id: UniqueTypeId<'tcx>, + name: String, + adt_def: AdtDef<'tcx>, + (element_count, element_ty, number_of_vectors): (u16, Ty<'tcx>, NumScalableVectors), + layout: Layout<'tcx>, + def_location: Option>, + containing_scope: &'ll DIScope, +) -> DINodeCreationResult<'ll> { + use dwarf_const::{DW_OP_bregx, DW_OP_constu, DW_OP_minus, DW_OP_mul}; + assert!(adt_def.repr().scalable()); + // This logic is specific to AArch64 for the moment, but can be extended for other architectures + // later. + assert_matches!(cx.tcx.sess.target.arch, Arch::AArch64); + + let (file_metadata, line_number) = if let Some(def_location) = def_location { + (def_location.0, def_location.1) + } else { + (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) + }; + + let (bitstride, element_di_node) = if element_ty.is_bool() { + (Some(llvm::LLVMValueAsMetadata(cx.const_i64(1))), type_di_node(cx, cx.tcx.types.u8)) + } else { + (None, type_di_node(cx, element_ty)) + }; + + let number_of_elements: u64 = (element_count as u64) * (number_of_vectors.0 as u64); + let number_of_elements_per_vg = number_of_elements / 2; + let mut expr = smallvec::SmallVec::<[u64; 9]>::new(); + // `($number_of_elements_per_vector_granule * (value_of_register(AArch64::VG) + 0)) - 1` + expr.push(DW_OP_constu); // Push a constant onto the stack + expr.push(number_of_elements_per_vg); + expr.push(DW_OP_bregx); // Push the value of a register + offset on to the stack + expr.push(/* AArch64::VG */ 46u64); + expr.push(0u64); + expr.push(DW_OP_mul); // Multiply top two values on stack + expr.push(DW_OP_constu); // Push a constant onto the stack + expr.push(1u64); + expr.push(DW_OP_minus); // Subtract top two values on stack + + let di_builder = DIB(cx); + let metadata = unsafe { + let upper = llvm::LLVMDIBuilderCreateExpression(di_builder, expr.as_ptr(), expr.len()); + let subrange = llvm::LLVMRustDIGetOrCreateSubrange( + di_builder, + /* CountNode */ None, + llvm::LLVMValueAsMetadata(cx.const_i64(0)), + upper, + /* Stride */ None, + ); + let subscripts = create_DIArray(di_builder, &[Some(subrange)]); + let vector_ty = llvm::LLVMRustDICreateVectorType( + di_builder, + /* Size */ 0, + layout.align.bits() as u32, + element_di_node, + subscripts, + bitstride, + ); + llvm::LLVMDIBuilderCreateTypedef( + di_builder, + vector_ty, + name.as_ptr(), + name.len(), + file_metadata, + line_number, + Some(containing_scope), + layout.align.bits() as u32, + ) + }; + + debug_context(cx).type_map.insert(unique_type_id, metadata); + DINodeCreationResult { di_node: metadata, already_stored_in_typemap: true } +} + //=----------------------------------------------------------------------------- // Tuples //=----------------------------------------------------------------------------- diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 39bf4c10dab18..3e600914d6f42 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -3,7 +3,8 @@ use std::ffi::c_uint; use std::{assert_matches, ptr}; use rustc_abi::{ - Align, BackendRepr, ExternAbi, Float, HasDataLayout, Primitive, Size, WrappingRange, + Align, BackendRepr, ExternAbi, Float, HasDataLayout, 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}; @@ -605,6 +606,136 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { self.pointercast(val, self.type_ptr()) } + sym::sve_cast => { + let Some((in_cnt, in_elem, in_num_vecs)) = + args[0].layout.ty.scalable_vector_parts(self.cx.tcx) + else { + bug!("input parameter to `sve_cast` was not scalable vector"); + }; + let out_layout = self.layout_of(fn_args.type_at(1)); + let Some((out_cnt, out_elem, out_num_vecs)) = + out_layout.ty.scalable_vector_parts(self.cx.tcx) + else { + bug!("output parameter to `sve_cast` was not scalable vector"); + }; + assert_eq!(in_cnt, out_cnt); + assert_eq!(in_num_vecs, out_num_vecs); + let out_llty = self.backend_type(out_layout); + match simd_cast(self, sym::simd_cast, args, out_llty, in_elem, out_elem) { + Some(val) => val, + _ => bug!("could not cast scalable vectors"), + } + } + + sym::sve_tuple_create2 => { + assert_matches!( + self.layout_of(fn_args.type_at(0)).backend_repr, + BackendRepr::SimdScalableVector { + number_of_vectors: NumScalableVectors(1), + .. + } + ); + let tuple_ty = self.layout_of(fn_args.type_at(1)); + assert_matches!( + tuple_ty.backend_repr, + BackendRepr::SimdScalableVector { + number_of_vectors: NumScalableVectors(2), + .. + } + ); + let ret = self.const_poison(self.backend_type(tuple_ty)); + let ret = self.insert_value(ret, args[0].immediate(), 0); + self.insert_value(ret, args[1].immediate(), 1) + } + + sym::sve_tuple_create3 => { + assert_matches!( + self.layout_of(fn_args.type_at(0)).backend_repr, + BackendRepr::SimdScalableVector { + number_of_vectors: NumScalableVectors(1), + .. + } + ); + let tuple_ty = self.layout_of(fn_args.type_at(1)); + assert_matches!( + tuple_ty.backend_repr, + BackendRepr::SimdScalableVector { + number_of_vectors: NumScalableVectors(3), + .. + } + ); + let ret = self.const_poison(self.backend_type(tuple_ty)); + let ret = self.insert_value(ret, args[0].immediate(), 0); + let ret = self.insert_value(ret, args[1].immediate(), 1); + self.insert_value(ret, args[2].immediate(), 2) + } + + sym::sve_tuple_create4 => { + assert_matches!( + self.layout_of(fn_args.type_at(0)).backend_repr, + BackendRepr::SimdScalableVector { + number_of_vectors: NumScalableVectors(1), + .. + } + ); + let tuple_ty = self.layout_of(fn_args.type_at(1)); + assert_matches!( + tuple_ty.backend_repr, + BackendRepr::SimdScalableVector { + number_of_vectors: NumScalableVectors(4), + .. + } + ); + let ret = self.const_poison(self.backend_type(tuple_ty)); + let ret = self.insert_value(ret, args[0].immediate(), 0); + let ret = self.insert_value(ret, args[1].immediate(), 1); + let ret = self.insert_value(ret, args[2].immediate(), 2); + self.insert_value(ret, args[3].immediate(), 3) + } + + sym::sve_tuple_get => { + assert_matches!( + self.layout_of(fn_args.type_at(0)).backend_repr, + BackendRepr::SimdScalableVector { + number_of_vectors: NumScalableVectors(2 | 3 | 4 | 5 | 6 | 7 | 8), + .. + } + ); + assert_matches!( + self.layout_of(fn_args.type_at(1)).backend_repr, + BackendRepr::SimdScalableVector { + number_of_vectors: NumScalableVectors(1), + .. + } + ); + self.extract_value( + args[0].immediate(), + fn_args.const_at(2).to_leaf().to_i32() as u64, + ) + } + + sym::sve_tuple_set => { + assert_matches!( + self.layout_of(fn_args.type_at(0)).backend_repr, + BackendRepr::SimdScalableVector { + number_of_vectors: NumScalableVectors(2 | 3 | 4 | 5 | 6 | 7 | 8), + .. + } + ); + assert_matches!( + self.layout_of(fn_args.type_at(1)).backend_repr, + BackendRepr::SimdScalableVector { + number_of_vectors: NumScalableVectors(1), + .. + } + ); + self.insert_value( + args[0].immediate(), + args[1].immediate(), + fn_args.const_at(2).to_leaf().to_i32() as u64, + ) + } + _ if name.as_str().starts_with("simd_") => { // Unpack non-power-of-2 #[repr(packed, simd)] arguments. // This gives them the expected layout of a regular #[repr(simd)] vector. @@ -2662,96 +2793,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>( out_len } ); - // casting cares about nominal type, not just structural type - if in_elem == out_elem { - return Ok(args[0].immediate()); - } - - #[derive(Copy, Clone)] - enum Sign { - Unsigned, - Signed, - } - use Sign::*; - - enum Style { - Float, - Int(Sign), - Unsupported, - } - - let (in_style, in_width) = match in_elem.kind() { - // vectors of pointer-sized integers should've been - // disallowed before here, so this unwrap is safe. - ty::Int(i) => ( - Style::Int(Signed), - i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), - ), - ty::Uint(u) => ( - Style::Int(Unsigned), - u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), - ), - ty::Float(f) => (Style::Float, f.bit_width()), - _ => (Style::Unsupported, 0), - }; - let (out_style, out_width) = match out_elem.kind() { - ty::Int(i) => ( - Style::Int(Signed), - i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), - ), - ty::Uint(u) => ( - Style::Int(Unsigned), - u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), - ), - ty::Float(f) => (Style::Float, f.bit_width()), - _ => (Style::Unsupported, 0), - }; - - match (in_style, out_style) { - (Style::Int(sign), Style::Int(_)) => { - return Ok(match in_width.cmp(&out_width) { - Ordering::Greater => bx.trunc(args[0].immediate(), llret_ty), - Ordering::Equal => args[0].immediate(), - Ordering::Less => match sign { - Sign::Signed => bx.sext(args[0].immediate(), llret_ty), - Sign::Unsigned => bx.zext(args[0].immediate(), llret_ty), - }, - }); - } - (Style::Int(Sign::Signed), Style::Float) => { - return Ok(bx.sitofp(args[0].immediate(), llret_ty)); - } - (Style::Int(Sign::Unsigned), Style::Float) => { - return Ok(bx.uitofp(args[0].immediate(), llret_ty)); - } - (Style::Float, Style::Int(sign)) => { - return Ok(match (sign, name == sym::simd_as) { - (Sign::Unsigned, false) => bx.fptoui(args[0].immediate(), llret_ty), - (Sign::Signed, false) => bx.fptosi(args[0].immediate(), llret_ty), - (_, true) => bx.cast_float_to_int( - matches!(sign, Sign::Signed), - args[0].immediate(), - llret_ty, - ), - }); - } - (Style::Float, Style::Float) => { - return Ok(match in_width.cmp(&out_width) { - Ordering::Greater => bx.fptrunc(args[0].immediate(), llret_ty), - Ordering::Equal => args[0].immediate(), - Ordering::Less => bx.fpext(args[0].immediate(), llret_ty), - }); - } - _ => { /* Unsupported. Fallthrough. */ } + match simd_cast(bx, name, args, llret_ty, in_elem, out_elem) { + Some(val) => return Ok(val), + None => return_error!(InvalidMonomorphization::UnsupportedCast { + span, + name, + in_ty, + in_elem, + ret_ty, + out_elem + }), } - return_error!(InvalidMonomorphization::UnsupportedCast { - span, - name, - in_ty, - in_elem, - ret_ty, - out_elem - }); } macro_rules! arith_binary { ($($name: ident: $($($p: ident),* => $call: ident),*;)*) => { @@ -2925,3 +2977,86 @@ fn generic_simd_intrinsic<'ll, 'tcx>( span_bug!(span, "unknown SIMD intrinsic"); } + +/// Implementation of `core::intrinsics::simd_cast`, re-used by `core::scalable::sve_cast`. +fn simd_cast<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, + name: Symbol, + args: &[OperandRef<'tcx, &'ll Value>], + llret_ty: &'ll Type, + in_elem: Ty<'tcx>, + out_elem: Ty<'tcx>, +) -> Option<&'ll Value> { + // Casting cares about nominal type, not just structural type + if in_elem == out_elem { + return Some(args[0].immediate()); + } + + #[derive(Copy, Clone)] + enum Sign { + Unsigned, + Signed, + } + use Sign::*; + + enum Style { + Float, + Int(Sign), + Unsupported, + } + + let (in_style, in_width) = match in_elem.kind() { + // vectors of pointer-sized integers should've been + // disallowed before here, so this unwrap is safe. + ty::Int(i) => ( + Style::Int(Signed), + i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), + ), + ty::Uint(u) => ( + Style::Int(Unsigned), + u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), + ), + ty::Float(f) => (Style::Float, f.bit_width()), + _ => (Style::Unsupported, 0), + }; + let (out_style, out_width) = match out_elem.kind() { + ty::Int(i) => ( + Style::Int(Signed), + i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), + ), + ty::Uint(u) => ( + Style::Int(Unsigned), + u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), + ), + ty::Float(f) => (Style::Float, f.bit_width()), + _ => (Style::Unsupported, 0), + }; + + match (in_style, out_style) { + (Style::Int(sign), Style::Int(_)) => Some(match in_width.cmp(&out_width) { + Ordering::Greater => bx.trunc(args[0].immediate(), llret_ty), + Ordering::Equal => args[0].immediate(), + Ordering::Less => match sign { + Sign::Signed => bx.sext(args[0].immediate(), llret_ty), + Sign::Unsigned => bx.zext(args[0].immediate(), llret_ty), + }, + }), + (Style::Int(Sign::Signed), Style::Float) => Some(bx.sitofp(args[0].immediate(), llret_ty)), + (Style::Int(Sign::Unsigned), Style::Float) => { + Some(bx.uitofp(args[0].immediate(), llret_ty)) + } + (Style::Float, Style::Int(sign)) => Some(match (sign, name == sym::simd_as) { + (Sign::Unsigned, false) => bx.fptoui(args[0].immediate(), llret_ty), + (Sign::Signed, false) => bx.fptosi(args[0].immediate(), llret_ty), + (_, true) => { + bx.cast_float_to_int(matches!(sign, Sign::Signed), args[0].immediate(), llret_ty) + } + }), + (Style::Float, Style::Float) => Some(match in_width.cmp(&out_width) { + Ordering::Greater => bx.fptrunc(args[0].immediate(), llret_ty), + Ordering::Equal => args[0].immediate(), + Ordering::Less => bx.fpext(args[0].immediate(), llret_ty), + }), + _ => None, + } +} diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 7355d11367920..0ad74c9ca43a7 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2302,6 +2302,23 @@ unsafe extern "C" { Params: Option<&'a DIArray>, ); + pub(crate) fn LLVMRustDIGetOrCreateSubrange<'a>( + Builder: &DIBuilder<'a>, + CountNode: Option<&'a Metadata>, + LB: &'a Metadata, + UB: &'a Metadata, + Stride: Option<&'a Metadata>, + ) -> &'a Metadata; + + pub(crate) fn LLVMRustDICreateVectorType<'a>( + Builder: &DIBuilder<'a>, + Size: u64, + AlignInBits: u32, + Type: &'a DIType, + Subscripts: &'a DIArray, + BitStride: Option<&'a Metadata>, + ) -> &'a Metadata; + pub(crate) fn LLVMRustDILocationCloneWithBaseDiscriminator<'a>( Location: &'a DILocation, BD: c_uint, diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index e586ed0dd6b07..6d0490e4a1f79 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -24,14 +24,54 @@ fn uncached_llvm_type<'a, 'tcx>( let element = layout.scalar_llvm_type_at(cx, element); return cx.type_vector(element, count); } - BackendRepr::SimdScalableVector { ref element, count } => { + BackendRepr::SimdScalableVector { ref element, count, number_of_vectors } => { let element = if element.is_bool() { cx.type_i1() } else { layout.scalar_llvm_type_at(cx, *element) }; - return cx.type_scalable_vector(element, count); + let vector_type = cx.type_scalable_vector(element, count); + return match number_of_vectors.0 { + 1 => vector_type, + 2 => cx.type_struct(&[vector_type, vector_type], false), + 3 => cx.type_struct(&[vector_type, vector_type, vector_type], false), + 4 => cx.type_struct(&[vector_type, vector_type, vector_type, vector_type], false), + 5 => cx.type_struct( + &[vector_type, vector_type, vector_type, vector_type, vector_type], + false, + ), + 6 => cx.type_struct( + &[vector_type, vector_type, vector_type, vector_type, vector_type, vector_type], + false, + ), + 7 => cx.type_struct( + &[ + vector_type, + vector_type, + vector_type, + vector_type, + vector_type, + vector_type, + vector_type, + ], + false, + ), + 8 => cx.type_struct( + &[ + vector_type, + vector_type, + vector_type, + vector_type, + vector_type, + vector_type, + vector_type, + vector_type, + ], + false, + ), + _ => bug!("`#[rustc_scalable_vector]` tuple struct with too many fields"), + }; } BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {} } diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 2f93f688c316d..60ab13dbc6f76 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -438,8 +438,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if operand.layout.ty.is_scalable_vector() && bx.sess().target.arch == rustc_target::spec::Arch::AArch64 { - let (count, element_ty) = - operand.layout.ty.scalable_vector_element_count_and_type(bx.tcx()); + let (count, element_ty, _) = + operand.layout.ty.scalable_vector_parts(bx.tcx()).unwrap(); // i.e. `` when `N != 16` if element_ty.is_bool() && count != 16 { return; diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index d62e622b6fed3..53518fd816f31 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -1,3 +1,5 @@ +use std::ops::Deref as _; + use rustc_abi::{ Align, BackendRepr, FieldIdx, FieldsShape, Size, TagEncoding, VariantIdx, Variants, }; @@ -109,8 +111,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { bx: &mut Bx, layout: TyAndLayout<'tcx>, ) -> Self { - if layout.is_runtime_sized() { - Self::alloca_runtime_sized(bx, layout) + if layout.deref().is_scalable_vector() { + Self::alloca_scalable(bx, layout) } else { Self::alloca_size(bx, layout.size, layout) } @@ -151,16 +153,11 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { } } - fn alloca_runtime_sized>( + fn alloca_scalable>( bx: &mut Bx, layout: TyAndLayout<'tcx>, ) -> Self { - let (element_count, ty) = layout.ty.scalable_vector_element_count_and_type(bx.tcx()); - PlaceValue::new_sized( - bx.scalable_alloca(element_count as u64, layout.align.abi, ty), - layout.align.abi, - ) - .with_type(layout) + PlaceValue::new_sized(bx.alloca_with_ty(layout), layout.align.abi).with_type(layout) } } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 2076e2bb26274..c222aef4574bf 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -235,7 +235,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value; fn alloca(&mut self, size: Size, align: Align) -> Self::Value; - fn scalable_alloca(&mut self, elt: u64, align: Align, element_ty: Ty<'_>) -> Self::Value; + fn alloca_with_ty(&mut self, layout: TyAndLayout<'tcx>) -> Self::Value; fn load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value; fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value; diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs index 4178a9742e268..22784a8868ab5 100644 --- a/compiler/rustc_codegen_ssa/src/traits/consts.rs +++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs @@ -20,6 +20,7 @@ pub trait ConstCodegenMethods: BackendTypes { fn const_i8(&self, i: i8) -> Self::Value; fn const_i16(&self, i: i16) -> Self::Value; fn const_i32(&self, i: i32) -> Self::Value; + fn const_i64(&self, i: i64) -> Self::Value; fn const_int(&self, t: Self::Type, i: i64) -> Self::Value; fn const_u8(&self, i: u8) -> Self::Value; fn const_u32(&self, i: u32) -> Self::Value; diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 224b7273314b5..a9ad07be319c3 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -520,6 +520,8 @@ declare_features! ( (unstable, frontmatter, "1.88.0", Some(136889)), /// 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_exprs, "1.56.0", Some(76560)), /// Allows generic parameters and where-clauses on free & associated const items. @@ -623,8 +625,6 @@ declare_features! ( (unstable, offset_of_enum, "1.75.0", Some(120141)), /// Allows using fields with slice type in offset_of! (unstable, offset_of_slice, "1.81.0", Some(126151)), - /// Allows using generics in more complex const expressions, based on definitional equality. - (unstable, opaque_generic_const_args, "1.95.0", Some(151972)), /// Allows using `#[optimize(X)]`. (unstable, optimize_attribute, "1.34.0", Some(54882)), /// Allows specifying nop padding on functions for dynamic patching. @@ -806,6 +806,6 @@ pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[ /// Some features require one or more other features to be enabled. pub const DEPENDENT_FEATURES: &[(Symbol, &[Symbol])] = &[ - (sym::opaque_generic_const_args, &[sym::min_generic_const_args]), + (sym::generic_const_args, &[sym::min_generic_const_args]), (sym::unsized_const_params, &[sym::adt_const_params]), ]; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index b1dc593331c6c..58454cfc489c6 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -783,6 +783,13 @@ pub(crate) fn check_intrinsic_type( sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)), sym::simd_shuffle_const_generic => (2, 1, vec![param(0), param(0)], param(1)), + sym::sve_cast => (2, 0, vec![param(0)], param(1)), + sym::sve_tuple_create2 => (2, 0, vec![param(0), param(0)], param(1)), + sym::sve_tuple_create3 => (2, 0, vec![param(0), param(0), param(0)], param(1)), + sym::sve_tuple_create4 => (2, 0, vec![param(0), param(0), param(0), param(0)], param(1)), + sym::sve_tuple_get => (2, 1, vec![param(0)], param(1)), + sym::sve_tuple_set => (2, 1, vec![param(0), param(1)], param(0)), + sym::atomic_cxchg | sym::atomic_cxchgweak => ( 1, 2, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 80ef2001cc72e..cfda0300f3f02 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1598,8 +1598,8 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin let parent_hir_node = tcx.hir_node(tcx.parent_hir_id(const_arg_id)); if tcx.features().generic_const_exprs() { ty::AnonConstKind::GCE - } else if tcx.features().opaque_generic_const_args() { - // Only anon consts that are the RHS of a const item can be OGCA. + } else if tcx.features().generic_const_args() { + // Only anon consts that are the RHS of a const item can be GCA. // Note: We can't just check tcx.parent because it needs to be EXACTLY // the RHS, not just part of the RHS. if !is_anon_const_rhs_of_const_item(tcx, def) { @@ -1607,9 +1607,9 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin } let body = tcx.hir_body_owned_by(def); - let mut visitor = OGCAParamVisitor(tcx); + let mut visitor = GCAParamVisitor(tcx); match visitor.visit_body(body) { - ControlFlow::Break(UsesParam) => ty::AnonConstKind::OGCA, + ControlFlow::Break(UsesParam) => ty::AnonConstKind::GCA, ControlFlow::Continue(()) => ty::AnonConstKind::MCG, } } else if tcx.features().min_generic_const_args() { @@ -1650,11 +1650,11 @@ fn is_anon_const_rhs_of_const_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) def_id == rhs_anon.def_id } -struct OGCAParamVisitor<'tcx>(TyCtxt<'tcx>); +struct GCAParamVisitor<'tcx>(TyCtxt<'tcx>); struct UsesParam; -impl<'tcx> Visitor<'tcx> for OGCAParamVisitor<'tcx> { +impl<'tcx> Visitor<'tcx> for GCAParamVisitor<'tcx> { type NestedFilter = nested_filter::OnlyBodies; type Result = ControlFlow; diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index ea98beb955805..3647c91fb7f15 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -97,8 +97,8 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { match tcx.anon_const_kind(def_id) { // Stable: anon consts are not able to use any generic parameters... ty::AnonConstKind::MCG => None, - // OGCA anon consts inherit their parent's generics. - ty::AnonConstKind::OGCA => Some(parent_did), + // GCA anon consts inherit their parent's generics. + ty::AnonConstKind::GCA => Some(parent_did), // we provide generics to repeat expr counts as a backwards compatibility hack. #76200 ty::AnonConstKind::RepeatExprCount => Some(parent_did), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 91660fc655377..9ec5632a74982 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -387,7 +387,7 @@ impl<'tcx> ForbidMCGParamUsesFolder<'tcx> { fn error(&self) -> ErrorGuaranteed { let msg = if self.is_self_alias { "generic `Self` types are currently not permitted in anonymous constants" - } else if self.tcx.features().opaque_generic_const_args() { + } else if self.tcx.features().generic_const_args() { "generic parameters in const blocks are only allowed as the direct value of a `type const`" } else { "generic parameters may not be used in const operations" @@ -408,8 +408,8 @@ impl<'tcx> ForbidMCGParamUsesFolder<'tcx> { } } if self.tcx.features().min_generic_const_args() { - if !self.tcx.features().opaque_generic_const_args() { - diag.help("add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items"); + if !self.tcx.features().generic_const_args() { + diag.help("add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items"); } else { diag.help("consider factoring the expression into a `type const` item and use it as the const argument instead"); } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 89ea6324d8543..87d389a5dea5a 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -341,7 +341,7 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { } debug!("canonical: type var found with vid {:?}", vid); - match self.infcx.unwrap().probe_ty_var(vid) { + match self.infcx.unwrap().try_resolve_ty_var(vid) { // `t` could be a float / int variable; canonicalize that instead. Ok(t) => { debug!("(resolved to {:?})", t); @@ -443,7 +443,7 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { } debug!("canonical: const var found with vid {:?}", vid); - match self.infcx.unwrap().probe_const_var(vid) { + match self.infcx.unwrap().try_resolve_const_var(vid) { Ok(c) => { debug!("(resolved to {:?})", c); return self.fold_const(c); diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 09403513aa08c..fada30ff30633 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -35,7 +35,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } fn universe_of_ty(&self, vid: ty::TyVid) -> Option { - match self.probe_ty_var(vid) { + match self.try_resolve_ty_var(vid) { Err(universe) => Some(universe), Ok(_) => None, } @@ -49,7 +49,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } fn universe_of_ct(&self, ct: ty::ConstVid) -> Option { - match self.probe_const_var(ct) { + match self.try_resolve_const_var(ct) { Err(universe) => Some(universe), Ok(_) => None, } @@ -68,7 +68,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> { - match self.probe_ty_var(vid) { + match self.try_resolve_ty_var(vid) { Ok(ty) => ty, Err(_) => Ty::new_var(self.tcx, self.root_var(vid)), } @@ -83,7 +83,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } fn opportunistic_resolve_ct_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> { - match self.probe_const_var(vid) { + match self.try_resolve_const_var(vid) { Ok(ct) => ct, Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid)), } @@ -103,7 +103,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { if let ty::Infer(infer_ty) = *ty.kind() { match infer_ty { ty::InferTy::TyVar(vid) => { - !self.probe_ty_var(vid).is_err_and(|_| self.root_var(vid) == vid) + !self.try_resolve_ty_var(vid).is_err_and(|_| self.root_var(vid) == vid) } ty::InferTy::IntVar(vid) => { let mut inner = self.inner.borrow_mut(); @@ -133,7 +133,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { if let ty::ConstKind::Infer(infer_ct) = ct.kind() { match infer_ct { ty::InferConst::Var(vid) => !self - .probe_const_var(vid) + .try_resolve_const_var(vid) .is_err_and(|_| self.root_const_var(vid) == vid), ty::InferConst::Fresh(_) => true, } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index e15b25500bb57..2057eeb875970 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1074,7 +1074,7 @@ impl<'tcx> InferCtxt<'tcx> { /// If `TyVar(vid)` resolves to a type, return that type. Else, return the /// universe index of `TyVar(vid)`. - pub fn probe_ty_var(&self, vid: TyVid) -> Result, ty::UniverseIndex> { + pub fn try_resolve_ty_var(&self, vid: TyVid) -> Result, ty::UniverseIndex> { use self::type_variable::TypeVariableValue; match self.inner.borrow_mut().type_variables().probe(vid) { @@ -1228,7 +1228,10 @@ impl<'tcx> InferCtxt<'tcx> { value.fold_with(&mut r) } - pub fn probe_const_var(&self, vid: ty::ConstVid) -> Result, ty::UniverseIndex> { + pub fn try_resolve_const_var( + &self, + vid: ty::ConstVid, + ) -> Result, ty::UniverseIndex> { match self.inner.borrow_mut().const_unification_table().probe_value(vid) { ConstVariableValue::Known { value } => Ok(value), ConstVariableValue::Unknown { origin: _, universe } => Err(universe), diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 3ab39e83f3123..0b29421a8da8b 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -300,10 +300,10 @@ impl<'tcx> InferCtxt<'tcx> { assert!(!source_term.has_escaping_bound_vars()); let (for_universe, root_vid) = match target_vid { TermVid::Ty(ty_vid) => { - (self.probe_ty_var(ty_vid).unwrap_err(), TermVid::Ty(self.root_var(ty_vid))) + (self.try_resolve_ty_var(ty_vid).unwrap_err(), TermVid::Ty(self.root_var(ty_vid))) } TermVid::Const(ct_vid) => ( - self.probe_const_var(ct_vid).unwrap_err(), + self.try_resolve_const_var(ct_vid).unwrap_err(), TermVid::Const(self.inner.borrow_mut().const_unification_table().find(ct_vid).vid), ), }; diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 63ff0b2a0a0df..f0cda4493c851 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -70,6 +70,10 @@ using namespace llvm::object; // This opcode is an LLVM detail that could hypothetically change (?), so // verify that the hard-coded value in `dwarf_const.rs` still agrees with LLVM. static_assert(dwarf::DW_OP_LLVM_fragment == 0x1000); +static_assert(dwarf::DW_OP_constu == 0x10); +static_assert(dwarf::DW_OP_minus == 0x1c); +static_assert(dwarf::DW_OP_mul == 0x1e); +static_assert(dwarf::DW_OP_bregx == 0x92); static_assert(dwarf::DW_OP_stack_value == 0x9f); static LLVM_THREAD_LOCAL char *LastError; @@ -731,7 +735,7 @@ extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints, } template DIT *unwrapDIPtr(LLVMMetadataRef Ref) { - return (DIT *)(Ref ? unwrap(Ref) : nullptr); + return (DIT *)(Ref ? unwrap(Ref) : nullptr); } #define DIDescriptor DIScope @@ -1207,6 +1211,36 @@ extern "C" void LLVMRustDICompositeTypeReplaceArrays( DINodeArray(unwrap(Params))); } +// LLVM's C FFI bindings don't expose the overload of `GetOrCreateSubrange` +// which takes a metadata node as the upper bound. +extern "C" LLVMMetadataRef +LLVMRustDIGetOrCreateSubrange(LLVMDIBuilderRef Builder, + LLVMMetadataRef CountNode, LLVMMetadataRef LB, + LLVMMetadataRef UB, LLVMMetadataRef Stride) { + return wrap(unwrap(Builder)->getOrCreateSubrange( + unwrapDI(CountNode), unwrapDI(LB), + unwrapDI(UB), unwrapDI(Stride))); +} + +// LLVM's CI FFI bindings don't expose the `BitStride` parameter of +// `createVectorType`. +extern "C" LLVMMetadataRef +LLVMRustDICreateVectorType(LLVMDIBuilderRef Builder, uint64_t Size, + uint32_t AlignInBits, LLVMMetadataRef Type, + LLVMMetadataRef Subscripts, + LLVMMetadataRef BitStride) { +#if LLVM_VERSION_GE(22, 0) + return wrap(unwrap(Builder)->createVectorType( + Size, AlignInBits, unwrapDI(Type), + DINodeArray(unwrapDI(Subscripts)), + unwrapDI(BitStride))); +#else + return wrap(unwrap(Builder)->createVectorType( + Size, AlignInBits, unwrapDI(Type), + DINodeArray(unwrapDI(Subscripts)))); +#endif +} + extern "C" LLVMMetadataRef LLVMRustDILocationCloneWithBaseDiscriminator(LLVMMetadataRef Location, unsigned BD) { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 0d047b348d9e1..621ceeffac658 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -7,7 +7,7 @@ use std::debug_assert_matches; use std::ops::{ControlFlow, Range}; use hir::def::{CtorKind, DefKind}; -use rustc_abi::{FIRST_VARIANT, FieldIdx, ScalableElt, VariantIdx}; +use rustc_abi::{FIRST_VARIANT, FieldIdx, NumScalableVectors, ScalableElt, VariantIdx}; use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::LangItem; @@ -1261,17 +1261,27 @@ impl<'tcx> Ty<'tcx> { } } - pub fn scalable_vector_element_count_and_type(self, tcx: TyCtxt<'tcx>) -> (u16, Ty<'tcx>) { + pub fn scalable_vector_parts( + self, + tcx: TyCtxt<'tcx>, + ) -> Option<(u16, Ty<'tcx>, NumScalableVectors)> { let Adt(def, args) = self.kind() else { - bug!("`scalable_vector_size_and_type` called on invalid type") + return None; }; - let Some(ScalableElt::ElementCount(element_count)) = def.repr().scalable else { - bug!("`scalable_vector_size_and_type` called on non-scalable vector type"); + let (num_vectors, vec_def) = match def.repr().scalable? { + ScalableElt::ElementCount(_) => (NumScalableVectors::for_non_tuple(), *def), + ScalableElt::Container => ( + NumScalableVectors::from_field_count(def.non_enum_variant().fields.len())?, + def.non_enum_variant().fields[FieldIdx::ZERO].ty(tcx, args).ty_adt_def()?, + ), }; - let variant = def.non_enum_variant(); + let Some(ScalableElt::ElementCount(element_count)) = vec_def.repr().scalable else { + return None; + }; + let variant = vec_def.non_enum_variant(); assert_eq!(variant.fields.len(), 1); let field_ty = variant.fields[FieldIdx::ZERO].ty(tcx, args); - (element_count, field_ty) + Some((element_count, field_ty, num_vectors)) } pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) { diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index 5a0f149fd0550..ce2be24adc586 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -78,7 +78,7 @@ pub(super) struct Canonicalizer<'a, D: SolverDelegate, I: Interner /// We can simply cache based on the ty itself, because we use /// `ty::BoundVarIndexKind::Canonical`. - cache: HashMap, ty::Ty>, + cache: HashMap, } impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { @@ -316,7 +316,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { (max_universe, self.variables, var_kinds) } - fn inner_fold_ty(&mut self, t: ty::Ty) -> ty::Ty { + fn inner_fold_ty(&mut self, t: I::Ty) -> I::Ty { let kind = match t.kind() { ty::Infer(i) => match i { ty::TyVar(vid) => { @@ -475,7 +475,7 @@ impl, I: Interner> TypeFolder for Canonicaliz Region::new_canonical_bound(self.cx(), var) } - fn fold_ty(&mut self, t: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { if !t.flags().intersects(NEEDS_CANONICAL) { t } else if let Some(&ty) = self.cache.get(&t) { diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index cd42bf8b57b60..1f64f09fe787f 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -16,7 +16,7 @@ use rustc_index::IndexVec; use rustc_type_ir::inherent::*; use rustc_type_ir::relate::solver_relating::RelateExt; use rustc_type_ir::{ - self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner, Ty, + self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner, TypeFoldable, }; use tracing::instrument; @@ -53,7 +53,7 @@ impl ResponseT for inspect::State { pub(super) fn canonicalize_goal( delegate: &D, goal: Goal, - opaque_types: &[(ty::OpaqueTypeKey, Ty)], + opaque_types: &[(ty::OpaqueTypeKey, I::Ty)], ) -> (Vec, CanonicalInput) where D: SolverDelegate, @@ -264,7 +264,7 @@ fn register_region_constraints( fn register_new_opaque_types( delegate: &D, - opaque_types: &[(ty::OpaqueTypeKey, Ty)], + opaque_types: &[(ty::OpaqueTypeKey, I::Ty)], span: I::Span, ) where D: SolverDelegate, diff --git a/compiler/rustc_next_trait_solver/src/coherence.rs b/compiler/rustc_next_trait_solver/src/coherence.rs index 69cebb0a3dc64..c370fd24a1bb3 100644 --- a/compiler/rustc_next_trait_solver/src/coherence.rs +++ b/compiler/rustc_next_trait_solver/src/coherence.rs @@ -47,7 +47,7 @@ pub enum Conflict { pub fn trait_ref_is_knowable( infcx: &Infcx, trait_ref: ty::TraitRef, - mut lazily_normalize_ty: impl FnMut(ty::Ty) -> Result, E>, + mut lazily_normalize_ty: impl FnMut(I::Ty) -> Result, ) -> Result, E> where Infcx: InferCtxtLike, @@ -115,14 +115,14 @@ impl From for IsFirstInputType { #[derive_where(Debug; I: Interner, T: Debug)] pub enum OrphanCheckErr { - NonLocalInputType(Vec<(ty::Ty, IsFirstInputType)>), + NonLocalInputType(Vec<(I::Ty, IsFirstInputType)>), UncoveredTyParams(UncoveredTyParams), } #[derive_where(Debug; I: Interner, T: Debug)] pub struct UncoveredTyParams { pub uncovered: T, - pub local_ty: Option>, + pub local_ty: Option, } /// Checks whether a trait-ref is potentially implementable by a crate. @@ -222,8 +222,8 @@ pub fn orphan_check_trait_ref( infcx: &Infcx, trait_ref: ty::TraitRef, in_crate: InCrate, - lazily_normalize_ty: impl FnMut(ty::Ty) -> Result, E>, -) -> Result>>, E> + lazily_normalize_ty: impl FnMut(I::Ty) -> Result, +) -> Result>, E> where Infcx: InferCtxtLike, I: Interner, @@ -262,14 +262,14 @@ struct OrphanChecker<'a, Infcx, I: Interner, F> { lazily_normalize_ty: F, /// Ignore orphan check failures and exclusively search for the first local type. search_first_local_ty: bool, - non_local_tys: Vec<(ty::Ty, IsFirstInputType)>, + non_local_tys: Vec<(I::Ty, IsFirstInputType)>, } impl<'a, Infcx, I, F, E> OrphanChecker<'a, Infcx, I, F> where Infcx: InferCtxtLike, I: Interner, - F: FnOnce(ty::Ty) -> Result, E>, + F: FnOnce(I::Ty) -> Result, { fn new(infcx: &'a Infcx, in_crate: InCrate, lazily_normalize_ty: F) -> Self { OrphanChecker { @@ -282,15 +282,12 @@ where } } - fn found_non_local_ty(&mut self, t: ty::Ty) -> ControlFlow> { + fn found_non_local_ty(&mut self, t: I::Ty) -> ControlFlow> { self.non_local_tys.push((t, self.in_self_ty.into())); ControlFlow::Continue(()) } - fn found_uncovered_ty_param( - &mut self, - ty: ty::Ty, - ) -> ControlFlow> { + fn found_uncovered_ty_param(&mut self, ty: I::Ty) -> ControlFlow> { if self.search_first_local_ty { return ControlFlow::Continue(()); } @@ -308,15 +305,15 @@ where enum OrphanCheckEarlyExit { NormalizationFailure(E), - UncoveredTyParam(ty::Ty), - LocalTy(ty::Ty), + UncoveredTyParam(I::Ty), + LocalTy(I::Ty), } impl<'a, Infcx, I, F, E> TypeVisitor for OrphanChecker<'a, Infcx, I, F> where Infcx: InferCtxtLike, I: Interner, - F: FnMut(ty::Ty) -> Result, E>, + F: FnMut(I::Ty) -> Result, { type Result = ControlFlow>; @@ -324,7 +321,7 @@ where ControlFlow::Continue(()) } - fn visit_ty(&mut self, ty: ty::Ty) -> Self::Result { + fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { let ty = self.infcx.shallow_resolve(ty); let ty = match (self.lazily_normalize_ty)(ty) { Ok(norm_ty) if norm_ty.is_ty_var() => ty, diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 1714ae3dd6b2e..9d5aa8bc124b6 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -1,7 +1,7 @@ use std::ops::Deref; use rustc_type_ir::solve::{Certainty, Goal, NoSolution}; -use rustc_type_ir::{self as ty, InferCtxtLike, Interner, Ty, TypeFoldable}; +use rustc_type_ir::{self as ty, InferCtxtLike, Interner, TypeFoldable}; pub trait SolverDelegate: Deref + Sized { type Infcx: InferCtxtLike; @@ -70,7 +70,7 @@ pub trait SolverDelegate: Deref + Sized { def_id: ::DefId, args: ::GenericArgs, param_env: ::ParamEnv, - hidden_ty: Ty, + hidden_ty: ::Ty, goals: &mut Vec::Predicate>>, ); @@ -86,8 +86,8 @@ pub trait SolverDelegate: Deref + Sized { fn is_transmutable( &self, - src: Ty, - dst: Ty, + src: ::Ty, + dst: ::Ty, assume: ::Const, ) -> Result; } diff --git a/compiler/rustc_next_trait_solver/src/placeholder.rs b/compiler/rustc_next_trait_solver/src/placeholder.rs index fe7521c86e9be..83f3bdf01dc83 100644 --- a/compiler/rustc_next_trait_solver/src/placeholder.rs +++ b/compiler/rustc_next_trait_solver/src/placeholder.rs @@ -113,7 +113,7 @@ where } } - fn fold_ty(&mut self, t: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { match t.kind() { ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), _) if debruijn.as_usize() + 1 diff --git a/compiler/rustc_next_trait_solver/src/resolve.rs b/compiler/rustc_next_trait_solver/src/resolve.rs index 86bf05bdb57cc..c3c57eccd6eff 100644 --- a/compiler/rustc_next_trait_solver/src/resolve.rs +++ b/compiler/rustc_next_trait_solver/src/resolve.rs @@ -1,7 +1,7 @@ use rustc_type_ir::data_structures::DelayedMap; use rustc_type_ir::inherent::*; use rustc_type_ir::{ - self as ty, InferCtxtLike, Interner, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, + self as ty, InferCtxtLike, Interner, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; @@ -19,7 +19,7 @@ where delegate: &'a D, /// We're able to use a cache here as the folder does not have any /// mutable state. - cache: DelayedMap, Ty>, + cache: DelayedMap, } pub fn eager_resolve_vars>( @@ -45,7 +45,7 @@ impl, I: Interner> TypeFolder for EagerResolv self.delegate.cx() } - fn fold_ty(&mut self, t: Ty) -> Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { match t.kind() { ty::Infer(ty::TyVar(vid)) => { let resolved = self.delegate.opportunistic_resolve_ty_var(vid); diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index f58318b83625d..32b1e93bf98be 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -46,11 +46,11 @@ where D: SolverDelegate, I: Interner, { - fn self_ty(self) -> ty::Ty; + fn self_ty(self) -> I::Ty; fn trait_ref(self, cx: I) -> ty::TraitRef; - fn with_replaced_self_ty(self, cx: I, self_ty: ty::Ty) -> Self; + fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self; fn trait_def_id(self, cx: I) -> I::TraitId; @@ -683,7 +683,7 @@ where // hitting another overflow error something. Add a depth parameter needed later. fn assemble_alias_bound_candidates_recur>( &mut self, - self_ty: ty::Ty, + self_ty: I::Ty, goal: Goal, candidates: &mut Vec>, consider_self_bounds: AliasBoundKind, @@ -1017,13 +1017,13 @@ where struct ReplaceOpaque { cx: I, alias_ty: ty::AliasTy, - self_ty: ty::Ty, + self_ty: I::Ty, } impl TypeFolder for ReplaceOpaque { fn cx(&self) -> I { self.cx } - fn fold_ty(&mut self, ty: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, ty: I::Ty) -> I::Ty { if let ty::Alias(ty::Opaque, alias_ty) = ty.kind() { if alias_ty == self.alias_ty { return self.self_ty; @@ -1280,7 +1280,7 @@ where ControlFlow::Continue(()) } - fn visit_ty(&mut self, ty: ty::Ty) -> Self::Result { + fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { let ty = self.ecx.replace_bound_vars(ty, &mut self.universes); let Ok(ty) = self.ecx.structurally_normalize_ty(self.param_env, ty) else { return ControlFlow::Break(Err(NoSolution)); diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index cbdf0b0a4cc72..433cad188bb6c 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -21,8 +21,8 @@ use crate::solve::{AdtDestructorKind, EvalCtxt, Goal, NoSolution}; #[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait( ecx: &EvalCtxt<'_, D>, - ty: ty::Ty, -) -> Result>>, NoSolution> + ty: I::Ty, +) -> Result>, NoSolution> where D: SolverDelegate, I: Interner, @@ -108,8 +108,8 @@ where pub(in crate::solve) fn instantiate_constituent_tys_for_sizedness_trait( ecx: &EvalCtxt<'_, D>, sizedness: SizedTraitKind, - ty: ty::Ty, -) -> Result>>, NoSolution> + ty: I::Ty, +) -> Result>, NoSolution> where D: SolverDelegate, I: Interner, @@ -186,8 +186,8 @@ where #[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait( ecx: &EvalCtxt<'_, D>, - ty: ty::Ty, -) -> Result>>, NoSolution> + ty: I::Ty, +) -> Result>, NoSolution> where D: SolverDelegate, I: Interner, @@ -268,9 +268,9 @@ where // Returns a binder of the tupled inputs types and output type from a builtin callable type. pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable( cx: I, - self_ty: ty::Ty, + self_ty: I::Ty, goal_kind: ty::ClosureKind, -) -> Result, ty::Ty)>>, NoSolution> { +) -> Result>, NoSolution> { match self_ty.kind() { // keep this in sync with assemble_fn_pointer_candidates until the old solver is removed. ty::FnDef(def_id, args) => { @@ -408,13 +408,13 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable { - pub tupled_inputs_ty: ty::Ty, + pub tupled_inputs_ty: I::Ty, /// Type returned by calling the closure /// i.e. `f()`. - pub output_coroutine_ty: ty::Ty, + pub output_coroutine_ty: I::Ty, /// Type returned by `await`ing the output /// i.e. `f().await`. - pub coroutine_return_ty: ty::Ty, + pub coroutine_return_ty: I::Ty, } // Returns a binder of the tupled inputs types, output type, and coroutine type @@ -424,7 +424,7 @@ pub(in crate::solve) struct AsyncCallableRelevantTypes { // know the kind already, we can short-circuit this check. pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable( cx: I, - self_ty: ty::Ty, + self_ty: I::Ty, goal_kind: ty::ClosureKind, env_region: I::Region, ) -> Result<(ty::Binder>, Vec), NoSolution> { @@ -608,7 +608,7 @@ fn coroutine_closure_to_certain_coroutine( def_id: I::CoroutineClosureId, args: ty::CoroutineClosureArgs, sig: ty::CoroutineClosureSignature, -) -> ty::Ty { +) -> I::Ty { sig.to_coroutine_given_kind_and_upvars( cx, args.parent_args(), @@ -632,7 +632,7 @@ fn coroutine_closure_to_ambiguous_coroutine( def_id: I::CoroutineClosureId, args: ty::CoroutineClosureArgs, sig: ty::CoroutineClosureSignature, -) -> ty::Ty { +) -> I::Ty { let upvars_projection_def_id = cx.require_lang_item(SolverLangItem::AsyncFnKindUpvars); let tupled_upvars_ty = Ty::new_projection( cx, @@ -664,8 +664,8 @@ fn coroutine_closure_to_ambiguous_coroutine( #[instrument(level = "trace", skip(cx), ret)] pub(in crate::solve) fn extract_fn_def_from_const_callable( cx: I, - self_ty: ty::Ty, -) -> Result<(ty::Binder, ty::Ty)>, I::DefId, I::GenericArgs), NoSolution> { + self_ty: I::Ty, +) -> Result<(ty::Binder, I::DefId, I::GenericArgs), NoSolution> { match self_ty.kind() { ty::FnDef(def_id, args) => { let sig = cx.fn_sig(def_id); @@ -742,7 +742,7 @@ pub(in crate::solve) fn extract_fn_def_from_const_callable( // the old solver, for as long as that exists. pub(in crate::solve) fn const_conditions_for_destruct( cx: I, - self_ty: ty::Ty, + self_ty: I::Ty, ) -> Result>, NoSolution> { let destruct_def_id = cx.require_trait_lang_item(SolverTraitLangItem::Destruct); @@ -927,7 +927,7 @@ where struct ReplaceProjectionWith<'a, 'b, I: Interner, D: SolverDelegate> { ecx: &'a mut EvalCtxt<'b, D>, param_env: I::ParamEnv, - self_ty: ty::Ty, + self_ty: I::Ty, mapping: &'a HashMap>>>, nested: Vec>, } @@ -1013,7 +1013,7 @@ where self.ecx.cx() } - fn try_fold_ty(&mut self, ty: ty::Ty) -> Result, Ambiguous> { + fn try_fold_ty(&mut self, ty: I::Ty) -> Result { if let ty::Alias(ty::Projection, alias_ty) = ty.kind() && let Some(term) = self.try_eagerly_replace_alias(alias_ty.into())? { diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 9a0a82acbc931..4b1e4b2de571d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -13,7 +13,7 @@ use super::assembly::{Candidate, structural_traits}; use crate::delegate::SolverDelegate; use crate::solve::{ BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, NoSolution, - QueryResult, Ty, assembly, + QueryResult, assembly, }; impl assembly::GoalKind for ty::HostEffectPredicate @@ -21,7 +21,7 @@ where D: SolverDelegate, I: Interner, { - fn self_ty(self) -> Ty { + fn self_ty(self) -> I::Ty { self.self_ty() } @@ -29,7 +29,7 @@ where self.trait_ref } - fn with_replaced_self_ty(self, cx: I, self_ty: Ty) -> Self { + fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self { self.with_replaced_self_ty(cx, self_ty) } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index d6ed220909732..6841fe1c5124e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -10,7 +10,7 @@ use rustc_type_ir::relate::solver_relating::RelateExt; use rustc_type_ir::search_graph::{CandidateHeadUsages, PathKind}; use rustc_type_ir::solve::OpaqueTypesJank; use rustc_type_ir::{ - self as ty, CanonicalVarValues, InferCtxtLike, Interner, Ty, TypeFoldable, TypeFolder, + self as ty, CanonicalVarValues, InferCtxtLike, Interner, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, }; @@ -781,7 +781,7 @@ where region } - pub(super) fn next_ty_infer(&mut self) -> Ty { + pub(super) fn next_ty_infer(&mut self) -> I::Ty { let ty = self.delegate.next_ty_infer(); self.inspect.add_var_value(ty); ty @@ -829,7 +829,7 @@ where term: I::Term, universe_of_term: ty::UniverseIndex, delegate: &'a D, - cache: HashSet>, + cache: HashSet, } impl, I: Interner> ContainsTermOrNotNameable<'_, D, I> { @@ -846,7 +846,7 @@ where for ContainsTermOrNotNameable<'_, D, I> { type Result = ControlFlow<()>; - fn visit_ty(&mut self, t: Ty) -> Self::Result { + fn visit_ty(&mut self, t: I::Ty) -> Self::Result { if self.cache.contains(&t) { return ControlFlow::Continue(()); } @@ -1072,7 +1072,7 @@ where self.delegate.resolve_vars_if_possible(value) } - pub(super) fn shallow_resolve(&self, ty: Ty) -> Ty { + pub(super) fn shallow_resolve(&self, ty: I::Ty) -> I::Ty { self.delegate.shallow_resolve(ty) } @@ -1092,7 +1092,7 @@ where args } - pub(super) fn register_ty_outlives(&self, ty: Ty, lt: I::Region) { + pub(super) fn register_ty_outlives(&self, ty: I::Ty, lt: I::Region) { self.delegate.register_ty_outlives(ty, lt, self.origin_span); } @@ -1134,8 +1134,8 @@ where pub(super) fn register_hidden_type_in_storage( &mut self, opaque_type_key: ty::OpaqueTypeKey, - hidden_ty: Ty, - ) -> Option> { + hidden_ty: I::Ty, + ) -> Option { self.delegate.register_hidden_type_in_storage(opaque_type_key, hidden_ty, self.origin_span) } @@ -1144,7 +1144,7 @@ where opaque_def_id: I::DefId, opaque_args: I::GenericArgs, param_env: I::ParamEnv, - hidden_ty: Ty, + hidden_ty: I::Ty, ) { let mut goals = Vec::new(); self.delegate.add_item_bounds_for_hidden_type( @@ -1170,8 +1170,8 @@ where pub(super) fn is_transmutable( &mut self, - src: Ty, - dst: Ty, + src: I::Ty, + dst: I::Ty, assume: I::Const, ) -> Result { self.delegate.is_transmutable(dst, src, assume) @@ -1195,7 +1195,7 @@ where pub(crate) fn opaques_with_sub_unified_hidden_type( &self, - self_ty: Ty, + self_ty: I::Ty, ) -> Vec> { if let ty::Infer(ty::TyVar(vid)) = self_ty.kind() { self.delegate.opaques_with_sub_unified_hidden_type(vid) @@ -1389,7 +1389,7 @@ where ecx: &'me mut EvalCtxt<'a, D>, param_env: I::ParamEnv, normalization_goal_source: GoalSource, - cache: HashMap, Ty>, + cache: HashMap, } impl<'me, 'a, D, I> ReplaceAliasWithInfer<'me, 'a, D, I> @@ -1421,7 +1421,7 @@ where self.ecx.cx() } - fn fold_ty(&mut self, ty: Ty) -> Ty { + fn fold_ty(&mut self, ty: I::Ty) -> I::Ty { match ty.kind() { ty::Alias(..) if !ty.has_escaping_bound_vars() => { let infer_ty = self.ecx.next_ty_infer(); diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 71b28cf1ad277..58bd7cf663d98 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -24,7 +24,7 @@ mod trait_goals; use derive_where::derive_where; use rustc_type_ir::inherent::*; pub use rustc_type_ir::solve::*; -use rustc_type_ir::{self as ty, Interner, Ty, TyVid, TypingMode}; +use rustc_type_ir::{self as ty, Interner, TyVid, TypingMode}; use tracing::instrument; pub use self::eval_ctxt::{ @@ -88,7 +88,7 @@ where #[instrument(level = "trace", skip(self))] fn compute_type_outlives_goal( &mut self, - goal: Goal>>, + goal: Goal>, ) -> QueryResult { let ty::OutlivesPredicate(ty, lt) = goal.predicate; self.register_ty_outlives(ty, lt); @@ -205,7 +205,7 @@ where #[instrument(level = "trace", skip(self), ret)] fn compute_const_arg_has_type_goal( &mut self, - goal: Goal)>, + goal: Goal, ) -> QueryResult { let (ct, ty) = goal.predicate; let ct = self.structurally_normalize_const(goal.param_env, ct)?; @@ -315,8 +315,8 @@ where fn structurally_normalize_ty( &mut self, param_env: I::ParamEnv, - ty: Ty, - ) -> Result, NoSolution> { + ty: I::Ty, + ) -> Result { self.structurally_normalize_term(param_env, ty.into()).map(|term| term.expect_ty()) } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs index eb6a1b51421ca..46312be5ea9a9 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs @@ -1,4 +1,4 @@ -use rustc_type_ir::{self as ty, Interner, TypingMode}; +use rustc_type_ir::{self as ty, Interner}; use tracing::instrument; use crate::delegate::SolverDelegate; @@ -14,18 +14,7 @@ where &mut self, goal: Goal>, ) -> QueryResult { - if self.typing_mode() == TypingMode::Coherence - && self.cx().anon_const_kind(goal.predicate.alias.def_id) == ty::AnonConstKind::OGCA - { - // During coherence, OGCA consts should be normalized ambiguously - // because they are opaque but eventually resolved to a real value. - // We don't want two OGCAs that have the same value to be treated - // as distinct for coherence purposes. (Just like opaque types.) - // - // We can't rely on evaluate_const below because that particular wrapper - // treats too-generic consts as a successful evaluation. - self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) - } else if let Some(normalized_const) = self.evaluate_const( + if let Some(normalized_const) = self.evaluate_const( goal.param_env, ty::UnevaluatedConst::new( goal.predicate.alias.def_id.try_into().unwrap(), diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 13ed945857db2..13f2ad8f82eba 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -125,7 +125,7 @@ where D: SolverDelegate, I: Interner, { - fn self_ty(self) -> ty::Ty { + fn self_ty(self) -> I::Ty { self.self_ty() } @@ -133,7 +133,7 @@ where self.alias.trait_ref(cx) } - fn with_replaced_self_ty(self, cx: I, self_ty: ty::Ty) -> Self { + fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self { self.with_replaced_self_ty(cx, self_ty) } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 82051b2fea4ef..6589a12c4cc2d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -29,7 +29,7 @@ where D: SolverDelegate, I: Interner, { - fn self_ty(self) -> ty::Ty { + fn self_ty(self) -> I::Ty { self.self_ty() } @@ -37,7 +37,7 @@ where self.trait_ref } - fn with_replaced_self_ty(self, cx: I, self_ty: ty::Ty) -> Self { + fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self { self.with_replaced_self_ty(cx, self_ty) } @@ -929,7 +929,7 @@ where /// ``` fn consider_builtin_dyn_upcast_candidates( &mut self, - goal: Goal, ty::Ty)>, + goal: Goal, a_data: I::BoundExistentialPredicates, a_region: I::Region, b_data: I::BoundExistentialPredicates, @@ -977,7 +977,7 @@ where fn consider_builtin_unsize_to_dyn_candidate( &mut self, - goal: Goal, ty::Ty)>, + goal: Goal, b_data: I::BoundExistentialPredicates, b_region: I::Region, ) -> Result, NoSolution> { @@ -1018,7 +1018,7 @@ where fn consider_builtin_upcast_to_principal( &mut self, - goal: Goal, ty::Ty)>, + goal: Goal, source: CandidateSource, a_data: I::BoundExistentialPredicates, a_region: I::Region, @@ -1132,9 +1132,9 @@ where /// `#[rustc_deny_explicit_impl]` in this case. fn consider_builtin_array_unsize( &mut self, - goal: Goal, ty::Ty)>, - a_elem_ty: ty::Ty, - b_elem_ty: ty::Ty, + goal: Goal, + a_elem_ty: I::Ty, + b_elem_ty: I::Ty, ) -> Result, NoSolution> { self.eq(goal.param_env, a_elem_ty, b_elem_ty)?; self.probe_builtin_trait_candidate(BuiltinImplSource::Misc) @@ -1156,7 +1156,7 @@ where /// ``` fn consider_builtin_struct_unsize( &mut self, - goal: Goal, ty::Ty)>, + goal: Goal, def: I::AdtDef, a_args: I::GenericArgs, b_args: I::GenericArgs, @@ -1319,8 +1319,8 @@ where goal: Goal>, constituent_tys: impl Fn( &EvalCtxt<'_, D>, - ty::Ty, - ) -> Result>>, NoSolution>, + I::Ty, + ) -> Result>, NoSolution>, ) -> Result, NoSolution> { self.probe_trait_candidate(source).enter(|ecx| { let goals = @@ -1542,10 +1542,7 @@ where self.merge_trait_candidates(candidate_preference_mode, candidates, failed_candidate_info) } - fn try_stall_coroutine( - &mut self, - self_ty: ty::Ty, - ) -> Option, NoSolution>> { + fn try_stall_coroutine(&mut self, self_ty: I::Ty) -> Option, NoSolution>> { if let ty::Coroutine(def_id, _) = self_ty.kind() { match self.typing_mode() { TypingMode::Analysis { diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs index 1403e57a7e6a9..4a780d652df81 100644 --- a/compiler/rustc_public/src/abi.rs +++ b/compiler/rustc_public/src/abi.rs @@ -232,6 +232,10 @@ pub enum TagEncoding { }, } +/// How many scalable vectors are in a `ValueAbi::ScalableVector`? +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] +pub struct NumScalableVectors(pub(crate) u8); + /// Describes how values of the type are passed by target ABIs, /// in terms of categories of C types there are ABI rules for. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] @@ -245,6 +249,7 @@ pub enum ValueAbi { ScalableVector { element: Scalar, count: u64, + number_of_vectors: NumScalableVectors, }, Aggregate { /// If true, the size is exact, otherwise it's only a lower bound. diff --git a/compiler/rustc_public/src/unstable/convert/stable/abi.rs b/compiler/rustc_public/src/unstable/convert/stable/abi.rs index b3edc6194c307..d8c4cee7abbe4 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/abi.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/abi.rs @@ -10,8 +10,9 @@ use rustc_target::callconv; use crate::abi::{ AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength, - IntegerType, Layout, LayoutShape, PassMode, Primitive, ReprFlags, ReprOptions, Scalar, - TagEncoding, TyAndLayout, ValueAbi, VariantFields, VariantsShape, WrappingRange, + IntegerType, Layout, LayoutShape, NumScalableVectors, PassMode, Primitive, ReprFlags, + ReprOptions, Scalar, TagEncoding, TyAndLayout, ValueAbi, VariantFields, VariantsShape, + WrappingRange, }; use crate::compiler_interface::BridgeTys; use crate::target::MachineSize as Size; @@ -249,6 +250,18 @@ impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding { } } +impl<'tcx> Stable<'tcx> for rustc_abi::NumScalableVectors { + type T = NumScalableVectors; + + fn stable<'cx>( + &self, + _tables: &mut Tables<'cx, BridgeTys>, + _cx: &CompilerCtxt<'cx, BridgeTys>, + ) -> Self::T { + NumScalableVectors(self.0) + } +} + impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr { type T = ValueAbi; @@ -265,8 +278,12 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr { rustc_abi::BackendRepr::SimdVector { element, count } => { ValueAbi::Vector { element: element.stable(tables, cx), count } } - rustc_abi::BackendRepr::SimdScalableVector { element, count } => { - ValueAbi::ScalableVector { element: element.stable(tables, cx), count } + rustc_abi::BackendRepr::SimdScalableVector { element, count, number_of_vectors } => { + ValueAbi::ScalableVector { + element: element.stable(tables, cx), + count, + number_of_vectors: number_of_vectors.stable(tables, cx), + } } rustc_abi::BackendRepr::Memory { sized } => ValueAbi::Aggregate { sized }, } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 97c88064e9799..cab37f5c0faa6 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1011,14 +1011,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ResolutionError::ParamInTyOfConstParam { name } => { self.dcx().create_err(errs::ParamInTyOfConstParam { span, name }) } - ResolutionError::ParamInNonTrivialAnonConst { is_ogca, name, param_kind: is_type } => { + ResolutionError::ParamInNonTrivialAnonConst { is_gca, name, param_kind: is_type } => { self.dcx().create_err(errs::ParamInNonTrivialAnonConst { span, name, param_kind: is_type, help: self.tcx.sess.is_nightly_build(), - is_ogca, - help_ogca: is_ogca, + is_gca, + help_gca: is_gca, }) } ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index c9dad4dcd4a75..43b006d72e500 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -407,7 +407,7 @@ pub(crate) struct SelfInConstGenericTy { #[derive(Diagnostic)] #[diag( - "{$is_ogca -> + "{$is_gca -> [true] generic parameters in const blocks are only allowed as the direct value of a `type const` *[false] generic parameters may not be used in const operations }" @@ -421,11 +421,11 @@ pub(crate) struct ParamInNonTrivialAnonConst { pub(crate) param_kind: ParamKindInNonTrivialAnonConst, #[help("add `#![feature(generic_const_exprs)]` to allow generic const expressions")] pub(crate) help: bool, - pub(crate) is_ogca: bool, + pub(crate) is_gca: bool, #[help( "consider factoring the expression into a `type const` item and use it as the const argument instead" )] - pub(crate) help_ogca: bool, + pub(crate) help_gca: bool, } #[derive(Debug)] @@ -1198,6 +1198,15 @@ pub(crate) struct AttributesStartingWithRustcAreReserved { pub(crate) span: Span, } +#[derive(Diagnostic)] +#[diag( + "attributes containing a segment starting with `rustc` are reserved for use by the `rustc` compiler" +)] +pub(crate) struct AttributesContainingRustcAreReserved { + #[primary_span] + pub(crate) span: Span, +} + #[derive(Diagnostic)] #[diag("cannot use {$article} {$descr} through an import")] pub(crate) struct CannotUseThroughAnImport { diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 069018139145d..b7561d58401ab 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1568,10 +1568,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } NoConstantGenericsReason::NonTrivialConstArg => { ResolutionError::ParamInNonTrivialAnonConst { - is_ogca: self - .tcx - .features() - .opaque_generic_const_args(), + is_gca: self.tcx.features().generic_const_args(), name: rib_ident.name, param_kind: ParamKindInNonTrivialAnonConst::Type, } @@ -1663,10 +1660,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } NoConstantGenericsReason::NonTrivialConstArg => { ResolutionError::ParamInNonTrivialAnonConst { - is_ogca: self - .tcx - .features() - .opaque_generic_const_args(), + is_gca: self.tcx.features().generic_const_args(), name: rib_ident.name, param_kind: ParamKindInNonTrivialAnonConst::Const { name: rib_ident.name, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index cf048231bd607..7539e3c4f499f 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3921,8 +3921,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { name: lifetime_ref.ident.name, param_kind: errors::ParamKindInNonTrivialAnonConst::Lifetime, help: self.r.tcx.sess.is_nightly_build(), - is_ogca: self.r.tcx.features().opaque_generic_const_args(), - help_ogca: self.r.tcx.features().opaque_generic_const_args(), + is_gca: self.r.tcx.features().generic_const_args(), + help_gca: self.r.tcx.features().generic_const_args(), }) .emit() } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 72d5cdcf1f3b6..d75f2981a7724 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -308,7 +308,7 @@ enum ResolutionError<'ra> { /// /// This error is only emitted when using `min_const_generics`. ParamInNonTrivialAnonConst { - is_ogca: bool, + is_gca: bool, name: Symbol, param_kind: ParamKindInNonTrivialAnonConst, }, diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 6ae9d3aaeb236..619e61211984d 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -618,14 +618,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // Report errors for the resolved macro. - for segment in &path.segments { + for (idx, segment) in path.segments.iter().enumerate() { if let Some(args) = &segment.args { self.dcx().emit_err(errors::GenericArgumentsInMacroPath { span: args.span() }); } if kind == MacroKind::Attr && segment.ident.as_str().starts_with("rustc") { - self.dcx().emit_err(errors::AttributesStartingWithRustcAreReserved { - span: segment.ident.span, - }); + if idx == 0 { + self.dcx().emit_err(errors::AttributesStartingWithRustcAreReserved { + span: segment.ident.span, + }); + } else { + self.dcx().emit_err(errors::AttributesContainingRustcAreReserved { + span: segment.ident.span, + }); + } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 30bf8dd7c2206..b7ad81c15f1cd 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1014,6 +1014,7 @@ symbols! { generic_assert, generic_associated_types, generic_associated_types_extended, + generic_const_args, generic_const_exprs, generic_const_items, generic_const_parameter_types, @@ -1414,7 +1415,6 @@ symbols! { on_move, on_unimplemented, opaque, - opaque_generic_const_args, opaque_module_name_placeholder: "", ops, opt_out_copy, @@ -1979,6 +1979,12 @@ symbols! { suggestion, super_let, supertrait_item_shadowing, + sve_cast, + sve_tuple_create2, + sve_tuple_create3, + sve_tuple_create4, + sve_tuple_get, + sve_tuple_set, sym, sync, synthetic, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 46bc9bdee04b8..d891cb3fb800d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -255,7 +255,7 @@ impl<'a, 'tcx> TypeFolder> for ClosureEraser<'a, 'tcx> { fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> { let mut p = FmtPrinter::new(infcx.tcx, ns); let ty_getter = move |ty_vid| { - if infcx.probe_ty_var(ty_vid).is_ok() { + if infcx.try_resolve_ty_var(ty_vid).is_ok() { warn!("resolved ty var in error message"); } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index bdad1b259b733..94ce7631b3c88 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -676,21 +676,10 @@ pub fn try_evaluate_const<'tcx>( (args, typing_env) } - Some(ty::AnonConstKind::OGCA) => { - if infcx.typing_mode() != TypingMode::PostAnalysis { - // OGCA anon consts should be treated as always having generics - // during anything before codegen (or maybe MIR opts too). - return Err(EvaluateConstErr::HasGenericsOrInfers); - } - - if uv.args.has_non_region_param() || uv.args.has_non_region_infer() { - return Err(EvaluateConstErr::HasGenericsOrInfers); - } - - let typing_env = ty::TypingEnv::fully_monomorphized(); - (uv.args, typing_env) - } - Some(ty::AnonConstKind::MCG) | Some(ty::AnonConstKind::NonTypeSystem) | None => { + Some(ty::AnonConstKind::GCA) + | Some(ty::AnonConstKind::MCG) + | Some(ty::AnonConstKind::NonTypeSystem) + | None => { // We are only dealing with "truly" generic/uninferred constants here: // - GCEConsts have been handled separately // - Repeat expr count back compat consts have also been handled separately diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 391f50edf23fa..136df923ee47a 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -4,8 +4,8 @@ use rustc_abi::Integer::{I8, I32}; use rustc_abi::Primitive::{self, Float, Int, Pointer}; use rustc_abi::{ AddressSpace, BackendRepr, FIRST_VARIANT, FieldIdx, FieldsShape, HasDataLayout, Layout, - LayoutCalculatorError, LayoutData, Niche, ReprOptions, ScalableElt, Scalar, Size, StructKind, - TagEncoding, VariantIdx, Variants, WrappingRange, + LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, StructKind, TagEncoding, + VariantIdx, Variants, WrappingRange, }; use rustc_hashes::Hash64; use rustc_hir as hir; @@ -572,30 +572,26 @@ fn layout_of_uncached<'tcx>( // ```rust (ignore, example) // #[rustc_scalable_vector(3)] // struct svuint32_t(u32); + // + // #[rustc_scalable_vector] + // struct svuint32x2_t(svuint32_t, svuint32_t); // ``` - ty::Adt(def, args) - if matches!(def.repr().scalable, Some(ScalableElt::ElementCount(..))) => - { - let Some(element_ty) = def - .is_struct() - .then(|| &def.variant(FIRST_VARIANT).fields) - .filter(|fields| fields.len() == 1) - .map(|fields| fields[FieldIdx::ZERO].ty(tcx, args)) + ty::Adt(def, _args) if def.repr().scalable() => { + let Some((element_count, element_ty, number_of_vectors)) = + ty.scalable_vector_parts(tcx) else { let guar = tcx .dcx() - .delayed_bug("#[rustc_scalable_vector] was applied to an invalid type"); - return Err(error(cx, LayoutError::ReferencesError(guar))); - }; - let Some(ScalableElt::ElementCount(element_count)) = def.repr().scalable else { - let guar = tcx - .dcx() - .delayed_bug("#[rustc_scalable_vector] was applied to an invalid type"); + .delayed_bug("`#[rustc_scalable_vector]` was applied to an invalid type"); return Err(error(cx, LayoutError::ReferencesError(guar))); }; let element_layout = cx.layout_of(element_ty)?; - map_layout(cx.calc.scalable_vector_type(element_layout, element_count as u64))? + map_layout(cx.calc.scalable_vector_type( + element_layout, + element_count as u64, + number_of_vectors, + ))? } // SIMD vector types. diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 6528aa7526b21..0b0f0fd2f4249 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -16,7 +16,7 @@ use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldabl use crate::inherent::*; use crate::lift::Lift; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; -use crate::{self as ty, DebruijnIndex, Interner, Ty, UniverseIndex}; +use crate::{self as ty, DebruijnIndex, Interner, UniverseIndex}; /// `Binder` is a binder for higher-ranked lifetimes or types. It is part of the /// compiler's representation for things like `for<'a> Fn(&'a isize)` @@ -274,7 +274,7 @@ pub struct ValidateBoundVars { // We only cache types because any complex const will have to step through // a type at some point anyways. We may encounter the same variable at // different levels of binding, so this can't just be `Ty`. - visited: SsoHashSet<(ty::DebruijnIndex, Ty)>, + visited: SsoHashSet<(ty::DebruijnIndex, I::Ty)>, } impl ValidateBoundVars { @@ -297,7 +297,7 @@ impl TypeVisitor for ValidateBoundVars { result } - fn visit_ty(&mut self, t: Ty) -> Self::Result { + fn visit_ty(&mut self, t: I::Ty) -> Self::Result { if t.outer_exclusive_binder() < self.binder_index || !self.visited.insert((self.binder_index, t)) { @@ -724,7 +724,7 @@ impl<'a, I: Interner> TypeFolder for ArgFolder<'a, I> { } } - fn fold_ty(&mut self, t: Ty) -> Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { if !t.has_param() { return t; } @@ -753,7 +753,7 @@ impl<'a, I: Interner> TypeFolder for ArgFolder<'a, I> { } impl<'a, I: Interner> ArgFolder<'a, I> { - fn ty_for_param(&self, p: I::ParamTy, source_ty: Ty) -> Ty { + fn ty_for_param(&self, p: I::ParamTy, source_ty: I::Ty) -> I::Ty { // Look up the type in the args. It really should be in there. let opt_ty = self.args.get(p.index() as usize).map(|arg| arg.kind()); let ty = match opt_ty { @@ -767,7 +767,7 @@ impl<'a, I: Interner> ArgFolder<'a, I> { #[cold] #[inline(never)] - fn type_param_expected(&self, p: I::ParamTy, ty: Ty, kind: ty::GenericArgKind) -> ! { + fn type_param_expected(&self, p: I::ParamTy, ty: I::Ty, kind: ty::GenericArgKind) -> ! { panic!( "expected type for `{:?}` ({:?}/{}) but found {:?} when instantiating, args={:?}", p, @@ -780,7 +780,7 @@ impl<'a, I: Interner> ArgFolder<'a, I> { #[cold] #[inline(never)] - fn type_param_out_of_range(&self, p: I::ParamTy, ty: Ty) -> ! { + fn type_param_out_of_range(&self, p: I::ParamTy, ty: I::Ty) -> ! { panic!( "type parameter `{:?}` ({:?}/{}) out of range when instantiating, args={:?}", p, @@ -1277,7 +1277,7 @@ impl PlaceholderConst { Self { universe: ui, bound, _tcx: PhantomData } } - pub fn find_const_ty_from_env(self, env: I::ParamEnv) -> Ty { + pub fn find_const_ty_from_env(self, env: I::ParamEnv) -> I::Ty { let mut candidates = env.caller_bounds().iter().filter_map(|clause| { // `ConstArgHasType` are never desugared to be higher ranked. match clause.kind().skip_binder() { diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 9786608ab4bc0..2877364762f46 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -210,9 +210,9 @@ pub enum AnonConstKind { GCE, /// stable `min_const_generics` anon consts are not allowed to use any generic parameters MCG, - /// `feature(opaque_generic_const_args)` anon consts are allowed to use arbitrary + /// `feature(generic_const_args)` anon consts are allowed to use arbitrary /// generic parameters in scope, but only if they syntactically reference them. - OGCA, + GCA, /// anon consts used as the length of a repeat expr are syntactically allowed to use generic parameters /// but must not depend on the actual instantiation. See #76200 for more information RepeatExprCount, diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs index ef542af7f1f9a..eba4c7c6644ac 100644 --- a/compiler/rustc_type_ir/src/error.rs +++ b/compiler/rustc_type_ir/src/error.rs @@ -2,7 +2,7 @@ use derive_where::derive_where; use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; use crate::solve::NoSolution; -use crate::{self as ty, Interner, Ty}; +use crate::{self as ty, Interner}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(TypeFoldable_Generic, TypeVisitable_Generic, GenericTypeVisitable)] @@ -36,15 +36,15 @@ pub enum TypeError { RegionsInsufficientlyPolymorphic(ty::BoundRegion, I::Region), RegionsPlaceholderMismatch, - Sorts(ExpectedFound>), - ArgumentSorts(ExpectedFound>, usize), + Sorts(ExpectedFound), + ArgumentSorts(ExpectedFound, usize), Traits(ExpectedFound), VariadicMismatch(ExpectedFound), /// Instantiating a type variable with the given type would have /// created a cycle (because it appears somewhere within that /// type). - CyclicTy(Ty), + CyclicTy(I::Ty), CyclicConst(I::Const), ProjectionMismatched(ExpectedFound), ExistentialMismatch(ExpectedFound), diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs index 6bd985a20ae01..5e24e53c62d9a 100644 --- a/compiler/rustc_type_ir/src/fast_reject.rs +++ b/compiler/rustc_type_ir/src/fast_reject.rs @@ -113,7 +113,7 @@ pub enum TreatParams { /// ¹ meaning that if the outermost layers are different, then the whole types are also different. pub fn simplify_type( cx: I, - ty: ty::Ty, + ty: I::Ty, treat_params: TreatParams, ) -> Option> { match ty.kind() { @@ -236,16 +236,11 @@ impl, rhs: ty::Ty) -> bool { + pub fn types_may_unify(self, lhs: I::Ty, rhs: I::Ty) -> bool { self.types_may_unify_inner(lhs, rhs, Self::STARTING_DEPTH) } - pub fn types_may_unify_with_depth( - self, - lhs: ty::Ty, - rhs: ty::Ty, - depth_limit: usize, - ) -> bool { + pub fn types_may_unify_with_depth(self, lhs: I::Ty, rhs: I::Ty, depth_limit: usize) -> bool { self.types_may_unify_inner(lhs, rhs, depth_limit) } @@ -273,7 +268,7 @@ impl, rhs: ty::Ty, depth: usize) -> bool { + fn types_may_unify_inner(self, lhs: I::Ty, rhs: I::Ty, depth: usize) -> bool { if lhs == rhs { return true; } @@ -532,7 +527,7 @@ impl) -> bool { + fn var_and_ty_may_unify(self, var: ty::InferTy, ty: I::Ty) -> bool { if !ty.is_known_rigid() { return true; } diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 6962a7ab1d727..7e905da0785f8 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -1,6 +1,6 @@ use crate::inherent::*; use crate::visit::Flags; -use crate::{self as ty, Interner, Ty}; +use crate::{self as ty, Interner}; bitflags::bitflags! { /// Flags that we track on types. These flags are propagated upwards @@ -430,7 +430,7 @@ impl FlagComputation { } } - fn add_ty(&mut self, ty: Ty) { + fn add_ty(&mut self, ty: I::Ty) { self.add_flags(ty.flags()); self.add_exclusive_binder(ty.outer_exclusive_binder()); } diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index ef162b21b660e..d1a50599e8b9c 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -135,7 +135,7 @@ pub trait TypeFolder: Sized { t.super_fold_with(self) } - fn fold_ty(&mut self, t: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { t.super_fold_with(self) } @@ -177,7 +177,7 @@ pub trait FallibleTypeFolder: Sized { t.try_super_fold_with(self) } - fn try_fold_ty(&mut self, t: ty::Ty) -> Result, Self::Error> { + fn try_fold_ty(&mut self, t: I::Ty) -> Result { t.try_super_fold_with(self) } @@ -408,7 +408,7 @@ impl TypeFolder for Shifter { } } - fn fold_ty(&mut self, ty: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, ty: I::Ty) -> I::Ty { match ty.kind() { ty::Bound(BoundVarIndexKind::Bound(debruijn), bound_ty) if debruijn >= self.current_index => @@ -538,7 +538,7 @@ where } } - fn fold_ty(&mut self, t: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { if t.has_type_flags( TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED, ) { diff --git a/compiler/rustc_type_ir/src/generic_arg.rs b/compiler/rustc_type_ir/src/generic_arg.rs index 22a4ebd03b69c..5d612740fdd84 100644 --- a/compiler/rustc_type_ir/src/generic_arg.rs +++ b/compiler/rustc_type_ir/src/generic_arg.rs @@ -3,7 +3,7 @@ use derive_where::derive_where; use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; use rustc_type_ir_macros::GenericTypeVisitable; -use crate::{Interner, Ty}; +use crate::Interner; #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] #[derive(GenericTypeVisitable)] @@ -13,7 +13,7 @@ use crate::{Interner, Ty}; )] pub enum GenericArgKind { Lifetime(I::Region), - Type(Ty), + Type(I::Ty), Const(I::Const), } @@ -26,7 +26,7 @@ impl Eq for GenericArgKind {} derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) )] pub enum TermKind { - Ty(Ty), + Ty(I::Ty), Const(I::Const), } diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 843d1eb37b7d9..feafcee7bad9e 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -6,7 +6,7 @@ use crate::fold::TypeFoldable; use crate::inherent::*; use crate::relate::RelateResult; use crate::relate::combine::PredicateEmittingRelation; -use crate::{self as ty, Interner, Ty, TyVid}; +use crate::{self as ty, Interner, TyVid}; /// The current typing mode of an inference context. We unfortunately have some /// slightly different typing rules depending on the current context. See the @@ -161,9 +161,12 @@ pub trait InferCtxtLike: Sized { fn sub_unification_table_root_var(&self, var: ty::TyVid) -> ty::TyVid; fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid; - fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty; - fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty; - fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty; + fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> ::Ty; + fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> ::Ty; + fn opportunistic_resolve_float_var( + &self, + vid: ty::FloatVid, + ) -> ::Ty; fn opportunistic_resolve_ct_var( &self, vid: ty::ConstVid, @@ -176,7 +179,7 @@ pub trait InferCtxtLike: Sized { fn is_changed_arg(&self, arg: ::GenericArg) -> bool; fn next_region_infer(&self) -> ::Region; - fn next_ty_infer(&self) -> Ty; + fn next_ty_infer(&self) -> ::Ty; fn next_const_infer(&self) -> ::Const; fn fresh_args_for_item( &self, @@ -206,7 +209,7 @@ pub trait InferCtxtLike: Sized { target_is_expected: bool, target_vid: ty::TyVid, instantiation_variance: ty::Variance, - source_ty: Ty, + source_ty: ::Ty, ) -> RelateResult; fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue); fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue); @@ -220,7 +223,10 @@ pub trait InferCtxtLike: Sized { fn set_tainted_by_errors(&self, e: ::ErrorGuaranteed); - fn shallow_resolve(&self, ty: Ty) -> Ty; + fn shallow_resolve( + &self, + ty: ::Ty, + ) -> ::Ty; fn shallow_resolve_const( &self, ty: ::Const, @@ -248,7 +254,7 @@ pub trait InferCtxtLike: Sized { fn register_ty_outlives( &self, - ty: Ty, + ty: ::Ty, r: ::Region, span: ::Span, ); @@ -257,26 +263,26 @@ pub trait InferCtxtLike: Sized { fn opaque_types_storage_num_entries(&self) -> Self::OpaqueTypeStorageEntries; fn clone_opaque_types_lookup_table( &self, - ) -> Vec<(ty::OpaqueTypeKey, Ty)>; + ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; fn clone_duplicate_opaque_types( &self, - ) -> Vec<(ty::OpaqueTypeKey, Ty)>; + ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; fn clone_opaque_types_added_since( &self, prev_entries: Self::OpaqueTypeStorageEntries, - ) -> Vec<(ty::OpaqueTypeKey, Ty)>; + ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; fn opaques_with_sub_unified_hidden_type(&self, ty: TyVid) -> Vec>; fn register_hidden_type_in_storage( &self, opaque_type_key: ty::OpaqueTypeKey, - hidden_ty: Ty, + hidden_ty: ::Ty, span: ::Span, - ) -> Option>; + ) -> Option<::Ty>; fn add_duplicate_opaque_type( &self, opaque_type_key: ty::OpaqueTypeKey, - hidden_ty: Ty, + hidden_ty: ::Ty, span: ::Span, ); diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 45590561d9d08..fcadeb6174812 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -108,7 +108,7 @@ pub trait Ty>: fn new_slice(interner: I, ty: Self) -> Self; - fn new_tup(interner: I, tys: &[ty::Ty]) -> Self; + fn new_tup(interner: I, tys: &[I::Ty]) -> Self; fn new_tup_from_iter(interner: I, iter: It) -> T::Output where @@ -121,7 +121,7 @@ pub trait Ty>: fn new_pat(interner: I, ty: Self, pat: I::Pat) -> Self; - fn new_unsafe_binder(interner: I, ty: ty::Binder>) -> Self; + fn new_unsafe_binder(interner: I, ty: ty::Binder) -> Self; fn tuple_fields(self) -> I::Tys; @@ -158,7 +158,7 @@ pub trait Ty>: self.kind().fn_sig(interner) } - fn discriminant_ty(self, interner: I) -> ty::Ty; + fn discriminant_ty(self, interner: I) -> I::Ty; fn is_known_rigid(self) -> bool { self.kind().is_known_rigid() @@ -198,11 +198,11 @@ pub trait Ty>: } pub trait Tys>: - Copy + Debug + Hash + Eq + SliceLike> + TypeFoldable + Default + Copy + Debug + Hash + Eq + SliceLike + TypeFoldable + Default { fn inputs(self) -> I::FnInputTys; - fn output(self) -> ty::Ty; + fn output(self) -> I::Ty; } pub trait Abi>: Copy + Debug + Hash + Eq { @@ -290,7 +290,7 @@ pub trait Const>: } pub trait ValueConst>: Copy + Debug + Hash + Eq { - fn ty(self) -> ty::Ty; + fn ty(self) -> I::Ty; fn valtree(self) -> I::ValTree; } @@ -310,7 +310,7 @@ pub trait GenericArg>: + IntoKind> + TypeVisitable + Relate - + From> + + From + From + From + From @@ -323,11 +323,11 @@ pub trait GenericArg>: } } - fn as_type(&self) -> Option> { + fn as_type(&self) -> Option { if let ty::GenericArgKind::Type(ty) = self.kind() { Some(ty) } else { None } } - fn expect_ty(&self) -> ty::Ty { + fn expect_ty(&self) -> I::Ty { self.as_type().expect("expected a type") } @@ -359,11 +359,11 @@ pub trait GenericArg>: pub trait Term>: Copy + Debug + Hash + Eq + IntoKind> + TypeFoldable + Relate { - fn as_type(&self) -> Option> { + fn as_type(&self) -> Option { if let ty::TermKind::Ty(ty) = self.kind() { Some(ty) } else { None } } - fn expect_ty(&self) -> ty::Ty { + fn expect_ty(&self) -> I::Ty { self.as_type().expect("expected a type, but found a const") } @@ -413,7 +413,7 @@ pub trait GenericArgs>: target: I::GenericArgs, ) -> I::GenericArgs; - fn type_at(self, i: usize) -> ty::Ty; + fn type_at(self, i: usize) -> I::Ty; fn region_at(self, i: usize) -> I::Region; @@ -459,7 +459,7 @@ pub trait Predicate>: + UpcastFrom> + UpcastFrom>> + UpcastFrom> - + UpcastFrom>> + + UpcastFrom> + UpcastFrom> + IntoKind>> + Elaboratable @@ -578,7 +578,7 @@ pub trait AdtDef: Copy + Debug + Hash + Eq { /// Returns the type of the struct tail. /// /// Expects the `AdtDef` to be a struct. If it is not, then this will panic. - fn struct_tail_ty(self, interner: I) -> Option>>; + fn struct_tail_ty(self, interner: I) -> Option>; fn is_phantom_data(self) -> bool; @@ -591,13 +591,13 @@ pub trait AdtDef: Copy + Debug + Hash + Eq { ) -> Option>; // FIXME: perhaps use `all_fields` and expose `FieldDef`. - fn all_field_tys(self, interner: I) -> ty::EarlyBinder>>; + fn all_field_tys(self, interner: I) -> ty::EarlyBinder>; fn sizedness_constraint( self, interner: I, sizedness: SizedTraitKind, - ) -> Option>>; + ) -> Option>; fn is_fundamental(self) -> bool; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 6c838cf8a48ac..a0b444024ca79 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -31,7 +31,6 @@ pub mod outlives; pub mod relate; pub mod search_graph; pub mod solve; -pub mod sty; pub mod walk; // These modules are not `pub` since they are glob-imported. @@ -79,7 +78,6 @@ pub use predicate_kind::*; pub use region_kind::*; pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy}; use rustc_type_ir_macros::GenericTypeVisitable; -pub use sty::*; pub use ty_info::*; pub use ty_kind::*; pub use upcast::*; @@ -445,8 +443,8 @@ impl fmt::Display for ClosureKind { } pub struct FieldInfo { - pub base: Ty, - pub ty: Ty, + pub base: I::Ty, + pub ty: I::Ty, pub variant: Option, pub variant_idx: VariantIdx, pub name: I::Symbol, diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs index cc79d6589e6fb..300e5c0b46956 100644 --- a/compiler/rustc_type_ir/src/outlives.rs +++ b/compiler/rustc_type_ir/src/outlives.rs @@ -8,7 +8,7 @@ use smallvec::{SmallVec, smallvec}; use crate::data_structures::SsoHashSet; use crate::inherent::*; use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt as _, TypeVisitor}; -use crate::{self as ty, Interner, Ty}; +use crate::{self as ty, Interner}; #[derive_where(Debug; I: Interner)] pub enum Component { @@ -55,7 +55,7 @@ pub enum Component { /// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**. pub fn push_outlives_components( cx: I, - ty: Ty, + ty: I::Ty, out: &mut SmallVec<[Component; 4]>, ) { ty.visit_with(&mut OutlivesCollector { cx, out, visited: Default::default() }); @@ -64,14 +64,14 @@ pub fn push_outlives_components( struct OutlivesCollector<'a, I: Interner> { cx: I, out: &'a mut SmallVec<[Component; 4]>, - visited: SsoHashSet>, + visited: SsoHashSet, } impl TypeVisitor for OutlivesCollector<'_, I> { #[cfg(not(feature = "nightly"))] type Result = (); - fn visit_ty(&mut self, ty: Ty) -> Self::Result { + fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { if !self.visited.insert(ty) { return; } diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index f4975f3ad4486..113192cc02eb8 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -101,7 +101,7 @@ impl TraitRef { ) } - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { TraitRef::new( interner, self.def_id, @@ -110,13 +110,13 @@ impl TraitRef { } #[inline] - pub fn self_ty(&self) -> ty::Ty { + pub fn self_ty(&self) -> I::Ty { self.args.type_at(0) } } impl ty::Binder> { - pub fn self_ty(&self) -> ty::Binder> { + pub fn self_ty(&self) -> ty::Binder { self.map_bound_ref(|tr| tr.self_ty()) } @@ -152,7 +152,7 @@ pub struct TraitPredicate { impl Eq for TraitPredicate {} impl TraitPredicate { - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), polarity: self.polarity, @@ -163,7 +163,7 @@ impl TraitPredicate { self.trait_ref.def_id } - pub fn self_ty(self) -> ty::Ty { + pub fn self_ty(self) -> I::Ty { self.trait_ref.self_ty() } } @@ -174,7 +174,7 @@ impl ty::Binder> { self.skip_binder().def_id() } - pub fn self_ty(self) -> ty::Binder> { + pub fn self_ty(self) -> ty::Binder { self.map_bound(|trait_ref| trait_ref.self_ty()) } @@ -307,7 +307,7 @@ impl ty::Binder> { /// Given an existential predicate like `?Self: PartialEq` (e.g., derived from `dyn PartialEq`), /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self` /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq`, in our example). - pub fn with_self_ty(&self, cx: I, self_ty: ty::Ty) -> I::Clause { + pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> I::Clause { match self.skip_binder() { ExistentialPredicate::Trait(tr) => self.rebind(tr).with_self_ty(cx, self_ty).upcast(cx), ExistentialPredicate::Projection(p) => { @@ -384,7 +384,7 @@ impl ExistentialTraitRef { /// we convert the principal trait-ref into a normal trait-ref, /// you must give *some* self type. A common choice is `mk_err()` /// or some placeholder type. - pub fn with_self_ty(self, interner: I, self_ty: ty::Ty) -> TraitRef { + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> TraitRef { // otherwise the escaping vars would be captured by the binder // debug_assert!(!self_ty.has_escaping_bound_vars()); @@ -401,7 +401,7 @@ impl ty::Binder> { /// we convert the principal trait-ref into a normal trait-ref, /// you must give *some* self type. A common choice is `mk_err()` /// or some placeholder type. - pub fn with_self_ty(&self, cx: I, self_ty: ty::Ty) -> ty::Binder> { + pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder> { self.map_bound(|trait_ref| trait_ref.with_self_ty(cx, self_ty)) } } @@ -459,7 +459,7 @@ impl ExistentialProjection { ExistentialTraitRef::new_from_args(interner, def_id.try_into().unwrap(), args) } - pub fn with_self_ty(&self, interner: I, self_ty: ty::Ty) -> ProjectionPredicate { + pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate { // otherwise the escaping regions would be captured by the binders debug_assert!(!self_ty.has_escaping_bound_vars()); @@ -487,7 +487,7 @@ impl ExistentialProjection { } impl ty::Binder> { - pub fn with_self_ty(&self, cx: I, self_ty: ty::Ty) -> ty::Binder> { + pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder> { self.map_bound(|p| p.with_self_ty(cx, self_ty)) } @@ -683,11 +683,11 @@ impl AliasTerm { /// The following methods work only with (trait) associated term projections. impl AliasTerm { - pub fn self_ty(self) -> ty::Ty { + pub fn self_ty(self) -> I::Ty { self.args.type_at(0) } - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { AliasTerm::new( interner, self.def_id, @@ -796,11 +796,11 @@ pub struct ProjectionPredicate { impl Eq for ProjectionPredicate {} impl ProjectionPredicate { - pub fn self_ty(self) -> ty::Ty { + pub fn self_ty(self) -> I::Ty { self.projection_term.self_ty() } - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> ProjectionPredicate { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate { Self { projection_term: self.projection_term.with_replaced_self_ty(interner, self_ty), ..self @@ -859,11 +859,11 @@ pub struct NormalizesTo { impl Eq for NormalizesTo {} impl NormalizesTo { - pub fn self_ty(self) -> ty::Ty { + pub fn self_ty(self) -> I::Ty { self.alias.self_ty() } - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> NormalizesTo { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo { Self { alias: self.alias.with_replaced_self_ty(interner, self_ty), ..self } } @@ -896,11 +896,11 @@ pub struct HostEffectPredicate { impl Eq for HostEffectPredicate {} impl HostEffectPredicate { - pub fn self_ty(self) -> ty::Ty { + pub fn self_ty(self) -> I::Ty { self.trait_ref.self_ty() } - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), ..self } } @@ -915,7 +915,7 @@ impl ty::Binder> { self.skip_binder().def_id() } - pub fn self_ty(self) -> ty::Binder> { + pub fn self_ty(self) -> ty::Binder { self.map_bound(|trait_ref| trait_ref.self_ty()) } @@ -936,8 +936,8 @@ impl ty::Binder> { )] pub struct SubtypePredicate { pub a_is_expected: bool, - pub a: ty::Ty, - pub b: ty::Ty, + pub a: I::Ty, + pub b: I::Ty, } impl Eq for SubtypePredicate {} @@ -950,8 +950,8 @@ impl Eq for SubtypePredicate {} derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) )] pub struct CoercePredicate { - pub a: ty::Ty, - pub b: ty::Ty, + pub a: I::Ty, + pub b: I::Ty, } impl Eq for CoercePredicate {} diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index b6ff27fb238e6..445e85a888fca 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -5,7 +5,7 @@ use derive_where::derive_where; use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; -use crate::{self as ty, Interner, Ty}; +use crate::{self as ty, Interner}; /// A clause is something that can appear in where bounds or be inferred /// by implied bounds. @@ -25,7 +25,7 @@ pub enum ClauseKind { RegionOutlives(ty::OutlivesPredicate), /// `where T: 'r` - TypeOutlives(ty::OutlivesPredicate>), + TypeOutlives(ty::OutlivesPredicate), /// `where ::Name == X`, approximately. /// See the `ProjectionPredicate` struct for details. @@ -33,7 +33,7 @@ pub enum ClauseKind { /// Ensures that a const generic argument to a parameter `const N: u8` /// is of type `u8`. - ConstArgHasType(I::Const, Ty), + ConstArgHasType(I::Const, I::Ty), /// No syntax: `T` well-formed. WellFormed(I::Term), diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 31248bea4cf85..d33c6036dadd8 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -44,7 +44,7 @@ pub enum VarianceDiagInfo { Invariant { /// The generic type containing the generic parameter /// that changes the variance (e.g. `*mut T`, `MyStruct`) - ty: ty::Ty, + ty: I::Ty, /// The index of the generic parameter being used /// (e.g. `0` for `*mut T`, `1` for `MyStruct<'CovariantParam, 'InvariantParam>`) param_index: u32, @@ -75,13 +75,13 @@ pub trait TypeRelation: Sized { fn relate_ty_args( &mut self, - a_ty: ty::Ty, - b_ty: ty::Ty, + a_ty: I::Ty, + b_ty: I::Ty, ty_def_id: I::DefId, a_arg: I::GenericArgs, b_arg: I::GenericArgs, - mk: impl FnOnce(I::GenericArgs) -> ty::Ty, - ) -> RelateResult>; + mk: impl FnOnce(I::GenericArgs) -> I::Ty, + ) -> RelateResult; /// Switch variance for the purpose of relating `a` and `b`. fn relate_with_variance>( @@ -98,7 +98,7 @@ pub trait TypeRelation: Sized { // additional hooks for other types in the future if needed // without making older code, which called `relate`, obsolete. - fn tys(&mut self, a: ty::Ty, b: ty::Ty) -> RelateResult>; + fn tys(&mut self, a: I::Ty, b: I::Ty) -> RelateResult; fn regions(&mut self, a: I::Region, b: I::Region) -> RelateResult; @@ -332,9 +332,9 @@ impl Relate for ty::ExistentialTraitRef { #[instrument(level = "trace", skip(relation), ret)] pub fn structurally_relate_tys>( relation: &mut R, - a: ty::Ty, - b: ty::Ty, -) -> RelateResult> { + a: I::Ty, + b: I::Ty, +) -> RelateResult { let cx = relation.cx(); match (a.kind(), b.kind()) { (ty::Infer(_), _) | (_, ty::Infer(_)) => { diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index 11fbbf89b9c7b..64b87fac77f94 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -39,15 +39,15 @@ where ); /// Register `AliasRelate` obligation(s) that both types must be related to each other. - fn register_alias_relate_predicate(&mut self, a: ty::Ty, b: ty::Ty); + fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty); } pub fn super_combine_tys( infcx: &Infcx, relation: &mut R, - a: ty::Ty, - b: ty::Ty, -) -> RelateResult> + a: I::Ty, + b: I::Ty, +) -> RelateResult where Infcx: InferCtxtLike, I: Interner, @@ -226,13 +226,13 @@ where pub fn combine_ty_args( infcx: &Infcx, relation: &mut R, - a_ty: ty::Ty, - b_ty: ty::Ty, + a_ty: I::Ty, + b_ty: I::Ty, variances: I::VariancesOf, a_args: I::GenericArgs, b_args: I::GenericArgs, - mk: impl FnOnce(I::GenericArgs) -> ty::Ty, -) -> RelateResult> + mk: impl FnOnce(I::GenericArgs) -> I::Ty, +) -> RelateResult where Infcx: InferCtxtLike, I: Interner, diff --git a/compiler/rustc_type_ir/src/relate/solver_relating.rs b/compiler/rustc_type_ir/src/relate/solver_relating.rs index 1494d67d3c603..82ee4f75fcb0a 100644 --- a/compiler/rustc_type_ir/src/relate/solver_relating.rs +++ b/compiler/rustc_type_ir/src/relate/solver_relating.rs @@ -5,7 +5,7 @@ use crate::data_structures::DelayedSet; use crate::relate::combine::combine_ty_args; pub use crate::relate::*; use crate::solve::Goal; -use crate::{self as ty, InferCtxtLike, Interner, Ty}; +use crate::{self as ty, InferCtxtLike, Interner}; pub trait RelateExt: InferCtxtLike { fn relate>( @@ -104,7 +104,7 @@ pub struct SolverRelating<'infcx, Infcx, I: Interner> { /// constrain `?1` to `u32`. When using the cache entry from the /// first time we've related these types, this only happens when /// later proving the `Subtype(?0, ?1)` goal from the first relation. - cache: DelayedSet<(ty::Variance, Ty, Ty)>, + cache: DelayedSet<(ty::Variance, I::Ty, I::Ty)>, } impl<'infcx, Infcx, I> SolverRelating<'infcx, Infcx, I> @@ -142,13 +142,13 @@ where fn relate_ty_args( &mut self, - a_ty: Ty, - b_ty: Ty, + a_ty: I::Ty, + b_ty: I::Ty, def_id: I::DefId, a_args: I::GenericArgs, b_args: I::GenericArgs, - _: impl FnOnce(I::GenericArgs) -> Ty, - ) -> RelateResult> { + _: impl FnOnce(I::GenericArgs) -> I::Ty, + ) -> RelateResult { if self.ambient_variance == ty::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles @@ -178,7 +178,7 @@ where } #[instrument(skip(self), level = "trace")] - fn tys(&mut self, a: Ty, b: Ty) -> RelateResult> { + fn tys(&mut self, a: I::Ty, b: I::Ty) -> RelateResult { if a == b { return Ok(a); } @@ -383,7 +383,7 @@ where self.goals.extend(obligations); } - fn register_alias_relate_predicate(&mut self, a: Ty, b: Ty) { + fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty) { self.register_predicates([ty::Binder::dummy(match self.ambient_variance { ty::Covariant => ty::PredicateKind::AliasRelate( a.into(), diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 23e6075452b18..72b7df22b30d5 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -11,7 +11,7 @@ use rustc_type_ir_macros::{ use crate::lang_items::SolverTraitLangItem; use crate::search_graph::PathKind; -use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Ty, Upcast}; +use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast}; pub type CanonicalInput::Predicate> = ty::CanonicalQueryInput>; @@ -254,7 +254,7 @@ impl Eq for Response {} #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub struct ExternalConstraintsData { pub region_constraints: Vec>, - pub opaque_types: Vec<(ty::OpaqueTypeKey, Ty)>, + pub opaque_types: Vec<(ty::OpaqueTypeKey, I::Ty)>, pub normalization_nested_goals: NestedNormalizationGoals, } diff --git a/compiler/rustc_type_ir/src/sty/mod.rs b/compiler/rustc_type_ir/src/sty/mod.rs deleted file mode 100644 index 5b73d372384b8..0000000000000 --- a/compiler/rustc_type_ir/src/sty/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -/// This type is temporary and exists to cut down the bloat of further PR's -/// moving `struct Ty` from `rustc_middle` to `rustc_type_ir`. -pub type Ty = ::Ty; diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index ad7a934bb28a5..9afd39e2c7627 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -100,7 +100,7 @@ pub enum TyKind { Str, /// An array with the given length. Written as `[T; N]`. - Array(ty::Ty, I::Const), + Array(I::Ty, I::Const), /// A pattern newtype. /// @@ -109,17 +109,17 @@ pub enum TyKind { /// Only `Copy` and `Clone` will automatically get implemented for pattern types. /// Auto-traits treat this as if it were an aggregate with a single nested type. /// Only supports integer range patterns for now. - Pat(ty::Ty, I::Pat), + Pat(I::Ty, I::Pat), /// The pointee of an array slice. Written as `[T]`. - Slice(ty::Ty), + Slice(I::Ty), /// A raw pointer. Written as `*mut T` or `*const T` - RawPtr(ty::Ty, Mutability), + RawPtr(I::Ty, Mutability), /// A reference; a pointer with an associated lifetime. Written as /// `&'a mut T` or `&'a T`. - Ref(I::Region, ty::Ty, Mutability), + Ref(I::Region, I::Ty, Mutability), /// The anonymous type of a function declaration/definition. /// @@ -469,18 +469,18 @@ impl AliasTy { matches!(self.kind(interner), AliasTyKind::Opaque) } - pub fn to_ty(self, interner: I) -> ty::Ty { + pub fn to_ty(self, interner: I) -> I::Ty { Ty::new_alias(interner, self.kind(interner), self) } } /// The following methods work only with (trait) associated type projections. impl AliasTy { - pub fn self_ty(self) -> ty::Ty { + pub fn self_ty(self) -> I::Ty { self.args.type_at(0) } - pub fn with_replaced_self_ty(self, interner: I, self_ty: ty::Ty) -> Self { + pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self { AliasTy::new( interner, self.def_id, @@ -735,7 +735,7 @@ impl fmt::Debug for InferTy { )] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct TypeAndMut { - pub ty: ty::Ty, + pub ty: I::Ty, pub mutbl: Mutability, } @@ -765,7 +765,7 @@ impl FnSig { self.inputs_and_output.inputs() } - pub fn output(self) -> ty::Ty { + pub fn output(self) -> I::Ty { self.inputs_and_output.output() } @@ -783,7 +783,7 @@ impl ty::Binder> { #[inline] #[track_caller] - pub fn input(self, index: usize) -> ty::Binder> { + pub fn input(self, index: usize) -> ty::Binder { self.map_bound(|fn_sig| fn_sig.inputs().get(index).unwrap()) } @@ -792,7 +792,7 @@ impl ty::Binder> { } #[inline] - pub fn output(self) -> ty::Binder> { + pub fn output(self) -> ty::Binder { self.map_bound(|fn_sig| fn_sig.output()) } @@ -856,21 +856,21 @@ impl fmt::Debug for FnSig { } // FIXME: this is a distinct type because we need to define `Encode`/`Decode` -// impls in this crate for `Binder>`. +// impls in this crate for `Binder`. #[derive_where(Clone, Copy, PartialEq, Hash; I: Interner)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] -pub struct UnsafeBinderInner(ty::Binder>); +pub struct UnsafeBinderInner(ty::Binder); impl Eq for UnsafeBinderInner {} -impl From>> for UnsafeBinderInner { - fn from(value: ty::Binder>) -> Self { +impl From> for UnsafeBinderInner { + fn from(value: ty::Binder) -> Self { UnsafeBinderInner(value) } } -impl From> for ty::Binder> { +impl From> for ty::Binder { fn from(value: UnsafeBinderInner) -> Self { value.0 } @@ -883,7 +883,7 @@ impl fmt::Debug for UnsafeBinderInner { } impl Deref for UnsafeBinderInner { - type Target = ty::Binder>; + type Target = ty::Binder; fn deref(&self) -> &Self::Target { &self.0 @@ -894,7 +894,7 @@ impl Deref for UnsafeBinderInner { impl rustc_serialize::Encodable for UnsafeBinderInner where - ty::Ty: rustc_serialize::Encodable, + I::Ty: rustc_serialize::Encodable, I::BoundVarKinds: rustc_serialize::Encodable, { fn encode(&self, e: &mut E) { @@ -907,7 +907,7 @@ where impl rustc_serialize::Decodable for UnsafeBinderInner where - ty::Ty: TypeVisitable + rustc_serialize::Decodable, + I::Ty: TypeVisitable + rustc_serialize::Decodable, I::BoundVarKinds: rustc_serialize::Decodable, { fn decode(decoder: &mut D) -> Self { @@ -937,7 +937,7 @@ impl FnSigTys { self.inputs_and_output.inputs() } - pub fn output(self) -> ty::Ty { + pub fn output(self) -> I::Ty { self.inputs_and_output.output() } } @@ -960,7 +960,7 @@ impl ty::Binder> { #[inline] #[track_caller] - pub fn input(self, index: usize) -> ty::Binder> { + pub fn input(self, index: usize) -> ty::Binder { self.map_bound(|sig_tys| sig_tys.inputs().get(index).unwrap()) } @@ -969,7 +969,7 @@ impl ty::Binder> { } #[inline] - pub fn output(self) -> ty::Binder> { + pub fn output(self) -> ty::Binder { self.map_bound(|sig_tys| sig_tys.output()) } } diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs index 08c303b8de9c8..e8f94c8e7cc92 100644 --- a/compiler/rustc_type_ir/src/ty_kind/closure.rs +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs @@ -121,13 +121,13 @@ pub struct ClosureArgsParts { /// This is the args of the typeck root. pub parent_args: I::GenericArgsSlice, /// Represents the maximum calling capability of the closure. - pub closure_kind_ty: ty::Ty, + pub closure_kind_ty: I::Ty, /// Captures the closure's signature. This closure signature is "tupled", and /// thus has a peculiar signature of `extern "rust-call" fn((Args, ...)) -> Ty`. - pub closure_sig_as_fn_ptr_ty: ty::Ty, + pub closure_sig_as_fn_ptr_ty: I::Ty, /// The upvars captured by the closure. Remains an inference variable /// until the upvar analysis, which happens late in HIR typeck. - pub tupled_upvars_ty: ty::Ty, + pub tupled_upvars_ty: I::Ty, } impl ClosureArgs { @@ -169,14 +169,14 @@ impl ClosureArgs { /// Returns the tuple type representing the upvars for this closure. #[inline] - pub fn tupled_upvars_ty(self) -> ty::Ty { + pub fn tupled_upvars_ty(self) -> I::Ty { self.split().tupled_upvars_ty } /// Returns the closure kind for this closure; may return a type /// variable during inference. To get the closure kind during /// inference, use `infcx.closure_kind(args)`. - pub fn kind_ty(self) -> ty::Ty { + pub fn kind_ty(self) -> I::Ty { self.split().closure_kind_ty } @@ -185,7 +185,7 @@ impl ClosureArgs { // FIXME(eddyb) this should be unnecessary, as the shallowly resolved // type is known at the time of the creation of `ClosureArgs`, // see `rustc_hir_analysis::check::closure`. - pub fn sig_as_fn_ptr_ty(self) -> ty::Ty { + pub fn sig_as_fn_ptr_ty(self) -> I::Ty { self.split().closure_sig_as_fn_ptr_ty } @@ -223,7 +223,7 @@ pub struct CoroutineClosureArgsParts { /// This is the args of the typeck root. pub parent_args: I::GenericArgsSlice, /// Represents the maximum calling capability of the closure. - pub closure_kind_ty: ty::Ty, + pub closure_kind_ty: I::Ty, /// Represents all of the relevant parts of the coroutine returned by this /// coroutine-closure. This signature parts type will have the general /// shape of `fn(tupled_inputs, resume_ty) -> (return_ty, yield_ty)`, where @@ -232,10 +232,10 @@ pub struct CoroutineClosureArgsParts { /// /// Use `coroutine_closure_sig` to break up this type rather than using it /// yourself. - pub signature_parts_ty: ty::Ty, + pub signature_parts_ty: I::Ty, /// The upvars captured by the closure. Remains an inference variable /// until the upvar analysis, which happens late in HIR typeck. - pub tupled_upvars_ty: ty::Ty, + pub tupled_upvars_ty: I::Ty, /// a function pointer that has the shape `for<'env> fn() -> (&'env T, ...)`. /// This allows us to represent the binder of the self-captures of the closure. /// @@ -243,7 +243,7 @@ pub struct CoroutineClosureArgsParts { /// from the closure's upvars, this will be `for<'env> fn() -> (&'env String,)`, /// while the `tupled_upvars_ty`, representing the by-move version of the same /// captures, will be `(String,)`. - pub coroutine_captures_by_ref_ty: ty::Ty, + pub coroutine_captures_by_ref_ty: I::Ty, } impl CoroutineClosureArgs { @@ -277,11 +277,11 @@ impl CoroutineClosureArgs { } #[inline] - pub fn tupled_upvars_ty(self) -> ty::Ty { + pub fn tupled_upvars_ty(self) -> I::Ty { self.split().tupled_upvars_ty } - pub fn kind_ty(self) -> ty::Ty { + pub fn kind_ty(self) -> I::Ty { self.split().closure_kind_ty } @@ -289,7 +289,7 @@ impl CoroutineClosureArgs { self.kind_ty().to_opt_closure_kind().unwrap() } - pub fn signature_parts_ty(self) -> ty::Ty { + pub fn signature_parts_ty(self) -> I::Ty { self.split().signature_parts_ty } @@ -314,7 +314,7 @@ impl CoroutineClosureArgs { }) } - pub fn coroutine_captures_by_ref_ty(self) -> ty::Ty { + pub fn coroutine_captures_by_ref_ty(self) -> I::Ty { self.split().coroutine_captures_by_ref_ty } @@ -358,10 +358,10 @@ impl TypeVisitor for HasRegionsBoundAt { #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct CoroutineClosureSignature { - pub tupled_inputs_ty: ty::Ty, - pub resume_ty: ty::Ty, - pub yield_ty: ty::Ty, - pub return_ty: ty::Ty, + pub tupled_inputs_ty: I::Ty, + pub resume_ty: I::Ty, + pub yield_ty: I::Ty, + pub return_ty: I::Ty, // Like the `fn_sig_as_fn_ptr_ty` of a regular closure, these types // never actually differ. But we save them rather than recreating them @@ -393,10 +393,10 @@ impl CoroutineClosureSignature { self, cx: I, parent_args: I::GenericArgsSlice, - coroutine_kind_ty: ty::Ty, + coroutine_kind_ty: I::Ty, coroutine_def_id: I::CoroutineId, - tupled_upvars_ty: ty::Ty, - ) -> ty::Ty { + tupled_upvars_ty: I::Ty, + ) -> I::Ty { let coroutine_args = ty::CoroutineArgs::new( cx, ty::CoroutineArgsParts { @@ -424,9 +424,9 @@ impl CoroutineClosureSignature { coroutine_def_id: I::CoroutineId, goal_kind: ty::ClosureKind, env_region: I::Region, - closure_tupled_upvars_ty: ty::Ty, - coroutine_captures_by_ref_ty: ty::Ty, - ) -> ty::Ty { + closure_tupled_upvars_ty: I::Ty, + coroutine_captures_by_ref_ty: I::Ty, + ) -> I::Ty { let tupled_upvars_ty = Self::tupled_upvars_by_closure_kind( cx, goal_kind, @@ -457,11 +457,11 @@ impl CoroutineClosureSignature { pub fn tupled_upvars_by_closure_kind( cx: I, kind: ty::ClosureKind, - tupled_inputs_ty: ty::Ty, - closure_tupled_upvars_ty: ty::Ty, - coroutine_captures_by_ref_ty: ty::Ty, + tupled_inputs_ty: I::Ty, + closure_tupled_upvars_ty: I::Ty, + coroutine_captures_by_ref_ty: I::Ty, env_region: I::Region, - ) -> ty::Ty { + ) -> I::Ty { match kind { ty::ClosureKind::Fn | ty::ClosureKind::FnMut => { let ty::FnPtr(sig_tys, _) = coroutine_captures_by_ref_ty.kind() else { @@ -503,7 +503,7 @@ struct FoldEscapingRegions { // Depends on `debruijn` because we may have types with regions of different // debruijn depths depending on the binders we've entered. - cache: DelayedMap<(ty::DebruijnIndex, ty::Ty), ty::Ty>, + cache: DelayedMap<(ty::DebruijnIndex, I::Ty), I::Ty>, } impl TypeFolder for FoldEscapingRegions { @@ -511,7 +511,7 @@ impl TypeFolder for FoldEscapingRegions { self.interner } - fn fold_ty(&mut self, t: ty::Ty) -> ty::Ty { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { if !t.has_vars_bound_at_or_above(self.debruijn) { t } else if let Some(&t) = self.cache.get(&(self.debruijn, t)) { @@ -553,9 +553,9 @@ impl TypeFolder for FoldEscapingRegions { #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct GenSig { - pub resume_ty: ty::Ty, - pub yield_ty: ty::Ty, - pub return_ty: ty::Ty, + pub resume_ty: I::Ty, + pub yield_ty: I::Ty, + pub return_ty: I::Ty, } impl Eq for GenSig {} @@ -581,15 +581,15 @@ pub struct CoroutineArgsParts { /// kind: `i8`/`i16`/`i32`. /// /// For regular coroutines, this field will always just be `()`. - pub kind_ty: ty::Ty, + pub kind_ty: I::Ty, - pub resume_ty: ty::Ty, - pub yield_ty: ty::Ty, - pub return_ty: ty::Ty, + pub resume_ty: I::Ty, + pub yield_ty: I::Ty, + pub return_ty: I::Ty, /// The upvars captured by the closure. Remains an inference variable /// until the upvar analysis, which happens late in HIR typeck. - pub tupled_upvars_ty: ty::Ty, + pub tupled_upvars_ty: I::Ty, } impl CoroutineArgs { @@ -619,7 +619,7 @@ impl CoroutineArgs { } // Returns the kind of the coroutine. See docs on the `kind_ty` field. - pub fn kind_ty(self) -> ty::Ty { + pub fn kind_ty(self) -> I::Ty { self.split().kind_ty } @@ -638,22 +638,22 @@ impl CoroutineArgs { /// Returns the tuple type representing the upvars for this coroutine. #[inline] - pub fn tupled_upvars_ty(self) -> ty::Ty { + pub fn tupled_upvars_ty(self) -> I::Ty { self.split().tupled_upvars_ty } /// Returns the type representing the resume type of the coroutine. - pub fn resume_ty(self) -> ty::Ty { + pub fn resume_ty(self) -> I::Ty { self.split().resume_ty } /// Returns the type representing the yield type of the coroutine. - pub fn yield_ty(self) -> ty::Ty { + pub fn yield_ty(self) -> I::Ty { self.split().yield_ty } /// Returns the type representing the return type of the coroutine. - pub fn return_ty(self) -> ty::Ty { + pub fn return_ty(self) -> I::Ty { self.split().return_ty } diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 1ee4bff6b7a11..6e62e1031a969 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -52,7 +52,7 @@ use smallvec::SmallVec; use thin_vec::ThinVec; use crate::inherent::*; -use crate::{self as ty, Interner, Ty, TypeFlags}; +use crate::{self as ty, Interner, TypeFlags}; /// This trait is implemented for every type that can be visited, /// providing the skeleton of the traversal. @@ -98,7 +98,7 @@ pub trait TypeVisitor: Sized { t.super_visit_with(self) } - fn visit_ty(&mut self, t: Ty) -> Self::Result { + fn visit_ty(&mut self, t: I::Ty) -> Self::Result { t.super_visit_with(self) } @@ -417,7 +417,7 @@ impl TypeVisitor for HasTypeFlagsVisitor { } #[inline] - fn visit_ty(&mut self, t: Ty) -> Self::Result { + fn visit_ty(&mut self, t: I::Ty) -> Self::Result { // Note: no `super_visit_with` call. let flags = t.flags(); if flags.intersects(self.flags) { @@ -522,7 +522,7 @@ impl TypeVisitor for HasEscapingVarsVisitor { } #[inline] - fn visit_ty(&mut self, t: Ty) -> Self::Result { + fn visit_ty(&mut self, t: I::Ty) -> Self::Result { // If the outer-exclusive-binder is *strictly greater* than // `outer_index`, that means that `t` contains some content // bound at `outer_index` or above (because diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd/mod.rs similarity index 99% rename from library/core/src/intrinsics/simd.rs rename to library/core/src/intrinsics/simd/mod.rs index ae86690dc418d..084d8a3f1f247 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd/mod.rs @@ -2,6 +2,8 @@ //! //! In this module, a "vector" is any `repr(simd)` type. +pub mod scalable; + use crate::marker::ConstParamTy; /// Inserts an element into a vector, returning the updated vector. diff --git a/library/core/src/intrinsics/simd/scalable.rs b/library/core/src/intrinsics/simd/scalable.rs new file mode 100644 index 0000000000000..f33831a30c070 --- /dev/null +++ b/library/core/src/intrinsics/simd/scalable.rs @@ -0,0 +1,93 @@ +//! Scalable vector compiler intrinsics. +//! +//! In this module, a "vector" is any `#[rustc_scalable_vector]`-annotated type. + +/// Numerically casts a vector, elementwise. +/// +/// `T` and `U` must be vectors of integers or floats, and must have the same length. +/// +/// When casting floats to integers, the result is truncated. Out-of-bounds result lead to UB. +/// When casting integers to floats, the result is rounded. +/// Otherwise, truncates or extends the value, maintaining the sign for signed integers. +/// +/// # Safety +/// Casting from integer types is always safe. +/// Casting between two float types is also always safe. +/// +/// Casting floats to integers truncates, following the same rules as `to_int_unchecked`. +/// Specifically, each element must: +/// * Not be `NaN` +/// * Not be infinite +/// * Be representable in the return type, after truncating off its fractional part +#[cfg(target_arch = "aarch64")] +#[rustc_intrinsic] +#[rustc_nounwind] +pub unsafe fn sve_cast(x: T) -> U; + +/// Create a tuple of two vectors. +/// +/// `SVecTup` must be a scalable vector tuple (`#[rustc_scalable_vector]`) and `SVec` must be a +/// scalable vector (`#[rustc_scalable_vector(N)]`). `SVecTup` must be a tuple of vectors of +/// type `SVec`. +/// +/// Corresponds to Clang's `__builtin_sve_svcreate2*` builtins. +#[cfg(target_arch = "aarch64")] +#[rustc_nounwind] +#[rustc_intrinsic] +pub unsafe fn sve_tuple_create2(x0: SVec, x1: SVec) -> SVecTup; + +/// Create a tuple of three vectors. +/// +/// `SVecTup` must be a scalable vector tuple (`#[rustc_scalable_vector]`) and `SVec` must be a +/// scalable vector (`#[rustc_scalable_vector(N)]`). `SVecTup` must be a tuple of vectors of +/// type `SVec`. +/// +/// Corresponds to Clang's `__builtin_sve_svcreate3*` builtins. +#[cfg(target_arch = "aarch64")] +#[rustc_intrinsic] +#[rustc_nounwind] +pub unsafe fn sve_tuple_create3(x0: SVec, x1: SVec, x2: SVec) -> SVecTup; + +/// Create a tuple of four vectors. +/// +/// `SVecTup` must be a scalable vector tuple (`#[rustc_scalable_vector]`) and `SVec` must be a +/// scalable vector (`#[rustc_scalable_vector(N)]`). `SVecTup` must be a tuple of vectors of +/// type `SVec`. +/// +/// Corresponds to Clang's `__builtin_sve_svcreate4*` builtins. +#[cfg(target_arch = "aarch64")] +#[rustc_intrinsic] +#[rustc_nounwind] +pub unsafe fn sve_tuple_create4(x0: SVec, x1: SVec, x2: SVec, x3: SVec) -> SVecTup; + +/// Get one vector from a tuple of vectors. +/// +/// `SVecTup` must be a scalable vector tuple (`#[rustc_scalable_vector]`) and `SVec` must be a +/// scalable vector (`#[rustc_scalable_vector(N)]`). `SVecTup` must be a tuple of vectors of +/// type `SVec`. +/// +/// Corresponds to Clang's `__builtin_sve_svget*` builtins. +/// +/// # Safety +/// +/// `IDX` must be in-bounds of the tuple. +#[cfg(target_arch = "aarch64")] +#[rustc_intrinsic] +#[rustc_nounwind] +pub unsafe fn sve_tuple_get(tuple: SVecTup) -> SVec; + +/// Change one vector in a tuple of vectors. +/// +/// `SVecTup` must be a scalable vector tuple (`#[rustc_scalable_vector]`) and `SVec` must be a +/// scalable vector (`#[rustc_scalable_vector(N)]`). `SVecTup` must be a tuple of vectors of +/// type `SVec`. +/// +/// Corresponds to Clang's `__builtin_sve_svset*` builtins. +/// +/// # Safety +/// +/// `IDX` must be in-bounds of the tuple. +#[cfg(target_arch = "aarch64")] +#[rustc_intrinsic] +#[rustc_nounwind] +pub unsafe fn sve_tuple_set(tuple: SVecTup, x: SVec) -> SVecTup; diff --git a/tests/codegen-llvm/scalable-vectors/debuginfo-tuples-x2.rs b/tests/codegen-llvm/scalable-vectors/debuginfo-tuples-x2.rs new file mode 100644 index 0000000000000..1aaba621d0e10 --- /dev/null +++ b/tests/codegen-llvm/scalable-vectors/debuginfo-tuples-x2.rs @@ -0,0 +1,149 @@ +//@ only-aarch64 +//@ compile-flags: -Cdebuginfo=2 -Copt-level=0 + +#![crate_type = "lib"] +#![allow(incomplete_features, internal_features)] +#![feature(rustc_attrs)] + +// Test that we generate the correct debuginfo for scalable vector types. + +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +struct svint8_t(i8); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svint8x2_t(svint8_t, svint8_t); + +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +struct svuint8_t(u8); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svuint8x2_t(svuint8_t, svuint8_t); + +#[rustc_scalable_vector(8)] +#[allow(non_camel_case_types)] +struct svint16_t(i16); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svint16x2_t(svint16_t, svint16_t); + +#[rustc_scalable_vector(8)] +#[allow(non_camel_case_types)] +struct svuint16_t(u16); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svuint16x2_t(svuint16_t, svuint16_t); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svint32_t(i32); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svint32x2_t(svint32_t, svint32_t); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svuint32_t(u32); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svuint32x2_t(svuint32_t, svuint32_t); + +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +struct svint64_t(i64); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svint64x2_t(svint64_t, svint64_t); + +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +struct svuint64_t(u64); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svuint64x2_t(svuint64_t, svuint64_t); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svfloat32_t(f32); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svfloat32x2_t(svfloat32_t, svfloat32_t); + +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +struct svfloat64_t(f64); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svfloat64x2_t(svfloat64_t, svfloat64_t); + +#[target_feature(enable = "sve")] +pub fn locals() { + // CHECK-DAG: name: "svint8x2_t",{{.*}}, baseType: ![[CT8:[0-9]+]] + // CHECK-DAG: ![[CT8]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY8:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS8x2:[0-9]+]]) + // CHECK-DAG: ![[ELTTY8]] = !DIBasicType(name: "i8", size: 8, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS8x2]] = !{![[REALELTS8x2:[0-9]+]]} + // CHECK-DAG: ![[REALELTS8x2]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 16, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s8: svint8x2_t; + + // CHECK-DAG: name: "svuint8x2_t",{{.*}}, baseType: ![[CT8:[0-9]+]] + // CHECK-DAG: ![[CT8]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY8:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS8x2]]) + // CHECK-DAG: ![[ELTTY8]] = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned) + let u8: svuint8x2_t; + + // CHECK-DAG: name: "svint16x2_t",{{.*}}, baseType: ![[CT16:[0-9]+]] + // CHECK-DAG: ![[CT16]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY16:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS16x2:[0-9]+]]) + // CHECK-DAG: ![[ELTTY16]] = !DIBasicType(name: "i16", size: 16, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS16x2]] = !{![[REALELTS16x2:[0-9]+]]} + // CHECK-DAG: ![[REALELTS16x2]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 8, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s16: svint16x2_t; + + // CHECK-DAG: name: "svuint16x2_t",{{.*}}, baseType: ![[CT16:[0-9]+]] + // CHECK-DAG: ![[CT16]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY16:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS16x2]]) + // CHECK-DAG: ![[ELTTY16]] = !DIBasicType(name: "u16", size: 16, encoding: DW_ATE_unsigned) + let u16: svuint16x2_t; + + // CHECK-DAG: name: "svint32x2_t",{{.*}}, baseType: ![[CT32:[0-9]+]] + // CHECK-DAG: ![[CT32]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY32:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS32x2:[0-9]+]]) + // CHECK-DAG: ![[ELTTY32]] = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS32x2]] = !{![[REALELTS32x2:[0-9]+]]} + // CHECK-DAG: ![[REALELTS32x2]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 4, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s32: svint32x2_t; + + // CHECK-DAG: name: "svuint32x2_t",{{.*}}, baseType: ![[CT32:[0-9]+]] + // CHECK-DAG: ![[CT32]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY32:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS32x2]]) + // CHECK-DAG: ![[ELTTY32]] = !DIBasicType(name: "u32", size: 32, encoding: DW_ATE_unsigned) + let u32: svuint32x2_t; + + // CHECK-DAG: name: "svint64x2_t",{{.*}}, baseType: ![[CT64:[0-9]+]] + // CHECK-DAG: ![[CT64]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY64:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS1x2_64:[0-9]+]]) + // CHECK-DAG: ![[ELTTY64]] = !DIBasicType(name: "i64", size: 64, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS1x2_64]] = !{![[REALELTS1x2_64:[0-9]+]]} + // CHECK-DAG: ![[REALELTS1x2_64]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 2, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s64: svint64x2_t; + + // CHECK-DAG: name: "svuint64x2_t",{{.*}}, baseType: ![[CT64:[0-9]+]] + // CHECK-DAG: ![[CT64]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY64:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS1x2_64]]) + // CHECK-DAG: ![[ELTTY64]] = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned) + let u64: svuint64x2_t; + + // CHECK: name: "svfloat32x2_t",{{.*}}, baseType: ![[CT32:[0-9]+]] + // CHECK-DAG: ![[CT32]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY32:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS32x2]]) + // CHECK-DAG: ![[ELTTY32]] = !DIBasicType(name: "f32", size: 32, encoding: DW_ATE_float) + let f32: svfloat32x2_t; + + // CHECK: name: "svfloat64x2_t",{{.*}}, baseType: ![[CT64:[0-9]+]] + // CHECK-DAG: ![[CT64]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY64:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS1x2_64]]) + // CHECK-DAG: ![[ELTTY64]] = !DIBasicType(name: "f64", size: 64, encoding: DW_ATE_float) + let f64: svfloat64x2_t; +} diff --git a/tests/codegen-llvm/scalable-vectors/debuginfo-tuples-x3.rs b/tests/codegen-llvm/scalable-vectors/debuginfo-tuples-x3.rs new file mode 100644 index 0000000000000..b19051e2c743d --- /dev/null +++ b/tests/codegen-llvm/scalable-vectors/debuginfo-tuples-x3.rs @@ -0,0 +1,149 @@ +//@ only-aarch64 +//@ compile-flags: -Cdebuginfo=2 -Copt-level=0 + +#![crate_type = "lib"] +#![allow(incomplete_features, internal_features)] +#![feature(rustc_attrs)] + +// Test that we generate the correct debuginfo for scalable vector types. + +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +struct svint8_t(i8); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svint8x3_t(svint8_t, svint8_t, svint8_t); + +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +struct svuint8_t(u8); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svuint8x3_t(svuint8_t, svuint8_t, svuint8_t); + +#[rustc_scalable_vector(8)] +#[allow(non_camel_case_types)] +struct svint16_t(i16); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svint16x3_t(svint16_t, svint16_t, svint16_t); + +#[rustc_scalable_vector(8)] +#[allow(non_camel_case_types)] +struct svuint16_t(u16); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svuint16x3_t(svuint16_t, svuint16_t, svuint16_t); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svint32_t(i32); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svint32x3_t(svint32_t, svint32_t, svint32_t); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svuint32_t(u32); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svuint32x3_t(svuint32_t, svuint32_t, svuint32_t); + +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +struct svint64_t(i64); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svint64x3_t(svint64_t, svint64_t, svint64_t); + +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +struct svuint64_t(u64); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svuint64x3_t(svuint64_t, svuint64_t, svuint64_t); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svfloat32_t(f32); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svfloat32x3_t(svfloat32_t, svfloat32_t, svfloat32_t); + +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +struct svfloat64_t(f64); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svfloat64x3_t(svfloat64_t, svfloat64_t, svfloat64_t); + +#[target_feature(enable = "sve")] +pub fn locals() { + // CHECK-DAG: name: "svint8x3_t",{{.*}}, baseType: ![[CT8:[0-9]+]] + // CHECK-DAG: ![[CT8]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY8:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS8x3:[0-9]+]]) + // CHECK-DAG: ![[ELTTY8]] = !DIBasicType(name: "i8", size: 8, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS8x3]] = !{![[REALELTS8x3:[0-9]+]]} + // CHECK-DAG: ![[REALELTS8x3]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 24, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s8: svint8x3_t; + + // CHECK-DAG: name: "svuint8x3_t",{{.*}}, baseType: ![[CT8:[0-9]+]] + // CHECK-DAG: ![[CT8]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY8:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS8x3]]) + // CHECK-DAG: ![[ELTTY8]] = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned) + let u8: svuint8x3_t; + + // CHECK-DAG: name: "svint16x3_t",{{.*}}, baseType: ![[CT16:[0-9]+]] + // CHECK-DAG: ![[CT16]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY16:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS16x3:[0-9]+]]) + // CHECK-DAG: ![[ELTTY16]] = !DIBasicType(name: "i16", size: 16, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS16x3]] = !{![[REALELTS16x3:[0-9]+]]} + // CHECK-DAG: ![[REALELTS16x3]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 12, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s16: svint16x3_t; + + // CHECK-DAG: name: "svuint16x3_t",{{.*}}, baseType: ![[CT16:[0-9]+]] + // CHECK-DAG: ![[CT16]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY16:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS16x3]]) + // CHECK-DAG: ![[ELTTY16]] = !DIBasicType(name: "u16", size: 16, encoding: DW_ATE_unsigned) + let u16: svuint16x3_t; + + // CHECK-DAG: name: "svint32x3_t",{{.*}}, baseType: ![[CT32:[0-9]+]] + // CHECK-DAG: ![[CT32]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY32:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS32x3:[0-9]+]]) + // CHECK-DAG: ![[ELTTY32]] = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS32x3]] = !{![[REALELTS32x3:[0-9]+]]} + // CHECK-DAG: ![[REALELTS32x3]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 6, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s32: svint32x3_t; + + // CHECK-DAG: name: "svuint32x3_t",{{.*}}, baseType: ![[CT32:[0-9]+]] + // CHECK-DAG: ![[CT32]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY32:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS32x3]]) + // CHECK-DAG: ![[ELTTY32]] = !DIBasicType(name: "u32", size: 32, encoding: DW_ATE_unsigned) + let u32: svuint32x3_t; + + // CHECK-DAG: name: "svint64x3_t",{{.*}}, baseType: ![[CT64:[0-9]+]] + // CHECK-DAG: ![[CT64]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY64:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS1x3_64:[0-9]+]]) + // CHECK-DAG: ![[ELTTY64]] = !DIBasicType(name: "i64", size: 64, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS1x3_64]] = !{![[REALELTS1x3_64:[0-9]+]]} + // CHECK-DAG: ![[REALELTS1x3_64]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 3, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s64: svint64x3_t; + + // CHECK-DAG: name: "svuint64x3_t",{{.*}}, baseType: ![[CT64:[0-9]+]] + // CHECK-DAG: ![[CT64]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY64:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS1x3_64]]) + // CHECK-DAG: ![[ELTTY64]] = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned) + let u64: svuint64x3_t; + + // CHECK: name: "svfloat32x3_t",{{.*}}, baseType: ![[CT32:[0-9]+]] + // CHECK-DAG: ![[CT32]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY32:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS32x3]]) + // CHECK-DAG: ![[ELTTY32]] = !DIBasicType(name: "f32", size: 32, encoding: DW_ATE_float) + let f32: svfloat32x3_t; + + // CHECK: name: "svfloat64x3_t",{{.*}}, baseType: ![[CT64:[0-9]+]] + // CHECK-DAG: ![[CT64]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY64:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS1x3_64]]) + // CHECK-DAG: ![[ELTTY64]] = !DIBasicType(name: "f64", size: 64, encoding: DW_ATE_float) + let f64: svfloat64x3_t; +} diff --git a/tests/codegen-llvm/scalable-vectors/debuginfo-tuples-x4.rs b/tests/codegen-llvm/scalable-vectors/debuginfo-tuples-x4.rs new file mode 100644 index 0000000000000..911af76f42ebb --- /dev/null +++ b/tests/codegen-llvm/scalable-vectors/debuginfo-tuples-x4.rs @@ -0,0 +1,149 @@ +//@ only-aarch64 +//@ compile-flags: -Cdebuginfo=2 -Copt-level=0 + +#![crate_type = "lib"] +#![allow(incomplete_features, internal_features)] +#![feature(rustc_attrs)] + +// Test that we generate the correct debuginfo for scalable vector types. + +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +struct svint8_t(i8); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svint8x4_t(svint8_t, svint8_t, svint8_t, svint8_t); + +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +struct svuint8_t(u8); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svuint8x4_t(svuint8_t, svuint8_t, svuint8_t, svuint8_t); + +#[rustc_scalable_vector(8)] +#[allow(non_camel_case_types)] +struct svint16_t(i16); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svint16x4_t(svint16_t, svint16_t, svint16_t, svint16_t); + +#[rustc_scalable_vector(8)] +#[allow(non_camel_case_types)] +struct svuint16_t(u16); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svuint16x4_t(svuint16_t, svuint16_t, svuint16_t, svuint16_t); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svint32_t(i32); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svint32x4_t(svint32_t, svint32_t, svint32_t, svint32_t); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svuint32_t(u32); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svuint32x4_t(svuint32_t, svuint32_t, svuint32_t, svuint32_t); + +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +struct svint64_t(i64); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svint64x4_t(svint64_t, svint64_t, svint64_t, svint64_t); + +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +struct svuint64_t(u64); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svuint64x4_t(svuint64_t, svuint64_t, svuint64_t, svuint64_t); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svfloat32_t(f32); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svfloat32x4_t(svfloat32_t, svfloat32_t, svfloat32_t, svfloat32_t); + +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +struct svfloat64_t(f64); + +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +struct svfloat64x4_t(svfloat64_t, svfloat64_t, svfloat64_t, svfloat64_t); + +#[target_feature(enable = "sve")] +pub fn locals() { + // CHECK-DAG: name: "svint8x4_t",{{.*}}, baseType: ![[CT8:[0-9]+]] + // CHECK-DAG: ![[CT8]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY8:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS8x4:[0-9]+]]) + // CHECK-DAG: ![[ELTTY8]] = !DIBasicType(name: "i8", size: 8, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS8x4]] = !{![[REALELTS8x4:[0-9]+]]} + // CHECK-DAG: ![[REALELTS8x4]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 32, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s8: svint8x4_t; + + // CHECK-DAG: name: "svuint8x4_t",{{.*}}, baseType: ![[CT8:[0-9]+]] + // CHECK-DAG: ![[CT8]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY8:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS8x4]]) + // CHECK-DAG: ![[ELTTY8]] = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned) + let u8: svuint8x4_t; + + // CHECK-DAG: name: "svint16x4_t",{{.*}}, baseType: ![[CT16:[0-9]+]] + // CHECK-DAG: ![[CT16]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY16:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS16x4:[0-9]+]]) + // CHECK-DAG: ![[ELTTY16]] = !DIBasicType(name: "i16", size: 16, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS16x4]] = !{![[REALELTS16x4:[0-9]+]]} + // CHECK-DAG: ![[REALELTS16x4]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 16, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s16: svint16x4_t; + + // CHECK-DAG: name: "svuint16x4_t",{{.*}}, baseType: ![[CT16:[0-9]+]] + // CHECK-DAG: ![[CT16]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY16:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS16x4]]) + // CHECK-DAG: ![[ELTTY16]] = !DIBasicType(name: "u16", size: 16, encoding: DW_ATE_unsigned) + let u16: svuint16x4_t; + + // CHECK-DAG: name: "svint32x4_t",{{.*}}, baseType: ![[CT32:[0-9]+]] + // CHECK-DAG: ![[CT32]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY32:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS32x4:[0-9]+]]) + // CHECK-DAG: ![[ELTTY32]] = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS32x4]] = !{![[REALELTS32x4:[0-9]+]]} + // CHECK-DAG: ![[REALELTS32x4]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 8, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s32: svint32x4_t; + + // CHECK-DAG: name: "svuint32x4_t",{{.*}}, baseType: ![[CT32:[0-9]+]] + // CHECK-DAG: ![[CT32]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY32:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS32x4]]) + // CHECK-DAG: ![[ELTTY32]] = !DIBasicType(name: "u32", size: 32, encoding: DW_ATE_unsigned) + let u32: svuint32x4_t; + + // CHECK-DAG: name: "svint64x4_t",{{.*}}, baseType: ![[CT64:[0-9]+]] + // CHECK-DAG: ![[CT64]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY64:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS1x4_64:[0-9]+]]) + // CHECK-DAG: ![[ELTTY64]] = !DIBasicType(name: "i64", size: 64, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS1x4_64]] = !{![[REALELTS1x4_64:[0-9]+]]} + // CHECK-DAG: ![[REALELTS1x4_64]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 4, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s64: svint64x4_t; + + // CHECK-DAG: name: "svuint64x4_t",{{.*}}, baseType: ![[CT64:[0-9]+]] + // CHECK-DAG: ![[CT64]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY64:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS1x4_64]]) + // CHECK-DAG: ![[ELTTY64]] = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned) + let u64: svuint64x4_t; + + // CHECK: name: "svfloat32x4_t",{{.*}}, baseType: ![[CT32:[0-9]+]] + // CHECK-DAG: ![[CT32]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY32:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS32x4]]) + // CHECK-DAG: ![[ELTTY32]] = !DIBasicType(name: "f32", size: 32, encoding: DW_ATE_float) + let f32: svfloat32x4_t; + + // CHECK: name: "svfloat64x4_t",{{.*}}, baseType: ![[CT64:[0-9]+]] + // CHECK-DAG: ![[CT64]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY64:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS1x4_64]]) + // CHECK-DAG: ![[ELTTY64]] = !DIBasicType(name: "f64", size: 64, encoding: DW_ATE_float) + let f64: svfloat64x4_t; +} diff --git a/tests/codegen-llvm/scalable-vectors/debuginfo.rs b/tests/codegen-llvm/scalable-vectors/debuginfo.rs new file mode 100644 index 0000000000000..f4b34a5e1e7eb --- /dev/null +++ b/tests/codegen-llvm/scalable-vectors/debuginfo.rs @@ -0,0 +1,123 @@ +// ignore-tidy-linelength +//@ only-aarch64 +//@ compile-flags: -Cdebuginfo=2 -Copt-level=0 +//@ revisions: POST-LLVM-22 PRE-LLVM-22 +//@ [PRE-LLVM-22] max-llvm-major-version: 21 +//@ [POST-LLVM-22] min-llvm-version: 22 + +#![crate_type = "lib"] +#![allow(incomplete_features, internal_features)] +#![feature(rustc_attrs)] + +// Test that we generate the correct debuginfo for scalable vector types. + +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +struct svbool_t(bool); + +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +struct svint8_t(i8); + +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +struct svuint8_t(u8); + +#[rustc_scalable_vector(8)] +#[allow(non_camel_case_types)] +struct svint16_t(i16); + +#[rustc_scalable_vector(8)] +#[allow(non_camel_case_types)] +struct svuint16_t(u16); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svint32_t(i32); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svuint32_t(u32); + +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +struct svint64_t(i64); + +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +struct svuint64_t(u64); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svfloat32_t(f32); + +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +struct svfloat64_t(f64); + +#[target_feature(enable = "sve")] +pub fn locals() { + // CHECK-DAG: name: "svbool_t",{{.*}}, baseType: ![[CT1:[0-9]+]] + // PRE-LLVM-22-DAG: ![[CT1]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTYU8:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS8:[0-9]+]]) + // POST-LLVM-22-DAG: ![[CT1]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTYU8:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS8:[0-9]+]], bitStride: i64 1) + // CHECK-DAG: ![[ELTTYU8]] = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned) + // CHECK-DAG: ![[ELTS8]] = !{![[REALELTS8:[0-9]+]]} + // CHECK-DAG: ![[REALELTS8]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 8, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let b8: svbool_t; + + // CHECK-DAG: name: "svint8_t",{{.*}}, baseType: ![[CT8:[0-9]+]] + // CHECK-DAG: ![[CT8]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTYS8:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS8:[0-9]+]]) + // CHECK-DAG: ![[ELTTYS8]] = !DIBasicType(name: "i8", size: 8, encoding: DW_ATE_signed) + let s8: svint8_t; + + // PRE-LLVM-22-DAG: name: "svuint8_t",{{.*}}, baseType: ![[CT1:[0-9]+]] + // POST-LLVM-22-DAG: name: "svuint8_t",{{.*}}, baseType: ![[CT8:[0-9]+]] + // POST-LLVM-22-DAG: ![[CT8]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTYU8]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS8]]) + let u8: svuint8_t; + + // CHECK-DAG: name: "svint16_t",{{.*}}, baseType: ![[CT16:[0-9]+]] + // CHECK-DAG: ![[CT16]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY16:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS16:[0-9]+]]) + // CHECK-DAG: ![[ELTTY16]] = !DIBasicType(name: "i16", size: 16, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS16]] = !{![[REALELTS16:[0-9]+]]} + // CHECK-DAG: ![[REALELTS16]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 4, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s16: svint16_t; + + // CHECK-DAG: name: "svuint16_t",{{.*}}, baseType: ![[CT16:[0-9]+]] + // CHECK-DAG: ![[CT16]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY16:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS16]]) + // CHECK-DAG: ![[ELTTY16]] = !DIBasicType(name: "u16", size: 16, encoding: DW_ATE_unsigned) + let u16: svuint16_t; + + // CHECK-DAG: name: "svint32_t",{{.*}}, baseType: ![[CT32:[0-9]+]] + // CHECK-DAG: ![[CT32]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY32:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS32:[0-9]+]]) + // CHECK-DAG: ![[ELTTY32]] = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS32]] = !{![[REALELTS32:[0-9]+]]} + // CHECK-DAG: ![[REALELTS32]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 2, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s32: svint32_t; + + // CHECK-DAG: name: "svuint32_t",{{.*}}, baseType: ![[CT32:[0-9]+]] + // CHECK-DAG: ![[CT32]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY32:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS32]]) + // CHECK-DAG: ![[ELTTY32]] = !DIBasicType(name: "u32", size: 32, encoding: DW_ATE_unsigned) + let u32: svuint32_t; + + // CHECK-DAG: name: "svint64_t",{{.*}}, baseType: ![[CT64:[0-9]+]] + // CHECK-DAG: ![[CT64]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY64:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS64:[0-9]+]]) + // CHECK-DAG: ![[ELTTY64]] = !DIBasicType(name: "i64", size: 64, encoding: DW_ATE_signed) + // CHECK-DAG: ![[ELTS64]] = !{![[REALELTS64:[0-9]+]]} + // CHECK-DAG: ![[REALELTS64]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 1, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) + let s64: svint64_t; + + // CHECK-DAG: name: "svuint64_t",{{.*}}, baseType: ![[CT64:[0-9]+]] + // CHECK-DAG: ![[CT64]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY64:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS64]]) + // CHECK-DAG: ![[ELTTY64]] = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned) + let u64: svuint64_t; + + // CHECK: name: "svfloat32_t",{{.*}}, baseType: ![[CT32:[0-9]+]] + // CHECK-DAG: ![[CT32]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY32:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS32]]) + // CHECK-DAG: ![[ELTTY32]] = !DIBasicType(name: "f32", size: 32, encoding: DW_ATE_float) + let f32: svfloat32_t; + + // CHECK: name: "svfloat64_t",{{.*}}, baseType: ![[CT64:[0-9]+]] + // CHECK-DAG: ![[CT64]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTY64:[0-9]+]],{{.*}}, flags: DIFlagVector, elements: ![[ELTS64]]) + // CHECK-DAG: ![[ELTTY64]] = !DIBasicType(name: "f64", size: 64, encoding: DW_ATE_float) + let f64: svfloat64_t; +} diff --git a/tests/codegen-llvm/scalable-vectors/tuple-intrinsics.rs b/tests/codegen-llvm/scalable-vectors/tuple-intrinsics.rs new file mode 100644 index 0000000000000..e19fc40cb9d67 --- /dev/null +++ b/tests/codegen-llvm/scalable-vectors/tuple-intrinsics.rs @@ -0,0 +1,100 @@ +//@ build-pass +//@ only-aarch64 +#![crate_type = "lib"] +#![allow(incomplete_features, internal_features)] +#![feature(abi_unadjusted, core_intrinsics, link_llvm_intrinsics, rustc_attrs)] + +// Tests that tuples of scalable vectors are passed as immediates and that the intrinsics for +// creating/getting/setting tuples of scalable vectors generate the correct assembly + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +pub struct svfloat32_t(f32); + +#[derive(Copy, Clone)] +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +pub struct svfloat32x2_t(svfloat32_t, svfloat32_t); + +#[derive(Copy, Clone)] +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +pub struct svfloat32x3_t(svfloat32_t, svfloat32_t, svfloat32_t); + +#[derive(Copy, Clone)] +#[rustc_scalable_vector] +#[allow(non_camel_case_types)] +pub struct svfloat32x4_t(svfloat32_t, svfloat32_t, svfloat32_t, svfloat32_t); + +#[inline(never)] +#[target_feature(enable = "sve")] +pub fn svdup_n_f32(op: f32) -> svfloat32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4f32")] + fn _svdup_n_f32(op: f32) -> svfloat32_t; + } + unsafe { _svdup_n_f32(op) } +} + +// CHECK: define { , } @svcreate2_f32( %x0, %x1) +#[no_mangle] +#[target_feature(enable = "sve")] +pub fn svcreate2_f32(x0: svfloat32_t, x1: svfloat32_t) -> svfloat32x2_t { + // CHECK: %1 = insertvalue { , } poison, %x0, 0 + // CHECK-NEXT: %2 = insertvalue { , } %1, %x1, 1 + unsafe { std::intrinsics::simd::scalable::sve_tuple_create2(x0, x1) } +} + +// CHECK: define { , , } @svcreate3_f32( %x0, %x1, %x2) +#[no_mangle] +#[target_feature(enable = "sve")] +pub fn svcreate3_f32(x0: svfloat32_t, x1: svfloat32_t, x2: svfloat32_t) -> svfloat32x3_t { + // CHECK-LABEL: @_RNvCsk3YxfLN8zWY_6tuples13svcreate3_f32 + // CHECK: %1 = insertvalue { , , } poison, %x0, 0 + // CHECK-NEXT: %2 = insertvalue { , , } %1, %x1, 1 + // CHECK-NEXT: %3 = insertvalue { , , } %2, %x2, 2 + unsafe { std::intrinsics::simd::scalable::sve_tuple_create3(x0, x1, x2) } +} + +// CHECK: define { , , , } @svcreate4_f32( %x0, %x1, %x2, %x3) +#[no_mangle] +#[target_feature(enable = "sve")] +pub fn svcreate4_f32( + x0: svfloat32_t, + x1: svfloat32_t, + x2: svfloat32_t, + x3: svfloat32_t, +) -> svfloat32x4_t { + // CHECK-LABEL: @_RNvCsk3YxfLN8zWY_6tuples13svcreate4_f32 + // CHECK: %1 = insertvalue { , , , } poison, %x0, 0 + // CHECK-NEXT: %2 = insertvalue { , , , } %1, %x1, 1 + // CHECK-NEXT: %3 = insertvalue { , , , } %2, %x2, 2 + // CHECK-NEXT: %4 = insertvalue { , , , } %3, %x3, 3 + unsafe { std::intrinsics::simd::scalable::sve_tuple_create4(x0, x1, x2, x3) } +} + +// CHECK: define @svget2_f32({ , } %tup) +#[no_mangle] +#[target_feature(enable = "sve")] +pub fn svget2_f32(tup: svfloat32x2_t) -> svfloat32_t { + // CHECK: %1 = extractvalue { , } %tup, 0 + unsafe { std::intrinsics::simd::scalable::sve_tuple_get::<_, _, { IDX }>(tup) } +} + +// CHECK: define { , } @svset2_f32({ , } %tup, %x) +#[no_mangle] +#[target_feature(enable = "sve")] +pub fn svset2_f32(tup: svfloat32x2_t, x: svfloat32_t) -> svfloat32x2_t { + // CHECK: %1 = insertvalue { , } %tup, %x, 0 + unsafe { std::intrinsics::simd::scalable::sve_tuple_set::<_, _, { IDX }>(tup, x) } +} + +// This function exists only so there are calls to the generic functions +#[target_feature(enable = "sve")] +pub fn test() { + let x = svdup_n_f32(2f32); + let tup = svcreate2_f32(x, x); + let x = svget2_f32::<0>(tup); + let tup = svset2_f32::<0>(tup, x); +} diff --git a/tests/ui/const-generics/ogca/basic-fail.rs b/tests/ui/const-generics/gca/basic-different-definitions.rs similarity index 78% rename from tests/ui/const-generics/ogca/basic-fail.rs rename to tests/ui/const-generics/gca/basic-different-definitions.rs index e3db3dea3735e..d96c718617d24 100644 --- a/tests/ui/const-generics/ogca/basic-fail.rs +++ b/tests/ui/const-generics/gca/basic-different-definitions.rs @@ -1,6 +1,8 @@ +//@ check-pass + #![feature(generic_const_items)] #![feature(min_generic_const_args)] -#![feature(opaque_generic_const_args)] +#![feature(generic_const_args)] #![expect(incomplete_features)] type const ADD1: usize = const { N + 1 }; @@ -11,8 +13,6 @@ type const ONE: usize = ADD1::<0>; type const OTHER_ONE: usize = INC::<0>; -// Not definitionally equal. const ARR: [(); ADD1::<0>] = [(); INC::<0>]; -//~^ ERROR mismatched types fn main() {} diff --git a/tests/ui/const-generics/ogca/basic.rs b/tests/ui/const-generics/gca/basic.rs similarity index 90% rename from tests/ui/const-generics/ogca/basic.rs rename to tests/ui/const-generics/gca/basic.rs index e736484b5c3c9..e80540d621de5 100644 --- a/tests/ui/const-generics/ogca/basic.rs +++ b/tests/ui/const-generics/gca/basic.rs @@ -2,7 +2,7 @@ #![feature(generic_const_items)] #![feature(min_generic_const_args)] -#![feature(opaque_generic_const_args)] +#![feature(generic_const_args)] #![expect(incomplete_features)] type const ADD1: usize = const { N + 1 }; diff --git a/tests/ui/const-generics/gca/coherence-fail.rs b/tests/ui/const-generics/gca/coherence-fail.rs new file mode 100644 index 0000000000000..1b181d792d362 --- /dev/null +++ b/tests/ui/const-generics/gca/coherence-fail.rs @@ -0,0 +1,28 @@ +#![feature(generic_const_items, min_generic_const_args, generic_const_args)] +#![expect(incomplete_features)] + +// computing the same value with different constant items but same generic arguments should fail +trait Trait1 {} +type const FOO: usize = const { N + 1 }; +type const BAR: usize = const { N + 1 }; +impl Trait1 for [(); FOO::<1>] {} +impl Trait1 for [(); BAR::<1>] {} +//~^ ERROR conflicting implementations of trait `Trait1` for type `[(); 2]` + +// computing the same value with the same constant item but different generic arguments should fail +type const DIV2: usize = const { N / 2 }; +trait Trait2 {} +impl Trait2 for [(); DIV2::<2>] {} +impl Trait2 for [(); DIV2::<3>] {} +//~^ ERROR conflicting implementations of trait `Trait2` for type `[(); 1]` + +// computing the same value with different constant items and different generic arguments should +// fail +trait Trait3 {} +type const ADD1: usize = const { N + 1 }; +type const SUB1: usize = const { N - 1 }; +impl Trait3 for [(); ADD1::<1>] {} +impl Trait3 for [(); SUB1::<3>] {} +//~^ ERROR conflicting implementations of trait `Trait3` for type `[(); 2]` + +fn main() {} diff --git a/tests/ui/const-generics/gca/coherence-fail.stderr b/tests/ui/const-generics/gca/coherence-fail.stderr new file mode 100644 index 0000000000000..e8122c1b832f1 --- /dev/null +++ b/tests/ui/const-generics/gca/coherence-fail.stderr @@ -0,0 +1,27 @@ +error[E0119]: conflicting implementations of trait `Trait1` for type `[(); 2]` + --> $DIR/coherence-fail.rs:9:1 + | +LL | impl Trait1 for [(); FOO::<1>] {} + | ------------------------------ first implementation here +LL | impl Trait1 for [(); BAR::<1>] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); 2]` + +error[E0119]: conflicting implementations of trait `Trait2` for type `[(); 1]` + --> $DIR/coherence-fail.rs:16:1 + | +LL | impl Trait2 for [(); DIV2::<2>] {} + | ------------------------------- first implementation here +LL | impl Trait2 for [(); DIV2::<3>] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); 1]` + +error[E0119]: conflicting implementations of trait `Trait3` for type `[(); 2]` + --> $DIR/coherence-fail.rs:25:1 + | +LL | impl Trait3 for [(); ADD1::<1>] {} + | ------------------------------- first implementation here +LL | impl Trait3 for [(); SUB1::<3>] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); 2]` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/const-generics/gca/coherence-ok.rs b/tests/ui/const-generics/gca/coherence-ok.rs new file mode 100644 index 0000000000000..447f25bfdc36b --- /dev/null +++ b/tests/ui/const-generics/gca/coherence-ok.rs @@ -0,0 +1,14 @@ +//@ check-pass +#![feature(generic_const_items, min_generic_const_args, generic_const_args)] +#![expect(incomplete_features)] + +// computing different values with the same type const item should be fine + +type const ADD1: usize = const { N + 1 }; + +trait Trait {} + +impl Trait for [(); ADD1::<1>] {} +impl Trait for [(); ADD1::<2>] {} + +fn main() {} diff --git a/tests/ui/const-generics/ogca/generic-param-rhs.rs b/tests/ui/const-generics/gca/generic-param-rhs.rs similarity index 79% rename from tests/ui/const-generics/ogca/generic-param-rhs.rs rename to tests/ui/const-generics/gca/generic-param-rhs.rs index a62b509190bd6..ed4467d6f0039 100644 --- a/tests/ui/const-generics/ogca/generic-param-rhs.rs +++ b/tests/ui/const-generics/gca/generic-param-rhs.rs @@ -1,4 +1,4 @@ -#![feature(min_generic_const_args, opaque_generic_const_args)] +#![feature(min_generic_const_args, generic_const_args)] #![expect(incomplete_features)] fn foo() {} diff --git a/tests/ui/const-generics/ogca/generic-param-rhs.stderr b/tests/ui/const-generics/gca/generic-param-rhs.stderr similarity index 100% rename from tests/ui/const-generics/ogca/generic-param-rhs.stderr rename to tests/ui/const-generics/gca/generic-param-rhs.stderr diff --git a/tests/ui/const-generics/ogca/rhs-but-not-root.rs b/tests/ui/const-generics/gca/rhs-but-not-root.rs similarity index 77% rename from tests/ui/const-generics/ogca/rhs-but-not-root.rs rename to tests/ui/const-generics/gca/rhs-but-not-root.rs index bb6c6b667e1d0..6c0337dbbd470 100644 --- a/tests/ui/const-generics/ogca/rhs-but-not-root.rs +++ b/tests/ui/const-generics/gca/rhs-but-not-root.rs @@ -1,9 +1,9 @@ #![feature(generic_const_items)] #![feature(min_generic_const_args)] -#![feature(opaque_generic_const_args)] +#![feature(generic_const_args)] #![expect(incomplete_features)] -// Anon consts must be the root of the RHS to be OGCA. +// Anon consts must be the root of the RHS to be GCA. type const FOO: usize = ID::; //~^ ERROR generic parameters in const blocks are only allowed as the direct value of a `type const` type const ID: usize = N; diff --git a/tests/ui/const-generics/ogca/rhs-but-not-root.stderr b/tests/ui/const-generics/gca/rhs-but-not-root.stderr similarity index 100% rename from tests/ui/const-generics/ogca/rhs-but-not-root.stderr rename to tests/ui/const-generics/gca/rhs-but-not-root.stderr diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr index f1d5e5c674756..0060c94875b5c 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr +++ b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr @@ -10,7 +10,7 @@ error: generic parameters may not be used in const operations LL | foo::<{ Some:: { 0: const { N + 1 } } }>(); | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr index e0804158952d1..b25199bca2e28 100644 --- a/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr +++ b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr @@ -4,7 +4,7 @@ error: generic parameters may not be used in const operations LL | T: Trait | ^^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr index 1c72afce52c7d..f634ec1cf12e4 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -40,7 +40,7 @@ error: generic parameters may not be used in const operations LL | type const ITEM3: usize = const { N }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:60:31 @@ -48,7 +48,7 @@ error: generic parameters may not be used in const operations LL | T3: Trait, | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:69:58 @@ -56,7 +56,7 @@ error: generic parameters may not be used in const operations LL | struct Default3; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:28:27 @@ -64,7 +64,7 @@ error: generic parameters may not be used in const operations LL | let _3 = [(); const { N }]; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:33:26 @@ -72,7 +72,7 @@ error: generic parameters may not be used in const operations LL | let _6: [(); const { N }] = todo!(); | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:11:41 @@ -80,7 +80,7 @@ error: generic parameters may not be used in const operations LL | type Adt3 = Foo; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:19:42 @@ -88,7 +88,7 @@ error: generic parameters may not be used in const operations LL | type Arr3 = [(); const { N }]; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 13 previous errors diff --git a/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr b/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr index 1c841e39e6739..cf5974fd83df9 100644 --- a/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr +++ b/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr @@ -9,7 +9,7 @@ note: not a concrete type | LL | impl S { | ^^^^ - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/selftyparam.stderr b/tests/ui/const-generics/mgca/selftyparam.stderr index c3e0770fb978e..74d8f083ee09e 100644 --- a/tests/ui/const-generics/mgca/selftyparam.stderr +++ b/tests/ui/const-generics/mgca/selftyparam.stderr @@ -4,7 +4,7 @@ error: generic parameters may not be used in const operations LL | fn foo() -> [(); const { let _: Self; 1 }]; | ^^^^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr index 61e934380c360..694d4c8ebabd4 100644 --- a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr +++ b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr @@ -10,7 +10,7 @@ error: generic parameters may not be used in const operations LL | [0; const { size_of::<*mut T>() }]; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr index 2961c714d1415..3a873ec33fb19 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr +++ b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr @@ -10,7 +10,7 @@ error: generic parameters may not be used in const operations LL | with_point::<{ Point(const { N + 1 }, N) }>(); | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr index 95a98d857b1d4..a9d412964da29 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr @@ -22,7 +22,7 @@ error: generic parameters may not be used in const operations LL | takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.rs b/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.rs new file mode 100644 index 0000000000000..74c945b0881a4 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.rs @@ -0,0 +1,15 @@ +//! Regression test for +//! +//@ incremental +#![feature(min_generic_const_args)] +type const R: usize = 1_i32; //~ ERROR: the constant `1` is not of type `usize` +type const U: usize = -1_i32; //~ ERROR: the constant `-1` is not of type `usize` +type const S: bool = 1i32; //~ ERROR: the constant `1` is not of type `bool` +type const T: bool = -1i32; //~ ERROR: the constant `-1` is not of type `bool` + +fn main() { + R; + U; + S; + T; +} diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.stderr b/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.stderr new file mode 100644 index 0000000000000..b09ac22240325 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-mismatched-type-incremental.stderr @@ -0,0 +1,26 @@ +error: the constant `1` is not of type `usize` + --> $DIR/type_const-mismatched-type-incremental.rs:5:1 + | +LL | type const R: usize = 1_i32; + | ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i32` + +error: the constant `-1` is not of type `usize` + --> $DIR/type_const-mismatched-type-incremental.rs:6:1 + | +LL | type const U: usize = -1_i32; + | ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i32` + +error: the constant `1` is not of type `bool` + --> $DIR/type_const-mismatched-type-incremental.rs:7:1 + | +LL | type const S: bool = 1i32; + | ^^^^^^^^^^^^^^^^^^ expected `bool`, found `i32` + +error: the constant `-1` is not of type `bool` + --> $DIR/type_const-mismatched-type-incremental.rs:8:1 + | +LL | type const T: bool = -1i32; + | ^^^^^^^^^^^^^^^^^^ expected `bool`, found `i32` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr index 475d2cf312d64..0c88fbfb8578c 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr @@ -4,7 +4,7 @@ error: generic parameters may not be used in const operations LL | type const FREE1: usize = const { std::mem::size_of::() }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic-expr.rs:8:51 @@ -12,7 +12,7 @@ error: generic parameters may not be used in const operations LL | type const FREE2: usize = const { I + 1 }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr index e13d6fbcdd82f..78e38d800524e 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr @@ -4,7 +4,7 @@ error: generic parameters may not be used in const operations LL | type const N1: usize = const { std::mem::size_of::() }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic_expr-2.rs:15:52 @@ -12,7 +12,7 @@ error: generic parameters may not be used in const operations LL | type const N2: usize = const { I + 1 }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic_expr-2.rs:17:40 @@ -20,7 +20,7 @@ error: generic parameters may not be used in const operations LL | type const N3: usize = const { 2 & X }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/ogca/basic-fail.stderr b/tests/ui/const-generics/ogca/basic-fail.stderr deleted file mode 100644 index b1808deacd27f..0000000000000 --- a/tests/ui/const-generics/ogca/basic-fail.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/basic-fail.rs:15:30 - | -LL | const ARR: [(); ADD1::<0>] = [(); INC::<0>]; - | --------------- ^^^^^^^^^^^^^^ expected an array with a size of const { N + 1 }, found one with a size of const { N + 1 } - | | - | expected because of the type of the constant - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/ogca/coherence-ambiguous.rs b/tests/ui/const-generics/ogca/coherence-ambiguous.rs deleted file mode 100644 index bb20c0457c03d..0000000000000 --- a/tests/ui/const-generics/ogca/coherence-ambiguous.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ check-fail - -#![feature(generic_const_items, min_generic_const_args, opaque_generic_const_args)] -#![expect(incomplete_features)] - -type const FOO: usize = const { N + 1 }; - -type const BAR: usize = const { N + 1 }; - -trait Trait {} - -impl Trait for [(); FOO::<1>] {} -impl Trait for [(); BAR::<1>] {} -//~^ ERROR conflicting implementations of trait `Trait` for type `[(); FOO::<1>]` -impl Trait for [(); BAR::<2>] {} -//~^ ERROR conflicting implementations of trait `Trait` for type `[(); FOO::<1>]` - -fn main() {} diff --git a/tests/ui/const-generics/ogca/coherence-ambiguous.stderr b/tests/ui/const-generics/ogca/coherence-ambiguous.stderr deleted file mode 100644 index 919a0c8d70e94..0000000000000 --- a/tests/ui/const-generics/ogca/coherence-ambiguous.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0119]: conflicting implementations of trait `Trait` for type `[(); FOO::<1>]` - --> $DIR/coherence-ambiguous.rs:13:1 - | -LL | impl Trait for [(); FOO::<1>] {} - | ----------------------------- first implementation here -LL | impl Trait for [(); BAR::<1>] {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); FOO::<1>]` - -error[E0119]: conflicting implementations of trait `Trait` for type `[(); FOO::<1>]` - --> $DIR/coherence-ambiguous.rs:15:1 - | -LL | impl Trait for [(); FOO::<1>] {} - | ----------------------------- first implementation here -... -LL | impl Trait for [(); BAR::<2>] {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); FOO::<1>]` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/enum/enum_u8_variant.rs b/tests/ui/enum/enum_u8_variant.rs new file mode 100644 index 0000000000000..f61d42cd2bf01 --- /dev/null +++ b/tests/ui/enum/enum_u8_variant.rs @@ -0,0 +1,14 @@ +//@ run-pass +//Test that checks pattern matching works correctly on a repr(u8) enum +// whose only variant contains an inner 'u8' field +//https://github.com/rust-lang/rust/issues/34571 +#[repr(u8)] +enum Foo { + Foo(#[allow(dead_code)] u8), +} + +fn main() { + match Foo::Foo(1) { + _ => () + } +} diff --git a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs b/tests/ui/feature-gates/feature-gate-generic-const-args.rs similarity index 80% rename from tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs rename to tests/ui/feature-gates/feature-gate-generic-const-args.rs index f18f59cf60bd1..b62e7fb08099a 100644 --- a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs +++ b/tests/ui/feature-gates/feature-gate-generic-const-args.rs @@ -3,6 +3,6 @@ type const INC: usize = const { N + 1 }; //~^ ERROR generic parameters may not be used in const operations -//~| HELP add `#![feature(opaque_generic_const_args)]` +//~| HELP add `#![feature(generic_const_args)]` fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr b/tests/ui/feature-gates/feature-gate-generic-const-args.stderr similarity index 57% rename from tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr rename to tests/ui/feature-gates/feature-gate-generic-const-args.stderr index ef771e77f6923..27794b43966cd 100644 --- a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr +++ b/tests/ui/feature-gates/feature-gate-generic-const-args.stderr @@ -1,10 +1,10 @@ error: generic parameters may not be used in const operations - --> $DIR/feature-gate-opaque-generic-const-args.rs:4:49 + --> $DIR/feature-gate-generic-const-args.rs:4:49 | LL | type const INC: usize = const { N + 1 }; | ^ | - = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs.rs b/tests/ui/feature-gates/feature-gate-rustc-attrs.rs index e7b2eca6f858a..6382af32efb2a 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-attrs.rs +++ b/tests/ui/feature-gates/feature-gate-rustc-attrs.rs @@ -12,7 +12,7 @@ mod unknown { pub macro rustc() {} } fn f() {} #[unknown::rustc] -//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler +//~^ ERROR attributes containing a segment starting with `rustc` are reserved for use by the `rustc` compiler //~| ERROR expected attribute, found macro `unknown::rustc` //~| NOTE not an attribute fn g() {} diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr b/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr index d58603883f158..bc0db8b81aefc 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr @@ -10,7 +10,7 @@ error: expected attribute, found macro `rustc::unknown` LL | #[rustc::unknown] | ^^^^^^^^^^^^^^ not an attribute -error: attributes starting with `rustc` are reserved for use by the `rustc` compiler +error: attributes containing a segment starting with `rustc` are reserved for use by the `rustc` compiler --> $DIR/feature-gate-rustc-attrs.rs:14:12 | LL | #[unknown::rustc] diff --git a/tests/ui/issues/issue-28625.rs b/tests/ui/issues/issue-28625.rs deleted file mode 100644 index 54ed408e74881..0000000000000 --- a/tests/ui/issues/issue-28625.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ normalize-stderr: "\d+ bits" -> "N bits" - -trait Bar { - type Bar; -} - -struct ArrayPeano { - data: T::Bar, -} - -fn foo(a: &ArrayPeano) -> &[T] where T: Bar { - unsafe { std::mem::transmute(a) } //~ ERROR cannot transmute between types of different sizes -} - -impl Bar for () { - type Bar = (); -} - -fn main() { - let x: ArrayPeano<()> = ArrayPeano { data: () }; - foo(&x); -} diff --git a/tests/ui/issues/issue-34571.rs b/tests/ui/issues/issue-34571.rs deleted file mode 100644 index 1242a9e2b5c01..0000000000000 --- a/tests/ui/issues/issue-34571.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -#[repr(u8)] -enum Foo { - Foo(#[allow(dead_code)] u8), -} - -fn main() { - match Foo::Foo(1) { - _ => () - } -} diff --git a/tests/ui/issues/issue-49973.rs b/tests/ui/issues/issue-49973.rs deleted file mode 100644 index c8f7c8ea32fe7..0000000000000 --- a/tests/ui/issues/issue-49973.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -#[derive(Debug)] -#[repr(i32)] -enum E { - Min = -2147483648i32, - _Max = 2147483647i32, -} - -fn main() { - assert_eq!(Some(E::Min).unwrap() as i32, -2147483648i32); -} diff --git a/tests/ui/layout/opt-repr-i32-min.rs b/tests/ui/layout/opt-repr-i32-min.rs new file mode 100644 index 0000000000000..10e54c633ae03 --- /dev/null +++ b/tests/ui/layout/opt-repr-i32-min.rs @@ -0,0 +1,14 @@ +//@ run-pass +// Tests that Option niche optimisation does not incorrectly use i32::MIN +// as the None niche when a repr(i32) enum variant already holds that value. +// github.com/rust-lang/rust/issues/49973 +#[derive(Debug)] +#[repr(i32)] +enum E { + Min = -2147483648i32, + _Max = 2147483647i32, +} + +fn main() { + assert_eq!(Some(E::Min).unwrap() as i32, -2147483648i32); +} diff --git a/tests/ui/issues/issue-38160.rs b/tests/ui/macros/macro-const-stringify.rs similarity index 64% rename from tests/ui/issues/issue-38160.rs rename to tests/ui/macros/macro-const-stringify.rs index 0395aea63ee97..e2a110ffd09c6 100644 --- a/tests/ui/issues/issue-38160.rs +++ b/tests/ui/macros/macro-const-stringify.rs @@ -1,19 +1,16 @@ //@ check-pass - +//Tests to check that a macro generating an impl block with stringify for a trait associated const +//https://github.com/rust-lang/rust/issues/38160 trait MyTrait { const MY_CONST: &'static str; } - macro_rules! my_macro { () => { struct MyStruct; - impl MyTrait for MyStruct { const MY_CONST: &'static str = stringify!(abc); } } } - my_macro!(); - fn main() {} diff --git a/tests/ui/scalable-vectors/cast-intrinsic.rs b/tests/ui/scalable-vectors/cast-intrinsic.rs new file mode 100644 index 0000000000000..f2157d8bcc14b --- /dev/null +++ b/tests/ui/scalable-vectors/cast-intrinsic.rs @@ -0,0 +1,65 @@ +//@ check-pass +//@ only-aarch64 +#![crate_type = "lib"] +#![allow(incomplete_features, internal_features, improper_ctypes)] +#![feature(abi_unadjusted, core_intrinsics, link_llvm_intrinsics, rustc_attrs)] + +use std::intrinsics::simd::scalable::sve_cast; + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +pub struct svbool_t(bool); + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +pub struct svbool2_t(bool); + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +pub struct svint64_t(i64); + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(2)] +#[allow(non_camel_case_types)] +pub struct nxv2i16(i16); + +pub trait SveInto: Sized { + unsafe fn sve_into(self) -> T; +} + +impl SveInto for svbool_t { + #[target_feature(enable = "sve")] + unsafe fn sve_into(self) -> svbool2_t { + unsafe extern "C" { + #[cfg_attr( + target_arch = "aarch64", + link_name = concat!("llvm.aarch64.sve.convert.from.svbool.nxv2i1") + )] + fn convert_from_svbool(b: svbool_t) -> svbool2_t; + } + unsafe { convert_from_svbool(self) } + } +} + +#[target_feature(enable = "sve")] +pub unsafe fn svld1sh_gather_s64offset_s64( + pg: svbool_t, + base: *const i16, + offsets: svint64_t, +) -> svint64_t { + unsafe extern "unadjusted" { + #[cfg_attr( + target_arch = "aarch64", + link_name = "llvm.aarch64.sve.ld1.gather.nxv2i16" + )] + fn _svld1sh_gather_s64offset_s64( + pg: svbool2_t, + base: *const i16, + offsets: svint64_t, + ) -> nxv2i16; + } + sve_cast(_svld1sh_gather_s64offset_s64(pg.sve_into(), base, offsets)) +} diff --git a/tests/ui/simd/masked-load-store-check-fail.stderr b/tests/ui/simd/masked-load-store-check-fail.stderr index 4e63d04a3b158..037855c8ec9ca 100644 --- a/tests/ui/simd/masked-load-store-check-fail.stderr +++ b/tests/ui/simd/masked-load-store-check-fail.stderr @@ -21,7 +21,7 @@ LL | | Simd::([9; 4]), LL | | ); | |_________^ note: function defined here - --> $SRC_DIR/core/src/intrinsics/simd.rs:LL:COL + --> $SRC_DIR/core/src/intrinsics/simd/mod.rs:LL:COL error[E0308]: mismatched types --> $DIR/masked-load-store-check-fail.rs:25:13 @@ -46,7 +46,7 @@ LL | | default, LL | | ); | |_________^ note: function defined here - --> $SRC_DIR/core/src/intrinsics/simd.rs:LL:COL + --> $SRC_DIR/core/src/intrinsics/simd/mod.rs:LL:COL error: aborting due to 2 previous errors diff --git a/tests/ui/transmute/transmute-associated-type-to-slice.rs b/tests/ui/transmute/transmute-associated-type-to-slice.rs new file mode 100644 index 0000000000000..9521a944391cc --- /dev/null +++ b/tests/ui/transmute/transmute-associated-type-to-slice.rs @@ -0,0 +1,23 @@ +//! regression test for +//@ normalize-stderr: "\d+ bits" -> "N bits" + +trait MyTrait { + type MyType; +} + +struct ArrayPeano { + data: T::MyType, +} + +fn foo(a: &ArrayPeano) -> &[T] where T: MyTrait { + unsafe { std::mem::transmute(a) } //~ ERROR cannot transmute between types of different sizes +} + +impl MyTrait for () { + type MyType = (); +} + +fn main() { + let x: ArrayPeano<()> = ArrayPeano { data: () }; + foo(&x); +} diff --git a/tests/ui/issues/issue-28625.stderr b/tests/ui/transmute/transmute-associated-type-to-slice.stderr similarity index 87% rename from tests/ui/issues/issue-28625.stderr rename to tests/ui/transmute/transmute-associated-type-to-slice.stderr index 3600622a45424..ada3153165e57 100644 --- a/tests/ui/issues/issue-28625.stderr +++ b/tests/ui/transmute/transmute-associated-type-to-slice.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/issue-28625.rs:12:14 + --> $DIR/transmute-associated-type-to-slice.rs:13:14 | LL | unsafe { std::mem::transmute(a) } | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-23477.rs b/tests/ui/transmute/transmute-slice-to-dst.rs similarity index 77% rename from tests/ui/issues/issue-23477.rs rename to tests/ui/transmute/transmute-slice-to-dst.rs index fa69a1d762682..c1f77bee284dd 100644 --- a/tests/ui/issues/issue-23477.rs +++ b/tests/ui/transmute/transmute-slice-to-dst.rs @@ -1,3 +1,4 @@ +//! regression test for //@ build-pass //@ compile-flags: -g diff --git a/triagebot.toml b/triagebot.toml index f99d700310dfe..719fe2a75c82b 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1077,7 +1077,7 @@ cc = ["@Amanieu", "@folkertdev", "@sayantn"] message = "Some changes occurred in `std_detect`" cc = ["@Amanieu", "@folkertdev", "@sayantn"] -[mentions."library/core/src/intrinsics/simd.rs"] +[mentions."library/core/src/intrinsics/simd/mod.rs"] message = """ Some changes occurred to the platform-builtins intrinsics. Make sure the LLVM backend as well as portable-simd gets adapted for the changes.