diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index e759fd6618276..6158d1026bfec 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -26,7 +26,7 @@ use rustc_middle::mir::{ }; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{ - self, PredicateKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast, + self, CallerBoundsIterator, PredicateKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast, suggest_constraining_type_params, }; use rustc_mir_dataflow::move_paths::{Init, InitKind, InitLocation, MoveOutIndex, MovePathIndex}; @@ -285,7 +285,7 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { let place = &self.move_data.move_paths[mpi].place; let ty = place.ty(self.body, self.infcx.tcx).ty; - if self.infcx.param_env.caller_bounds().any(|c| { + if self.infcx.param_env.caller_bounds().all_clauses(self.infcx.tcx).iter().any(|c| { c.as_trait_clause().is_some_and(|pred| { pred.skip_binder().self_ty() == ty && self.infcx.tcx.is_fn_trait(pred.def_id()) }) diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index e5d4b9295578b..7045cddc27116 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -11,7 +11,7 @@ use rustc_infer::traits::query::MirBorrowckImpliedOutlivesBounds; use rustc_infer::traits::query::type_op::Normalize; use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::query::OutlivesBound; -use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, CallerBoundsIterator, RegionVid, Ty, TypeVisitableExt}; use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::solve::NoSolution; use rustc_trait_selection::traits::query::type_op; @@ -211,7 +211,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { // Normalize the assumptions we use to borrowck the program. let mut constraints = vec![]; let mut known_type_outlives_obligations = vec![]; - for bound in param_env.caller_bounds() { + for bound in param_env.caller_bounds().non_trait_clauses().iter() { if let Some(outlives) = bound.as_type_outlives_clause() { known_type_outlives_obligations.push(outlives); }; @@ -371,7 +371,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { // Normalize the assumptions we use to borrowck the program. let mut constraints = vec![]; let mut known_type_outlives_obligations = vec![]; - for bound in param_env.caller_bounds() { + for bound in param_env.caller_bounds().non_trait_clauses().iter() { if let Some(outlives) = bound.as_type_outlives_clause() { known_type_outlives_obligations.push(outlives); }; diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 999fa3edacaa4..cfaafc632e2c0 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1204,17 +1204,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // FIXME(antoyo) } - fn store(&mut self, val: RValue<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> { - self.store_with_flags(val, ptr, align, MemFlags::empty()) - } - fn store_with_flags( &mut self, val: RValue<'gcc>, ptr: RValue<'gcc>, align: Align, flags: MemFlags, - ) -> RValue<'gcc> { + ) { let ptr = self.check_store(val, ptr); let destination = ptr.dereference(self.location); // NOTE: libgccjit does not support specifying the alignment on the assignment, so we cast @@ -1231,10 +1227,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let modified_destination = modified_ptr.dereference(self.location); self.llbb().add_assignment(self.location, modified_destination, val); // FIXME(antoyo): handle `MemFlags::NONTEMPORAL`. - // NOTE: dummy value here since it's never used. FIXME(antoyo): API should not return a value here? // When adding support for NONTEMPORAL, make sure to not just emit MOVNT on x86; see the // LLVM backend for details. - self.cx.context.new_rvalue_zero(self.type_i32()) } fn atomic_store( diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index b8237443cccc3..7e71755ed4e70 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -657,22 +657,17 @@ pub(crate) unsafe fn llvm_optimize<'ll>( None }; - fn handle_offload<'ll>(cx: &SimpleCx<'ll>, old_fn: &'ll llvm::Value) { + // Wraps `old_fn` into a new kernel that takes the implicit `dyn_ptr` as its first argument. + // Returns the new function, or `None` if nothing was wrapped + fn handle_offload<'ll>( + cx: &SimpleCx<'ll>, + old_fn: &'ll llvm::Value, + ) -> Option<&'ll llvm::Value> { let old_fn_ty = cx.get_type_of_global(old_fn); let old_param_types = cx.func_params_types(old_fn_ty); let old_param_count = old_param_types.len(); if old_param_count == 0 { - return; - } - - let first_param = llvm::get_param(old_fn, 0); - let c_name = llvm::get_value_name(first_param); - let first_arg_name = str::from_utf8(&c_name).unwrap(); - // We might call llvm_optimize (and thus this code) multiple times on the same IR, - // but we shouldn't add this helper ptr multiple times. - // FIXME(offload): This could break if the user calls his first argument `dyn_ptr`. - if first_arg_name == "dyn_ptr" { - return; + return None; } // Create the new parameter list, with ptr as the first argument @@ -747,6 +742,7 @@ pub(crate) unsafe fn llvm_optimize<'ll>( } // Now we can re-use the old name, without name collision. llvm::set_value_name(new_fn, &name); + Some(new_fn) } if cgcx.target_is_like_gpu @@ -755,10 +751,13 @@ pub(crate) unsafe fn llvm_optimize<'ll>( let cx = SimpleCx::new(llmod, llcx, cgcx.pointer_size); for func in cx.get_functions() { let offload_kernel = "offload-kernel"; - if attributes::has_string_attr(func, offload_kernel) { - handle_offload(&cx, func); + if !attributes::has_string_attr(func, offload_kernel) { + continue; + } + match handle_offload(&cx, func) { + Some(new_fn) => attributes::remove_string_attr_from_llfn(new_fn, offload_kernel), + None => attributes::remove_string_attr_from_llfn(func, offload_kernel), } - attributes::remove_string_attr_from_llfn(func, offload_kernel); } } @@ -822,8 +821,9 @@ pub(crate) unsafe fn llvm_optimize<'ll>( }; // This assumes that we previously compiled our kernels for a gpu target, which created a - // `.bc` artifact. The user is supposed to provide us with a path to this artifact, we - // don't need any other artifacts from the previous run. + // `.ptx` (NVPTX) or `.elf` (AMDGPU) artifact. + // The user is supposed to provide us with a path to this artifact, + // we don't need any other artifacts from the previous run. if !cgcx.target_is_like_gpu && is_final_stage { if let Some(device_path) = config .offload @@ -833,15 +833,18 @@ pub(crate) unsafe fn llvm_optimize<'ll>( let device_pathbuf = PathBuf::from(device_path); if device_pathbuf.is_relative() { dcx.emit_err(crate::diagnostics::OffloadWithoutAbsPath); - } else if device_pathbuf.extension().and_then(|e| e.to_str()) != Some("bc") { + } else if !matches!( + device_pathbuf.extension().and_then(|e| e.to_str()), + Some("ptx" | "elf") + ) { dcx.emit_err(crate::diagnostics::OffloadWrongFileName); } else if !device_pathbuf.exists() { dcx.emit_err(crate::diagnostics::OffloadNonexistingPath); } - let device_bitcode_c = path_to_c_string(device_pathbuf.as_path()); + let device_image_c = path_to_c_string(device_pathbuf.as_path()); let ok = unsafe { llvm::RustOffloadWrapper::get_instance() - .llvm_rust_offload_wrap_images(llmod, device_bitcode_c.as_c_str()) + .llvm_rust_offload_wrap_images(llmod, device_image_c.as_c_str()) }; if !ok { dcx.emit_err(crate::diagnostics::OffloadWrapImagesFailed); diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 41b26e33e3c38..c36118af3e0b7 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -905,17 +905,13 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { self.set_metadata_node(load, llvm::MD_nonnull, &[]); } - fn store(&mut self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value { - self.store_with_flags(val, ptr, align, MemFlags::empty()) - } - fn store_with_flags( &mut self, val: &'ll Value, ptr: &'ll Value, align: Align, flags: MemFlags, - ) -> &'ll Value { + ) { debug!("Store {:?} -> {:?} ({:?})", val, ptr, flags); assert_eq!(self.cx.type_kind(self.cx.val_ty(ptr)), TypeKind::Pointer); unsafe { @@ -966,7 +962,6 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let md = llvm::LLVMMDNodeInContext2(self.cx.llcx, args.as_ptr(), args.len()); self.set_metadata(store, id, md); } - store } } diff --git a/compiler/rustc_codegen_llvm/src/diagnostics.rs b/compiler/rustc_codegen_llvm/src/diagnostics.rs index 094b683ded56b..19b2f68107e6c 100644 --- a/compiler/rustc_codegen_llvm/src/diagnostics.rs +++ b/compiler/rustc_codegen_llvm/src/diagnostics.rs @@ -73,7 +73,7 @@ pub(crate) struct RustOffloadComponentMissing { #[derive(Diagnostic)] #[diag( - "using the offload feature requires -Z offload=.bc>" + "using the offload feature requires -Z offload=.ptx or .elf>" )] pub(crate) struct OffloadWithoutEnable; @@ -82,18 +82,20 @@ pub(crate) struct OffloadWithoutEnable; pub(crate) struct OffloadWithoutFatLTO; #[derive(Diagnostic)] -#[diag("using the `-Z offload=Host=/absolute/path/to/.bc` flag requires an absolute path")] +#[diag( + "using the `-Z offload=Host=/absolute/path/to/.ptx` or `.elf` flag requires an absolute path" +)] pub(crate) struct OffloadWithoutAbsPath; #[derive(Diagnostic)] #[diag( - "using the `-Z offload=Host=/absolute/path/to/.bc` flag must point to a .bc file produced by the device compilation (--emit=llvm-bc)" + "using the `-Z offload=Host=/absolute/path/to/.ptx` or `.elf` flag must point to a .ptx or .elf file produced by the device compilation" )] pub(crate) struct OffloadWrongFileName; #[derive(Diagnostic)] #[diag( - "the given path/file to `.bc` does not exist. Did you forget to run the device compilation first?" + "the given path/file to `.ptx` or `.elf` does not exist. Did you forget to run the device compilation first?" )] pub(crate) struct OffloadNonexistingPath; diff --git a/compiler/rustc_codegen_llvm/src/llvm/offload_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/offload_ffi.rs index 60e0836a35d88..4f2369aef0d53 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/offload_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/offload_ffi.rs @@ -6,9 +6,8 @@ use super::ffi::{Module, Value}; type LLVMRustOffloadMapperFn = unsafe extern "C" fn(&Value, &Value, *const &Value); type LLVMRustOffloadWrapImagesFn = - for<'ll> unsafe extern "C" fn(Module<'ll>, *const c_char, *const c_char) -> bool; + for<'ll> unsafe extern "C" fn(Module<'ll>, *const c_char) -> bool; -use rustc_fs_util::path_to_c_string; use rustc_session::config::host_tuple; use rustc_session::filesearch; @@ -17,7 +16,6 @@ use crate::llvm; pub(crate) struct RustOffloadWrapper { LLVMRustOffloadMapper: LLVMRustOffloadMapperFn, LLVMRustOffloadWrapImages: LLVMRustOffloadWrapImagesFn, - lld_path: Option, // Keep the dynamic library loaded while the function pointers are used. _lib: libloading::Library, } @@ -59,18 +57,15 @@ impl RustOffloadWrapper { pub(crate) unsafe fn llvm_rust_offload_wrap_images<'ll>( &self, host_m: Module<'ll>, - device_bitcode_path: &CStr, + device_image_path: &CStr, ) -> bool { - let lld_c = self.lld_path.as_deref().map(path_to_c_string).unwrap_or_default(); - unsafe { - (self.LLVMRustOffloadWrapImages)(host_m, lld_c.as_ptr(), device_bitcode_path.as_ptr()) - } + unsafe { (self.LLVMRustOffloadWrapImages)(host_m, device_image_path.as_ptr()) } } fn call_dynamic( sysroot: &rustc_session::config::Sysroot, ) -> Result { - let (rust_offload_path, lld_path) = Self::get_offload_and_lld_paths(sysroot)?; + let rust_offload_path = Self::get_offload_path(sysroot)?; let lib = unsafe { libloading::Library::new(rust_offload_path)? }; let llvm_rust_offload_wrapper = @@ -81,14 +76,13 @@ impl RustOffloadWrapper { Ok(Self { LLVMRustOffloadMapper: llvm_rust_offload_wrapper, LLVMRustOffloadWrapImages: llvm_rust_offload_wrap_images, - lld_path, _lib: lib, }) } - fn get_offload_and_lld_paths( + fn get_offload_path( sysroot: &rustc_session::config::Sysroot, - ) -> Result<(PathBuf, Option), RustOffloadLibraryError> { + ) -> Result { let llvm_version_major = llvm::LLVMRustVersionMajor(); let mut searched = Vec::new(); @@ -102,11 +96,7 @@ impl RustOffloadWrapper { continue; } - let lld_path = filesearch::make_target_bin_path(root, host_tuple()) - .join(format!("rust-lld{}", std::env::consts::EXE_SUFFIX)); - let lld_path = lld_path.is_file().then_some(lld_path); - - return Ok((rust_offload_path, lld_path)); + return Ok(rust_offload_path); } Err(RustOffloadLibraryError::NotFound { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 10baf16915d15..8f7970da96402 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -96,8 +96,19 @@ fn process_builtin_attrs( AttributeKind::LinkSection { name } => codegen_fn_attrs.link_section = Some(*name), AttributeKind::NoMangle(attr_span) => { interesting_spans.no_mangle = Some(*attr_span); - if tcx.opt_item_name(did.to_def_id()).is_some() { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; + if let Some(name) = tcx.opt_item_name(did.to_def_id()) { + // Don't override #[export_name]. + + // Also don't override #[link_name]. All places where #[link_name] is allowed + // shouldn't allow #[no_mangle], so #[link_name] shouldn't be a concern here, + // however currently #[no_mangle] is currently merely a warning on foreign + // items rather than a hard error, so we still need to take #[no_mangle] + + // #[link_name] into account. + // FIXME remove this comment once #[no_mangle] on foreign items is a hard error. + + if codegen_fn_attrs.symbol_name.is_none() { + codegen_fn_attrs.symbol_name = Some(name); + } } else { tcx.dcx() .span_delayed_bug(*attr_span, "no_mangle should be on a named function"); @@ -429,6 +440,8 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code } // Foreign items by default use no mangling for their symbol name. + // Usually, `symbol_name` is controlled by `#[link_name]`/`#[export_name]`. Here we additionally + // set `symbol_name` on most foreign items so that their their symbol name does not get mangled. if tcx.is_foreign_item(did) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::FOREIGN_ITEM; @@ -444,16 +457,21 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code // Implementing an EII does the appropriate name resolution to make sure the implementations // get the same symbol name as the *mangled* foreign item they refer to so that's all good. } else if codegen_fn_attrs.symbol_name.is_some() { - // * This can be overridden with the `#[link_name]` attribute + // * If the name is already set by `#[link_name]`, we don't overwrite it. + } else if codegen_fn_attrs.link_ordinal.is_some() { + // * `#[link_ordinal]` and `#[link_name]` are incompatible with each other, so + // disable the implicit `#[link_name]` for foreign items below to avoid an + // error. } else { + // This effectively adds an implicit `#[link_name = ""]`. // NOTE: there's one more exception that we cannot apply here. On wasm, // some items cannot be `no_mangle`. // However, we don't have enough information here to determine that. // As such, no_mangle foreign items on wasm that have the same defid as some // import will *still* be mangled despite this. // - // if none of the exceptions apply; apply no_mangle - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; + // if none of the exceptions apply; do not mangle the symbol name + codegen_fn_attrs.symbol_name = Some(tcx.item_name(did)); } } } @@ -552,22 +570,24 @@ fn handle_lang_items( // strippable by the linker. // // Additionally weak lang items have predetermined symbol names. - if let Some(lang_item) = lang_item + let link_name_override = if let Some(lang_item) = lang_item && let Some(link_name) = lang_item.link_name() { codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; - codegen_fn_attrs.symbol_name = Some(link_name); - } + Some(link_name) + } else { + None + }; - // error when using no_mangle on a lang item item + // error when using no_mangle, or export_name on a lang item item if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) - && codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) + && codegen_fn_attrs.symbol_name.is_some() { let mut err = tcx .dcx() .struct_span_err( interesting_spans.no_mangle.unwrap_or_default(), - "`#[no_mangle]` cannot be used on internal language items", + "`#[no_mangle]` and `#[export_name]` cannot be used on internal language items", ) .with_note("Rustc requires this item to have a specific mangled name.") .with_span_label(tcx.def_span(did), "should be the internal language item"); @@ -583,6 +603,10 @@ fn handle_lang_items( } err.emit(); } + + if let Some(link_name_override) = link_name_override { + codegen_fn_attrs.symbol_name = Some(link_name_override); + } } /// Generate the [`CodegenFnAttrs`] for an item (identified by the [`LocalDefId`]). diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index c5f3665383e21..3b2d81bc48ff0 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -370,7 +370,7 @@ pub fn internal_target_features<'a, const N: usize>( } // Check feature stability. - if let Stability::InternalOnly { reason, hard_error } = stability { + if let Stability::InternalOnly { reason, hard_error, .. } = stability { let diag = diagnostics::InternalOnlyCTargetFeature { feature: base_feature, enabled: if enable { "enabled" } else { "disabled" }, diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 1c64a3cf877b6..9acfad1fb2a5e 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -319,10 +319,12 @@ pub trait BuilderMethods<'a, 'tcx>: fn range_metadata(&mut self, load: Self::Value, range: WrappingRange); fn nonnull_metadata(&mut self, load: Self::Value); - fn store(&mut self, val: Self::Value, ptr: Self::Value, align: Align) -> Self::Value; - fn store_to_place(&mut self, val: Self::Value, place: PlaceValue) -> Self::Value { + fn store(&mut self, val: Self::Value, ptr: Self::Value, align: Align) { + self.store_with_flags(val, ptr, align, MemFlags::empty()) + } + fn store_to_place(&mut self, val: Self::Value, place: PlaceValue) { assert_eq!(place.llextra, None); - self.store(val, place.llval, place.align) + self.store(val, place.llval, place.align); } fn store_with_flags( &mut self, @@ -330,13 +332,13 @@ pub trait BuilderMethods<'a, 'tcx>: ptr: Self::Value, align: Align, flags: MemFlags, - ) -> Self::Value; + ); fn store_to_place_with_flags( &mut self, val: Self::Value, place: PlaceValue, flags: MemFlags, - ) -> Self::Value { + ) { assert_eq!(place.llextra, None); self.store_with_flags(val, place.llval, place.align, flags) } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 1e08e9b3ddf36..522437ab1b0a8 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -14,9 +14,9 @@ use rustc_infer::infer::{self, BoundRegionConversionTime, InferCtxt, TyCtxtInfer use rustc_infer::traits::{TraitErrors, util}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ - self, BottomUpFolder, GenericArgs, GenericParamDefKind, Generics, Ty, TyCtxt, TypeFoldable, - TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, - Unnormalized, Upcast, + self, BottomUpFolder, CallerBoundsIterator, GenericArgs, GenericParamDefKind, Generics, Ty, + TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, + TypeVisitor, TypingMode, Unnormalized, Upcast, }; use rustc_span::{BytePos, DUMMY_SP, Span, bug, kw, span_bug}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; @@ -2777,7 +2777,7 @@ fn param_env_with_gat_bounds<'tcx>( ) -> ty::ParamEnv<'tcx> { let param_env = tcx.param_env(impl_ty.def_id); let container_id = impl_ty.container_id(tcx); - let mut clauses = param_env.caller_bounds().collect::>(); + let mut clauses = param_env.caller_bounds().all_clauses(tcx).iter().collect::>(); // for RPITITs, we should install predicates that allow us to project all // of the RPITITs associated with the same body. This is because checking diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 62df20baa9265..f4b4e50400530 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -29,9 +29,9 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::region_constraint::{And, LeafRegionConstraint, Or}; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ - self, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFlags, TypeFoldable, - TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, - Upcast, + self, CallerBoundsIterator, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, + TypeFlags, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, + TypingMode, Unnormalized, Upcast, }; use rustc_session::diagnostics::feature_err; use rustc_span::{DUMMY_SP, Span, bug, span_bug, sym}; @@ -577,7 +577,8 @@ fn augment_param_env<'tcx>( return param_env; } - let bounds = param_env.caller_bounds().chain(new_clauses.iter().copied()); + let bounds = + param_env.caller_bounds().all_clauses(tcx).iter().chain(new_clauses.iter().copied()); // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this // i.e. traits::normalize_param_env_or_error ty::ParamEnv::new(tcx, bounds) diff --git a/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs index 4d131b73f9cf1..d76e7d4dc7bf3 100644 --- a/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs @@ -1113,6 +1113,13 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let msg = { let def_kind = self.tcx.def_descr(self.def_id); let (quantifier, bound) = self.get_quantifier_and_bound(); + if let hir::def::DefKind::AssocFn | hir::def::DefKind::AssocTy = + self.tcx.def_kind(self.def_id) + { + spans.push_span_context( + self.tcx.def_span(self.tcx.parent(self.def_id)).shrink_to_lo(), + ); + } let params = if bound == 0 { String::new() diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 7db3c4a4d6eea..cd3ad364fe1fc 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -19,7 +19,8 @@ use rustc_hir_analysis::hir_ty_lowering::{ use rustc_infer::infer::{self, RegionVariableOrigin}; use rustc_infer::traits::{DynCompatibilityViolation, Obligation, TraitErrors}; use rustc_middle::ty::{ - self, CantBeErased, Const, Flags, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized, + self, CallerBoundsIterator, CantBeErased, Const, Flags, Ty, TyCtxt, TypeVisitableExt, + TypingMode, Unnormalized, }; use rustc_session::Session; use rustc_span::def_id::LocalModId; @@ -306,14 +307,19 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { // HACK(eddyb) should get the original `Span`. let span = tcx.def_span(def_id); - ty::EarlyBinder::bind_iter(tcx.arena.alloc_from_iter( - self.param_env.caller_bounds().filter_map(|clause| match clause.kind().skip_binder() { - ty::ClauseKind::Trait(data) if data.self_ty().is_param(index) => { - Some((ty::set_aliases_to_non_rigid(tcx, clause).skip_norm_wip(), span)) - } - _ => None, - }), - )) + ty::EarlyBinder::bind_iter( + tcx.arena.alloc_from_iter( + self.param_env + .caller_bounds() + .trait_clauses(tcx) + .validate_self_ty(|actual_self_ty| actual_self_ty.is_param(index)) + .interned() + .iter() + .map(|trait_clause| { + (ty::set_aliases_to_non_rigid(tcx, trait_clause).skip_norm_wip(), span) + }), + ), + ) } fn select_inherent_assoc_candidates( diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 4dc94d013eb55..b20115a6df556 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -22,8 +22,8 @@ use rustc_middle::middle::stability; use rustc_middle::ty::elaborate::supertrait_def_ids; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type}; use rustc_middle::ty::{ - self, AssocContainer, AssocItem, GenericArgs, GenericParamDefKind, ParamEnvAnd, Ty, TyCtxt, - TypeVisitableExt, Unnormalized, Upcast, + self, AssocContainer, AssocItem, CallerBoundsIterator, GenericArgs, GenericParamDefKind, + ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt, Unnormalized, Upcast, }; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::edit_distance::{ @@ -1042,22 +1042,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // We use `DeepRejectCtxt` here which may return false positive on where clauses // with alias self types. We need to later on reject these as inherent candidates // in `consider_probe`. - let bounds = self.param_env.caller_bounds().filter_map(|clause| { - let bound_clause = clause.kind(); - match bound_clause.skip_binder() { - ty::ClauseKind::Trait(trait_predicate) => DeepRejectCtxt::relate_rigid_rigid(tcx) - .types_may_unify(param_ty, trait_predicate.trait_ref.self_ty()) - .then(|| bound_clause.rebind(trait_predicate.trait_ref)), - ty::ClauseKind::RegionOutlives(_) - | ty::ClauseKind::TypeOutlives(_) - | ty::ClauseKind::Projection(_) - | ty::ClauseKind::ConstArgHasType(_, _) - | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) - | ty::ClauseKind::UnstableFeature(_) - | ty::ClauseKind::HostEffect(..) => None, - } - }); + let bounds = self.param_env.caller_bounds().trait_clauses(tcx).iter().filter_map( + |bound_trait_clause| { + let trait_clause = bound_trait_clause.skip_binder(); + DeepRejectCtxt::relate_rigid_rigid(tcx) + .types_may_unify(param_ty, trait_clause.trait_ref.self_ty()) + .then(|| bound_trait_clause.rebind(trait_clause.trait_ref)) + }, + ); self.assemble_candidates_for_bounds(bounds, |this, poly_trait_ref, item| { this.push_candidate( diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 75c178d4632be..f16af905017d1 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -5,6 +5,7 @@ use std::iter; use rustc_data_structures::undo_log::UndoLogs; use rustc_middle::traits::query::OutlivesBound; use rustc_middle::ty; +use rustc_type_ir::CallerBoundsIterator; use tracing::instrument; use self::env::OutlivesEnvironment; @@ -25,7 +26,8 @@ pub fn explicit_outlives_bounds<'tcx>( ) -> impl Iterator> { param_env .caller_bounds() - .into_iter() + .non_trait_clauses() + .iter() .filter_map(ty::Clause::as_region_outlives_clause) .filter_map(ty::Binder::no_bound_vars) .map(|ty::OutlivesClause(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a)) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 7a6a49f37278a..6c650f44aff8b 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -470,6 +470,11 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se is_nightly_build, is_crt_static, ); + util::add_target_modifiers( + &mut sess.early_sess.opts.target_modifiers, + &target_config, + &sess.early_sess.target, + ); sess.check_config = parse_check_cfg(&sess, config.crate_check_cfg); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 7df2ede5053b2..6dc3f74f054f1 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -36,7 +36,7 @@ use rustc_parse::lexer::StripTokens; use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; use rustc_passes::{abi_test, input_stats, layout_test}; use rustc_resolve::{Resolver, ResolverOutputs}; -use rustc_session::config::{Input, OutFileName, OutputFilenames, OutputType}; +use rustc_session::config::{Input, Offload, OutFileName, OutputFilenames, OutputType}; use rustc_session::diagnostics::feature_err; use rustc_session::output::{filename_for_input, invalid_output_for_target}; use rustc_session::search_paths::PathKind; @@ -1485,6 +1485,16 @@ pub fn collect_crate_types( } } + // GPU code is never run as a binary; the offload runtime looks up kernels by + // name, and only cdylibs export their symbols. + if session.opts.unstable_opts.offload.iter().any(|o| matches!(o, Offload::Device(_))) { + for crate_type in &mut base { + if *crate_type == CrateType::Executable { + *crate_type = CrateType::Cdylib; + } + } + } + base.retain(|crate_type| { if invalid_output_for_target(session, *crate_type) { session.dcx().emit_warn(diagnostics::UnsupportedCrateTypeForTarget { diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 06f354fef2413..53f62e8d8c04c 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -1,4 +1,5 @@ use std::any::Any; +use std::collections::BTreeMap; use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; use std::num::NonZero; use std::path::{Path, PathBuf}; @@ -23,7 +24,8 @@ use rustc_middle::ty::{CurrentGcx, TyCtxt}; use rustc_query_impl::{CollectActiveJobsKind, collect_active_query_jobs}; pub use rustc_session::config::DEFAULT_STACK_SIZE; use rustc_session::config::{ - Cfg, Jobs, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple, + Cfg, Jobs, OptionsTargetModifiers, OutFileName, OutputFilenames, OutputTypes, Sysroot, + host_tuple, }; use rustc_session::{EarlyDiagCtxt, EarlySession, IncrCompSession, Session, filesearch}; use rustc_span::edition::Edition; @@ -39,8 +41,7 @@ use crate::passes::parse_crate_name; /// Function pointer type that constructs a new CodegenBackend. type MakeBackendFn = fn() -> Box; -/// Adds `target_feature = "..."` cfgs for a variety of platform -/// specific features (SSE, NEON etc.). +/// Adds `cfg` values based on the current target configuration (in particular for target features). /// /// This is performed by checking whether a set of permitted features /// is available on the target machine, by querying the `TargetConfig` from the codegen backend. @@ -56,9 +57,9 @@ pub(crate) fn add_configuration( target .rust_target_features() .iter() - .filter_map(|(feature, gate, _)| { - if gate.in_cfg() - && (is_nightly_build || gate.requires_nightly(/* in_cfg */ true).is_none()) + .filter_map(|(feature, stab, _)| { + if stab.in_cfg() + && (is_nightly_build || stab.requires_nightly(/* in_cfg */ true).is_none()) { Some(Symbol::intern(feature)) } else { @@ -90,6 +91,26 @@ pub(crate) fn add_configuration( } } +/// Populates the target modifier database based on the current target. +pub(crate) fn add_target_modifiers( + tmod: &mut BTreeMap, + target_config: &TargetConfig, + target: &Target, +) { + // Record relevant target features as target modifier. + // Join all target-modifier target features into a single comma-separated string, + // sorted by the order they appear in in `rust_target_features`. + let target_feature_modifier = target + .rust_target_features() + .iter() + .filter(|(_, stab, _)| stab.is_target_modifier()) + .map(|(feature, ..)| *feature) + .filter(|feature| target_config.internal_target_features.contains(&Symbol::intern(feature))) + .collect::>() + .join(","); + tmod.insert(OptionsTargetModifiers::TargetFeatures, target_feature_modifier); +} + /// Ensures that all target features required by the ABI are present. /// Must be called after `internal_target_features` has been populated! pub(crate) fn check_abi_required_features(sess: &Session) { diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 14faf032799b6..67a8c814c2abb 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -76,23 +76,11 @@ struct ClashingExternDeclarations { seen_decls: UnordMap, } -/// Differentiate between whether the name for an extern decl came from the link_name attribute or -/// just from declaration itself. This is important because we don't want to report clashes on -/// symbol name if they don't actually clash because one or the other links against a symbol with a -/// different name. -enum SymbolName { - /// The name of the symbol + the span of the annotation which introduced the link name. - Link(Symbol, Span), - /// No link name, so just the name of the symbol. - Normal(Symbol), -} - -impl SymbolName { - fn get_name(&self) -> Symbol { - match self { - SymbolName::Link(s, _) | SymbolName::Normal(s) => *s, - } - } +struct SymbolName { + /// The name of the symbol that will be linked against. + link_name: Symbol, + /// The span of the annotation which introduced the link name. + span: Option, } impl ClashingExternDeclarations { @@ -139,7 +127,7 @@ impl ClashingExternDeclarations { // Finally, emit the diagnostic. let this = tcx.item_name(this_fi.owner_id.to_def_id()); - let orig = orig.get_name(); + let orig = orig.link_name; let previous_decl_label = get_relevant_span(tcx, existing_did); let mismatch_label = get_relevant_span(tcx, this_fi.owner_id); let sub = @@ -175,28 +163,24 @@ impl ClashingExternDeclarations { /// the name specified in a #[link_name = ...] attribute if one was specified, else, just the /// symbol's name. fn name_of_extern_decl(tcx: TyCtxt<'_>, fi: hir::OwnerId) -> SymbolName { - if let Some((overridden_link_name, overridden_link_name_span)) = - tcx.codegen_fn_attrs(fi).symbol_name.map(|overridden_link_name| { - // FIXME: Instead of searching through the attributes again to get span - // information, we could have codegen_fn_attrs also give span information back for - // where the attribute was defined. However, until this is found to be a - // bottleneck, this does just fine. - (overridden_link_name, find_attr!(tcx, fi, LinkName {span, ..} => *span).unwrap()) - }) - { - SymbolName::Link(overridden_link_name, overridden_link_name_span) - } else { - SymbolName::Normal(tcx.item_name(fi.to_def_id())) + // FIXME if symbol_name is not set, this is likely a #[rustc_std_internal_symbol] or EII which + // actually have their name mangled and thus should use the mangled name here. + let link_name = + tcx.codegen_fn_attrs(fi).symbol_name.unwrap_or_else(|| tcx.item_name(fi.to_def_id())); + SymbolName { + link_name, + // FIXME: Instead of searching through the attributes again to get span + // information, we could have codegen_fn_attrs also give span information back for + // where the attribute was defined. However, until this is found to be a + // bottleneck, this does just fine. + span: find_attr!(tcx, fi, LinkName {span, ..} => *span), } } /// We want to ensure that we use spans for both decls that include where the /// name was defined, whether that was from the link_name attribute or not. fn get_relevant_span(tcx: TyCtxt<'_>, fi: hir::OwnerId) -> Span { - match name_of_extern_decl(tcx, fi) { - SymbolName::Normal(_) => tcx.def_span(fi), - SymbolName::Link(_, annot_span) => annot_span, - } + if let Some(span) = name_of_extern_decl(tcx, fi).span { span } else { tcx.def_span(fi) } } /// Checks whether two types are structurally the same enough that the declarations shouldn't diff --git a/compiler/rustc_llvm/llvm-wrapper/offload/OffloadWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/offload/OffloadWrapper.cpp index 5c0fabb3fcee8..6a51e58f896be 100644 --- a/compiler/rustc_llvm/llvm-wrapper/offload/OffloadWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/offload/OffloadWrapper.cpp @@ -1,29 +1,22 @@ #include "../SuppressLLVMWarnings.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Bitcode/BitcodeReader.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Frontend/Offloading/OffloadWrapper.h" #include "llvm/Frontend/Offloading/Utility.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" -#include "llvm/MC/TargetRegistry.h" -#include "llvm/Support/CodeGen.h" #include "llvm/Support/Error.h" -#include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBufferRef.h" +#include "llvm/Support/Path.h" #include "llvm/Support/Program.h" +#include "llvm/Support/Regex.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/TargetParser/Triple.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/ValueMapper.h" @@ -34,18 +27,6 @@ using namespace llvm; -static Error writeFile(StringRef Filename, StringRef Data) { - Expected> OutputOrErr = - FileOutputBuffer::create(Filename, Data.size()); - if (!OutputOrErr) - return OutputOrErr.takeError(); - std::unique_ptr Output = std::move(*OutputOrErr); - llvm::copy(Data, Output->getBufferStart()); - if (Error E = Output->commit()) - return E; - return Error::success(); -} - // Clone OldFn into NewFn, remapping its arguments to RebuiltArgs. // Each arg of OldFn is replaced with the corresponding value in RebuiltArgs. // For scalars, RebuiltArgs contains the value cast and/or truncated to the @@ -96,37 +77,44 @@ static bool reportAndFailWrappingImages(Error E, const char *What) { return false; } +/// Returns the target architecture (e.g. "sm_86") named by the `.target` +/// directive of the given PTX text. The result points into `PtxBuf`. +static Expected getPtxArch(MemoryBufferRef PtxBuf) { + const Regex TargetRe("^\\.target[[:space:]]+([^,[:space:]]+)", + Regex::Newline); + + SmallVector M; + if (!TargetRe.match(PtxBuf.getBuffer(), &M)) + return createStringError("no .target directive in %s", + PtxBuf.getBufferIdentifier().str().c_str()); + + return M[1]; +} + static Expected> -assembleWithPtxas(StringRef Ptx, StringRef Arch) { +assembleWithPtxas(MemoryBufferRef PtxBuf) { + Expected ArchOrErr = getPtxArch(PtxBuf); + if (!ArchOrErr) + return ArchOrErr.takeError(); + const ErrorOr Ptxas = sys::findProgramByName("ptxas"); if (!Ptxas) return createStringError(Ptxas.getError(), "ptxas not found in PATH"); - SmallString<128> PtxFilePath; - if (std::error_code E = - sys::fs::createTemporaryFile("rust-offload", "ptx", PtxFilePath)) - return errorCodeToError(E); - SmallString<128> CubinFilePath; if (std::error_code E = sys::fs::createTemporaryFile("rust-offload", "cubin", CubinFilePath)) return errorCodeToError(E); auto Cleanup = scope_exit([&] { - if (std::error_code E = sys::fs::remove(PtxFilePath)) - (void)reportAndFailWrappingImages( - errorCodeToError(E), "assembleWithPtxas: PtxFilePath cleanup"); if (std::error_code E = sys::fs::remove(CubinFilePath)) (void)reportAndFailWrappingImages( errorCodeToError(E), "assembleWithPtxas: CubinFilePath cleanup"); }); - if (Error E = writeFile(PtxFilePath, Ptx)) - return std::move(E); - const StringRef Args[] = { - *Ptxas, "-m64", "-O3", "--gpu-name", - Arch, "--output-file", CubinFilePath, PtxFilePath, + *Ptxas, "-m64", "-O3", "--gpu-name", + *ArchOrErr, "--output-file", CubinFilePath, PtxBuf.getBufferIdentifier(), }; std::string ErrorMsg; @@ -145,130 +133,37 @@ assembleWithPtxas(StringRef Ptx, StringRef Arch) { return std::move(*CubinOrError); } -static Expected> -linkWithRustLld(StringRef Obj, StringRef LldPath) { - SmallString<128> ObjFilePath; - if (std::error_code E = - sys::fs::createTemporaryFile("rust-offload", "o", ObjFilePath)) - return errorCodeToError(E); - - SmallString<128> SoFilePath; - if (std::error_code E = - sys::fs::createTemporaryFile("rust-offload", "so", SoFilePath)) - return errorCodeToError(E); - - auto Cleanup = scope_exit([&] { - if (std::error_code E = sys::fs::remove(ObjFilePath)) - (void)reportAndFailWrappingImages(errorCodeToError(E), - "linkWithRustLld: ObjFilePath cleanup"); - if (std::error_code E = sys::fs::remove(SoFilePath)) - (void)reportAndFailWrappingImages(errorCodeToError(E), - "linkWithRustLld: SoFilePath cleanup"); - }); - - if (Error E = writeFile(ObjFilePath, Obj)) - return std::move(E); - - const StringRef Args[] = { - LldPath, "-flavor", "gnu", "-shared", - "--no-undefined", "-o", SoFilePath, ObjFilePath, - }; - - std::string ErrorMsg; - const int Status = - sys::ExecuteAndWait(LldPath, Args, std::nullopt, {}, 0, 0, &ErrorMsg); - - if (Status != 0) - return createStringError("linkWithRustLld: status %d: %s", Status, - ErrorMsg.c_str()); - - ErrorOr> ElfOrError = - MemoryBuffer::getFileAsStream(SoFilePath); - if (!ElfOrError) - return errorCodeToError(ElfOrError.getError()); - - return std::move(*ElfOrError); -} - -static Expected> -compileDeviceImage(MemoryBufferRef Input, const char *LldPath) { - LLVMContext Ctx; - Expected> ModOrErr = parseBitcodeFile(Input, Ctx); - if (!ModOrErr) - return ModOrErr.takeError(); - Module &M = **ModOrErr; - - const Triple &DeviceTriple = M.getTargetTriple(); - StringRef Arch; - for (Function &F : M) - if (F.hasFnAttribute("target-cpu")) { - Arch = F.getFnAttribute("target-cpu").getValueAsString(); - break; - } - - if (Arch.empty()) - return createStringError("no target-cpu attribute in device bitcode"); - - std::string ErrorMsg; - const Target *DeviceTarget = - TargetRegistry::lookupTarget(DeviceTriple, ErrorMsg); - if (!DeviceTarget) - return createStringError(ErrorMsg); - - std::unique_ptr TM(DeviceTarget->createTargetMachine( - DeviceTriple, Arch, /*Features=*/"", TargetOptions(), Reloc::PIC_)); - if (!TM) - return createStringError("createTargetMachine failed for %s", - DeviceTriple.str().c_str()); - - const bool IsNvptx = DeviceTriple.isNVPTX(); - - legacy::PassManager PM; - SmallString<0> Emitted; - raw_svector_ostream OS(Emitted); - const CodeGenFileType FileType = - IsNvptx ? CodeGenFileType::AssemblyFile : CodeGenFileType::ObjectFile; - if (TM->addPassesToEmitFile(PM, OS, nullptr, FileType)) - return createStringError("target %s cannot emit %s", - DeviceTriple.str().c_str(), - IsNvptx ? "assembly" : "object"); - - PM.run(**ModOrErr); - - if (IsNvptx) - return assembleWithPtxas(Emitted, Arch); - if (DeviceTriple.isAMDGPU()) { - if (!LldPath || !*LldPath) - return createStringError("rust-lld path was not provided for %s", - DeviceTriple.str().c_str()); - return linkWithRustLld(Emitted, LldPath); - } - - return createStringError("unsupported offload target %s", - DeviceTriple.str().c_str()); -} - extern "C" bool LLVMRustOffloadWrapImages(LLVMModuleRef HostMRef, - const char *LldPath, - const char *DeviceBitcodePath) { + const char *DeviceImagePath) { Module &M = *unwrap(HostMRef); if (!hasOffloadEntries(M)) return true; ErrorOr> BufOrErr = - MemoryBuffer::getFile(DeviceBitcodePath); + MemoryBuffer::getFile(DeviceImagePath); if (std::error_code EC = BufOrErr.getError()) - return reportAndFailWrappingImages(createFileError(DeviceBitcodePath, EC), - "device bitcode"); + return reportAndFailWrappingImages(createFileError(DeviceImagePath, EC), + "device image"); std::unique_ptr Buf = std::move(*BufOrErr); - Expected> ImageOrErr = - compileDeviceImage(Buf->getMemBufferRef(), LldPath); - if (!ImageOrErr) - return reportAndFailWrappingImages(ImageOrErr.takeError(), - "device compile"); + std::unique_ptr DeviceImage; + StringRef Ext = sys::path::extension(DeviceImagePath); + if (Ext == ".ptx") { + Expected> CubinOrErr = + assembleWithPtxas(Buf->getMemBufferRef()); + if (!CubinOrErr) + return reportAndFailWrappingImages(CubinOrErr.takeError(), "ptxas"); + DeviceImage = std::move(*CubinOrErr); + } else if (Ext == ".elf") { + DeviceImage = std::move(Buf); + } else { + return reportAndFailWrappingImages( + createStringError("unsupported device image %s: expected .ptx or .elf", + DeviceImagePath), + "device image path"); + } - StringRef ImageBuf = (*ImageOrErr)->getBuffer(); + StringRef ImageBuf = DeviceImage->getBuffer(); ArrayRef Image(ImageBuf.data(), ImageBuf.size()); if (Error E = offloading::wrapOpenMPBinaries( diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index df15f7d159866..70302bbef51cb 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -12,7 +12,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::owned_slice::OwnedSlice; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{self, FreezeReadGuard, FreezeWriteGuard}; -use rustc_data_structures::unord::UnordMap; +use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_expand::base::SyntaxExtension; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE, LocalDefId, StableCrateId}; use rustc_hir::definitions::{DefPathData, Definitions}; @@ -361,6 +361,61 @@ impl CStore { return; } let extern_crate = data.name(); + + if prefix.is_empty() { + // A synthetic target modifier, does not correspond to an actual flag. + match opt_name.as_str() { + "target-feature" => { + // Compute the features we have locally that don't exist in the other crate, + // and the features the other crate has that are missing locally. + let mut local_features = FxHashSet::from_iter( + flag_local_value.unwrap().split(",").filter(|s| !s.is_empty()), + ); + let mut extern_features = FxHashSet::from_iter( + flag_extern_value.unwrap().split(",").filter(|s| !s.is_empty()), + ); + #[allow(rustc::potential_query_instability)] // we are sorting below + let both_features = FxHashSet::from_iter( + local_features.intersection(&extern_features).copied(), + ); + #[allow(rustc::potential_query_instability)] // we are sorting below + for feature in both_features { + local_features.remove(feature); + extern_features.remove(feature); + } + let local_features = + UnordSet::from(local_features).into_sorted_stable_ord(); + let extern_features = + UnordSet::from(extern_features).into_sorted_stable_ord(); + assert!(local_features.len() > 0 || extern_features.len() > 0); + + let diag = format!( + "mixing target features will cause an ABI mismatch in crate `{local_crate}`" + ); + let mut diag = tcx.dcx().struct_warn(diag); + diag.help("some target features modify the ABI so Rust crates compiled with different values for these target features cannot be used together safely"); + if local_features.len() > 0 { + let features = local_features.join(", "); + let before = + if local_features.len() == 1 { "feature" } else { "features" }; + let after = if local_features.len() == 1 { "is" } else { "are" }; + diag.help(format!("the target {before} {features} {after} enabled in this crate but disabled in `{extern_crate}`")); + } + if extern_features.len() > 0 { + let features = extern_features.join(", "); + let before = + if extern_features.len() == 1 { "feature" } else { "features" }; + let after = if extern_features.len() == 1 { "is" } else { "are" }; + diag.help(format!("the target {before} {features} {after} enabled in `{extern_crate}` but disabled in this crate")); + } + diag.help("if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=target-feature` to silence this warning"); + diag.emit(); + } + _ => panic!("unhandled synthetic target feature {opt_name}"), + } + return; + } + let flag_name = opt_name.clone(); let flag_name_prefixed = format!("-{}{}", prefix, opt_name); diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index fc5345b0b0b92..b10ce28446c76 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -38,10 +38,6 @@ impl<'tcx> TyCtxt<'tcx> { if let InstanceKind::Shim(ShimKind::Reify(_, _)) = instance_kind && attrs.flags.contains(CodegenFnAttrFlags::TRACK_CALLER) { - if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { - attrs.to_mut().flags.remove(CodegenFnAttrFlags::NO_MANGLE); - } - if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) { attrs.to_mut().flags.remove(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); } @@ -189,9 +185,6 @@ bitflags::bitflags! { /// `#[naked]`: an indicator to LLVM that no function prologue/epilogue /// should be generated. const NAKED = 1 << 2; - /// `#[no_mangle]`: an indicator that the function's name should be the same - /// as its symbol. - const NO_MANGLE = 1 << 3; /// `#[rustc_std_internal_symbol]`: an indicator that this symbol is a /// "weird symbol" for the standard library in that it has slightly /// different linkage, visibility, and reachability rules. @@ -278,8 +271,7 @@ impl CodegenFnAttrs { return false; } - self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) - || self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) + self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) // note: for these we do also set a symbol name so technically also handled by the // condition below. However, I think that regardless these should be treated as extern. || self.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 406a42c2b9a80..8de81ccd1e2fb 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1030,7 +1030,10 @@ pub struct ParamEnv<'tcx> { static_assert_size!(ParamEnv<'_>, std::mem::size_of::()); impl<'tcx> rustc_type_ir::inherent::ParamEnv> for ParamEnv<'tcx> { - fn caller_bounds(self) -> impl Iterator> { + #[inline] + fn caller_bounds( + self, + ) -> CallerBoundsAccessor, impl Iterator>, NoClauses> { self.caller_bounds() } } @@ -1048,8 +1051,10 @@ impl<'tcx> ParamEnv<'tcx> { } #[inline] - pub fn caller_bounds(self) -> impl Iterator> + Clone { - self.caller_bounds.iter() + pub fn caller_bounds( + self, + ) -> CallerBoundsAccessor, impl Iterator>, NoClauses> { + CallerBoundsAccessor::new(self.caller_bounds.iter()) } #[inline] @@ -1078,7 +1083,12 @@ impl<'tcx> ParamEnv<'tcx> { if tcx.next_trait_solver_globally() { self } else { - ParamEnv::new(tcx, tcx.reveal_opaque_types_in_bounds(self.caller_bounds).iter()) + ParamEnv::new( + tcx, + tcx.reveal_opaque_types_in_bounds( + tcx.mk_clauses_from_iter(self.caller_bounds().all_clauses(tcx).iter()), + ), + ) } } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index b7719ec0598de..2a417812dd22e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -18,7 +18,8 @@ use rustc_type_ir::TyKind::*; use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::walk::TypeWalker; use rustc_type_ir::{ - self as ir, BoundVar, CollectAndApply, MayBeErased, TypeVisitableExt, elaborate, + self as ir, BoundVar, CallerBoundsIterator, CollectAndApply, MayBeErased, TypeVisitableExt, + elaborate, }; use tracing::instrument; use ty::util::IntTypeExt; @@ -327,7 +328,7 @@ impl ParamConst { #[instrument(level = "debug")] pub fn find_const_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> { - let mut candidates = env.caller_bounds().filter_map(|clause| { + let mut candidates = env.caller_bounds().non_trait_clauses().iter().filter_map(|clause| { // `ConstArgHasType` are never desugared to be higher ranked. match clause.kind().skip_binder() { ty::ClauseKind::ConstArgHasType(param_ct, ty) => { diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 4986d569349ff..978dda3d977b2 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -3,7 +3,7 @@ use rustc_abi::ExternAbi; use rustc_hir::def_id::DefId; use rustc_lint_defs::builtin::FUNCTION_ITEM_REFERENCES; use rustc_middle::mir::*; -use rustc_middle::ty::{self, EarlyBinder, GenericArgs, Ty, TyCtxt}; +use rustc_middle::ty::{self, CallerBoundsIterator, EarlyBinder, GenericArgs, Ty, TyCtxt}; use rustc_span::{Span, Spanned, sym}; use crate::diagnostics; @@ -78,8 +78,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { source_info: SourceInfo, ) { let param_env = self.tcx.param_env(def_id); - let bounds = param_env.caller_bounds(); - for bound in bounds { + for bound in param_env.caller_bounds().all_clauses(self.tcx).iter() { if let Some(bound_ty) = self.is_pointer_trait(bound) { // Get the argument types as they appear in the function signature. let arg_defs = 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 a06b0625654c2..cd52ab3098cb4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -14,9 +14,9 @@ use rustc_type_ir::solve::{ RerunNonErased, RerunReason, RerunResultExt, SizedTraitKind, StalledOnCoroutines, }; use rustc_type_ir::{ - self as ty, AliasTy, Const, Interner, MayBeErased, Region, TypeFlags, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, - TypingMode, Unnormalized, Upcast, elaborate, + self as ty, AliasTy, CallerBoundsIterator, Const, Interner, MayBeErased, Region, TypeFlags, + TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, Upcast, elaborate, }; use tracing::{debug, instrument}; @@ -739,7 +739,7 @@ where ) -> Result<(), RerunNonErased> { let goal_lang_item = self.cx().as_trait_lang_item(goal.predicate.trait_def_id(self.cx())); - for assumption in goal.param_env.caller_bounds() { + for assumption in goal.param_env.caller_bounds().all_clauses(self.cx()).iter() { match G::fast_reject_assumption(self, goal, goal_lang_item, assumption) { Ok(()) => { match G::probe_and_consider_param_env_candidate(self, goal, assumption)? { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 9ac479e8abe51..168c0ec8e803b 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -67,9 +67,11 @@ macro_rules! hash_substruct { /// Target modifier enum value + user value ('2') from external crate /// is converted into description: prefix ('Z'), name ('regparm'), tech value ('Some(2)'). pub struct ExtendedTargetModifierInfo { - /// Flag prefix (usually, 'C' for codegen flags or 'Z' for unstable flags) + /// Flag prefix (usually, 'C' for codegen flags or 'Z' for unstable flags). And empty string + /// indicates a synthetic target modifier, which does not correspond directly to a flag. pub prefix: String, - /// Flag name + /// Flag name. For synthetic features, this is still relevant as the name used to suppress + /// the error for mismatches involving this target modifier. pub name: String, /// Flag parsed technical value pub tech_value: String, @@ -205,6 +207,7 @@ impl TargetModifier { return target_modifier_consistency_check::target_cpu(sess, self, other); } }, + _ => {} }; match other { Some(other) => self.extend().tech_value == other.extend().tech_value, @@ -243,6 +246,9 @@ macro_rules! top_level_options { $tmod_variant($tmod_enum), )? )* + // Synthetic target modifiers, manually computed. + /// List of target features that are actually target modifiers. + TargetFeatures, } impl OptionsTargetModifiers { @@ -253,11 +259,23 @@ macro_rules! top_level_options { Self::$tmod_variant(v) => v.reparse(user_value), )? )* + + // Synthetic target modifiers. + Self::TargetFeatures => { + ExtendedTargetModifierInfo { + prefix: String::new(), + name: "target-feature".into(), + tech_value: format!("{:?}", user_value), + } + } + #[allow(unreachable_patterns)] _ => panic!("unknown target modifier option: {self:?}"), } } + /// Used by `-Cunsafe-allow-abi-mismatch` to determine whether this is a valid thing to + /// allow. pub fn is_target_modifier(flag_name: &str) -> bool { $( $( @@ -266,6 +284,12 @@ macro_rules! top_level_options { } )? )* + + // Synthetic target modifiers. The names must match `reparse` above. + if flag_name == "target-feature" { + return true; + } + false } } @@ -277,6 +301,8 @@ macro_rules! top_level_options { $(#[$attr])* pub $opt: $t, )* + /// Store values for target modifiers. `gather_target_modifiers` takes those values + /// to decide what to store in metadata. pub target_modifiers: BTreeMap, pub mitigation_coverage_map: mitigation_coverage::MitigationCoverageMap, } @@ -315,6 +341,7 @@ macro_rules! top_level_options { pub fn gather_target_modifiers(&self) -> Vec { let mut mods = Vec::::new(); + // Forward values from `self.target_modifiers` into `mods`. $( $( // Only expand for flags that have `TARGET_MODIFIER`. @@ -322,6 +349,7 @@ macro_rules! top_level_options { self.$opt.gather_target_modifiers(&mut mods, &self.target_modifiers); )? )* + tmod_push_impl(OptionsTargetModifiers::TargetFeatures, &self.target_modifiers, &mut mods); mods.sort_by(|a, b| a.opt.cmp(&b.opt)); mods } diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 9c465b409ca85..82732ef7f43b4 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -182,7 +182,6 @@ pub fn symbol_name_from_attrs<'tcx>( } } - // FIXME(eddyb) Precompute a custom symbol name based on attributes. let attrs = if tcx.def_kind(def_id).has_codegen_attrs() { &tcx.codegen_instance_attrs(instance_kind) } else { @@ -240,11 +239,6 @@ pub fn symbol_name_from_attrs<'tcx>( // Use provided name return Some(name.to_string()); } - - if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { - // Don't mangle - return Some(tcx.item_name(def_id).to_string()); - } } None diff --git a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs index 3b158c13521ea..d1810b6fa4860 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { max_atomic_width: Some(128), // As documented in https://developer.android.com/ndk/guides/cpu-features.html // the neon (ASIMD) and FP must exist on all android aarch64 targets. - features: "+v8a,+neon".into(), + features: "+v8a,+neon,+outline-atomics".into(), // the AAPCS64 expects use of non-leaf frame pointers per // https://github.com/ARM-software/abi-aa/blob/4492d1570eb70c8fd146623e0db65b2d241f12e7/aapcs64/aapcs64.rst#the-frame-pointer // and we tend to encounter interesting bugs in AArch64 unwinding code if we do not diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs index ce17280b153d6..db3cf83ddc999 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs @@ -3,7 +3,7 @@ use crate::spec::{Arch, Cc, FramePointer, LinkerFlavor, Lld, Target, TargetMetad pub(crate) fn target() -> Target { let mut base = base::windows_gnullvm::opts(); base.max_atomic_width = Some(128); - base.features = "+v8a,+neon".into(); + base.features = "+v8a,+neon,+outline-atomics".into(); base.linker = Some("aarch64-w64-mingw32-clang".into()); base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "arm64pe"]); diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs index 0d06bec21f4a4..e9f7f51a7a35b 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs @@ -3,7 +3,7 @@ use crate::spec::{Arch, FramePointer, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); base.max_atomic_width = Some(128); - base.features = "+v8a,+neon".into(); + base.features = "+v8a,+neon,+outline-atomics".into(); // Microsoft recommends enabling frame pointers on Arm64 Windows. // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs index 8ae72393b7cbf..2ece098734e71 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: Arch::AArch64, options: TargetOptions { - features: "+v8a".into(), + features: "+v8a,+outline-atomics".into(), max_atomic_width: Some(128), stack_probes: StackProbeType::Inline, supported_sanitizers: SanitizerSet::ADDRESS diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs index 8dede888055f7..19f996976e16c 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs @@ -5,7 +5,7 @@ use crate::spec::{ pub(crate) fn target() -> Target { let mut base = base::fuchsia::opts(); base.cpu = "generic".into(); - base.features = "+v8a,+crc,+aes,+sha2,+neon,+fix-cortex-a53-835769".into(); + base.features = "+v8a,+crc,+aes,+sha2,+neon,+fix-cortex-a53-835769,+outline-atomics".into(); base.max_atomic_width = Some(128); base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = SanitizerSet::ADDRESS diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs index e5e40cb38b911..14a2f007f1e8c 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: Arch::AArch64, options: TargetOptions { - features: "+v8a".into(), + features: "+v8a,+outline-atomics".into(), max_atomic_width: Some(128), stack_probes: StackProbeType::Inline, ..base::openbsd::opts() diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index b209fe188bf86..765512eb0b418 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -77,12 +77,15 @@ pub enum Stability { /// features are actually ABI configuration flags (such as "soft-float" on many targets). /// /// However, "internal" target features can still sometimes be enabled or disabled via - /// `-Ctarget-cpu` or Rust/LLVM target feature implications. Make sure nothing implies this - /// target feature and nothing is implied by this target feature (except for other internal-only - /// features). Ideally, ABI-relevant target features are pinned down (marked as required or - /// incompatible) in [`Target::abi_required_features`]. + /// `-Ctarget-cpu` or Rust/LLVM target feature implications. See `target_modifier` below for how + /// to protect ABI-relevant target features. InternalOnly { reason: &'static str, + /// Whether this target feature must be consistent across all crates in a crate graph. If + /// this is false, then either it should be fine for the target feature to differ across + /// crates, or the target feature is set by another flag that's already a target modifier, + /// or it needs to be pinned down via [`Target::abi_required_features`]. + target_modifier: bool, /// True if this is always an error, false if this can be reported as a warning when set via /// `-Ctarget-feature` (and a hard error when set via `#[target_feature]`). hard_error: bool, @@ -103,6 +106,11 @@ impl Stability { ) } + /// Returns whether this target feature is to be treated as a target modifier. + pub fn is_target_modifier(&self) -> bool { + matches!(self, Stability::InternalOnly { target_modifier: true, .. }) + } + /// Returns the nightly feature that is required to toggle this target feature via /// `#[target_feature]`/`-Ctarget-feature` or to test it via `cfg(target_feature)`. /// (For `cfg` we only care whether the feature is nightly or not, we don't require @@ -145,7 +153,7 @@ impl Stability { Stability::Unstable(_) | Stability::CfgStableToggleUnstable(_) | Stability::Stable { .. } => Ok(()), - Stability::InternalOnly { reason, hard_error: _ } => Err(reason), + Stability::InternalOnly { reason, .. } => Err(reason), } } } @@ -164,9 +172,9 @@ static ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("aes", Unstable(sym::arm_target_feature), &["neon"]), ( "atomics-32", - // Not implied by any CPU model or other feature. Stability::InternalOnly { reason: "unsound because it changes the ABI of atomic operations", + target_modifier: true, hard_error: false, }, &[], @@ -255,8 +263,11 @@ static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // We forbid directly toggling just `fp-armv8`; it must be toggled with `neon`. ( "fp-armv8", - // Pinned down by [`Target::abi_required_features`] when needed. - Stability::InternalOnly { reason: "Rust ties `fp-armv8` to `neon`", hard_error: false }, + Stability::InternalOnly { + reason: "unsound because it changes the ABI of float types", + target_modifier: true, + hard_error: false, + }, &[], ), // FEAT_FP8 @@ -323,8 +334,13 @@ static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("rdm", Stable, &["neon"]), ( "reserve-x18", - // Not implied by any CPU model or other feature; the compiler flag is a target modifier. - InternalOnly { reason: "use `-Zfixed-x18` compiler flag instead", hard_error: false }, + InternalOnly { + reason: "use `-Zfixed-x18` compiler flag instead", + // The compiler flag is already a target modifier so we don't need to track this again. + // Cannot be implicitly toggled via implications or CPU models. + target_modifier: false, + hard_error: false, + }, &[], ), // FEAT_SB @@ -507,27 +523,33 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("rdseed", Stable, &[]), ( "retpoline-external-thunk", - // Not implied by any CPU model or other feature; the compiler flag is a target modifier. Stability::InternalOnly { reason: "use `-Zretpoline-external-thunk` compiler flag instead", + // The compiler flag is already a target modifier so we don't need to track this again. + // Cannot be implicitly toggled via implications or CPU models. + target_modifier: false, hard_error: false, }, &[], ), ( "retpoline-indirect-branches", - // Not implied by any CPU model or other feature; the compiler flag is a target modifier. Stability::InternalOnly { reason: "use `-Zretpoline` compiler flag instead", + // The compiler flag is already a target modifier so we don't need to track this again. + // Cannot be implicitly toggled via implications or CPU models. + target_modifier: false, hard_error: false, }, &[], ), ( "retpoline-indirect-calls", - // Not implied by any CPU model or other feature; the compiler flag is a target modifier. Stability::InternalOnly { reason: "use `-Zretpoline` compiler flag instead", + // The compiler flag is already a target modifier so we don't need to track this again. + // Cannot be implicitly toggled via implications or CPU models. + target_modifier: false, hard_error: false, }, &[], @@ -539,8 +561,11 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("sm4", Stable, &["avx2"]), ( "soft-float", - // Pinned down by [`Target::abi_required_features`]. - Stability::InternalOnly { reason: "use a soft-float target instead", hard_error: false }, + Stability::InternalOnly { + reason: "use a soft-float target instead", + target_modifier: true, + hard_error: false, + }, &[], ), ("sse", Stable, &[]), @@ -604,8 +629,11 @@ static POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("altivec", Unstable(sym::powerpc_target_feature), &[]), ( "hard-float", - // Pinned down by [`Target::abi_required_features`]. - InternalOnly { reason: "unsupported ABI-configuration feature", hard_error: false }, + InternalOnly { + reason: "unsupported ABI-configuration feature", + target_modifier: true, + hard_error: false, + }, &[], ), ("msync", Unstable(sym::powerpc_target_feature), &[]), @@ -619,8 +647,11 @@ static POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("quadword-atomics", Unstable(sym::powerpc_target_feature), &[]), ( "spe", - // Pinned down by [`Target::abi_required_features`]. - InternalOnly { reason: "unsupported ABI-configuration feature", hard_error: false }, + InternalOnly { + reason: "unsupported ABI-configuration feature", + target_modifier: true, + hard_error: false, + }, &[], ), ("vsx", Unstable(sym::powerpc_target_feature), &["altivec"]), @@ -688,9 +719,9 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("f", Stable, &["zicsr"]), ( "forced-atomics", - // Not implied by any CPU model or other feature. Stability::InternalOnly { reason: "unsound because it changes the ABI of atomic operations", + target_modifier: true, hard_error: false, }, &[], @@ -957,8 +988,11 @@ const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("miscellaneous-extensions-3", Stable, &[]), ("miscellaneous-extensions-4", Stable, &[]), ("nnp-assist", Stable, &["vector"]), - // Pinned down by [`Target::abi_required_features`]. - ("soft-float", InternalOnly { reason: "unsupported ABI-configuration feature", hard_error: false }, &[]), + ( + "soft-float", + InternalOnly { reason: "unsupported ABI-configuration feature", target_modifier: true, hard_error: false }, + &[], + ), ("transactional-execution", Unstable(sym::s390x_target_feature), &[]), ("vector", Stable, &[]), ("vector-enhancements-1", Stable, &["vector"]), @@ -976,7 +1010,11 @@ const SPARC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("leoncasa", Unstable(sym::sparc_target_feature), &[]), ( "soft-float", - InternalOnly { reason: "unsupported ABI-configuration feature", hard_error: false }, + InternalOnly { + reason: "unsupported ABI-configuration feature", + target_modifier: true, + hard_error: false, + }, &[], ), ("v8plus", Unstable(sym::sparc_target_feature), &[]), @@ -1019,8 +1057,12 @@ static AVR_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("spmx", Unstable(sym::avr_target_feature), &[]), ( "sram", - // Pinned down by [`Target::abi_required_features`]. - InternalOnly { reason: "devices that have no SRAM are unsupported", hard_error: false }, + InternalOnly { + reason: "devices that have no SRAM are unsupported", + // Always required by [`Target::abi_required_features`]. + target_modifier: false, + hard_error: false, + }, &[], ), ("tinyencoding", Unstable(sym::avr_target_feature), &[]), @@ -1035,9 +1077,10 @@ const XTENSA_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("interrupt", Unstable(sym::xtensa_target_feature), &["exception"]), ( "windowed", - // Pinned down by [`Target::abi_required_features`]. InternalOnly { reason: "windowed changes the Xtensa calling convention", + // Always required by [`Target::abi_required_features`]. + target_modifier: false, hard_error: false, }, &["exception"], diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 1724db1966038..8f25647423b39 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -30,9 +30,10 @@ use rustc_middle::ty::print::{ with_types_for_suggestion, }; use rustc_middle::ty::{ - self, AdtKind, GenericArgs, InferTy, IsSuggestable, Ty, TyCtxt, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeSuperVisitable, TypeVisitableExt, TypeVisitor, TypeckResults, - Unnormalized, Upcast, suggest_arbitrary_trait_bound, suggest_constraining_type_param, + self, AdtKind, CallerBoundsIterator, GenericArgs, InferTy, IsSuggestable, Ty, TyCtxt, + TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitableExt, TypeVisitor, + TypeckResults, Unnormalized, Upcast, suggest_arbitrary_trait_bound, + suggest_constraining_type_param, }; use rustc_span::def_id::LocalDefId; use rustc_span::{ @@ -1575,7 +1576,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } else { DefIdOrName::Name("type parameter") }; - param_env.caller_bounds().find_map(|clause| { + + param_env.caller_bounds().non_trait_clauses().iter().find_map(|clause| { if let ty::ClauseKind::Projection(proj) = clause.kind().skip_binder() && self .tcx diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index f54d774e32670..4e8e9f3c8b223 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -6,7 +6,9 @@ use rustc_infer::infer::{ }; use rustc_macros::extension; use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized, elaborate}; +use rustc_middle::ty::{ + self, CallerBoundsIterator, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized, elaborate, +}; use rustc_span::DUMMY_SP; use crate::traits::ScrubbedTraitError; @@ -32,7 +34,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> { ) -> Self { let mut bounds = vec![]; - for bound in param_env.caller_bounds() { + for bound in param_env.caller_bounds().non_trait_clauses().iter() { if let Some(type_outlives) = bound.as_type_outlives_clause() { debug_assert!(!infcx.next_trait_solver() || !type_outlives.has_non_rigid_aliases()); bounds.push(type_outlives); diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 402241a7253e0..fefd26e29628f 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -238,7 +238,11 @@ impl<'tcx> AutoTraitFinder<'tcx> { .upcast(tcx) }) .collect::>>(); - let full_user_env = ty::ParamEnv::new(tcx, orig_env.caller_bounds().chain(field_clauses)); + + let full_user_env = ty::ParamEnv::new( + tcx, + orig_env.caller_bounds().all_clauses(tcx).iter().chain(field_clauses), + ); let fresh_args = infcx.fresh_args_for_item(DUMMY_SP, adt_def.did()); let fresh_ty = ty::EarlyBinder::bind(tcx, ty).instantiate(tcx, fresh_args).skip_norm_wip(); @@ -310,7 +314,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { // Don't try to process any nested obligations involving predicates // that are already in the `ParamEnv` (modulo regions): we already // know that they must hold. - for clause in param_env.caller_bounds() { + for clause in param_env.caller_bounds().all_clauses(infcx.tcx).iter() { fresh_preds.insert(self.clean_pred(infcx, clause.as_predicate())); } @@ -325,8 +329,10 @@ impl<'tcx> AutoTraitFinder<'tcx> { polarity: ty::ClausePolarity::Positive, })); - let computed_clauses = param_env.caller_bounds(); - let mut user_computed_clauses: FxIndexSet<_> = user_env.caller_bounds().collect(); + let computed_clauses = + param_env.caller_bounds().all_clauses(infcx.tcx).iter().collect::>(); + let mut user_computed_clauses: FxIndexSet<_> = + user_env.caller_bounds().all_clauses(infcx.tcx).iter().collect(); let mut new_env = param_env; let dummy_cause = ObligationCause::dummy(); @@ -401,7 +407,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { let normalized_preds = elaborate( tcx, - computed_clauses.clone().chain(user_computed_clauses.iter().cloned()), + computed_clauses.iter().copied().chain(user_computed_clauses.iter().cloned()), ); new_env = ty::ParamEnv::new(tcx, normalized_preds); } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 242aa260b8372..d482d97caf4f3 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -12,7 +12,9 @@ use rustc_infer::infer::InferCtxt; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::abstract_const::NotConstEvaluatable; -use rustc_middle::ty::{self, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor}; +use rustc_middle::ty::{ + self, CallerBoundsIterator, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor, +}; use rustc_span::{DUMMY_SP, Span, bug}; use tracing::{debug, instrument}; @@ -202,7 +204,7 @@ fn satisfied_from_param_env<'tcx>( let mut single_match: Option, ()>> = None; - for clause in param_env.caller_bounds() { + for clause in param_env.caller_bounds().non_trait_clauses().iter() { match clause.kind().skip_binder() { ty::ClauseKind::ConstEvaluatable(ce) => { let b_ct = tcx.expand_abstract_consts(ce); diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 5892e376126eb..f3fbd0ba6cafb 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -8,7 +8,7 @@ use rustc_infer::traits::{ use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::elaborate::elaborate; use rustc_middle::ty::fast_reject::DeepRejectCtxt; -use rustc_middle::ty::{self, Ty, Unnormalized}; +use rustc_middle::ty::{self, CallerBoundsIterator, Ty, Unnormalized}; use rustc_span::span_bug; use thin_vec::{ThinVec, thin_vec}; @@ -131,7 +131,7 @@ fn evaluate_host_effect_from_bounds<'tcx>( let drcx = DeepRejectCtxt::relate_rigid_rigid(selcx.tcx()); let mut candidate = None; - for clause in obligation.param_env.caller_bounds() { + for clause in obligation.param_env.caller_bounds().non_trait_clauses().iter() { let bound_clause = clause.kind(); let ty::ClauseKind::HostEffect(data) = bound_clause.skip_binder() else { continue; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 326710007564c..2e6e4436fe2c3 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -32,8 +32,8 @@ use rustc_macros::TypeVisitable; use rustc_middle::query::Providers; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ - self, BottomUpFolder, Clause, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypingMode, + self, BottomUpFolder, CallerBoundsIterator, Clause, GenericArgs, Ty, TyCtxt, TypeFoldable, + TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypingMode, Unnormalized, Upcast, }; use rustc_span::Span; @@ -349,15 +349,18 @@ fn do_normalize_clauses<'tcx>( let ocx = ObligationCtxt::new_with_diagnostics(&infcx); // FIXME: `elaborated_env` is not really rigid. We do this to be // consistent with the old solver. - let elaborated_env = if tcx.next_trait_solver_globally() - && !tcx.disable_param_env_normalization_hack() - { - let elaborated_env = ty::set_type_aliases_to_rigid(tcx, elaborated_env); - let elaborated_env = set_projection_term_to_non_rigid(tcx, elaborated_env.caller_bounds()); - ty::ParamEnv::new(tcx, elaborated_env) - } else { - elaborated_env - }; + let elaborated_env = + if tcx.next_trait_solver_globally() && !tcx.disable_param_env_normalization_hack() { + let elaborated_env = ty::set_type_aliases_to_rigid(tcx, elaborated_env); + let elaborated_env = set_projection_term_to_non_rigid( + tcx, + elaborated_env.caller_bounds().all_clauses(tcx).iter(), + ); + + ty::ParamEnv::new(tcx, elaborated_env) + } else { + elaborated_env + }; let clauses = ocx.normalize(&cause, elaborated_env, Unnormalized::new_wip(clauses)); let clauses = if tcx.next_trait_solver_globally() { if !tcx.disable_param_env_normalization_hack() { @@ -453,7 +456,7 @@ pub fn normalize_param_env_or_error<'tcx>( // can be sure that no errors should occur. let mut clauses: Vec<_> = util::elaborate( tcx, - unnormalized_env.caller_bounds().into_iter().map(|clause| { + unnormalized_env.caller_bounds().all_clauses(tcx).iter().map(|clause| { if tcx.features().generic_const_exprs() || tcx.next_trait_solver_globally() { return clause; } diff --git a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs b/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs index b9770aecb357d..3a8f3e9e8c375 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs @@ -6,8 +6,8 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_index::bit_set::DenseBitSet; use rustc_infer::infer::{SubregionOrigin, TypeOutlivesConstraint}; use rustc_middle::ty::{ - self, Flags, ImplTraitInTraitData, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, TypeVisitor, + self, CallerBoundsIterator, Flags, ImplTraitInTraitData, Ty, TyCtxt, TypeSuperVisitable, + TypeVisitable, TypeVisitableExt, TypeVisitor, }; use rustc_span::{DUMMY_SP, bug}; @@ -554,7 +554,7 @@ where }; let mut capturable = tcx.live_args_for_alias_from_outlives_bounds(kind).clone(); - for clause in param_env.caller_bounds() { + for clause in param_env.caller_bounds().non_trait_clauses().iter() { let Some(outlives) = clause.as_type_outlives_clause() else { continue; }; diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index c6a37d8d8147a..774fa5903c78f 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -12,7 +12,8 @@ use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{ - self, FieldInfo, Term, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized, Upcast, + self, CallerBoundsIterator, FieldInfo, Term, Ty, TyCtxt, TypeVisitableExt, TypingMode, + Unnormalized, Upcast, }; use rustc_span::{bug, span_bug, sym}; use tracing::{debug, instrument}; @@ -798,7 +799,7 @@ fn assemble_candidates_from_param_env<'cx, 'tcx>( obligation, candidate_set, ProjectionCandidate::ParamEnv, - obligation.param_env.caller_bounds(), + obligation.param_env.caller_bounds().all_clauses(selcx.tcx()).iter(), false, ); } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 0d497fe86cf44..925ff06c4131c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -15,8 +15,8 @@ use rustc_hir::{self as hir, CoroutineDesugaring, CoroutineKind}; use rustc_infer::traits::{Obligation, PolyTraitObligation, PredicateObligation, SelectionError}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{ - self, ExistentialPredicate, FieldInfo, IncludeSizedImplicitBounds, SizedTraitKind, TraitRef, - Ty, TypeVisitableExt, elaborate, + self, CallerBoundsIterator, ExistentialPredicate, FieldInfo, IncludeSizedImplicitBounds, + SizedTraitKind, TraitRef, Ty, TypeVisitableExt, elaborate, }; use rustc_span::{DUMMY_SP, bug, span_bug}; use tracing::{debug, instrument, trace}; @@ -280,9 +280,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .obligation .param_env .caller_bounds() - .filter_map(|c| c.as_trait_clause()) + .trait_clauses(self.tcx()) // Micro-optimization: filter out predicates with different polarities. - .filter(|p| p.polarity() == stack.obligation.predicate.polarity()); + .with_polarity(stack.obligation.predicate.polarity()) + .iter(); let drcx = DeepRejectCtxt::relate_rigid_rigid(self.tcx()); let obligation_args = stack.obligation.predicate.skip_binder().trait_ref.args; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 279392221a33c..f571baf278290 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -25,9 +25,9 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::TypeErrorToStringExt; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{ - self, CandidatePreferenceMode, CantBeErased, DeepRejectCtxt, GenericArgs, PolyProjectionClause, - SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingMode, Unnormalized, Upcast, - elaborate, may_use_unstable_feature, + self, CallerBoundsIterator, CandidatePreferenceMode, CantBeErased, DeepRejectCtxt, GenericArgs, + PolyProjectionClause, SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingMode, + Unnormalized, Upcast, elaborate, may_use_unstable_feature, }; use rustc_next_trait_solver::solve::AliasBoundKind; use rustc_span::bug; @@ -936,7 +936,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug_assert!(!self.typing_mode().is_coherence(), "old solver coherence"); if obligation.is_global() - && obligation.param_env.caller_bounds().all(|bound| bound.has_param()) + && obligation + .param_env + .caller_bounds() + .all_clauses(self.tcx()) + .iter() + .all(|bound| bound.has_param()) { // If a param env has no global bounds, global obligations do not // depend on its particular value in order to work, so we can clear diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 9cbb53c6f63bd..f09c17bb46263 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -8,8 +8,8 @@ use rustc_infer::traits::PolyTraitObligation; pub use rustc_infer::traits::util::*; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{ - self, ClausePolarity, PolyTraitClause, SizedTraitKind, TraitClause, TraitRef, Ty, TyCtxt, - TypeFoldable, TypeVisitableExt, Unnormalized, + self, CallerBoundsIterator, ClausePolarity, PolyTraitClause, SizedTraitKind, TraitClause, + TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Unnormalized, }; pub use rustc_next_trait_solver::placeholder::{BoundVarReplacer, PlaceholderReplacer}; use rustc_span::Span; @@ -241,13 +241,17 @@ pub fn implicit_fast_path<'tcx>( } if matches!(trait_pred.self_ty().kind(), ty::Param(_) | ty::Placeholder(_)) { - for clause in param_env.caller_bounds() { - if let ty::ClauseKind::Trait(clause_pred) = clause.kind().skip_binder() - && clause_pred.polarity == ty::ClausePolarity::Positive - && clause_pred.self_ty() == trait_pred.self_ty() - && (clause_pred.def_id() == trait_pred.def_id() - || (sizedness == SizedTraitKind::MetaSized - && tcx.is_lang_item(clause_pred.def_id(), LangItem::Sized))) + for clause_pred in param_env + .caller_bounds() + .trait_clauses(tcx) + .with_polarity(ty::ClausePolarity::Positive) + .with_self_ty(trait_pred.self_ty()) + .iter() + { + let clause_pred = clause_pred.skip_binder(); + if clause_pred.def_id() == trait_pred.def_id() + || (sizedness == SizedTraitKind::MetaSized + && tcx.is_lang_item(clause_pred.def_id(), LangItem::Sized)) { return true; } diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 8cd4cbd677c69..857f436ca82c6 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -16,7 +16,8 @@ use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldabl use crate::inherent::*; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; use crate::{ - self as ty, Const, DebruijnIndex, Interner, PredicateProxy, Region, UniverseIndex, Unnormalized, + self as ty, CallerBoundsIterator, Const, DebruijnIndex, Interner, PredicateProxy, Region, + UniverseIndex, Unnormalized, }; /// `Binder` is a binder for higher-ranked lifetimes or types. It is part of the @@ -1272,7 +1273,7 @@ impl PlaceholderConst { } pub fn find_const_ty_from_env(self, env: I::ParamEnv) -> I::Ty { - let mut candidates = env.caller_bounds().filter_map(|clause| { + let mut candidates = env.caller_bounds().non_trait_clauses().iter().filter_map(|clause| { // `ConstArgHasType` are never desugared to be higher ranked. match clause.kind().skip_binder() { ty::ClauseKind::ConstArgHasType(placeholder_ct, ty) => { diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index d6d4d27764c46..682bc8ef03a39 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -12,8 +12,8 @@ use crate::relate::RelateResult; use crate::relate::combine::PredicateEmittingRelation; use crate::solve::{TyOrConstInferVar, VisibleForLeakCheck}; use crate::{ - self as ty, Const, Interner, PredicateProxy, Region, TyVid, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeVisitableExt, + self as ty, CallerBoundsIterator, Const, Interner, PredicateProxy, Region, TyVid, TypeFoldable, + TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; mod private { @@ -600,7 +600,7 @@ where Infcx: InferCtxtLike, { // Iterate through all goals in param_env to find the one that has the same symbol. - for clause in param_env.caller_bounds() { + for clause in param_env.caller_bounds().non_trait_clauses().iter() { if let ty::ClauseKind::UnstableFeature(sym) = clause.kind().skip_binder() { if sym == symbol { return true; diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 3135523889014..cc65dd25e5af4 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -15,8 +15,8 @@ use crate::relate::Relate; use crate::solve::{AdtDestructorKind, SizedTraitKind}; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; use crate::{ - self as ty, ClauseKind, CollectAndApply, Const, FieldInfo, Interner, PredicateKind, Region, - UpcastFrom, + self as ty, CallerBoundsAccessor, ClauseKind, CollectAndApply, Const, FieldInfo, Interner, + NoClauses, PredicateKind, Region, UpcastFrom, }; #[rust_analyzer::prefer_underscore_import] @@ -586,7 +586,7 @@ pub trait AdtDef: Copy + Debug + Hash + Eq { #[rust_analyzer::prefer_underscore_import] pub trait ParamEnv: Copy + Debug + Hash + Eq + TypeFoldable { - fn caller_bounds(self) -> impl Iterator; + fn caller_bounds(self) -> CallerBoundsAccessor, NoClauses>; } #[rust_analyzer::prefer_underscore_import] diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index a1c5bcacc4b5f..2333fa9cbac1d 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -77,6 +77,7 @@ mod generic_visit; mod infer_ctxt; mod interner; mod opaque_ty; +mod param_env; mod pattern; mod predicate; mod predicate_kind; @@ -107,6 +108,7 @@ pub use generic_visit::*; pub use infer_ctxt::*; pub use interner::*; pub use opaque_ty::*; +pub use param_env::*; pub use pattern::*; pub use predicate::*; pub use predicate_kind::*; diff --git a/compiler/rustc_type_ir/src/param_env.rs b/compiler/rustc_type_ir/src/param_env.rs new file mode 100644 index 0000000000000..4a537c61d1d20 --- /dev/null +++ b/compiler/rustc_type_ir/src/param_env.rs @@ -0,0 +1,433 @@ +use std::marker::PhantomData; + +pub use clause_filter::NoClauses; +use clause_filter::*; +pub use iterator::CallerBoundsIterator; +use output_as::*; +use polarity_filter::*; +use self_ty_filter::*; +use trait_filter::*; + +use crate::inherent::*; +use crate::lang_items::SolverTraitLangItem; +use crate::{Binder, ClauseKind, ClausePolarity, Interner, TraitClause, Upcast}; + +#[must_use] +pub struct CallerBoundsAccessor +where + I: Interner, + Iter: Iterator, + CF: ClauseFilter, +{ + clauses: Iter, + clause_filter: CF, + cx: PhantomData, +} + +impl CallerBoundsAccessor +where + I: Interner, + Iter: Iterator, +{ + #[inline] + pub fn new(clauses: Iter) -> Self { + Self { clauses, clause_filter: NoClauses, cx: PhantomData } + } +} + +mod iterator { + use super::*; + use crate::param_env::output_as::OutputAs; + + pub trait CallerBoundsIterator + where + I: Interner, + Iter: Iterator, + { + type Item; + /// Note: likely less efficient than staying in `CallerBoundsIterator` land. + fn iter(self) -> impl Iterator; + } + impl CallerBoundsIterator for CallerBoundsAccessor + where + I: Interner, + Iter: Iterator, + { + type Item = I::Clause; + + #[inline] + fn iter(self) -> impl Iterator { + self.clauses.filter(|&i| !matches!(i.kind().skip_binder(), ClauseKind::Trait(_))) + } + } + + impl CallerBoundsIterator for CallerBoundsAccessor + where + I: Interner, + Iter: Iterator, + { + type Item = I::Clause; + + #[inline] + fn iter(self) -> impl Iterator { + self.clauses + } + } + + #[inline] + fn filter_trait_clause_helper( + filter: &TraitClauses, + clause: TraitClause, + ) -> bool + where + I: Interner, + P: PolarityFilter, + S: SelfTyFilter, + T: TraitFilter, + O: OutputAs, + { + let TraitClauses { cx: _, polarity_filter, self_type_filter, trait_filter, output: _ } = + filter; + polarity_filter.allow_polarity(clause.polarity) + && self_type_filter.allow_self_ty(clause.self_ty()) + && trait_filter.allow_clause(clause) + } + + impl CallerBoundsIterator + for CallerBoundsAccessor> + where + I: Interner, + Iter: Iterator, + P: PolarityFilter, + S: SelfTyFilter, + T: TraitFilter, + O: OutputAs, + { + type Item = O::Output; + + #[inline] + fn iter(self) -> impl Iterator { + self.clauses.filter_map(move |clause| { + let kind = clause.kind(); + match kind.skip_binder() { + ClauseKind::Trait(trait_clause) + if filter_trait_clause_helper(&self.clause_filter, trait_clause) => + { + Some(O::construct_from_trait_clause( + kind.rebind(trait_clause), + self.clause_filter.cx, + )) + } + _ => None, + } + }) + } + } +} + +mod clause_filter { + use super::*; + + pub trait ClauseFilter {} + + pub struct NoClauses; + impl ClauseFilter for NoClauses {} + + pub struct NonTraitClauses; + impl ClauseFilter for NonTraitClauses {} + + pub struct TraitClauses { + pub cx: I, + pub polarity_filter: P, + pub self_type_filter: S, + pub trait_filter: T, + pub output: O, + } + + impl ClauseFilter for TraitClauses {} + + pub struct AllClauses; + impl ClauseFilter for AllClauses {} + + impl CallerBoundsAccessor + where + I: Interner, + Iter: Iterator, + { + #[inline] + pub fn non_trait_clauses(self) -> CallerBoundsAccessor { + CallerBoundsAccessor { + clauses: self.clauses, + clause_filter: NonTraitClauses, + cx: PhantomData, + } + } + + #[inline] + pub fn trait_clauses( + self, + cx: I, + ) -> CallerBoundsAccessor> + { + CallerBoundsAccessor { + clauses: self.clauses, + clause_filter: TraitClauses { + polarity_filter: (), + self_type_filter: (), + trait_filter: (), + output: OutputAsTraitClause, + cx, + }, + cx: PhantomData, + } + } + + /// Warning: may be a performance hazzard! + #[inline] + // FIXME: asking for _cx here is useful down the line. + pub fn all_clauses(self, _cx: I) -> CallerBoundsAccessor { + CallerBoundsAccessor { + clauses: self.clauses, + clause_filter: AllClauses, + cx: PhantomData, + } + } + } +} + +mod polarity_filter { + use super::*; + + pub trait PolarityFilter { + fn allow_polarity(&self, p: ClausePolarity) -> bool; + } + impl PolarityFilter for () { + #[inline] + fn allow_polarity(&self, _p: ClausePolarity) -> bool { + true + } + } + impl PolarityFilter for ClausePolarity { + #[inline] + fn allow_polarity(&self, p: ClausePolarity) -> bool { + *self == p + } + } + + impl CallerBoundsAccessor> + where + I: Interner, + Iter: Iterator, + P: PolarityFilter, + S: SelfTyFilter, + T: TraitFilter, + O: OutputAs, + { + #[inline] + pub fn with_polarity( + self, + polarity: ClausePolarity, + ) -> CallerBoundsAccessor> { + let CallerBoundsAccessor { + clauses: iter, + clause_filter: + TraitClauses { cx, polarity_filter: _, self_type_filter, trait_filter, output }, + cx: PhantomData, + } = self; + CallerBoundsAccessor { + clauses: iter, + clause_filter: TraitClauses { + cx, + polarity_filter: polarity, + self_type_filter, + trait_filter, + output, + }, + cx: PhantomData, + } + } + #[inline] + pub fn validate_self_ty bool>( + self, + validate_fn: F, + ) -> CallerBoundsAccessor, T, O>> { + let CallerBoundsAccessor { + clauses: iter, + clause_filter: + TraitClauses { cx, polarity_filter, self_type_filter: _, trait_filter, output }, + cx: PhantomData, + } = self; + CallerBoundsAccessor { + clauses: iter, + clause_filter: TraitClauses { + cx, + polarity_filter, + self_type_filter: FilterFn { f: validate_fn }, + trait_filter, + output, + }, + cx: PhantomData, + } + } + #[inline] + pub fn with_self_ty( + self, + desired_self_ty: I::Ty, + ) -> CallerBoundsAccessor bool>, T, O>> + { + self.validate_self_ty(move |actual_self_ty| actual_self_ty == desired_self_ty) + } + #[inline] + pub fn for_trait( + self, + def_id: I::TraitId, + ) -> CallerBoundsAccessor, O>> { + let CallerBoundsAccessor { + clauses: iter, + clause_filter: + TraitClauses { polarity_filter, self_type_filter, trait_filter: _, output, cx }, + cx: PhantomData, + } = self; + CallerBoundsAccessor { + clauses: iter, + clause_filter: TraitClauses { + polarity_filter, + self_type_filter, + trait_filter: TraitWithId(def_id), + output, + cx, + }, + cx: PhantomData, + } + } + #[inline] + pub fn for_trait_lang_item( + self, + lang_item: SolverTraitLangItem, + ) -> CallerBoundsAccessor, O>> { + let cx = self.clause_filter.cx; + self.for_trait(cx.require_trait_lang_item(lang_item)) + } + + #[inline] + pub fn interned( + self, + ) -> CallerBoundsAccessor> + { + let CallerBoundsAccessor { + clauses: iter, + clause_filter: + TraitClauses { cx, polarity_filter, self_type_filter, trait_filter, output: _ }, + cx: PhantomData, + } = self; + CallerBoundsAccessor { + clauses: iter, + clause_filter: TraitClauses { + cx, + polarity_filter, + self_type_filter, + trait_filter, + output: OutputAsInternedClause, + }, + cx: PhantomData, + } + } + } +} + +mod self_ty_filter { + use super::*; + + pub trait SelfTyFilter + where + I: Interner, + { + fn allow_self_ty(&self, ty: I::Ty) -> bool; + } + + impl SelfTyFilter for () + where + I: Interner, + { + #[inline] + fn allow_self_ty(&self, _ty: I::Ty) -> bool { + true + } + } + + pub struct FilterFn { + pub f: F, + } + impl SelfTyFilter for FilterFn + where + I: Interner, + F: Fn(I::Ty) -> bool, + { + #[inline] + fn allow_self_ty(&self, ty: I::Ty) -> bool { + (self.f)(ty) + } + } +} + +mod trait_filter { + use super::*; + + pub trait TraitFilter + where + I: Interner, + { + fn allow_clause(&self, clause: TraitClause) -> bool; + } + + impl TraitFilter for () + where + I: Interner, + { + #[inline] + fn allow_clause(&self, _clause: TraitClause) -> bool { + true + } + } + + pub struct TraitWithId(pub I::TraitId) + where + I: Interner; + impl TraitFilter for TraitWithId + where + I: Interner, + { + #[inline] + fn allow_clause(&self, clause: TraitClause) -> bool { + clause.def_id() == self.0 + } + } +} + +mod output_as { + use super::*; + + pub trait OutputAs { + type Output; + fn construct_from_trait_clause(tc: Binder>, cx: I) -> Self::Output; + } + + pub struct OutputAsInternedClause; + impl OutputAs for OutputAsInternedClause { + type Output = I::Clause; + fn construct_from_trait_clause(tc: Binder>, cx: I) -> I::Clause { + tc.upcast(cx) + } + } + + pub struct OutputAsTraitClause; + impl OutputAs for OutputAsTraitClause { + type Output = Binder>; + fn construct_from_trait_clause( + tc: Binder>, + _cx: I, + ) -> Binder> { + tc + } + } +} diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 44435fcc14726..c4d9bfe777b16 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -702,6 +702,13 @@ impl BTreeMap { pub const fn new_in(alloc: A) -> BTreeMap { BTreeMap { root: None, length: 0, alloc: ManuallyDrop::new(alloc), _marker: PhantomData } } + + /// Returns a reference to the underlying allocator. + #[unstable(feature = "btreemap_alloc", issue = "163177")] + #[inline] + pub fn allocator(&self) -> &A { + &self.alloc + } } impl BTreeMap { diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 4ed18a0abb1ac..6008bcb4389ac 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -366,6 +366,13 @@ impl BTreeSet { BTreeSet { map: BTreeMap::new_in(alloc) } } + /// Returns a reference to the underlying allocator. + #[unstable(feature = "btreemap_alloc", issue = "163177")] + #[inline] + pub fn allocator(&self) -> &A { + self.map.allocator() + } + /// Constructs a double-ended iterator over a sub-range of elements in the set. /// The simplest way is to use the range syntax `min..max`, thus `range(min..max)` will /// yield elements from min (inclusive) to max (exclusive). diff --git a/library/std/src/sys/exit.rs b/library/std/src/sys/exit.rs index 1ca2bd8f6b514..51f8f2219c59c 100644 --- a/library/std/src/sys/exit.rs +++ b/library/std/src/sys/exit.rs @@ -107,7 +107,7 @@ pub fn exit(code: i32) -> ! { } target_os = "teeos" => { let _ = code; - panic!("TA should not call `exit`") + rtabort!("TA should not call `exit`") } target_os = "uefi" => { use r_efi::base::Status; diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 76560a8e2eeae..4bd22082ed439 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1058,6 +1058,7 @@ impl DirEntry { target_os = "horizon", target_os = "vxworks", target_os = "rtems", + target_os = "l4re", )) => { let fd = cvt(unsafe { libc::dirfd(self.dir.dirp.0) })?; diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index 5caed277dbf59..4834400a1c030 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -31,7 +31,7 @@ pub fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {} // SAFETY: must be called only once during runtime cleanup. // this is not guaranteed to run, for example when the program aborts. pub unsafe fn cleanup() { - unimplemented!() + rtabort!("TA should not call `exit`"); // We do NOT have stack overflow handler, because TEE OS will kill TA when it happens. // So cleanup is commented // stack_overflow::cleanup(); diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 46d4523f16566..5aa62bc68d2b5 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -2,7 +2,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet, IndexEntry}; use rustc_data_structures::thin_vec::ThinVec; use rustc_hir as hir; use rustc_infer::infer::region_constraints::{ConstraintKind, RegionConstraintData}; -use rustc_middle::ty::{self, Region, Ty, fold_regions}; +use rustc_middle::ty::{self, CallerBoundsIterator, Region, Ty, fold_regions}; use rustc_span::bug; use rustc_span::def_id::DefId; use rustc_span::symbol::{Symbol, kw}; @@ -173,10 +173,13 @@ fn clean_param_env<'tcx>( .collect(); // FIXME(#111101): Incorporate the explicit predicates of the item here... - let item_clauses: FxIndexSet<_> = tcx.param_env(item_def_id).caller_bounds().collect(); + let item_clauses: FxIndexSet<_> = + tcx.param_env(item_def_id).caller_bounds().all_clauses(tcx).iter().collect(); let where_predicates = cx.with_exact_param_env(param_env, |cx| { param_env .caller_bounds() + .all_clauses(tcx) + .iter() // FIXME: ...which hopefully allows us to simplify this: .filter(|clause| { !item_clauses.contains(clause) diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index 65b89934992dc..ff4460188f81d 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -16,7 +16,7 @@ use rustc_hir::{ }; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::{self, AssocTag, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty, Unnormalized}; +use rustc_middle::ty::{self, AssocTag, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty, Unnormalized, CallerBoundsIterator}; use rustc_span::symbol::Ident; use rustc_span::{Span, Symbol}; @@ -208,6 +208,8 @@ fn check_collect_into_intoiterator<'tcx>( .tcx .param_env(id) .caller_bounds() + .all_clauses(cx.tcx) + .iter() .filter_map(|c| { if let ClauseKind::Trait(t) = c.kind().skip_binder() && cx.tcx.is_diagnostic_item(sym::IntoIterator, t.trait_ref.def_id) diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 84cdefee365d8..36bac82c9ba99 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -17,7 +17,7 @@ use rustc_lint::LateContext; use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind, OverloadedDeref}; use rustc_middle::ty::{ - self, ClauseKind, GenericArg, GenericArgKind, GenericArgs, ParamTy, ProjectionClause, TraitClause, Ty, + self, ClauseKind, GenericArg, GenericArgKind, GenericArgs, ParamTy, ProjectionClause, TraitClause, Ty, CallerBoundsIterator }; use rustc_span::Symbol; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; @@ -476,7 +476,7 @@ fn get_input_traits_and_projections<'tcx>( ) -> (Vec>, Vec>) { let mut trait_predicates = Vec::new(); let mut projection_predicates = Vec::new(); - for clause in cx.tcx.param_env(callee_def_id).caller_bounds() { + for clause in cx.tcx.param_env(callee_def_id).caller_bounds().all_clauses(cx.tcx).iter() { match clause.kind().skip_binder() { ClauseKind::Trait(trait_predicate) if trait_predicate.trait_ref.self_ty() == input => { trait_predicates.push(trait_predicate); @@ -538,7 +538,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< return false; } - let mut trait_clauses = cx.tcx.param_env(callee_def_id).caller_bounds().filter(|clause| { + let mut trait_clauses = cx.tcx.param_env(callee_def_id).caller_bounds().all_clauses(cx.tcx).iter().filter(|clause| { if let ClauseKind::Trait(trait_predicate) = clause.kind().skip_binder() && trait_predicate.trait_ref.self_ty() == param_ty { diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index 865f71700bc98..7739783e2ecc0 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -14,7 +14,7 @@ use rustc_infer::infer::TyCtxtInferExt as _; use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; use rustc_middle::mir::{Rvalue, StatementKind}; use rustc_middle::ty::{ - self, ClauseKind, EarlyBinder, FnSig, GenericArg, GenericArgKind, ParamTy, ProjectionClause, Ty, Unnormalized, + self, ClauseKind, EarlyBinder, FnSig, GenericArg, GenericArgKind, ParamTy, ProjectionClause, Ty, Unnormalized, CallerBoundsIterator, }; use rustc_span::SyntaxContext; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; @@ -189,6 +189,8 @@ fn needless_borrow_count<'tcx>( .tcx .param_env(fn_id) .caller_bounds() + .all_clauses(cx.tcx) + .iter() // TODO: remove filter once https://github.com/rust-lang/rust/issues/160895 is in stable // // This sends the old trait solver into unbounded recursion for `[const] Destruct` on self-recursive types diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 7669a844fe518..c26a014ba24fd 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -17,7 +17,7 @@ use rustc_hir::{ use rustc_hir_typeck::expr_use_visitor as euv; use rustc_lint::{LateContext, LateLintPass, declare_lint_pass}; use rustc_middle::mir::FakeReadCause; -use rustc_middle::ty::{self, Ty, TypeVisitableExt as _}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt as _, CallerBoundsIterator}; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::kw; use rustc_span::{Span, Symbol}; @@ -122,7 +122,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { let sized_trait = need!(cx.tcx.lang_items().sized_trait()); let meta_sized_trait = need!(cx.tcx.lang_items().meta_sized_trait()); - let preds = traits::elaborate(cx.tcx, cx.param_env.caller_bounds()) + let preds = traits::elaborate(cx.tcx, cx.param_env.caller_bounds().all_clauses(cx.tcx).iter()) .filter(|c| !c.is_global()) .filter_map(|clause| { // Note that we do not want to deal with qualified clauses here. diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs index 24a50c5aea5e5..5c511e3399c84 100644 --- a/src/tools/clippy/clippy_lints/src/ranges.rs +++ b/src/tools/clippy/clippy_lints/src/ranges.rs @@ -15,7 +15,7 @@ use rustc_attr_ir::lang_items::LangItem; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, HirId, Node}; use rustc_lint::{LateContext, LateLintPass, Lint, impl_lint_pass}; -use rustc_middle::ty::{self, ClauseKind, ClausePolarity, GenericArgKind, Ty}; +use rustc_middle::ty::{self, ClauseKind, ClausePolarity, GenericArgKind, Ty, CallerBoundsIterator}; use rustc_span::{DesugaringKind, Span, Spanned, SyntaxContext}; use std::cmp::Ordering; @@ -428,6 +428,8 @@ fn can_switch_ranges<'tcx>( .tcx .param_env(id) .caller_bounds() + .all_clauses(cx.tcx) + .iter() .into_iter() .any(|c| { if let ClauseKind::Trait(t) = c.kind().skip_binder() diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index 4b7d9f3dd8fed..ec76ee78cbbee 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -13,7 +13,7 @@ use rustc_infer::traits::Obligation; use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability}; -use rustc_middle::ty::{self, EarlyBinder, GenericArg, GenericArgs, Ty, TypeVisitableExt as _}; +use rustc_middle::ty::{self, EarlyBinder, GenericArg, GenericArgs, Ty, TypeVisitableExt as _, CallerBoundsIterator}; use rustc_span::Span; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; @@ -343,7 +343,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { && let Some(self_ty) = inputs.first() && let ty::Ref(_, _, Mutability::Mut) = self_ty.kind() && let Some(second_ty) = inputs.get(1) - && cx.tcx.param_env(def_id).caller_bounds().any(|clause| { + && cx.tcx.param_env(def_id).caller_bounds().all_clauses(cx.tcx).iter().any(|clause| { if let ty::ClauseKind::Trait(trait_pred) = clause.kind().skip_binder() { trait_pred.self_ty() == *second_ty && cx.tcx.lang_items().fn_mut_trait() == Some(trait_pred.def_id()) diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 33853a3c5ed91..985a48ff509c9 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -18,7 +18,7 @@ use rustc_middle::mir::{ }; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ObligationCause}; use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::{self, GenericArgKind, Instance, TraitRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, GenericArgKind, Instance, TraitRef, Ty, TyCtxt, CallerBoundsIterator}; use rustc_span::Span; use rustc_span::symbol::sym; use rustc_trait_selection::traits::{ObligationCtxt, SelectionContext}; @@ -35,7 +35,7 @@ pub fn is_min_const_fn<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, msrv: Ms if !msrv.meets(cx, msrvs::CONST_FN_TRAIT_BOUND) && let Some(sized_did) = cx.tcx.lang_items().sized_trait() && let Some(meta_sized_did) = cx.tcx.lang_items().meta_sized_trait() - && cx.tcx.param_env(def_id).caller_bounds().any(|bound| { + && cx.tcx.param_env(def_id).caller_bounds().all_clauses(cx.tcx).iter().any(|bound| { bound.as_trait_clause().is_some_and(|clause| { let did = clause.def_id(); did != sized_did && did != meta_sized_did diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index 358f961f9097b..cd7e3b1ea77bc 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -26,7 +26,7 @@ use rustc_middle::ty::{ self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, BoundVarIndexKind, FnSig, GenericArg, GenericArgKind, GenericArgs, IntTy, ProjectionAliasTy, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable as _, TypeVisitable, TypeVisitableExt as _, TypeVisitor, UintTy, Unnormalized, VariantDef, - VariantDiscr, + VariantDiscr, CallerBoundsIterator, }; use rustc_span::symbol::Ident; use rustc_span::{DUMMY_SP, Span, Symbol}; @@ -821,9 +821,9 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option ty_sig(cx, normalized_ty), - _ => sig_for_projection(cx, proj).or_else(|| sig_from_bounds(cx, ty, cx.param_env.caller_bounds(), None)), + _ => sig_for_projection(cx, proj).or_else(|| sig_from_bounds(cx, ty, cx.param_env.caller_bounds().all_clauses(cx.tcx).iter(), None)), }, - ty::Param(_) => sig_from_bounds(cx, ty, cx.param_env.caller_bounds(), None), + ty::Param(_) => sig_from_bounds(cx, ty, cx.param_env.caller_bounds().all_clauses(cx.tcx).iter(), None), _ => None, } } diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 80c8603209c32..1c86cc6c91598 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -140,7 +140,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let attrs = tcx.codegen_fn_attrs(def_id); // Skip over items without an explicitly defined symbol name. if !(attrs.symbol_name.is_some() - || attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) || attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)) { return interp_ok(()); diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr index a29cf5bf5ad92..ed0773f5e4789 100644 --- a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr +++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr @@ -7,6 +7,7 @@ LL | fn f<'a>(arg : Box = &'a ()>>) {} note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/invalid_const_in_lifetime_position.rs:2:10 | +LL | trait X { LL | type Y<'a>; | ^ -- help: add missing lifetime argument @@ -25,6 +26,7 @@ LL | fn f<'a>(arg : Box = &'a ()>>) {} note: associated type defined here, with 0 generic parameters --> $DIR/invalid_const_in_lifetime_position.rs:2:10 | +LL | trait X { LL | type Y<'a>; | ^ diff --git a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr index 642847733a884..8bf80db05da12 100644 --- a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr +++ b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr @@ -7,6 +7,8 @@ LL | ::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- help: add missing lifetime argument @@ -23,6 +25,8 @@ LL | ::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - help: add missing generic argument @@ -39,6 +43,8 @@ LL | Output = ::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- help: add missing lifetime argument @@ -55,6 +61,8 @@ LL | Output = ::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - help: add missing generic argument @@ -71,6 +79,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- help: add missing lifetime argument @@ -87,6 +97,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - help: add missing generic argument @@ -103,6 +115,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- help: add missing lifetime argument @@ -119,6 +133,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - help: add missing generic argument @@ -135,6 +151,8 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- help: add missing lifetime argument @@ -151,6 +169,8 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - help: add missing generic argument @@ -167,6 +187,8 @@ LL | ::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -184,6 +206,8 @@ LL | ::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -201,6 +225,8 @@ LL | Output = ::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -218,6 +244,8 @@ LL | Output = ::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -235,6 +263,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -252,6 +282,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -269,6 +301,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -286,6 +320,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -332,6 +368,8 @@ LL | ::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -349,6 +387,8 @@ LL | ::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -366,6 +406,8 @@ LL | Output = ::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -383,6 +425,8 @@ LL | Output = ::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -400,6 +444,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -417,6 +463,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -434,6 +482,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -451,6 +501,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -468,6 +520,8 @@ LL | ::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -485,6 +539,8 @@ LL | ::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -502,6 +558,8 @@ LL | Output = ::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -519,6 +577,8 @@ LL | Output = ::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -536,6 +596,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -553,6 +615,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -570,6 +634,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -587,6 +653,8 @@ LL | Output = ::Item> as SVec>::Item, note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -604,6 +672,8 @@ LL | fn len(&self) -> ::Item; note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ -- help: add missing lifetime argument @@ -620,6 +690,8 @@ LL | fn len(&self) -> ::Item; note: associated type defined here, with 1 generic parameter: `T` --> $DIR/ice-generic-type-alias-105742.rs:62:10 | +LL | pub trait SVec: Index< +... LL | type Item<'a, T>; | ^^^^ - help: add missing generic argument diff --git a/tests/ui/attributes/z-crate-attr/edition.e2024.stderr b/tests/ui/attributes/z-crate-attr/edition.e2024.stderr new file mode 100644 index 0000000000000..6c0fa09bc637d --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/edition.e2024.stderr @@ -0,0 +1,14 @@ +error: invalid string literal + --> :1:19 + | +LL | #![doc=stringify!(#"a"#)] + | ^^^^^ + | + = note: unprefixed guarded string literals are reserved for future use since Rust 2024 +help: consider inserting whitespace here + | +LL | #![doc=stringify!(# "a"#)] + | + + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/z-crate-attr/edition.rs b/tests/ui/attributes/z-crate-attr/edition.rs new file mode 100644 index 0000000000000..2c0d3c40a3471 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/edition.rs @@ -0,0 +1,12 @@ +// This test checks that the --edition is respected by the crate-attr attributes + +//@ revisions: e2021 e2024 +//@ compile-flags: -Zcrate-attr=doc=stringify!(#"a"#) + +//@[e2021] edition: 2021 +//@[e2021] check-pass + +//@[e2024] edition: 2024 +//[e2024]~? ERROR invalid string literal + +fn main() {} diff --git a/tests/ui/attributes/z-crate-attr/position.rs b/tests/ui/attributes/z-crate-attr/position.rs new file mode 100644 index 0000000000000..571c4d8a43b59 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/position.rs @@ -0,0 +1,9 @@ +// This test checks the output of the macro positions. +// +// FIXME(#165450): RFC3791 says the injected `#![` and `]` should not be taken into account in spans +// but they currently are. + +//@ compile-flags: -Zcrate-attr=doc=compile_error!(concat!(file!(),":",line!(),":",column!())) +//~? ERROR :1:55 + +fn main() {} diff --git a/tests/ui/attributes/z-crate-attr/position.stderr b/tests/ui/attributes/z-crate-attr/position.stderr new file mode 100644 index 0000000000000..b33016260f760 --- /dev/null +++ b/tests/ui/attributes/z-crate-attr/position.stderr @@ -0,0 +1,8 @@ +error: :1:55 + --> :1:8 + | +LL | #![doc=compile_error!(concat!(file!(),":",line!(),":",column!()))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/codegen/no-mangle-on-internal-lang-items.rs b/tests/ui/codegen/no-mangle-on-internal-lang-items.rs index 37766936410ed..58a03f04554f6 100644 --- a/tests/ui/codegen/no-mangle-on-internal-lang-items.rs +++ b/tests/ui/codegen/no-mangle-on-internal-lang-items.rs @@ -4,11 +4,7 @@ #![feature(rustc_attrs)] #[rustc_std_internal_symbol] -#[unsafe(no_mangle)] //~ERROR `#[no_mangle]` cannot be used on internal language items -fn internal_lang_function () { +#[unsafe(no_mangle)] //~ERROR `#[no_mangle]` and `#[export_name]` cannot be used on internal language items +fn internal_lang_function() {} -} - -fn main() { - -} +fn main() {} diff --git a/tests/ui/codegen/no-mangle-on-internal-lang-items.stderr b/tests/ui/codegen/no-mangle-on-internal-lang-items.stderr index 12461a6abb964..a02111673309c 100644 --- a/tests/ui/codegen/no-mangle-on-internal-lang-items.stderr +++ b/tests/ui/codegen/no-mangle-on-internal-lang-items.stderr @@ -1,10 +1,10 @@ -error: `#[no_mangle]` cannot be used on internal language items +error: `#[no_mangle]` and `#[export_name]` cannot be used on internal language items --> $DIR/no-mangle-on-internal-lang-items.rs:7:1 | LL | #[unsafe(no_mangle)] | ^^^^^^^^^^^^^^^^^^^^ -LL | fn internal_lang_function () { - | ---------------------------- should be the internal language item +LL | fn internal_lang_function() {} + | --------------------------- should be the internal language item | = note: Rustc requires this item to have a specific mangled name. diff --git a/tests/ui/codegen/no-mangle-on-panic-handler.rs b/tests/ui/codegen/no-mangle-on-panic-handler.rs index 4ef9fd2b8d372..33ec6289b870f 100644 --- a/tests/ui/codegen/no-mangle-on-panic-handler.rs +++ b/tests/ui/codegen/no-mangle-on-panic-handler.rs @@ -1,13 +1,13 @@ // Issue an error when the user uses #[no_mangle] on the panic handler //@ edition:2024 -#![crate_type="lib"] +#![crate_type = "lib"] #![no_std] #![no_main] use core::panic::PanicInfo; -#[unsafe(no_mangle)] //~ ERROR `#[no_mangle]` cannot be used on internal language items +#[unsafe(no_mangle)] //~ ERROR `#[no_mangle]` and `#[export_name]` cannot be used on internal language items #[panic_handler] pub fn panic_fmt(pi: &PanicInfo) -> ! { loop {} diff --git a/tests/ui/codegen/no-mangle-on-panic-handler.stderr b/tests/ui/codegen/no-mangle-on-panic-handler.stderr index 46cf8e8aec5e9..a0036d48f1ee0 100644 --- a/tests/ui/codegen/no-mangle-on-panic-handler.stderr +++ b/tests/ui/codegen/no-mangle-on-panic-handler.stderr @@ -1,4 +1,4 @@ -error: `#[no_mangle]` cannot be used on internal language items +error: `#[no_mangle]` and `#[export_name]` cannot be used on internal language items --> $DIR/no-mangle-on-panic-handler.rs:10:1 | LL | #[unsafe(no_mangle)] diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr index 8e972100173f8..1a2fd150f453c 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr @@ -7,6 +7,7 @@ LL | fn f2<'a>(arg: Box = &'a ()>>) {} note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/issue-102768.rs:5:10 | +LL | trait X { LL | type Y<'a>; | ^ -- help: add missing lifetime argument @@ -25,6 +26,7 @@ LL | fn f2<'a>(arg: Box = &'a ()>>) {} note: associated type defined here, with 0 generic parameters --> $DIR/issue-102768.rs:5:10 | +LL | trait X { LL | type Y<'a>; | ^ diff --git a/tests/ui/delegation/generics/generics-gen-args-errors.stderr b/tests/ui/delegation/generics/generics-gen-args-errors.stderr index f677cf261a1fc..8a291e9b3f37d 100644 --- a/tests/ui/delegation/generics/generics-gen-args-errors.stderr +++ b/tests/ui/delegation/generics/generics-gen-args-errors.stderr @@ -613,6 +613,7 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; note: method defined here, with 1 lifetime parameter: `'d` --> $DIR/generics-gen-args-errors.rs:87:12 | +LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ -- help: add missing lifetime argument @@ -631,6 +632,7 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; note: method defined here, with 2 generic parameters: `U`, `M` --> $DIR/generics-gen-args-errors.rs:87:12 | +LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ - ------------- @@ -687,6 +689,7 @@ LL | reuse Trait::::foo::<1, 2, 3, _, note: method defined here, with 1 lifetime parameter: `'d` --> $DIR/generics-gen-args-errors.rs:87:12 | +LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ -- help: add missing lifetime argument @@ -705,6 +708,7 @@ LL | reuse Trait::::foo::<1, 2, 3, _, note: method defined here, with 2 generic parameters: `U`, `M` --> $DIR/generics-gen-args-errors.rs:87:12 | +LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ - ------------- diff --git a/tests/ui/delegation/generics/infer-defaults.stderr b/tests/ui/delegation/generics/infer-defaults.stderr index 6cab28a884933..ba90b4330fdd6 100644 --- a/tests/ui/delegation/generics/infer-defaults.stderr +++ b/tests/ui/delegation/generics/infer-defaults.stderr @@ -20,6 +20,7 @@ LL | W(S).foo::<1, 2, 3>(((), (), ()), &[1, 2]); note: method defined here, with 0 generic parameters --> $DIR/infer-defaults.rs:70:12 | +LL | trait Trait<'a, X, Y, T = (), const N: usize = 2> { LL | fn foo(&self, t: (T, T, T), slice: &[usize; N]) {} | ^^^ @@ -50,6 +51,8 @@ LL | W(S).bar::<((), ()), 0>(((), (), ()), &[1, 2]); note: method defined here, with 0 generic parameters --> $DIR/infer-defaults.rs:71:12 | +LL | trait Trait<'a, X, Y, T = (), const N: usize = 2> { +LL | fn foo(&self, t: (T, T, T), slice: &[usize; N]) {} LL | fn bar(&self, t: (T, T, T), slice: &[usize; N]) {} | ^^^ diff --git a/tests/ui/delegation/generics/infers.stderr b/tests/ui/delegation/generics/infers.stderr index 1ab3ef232832e..8e2bda7ca1774 100644 --- a/tests/ui/delegation/generics/infers.stderr +++ b/tests/ui/delegation/generics/infers.stderr @@ -666,6 +666,7 @@ LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ -- -------------- -- @@ -680,6 +681,7 @@ LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; note: method defined here, with 1 lifetime parameter: `'bb` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ --- @@ -694,6 +696,7 @@ LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ -- -------------- -- @@ -706,6 +709,7 @@ LL | reuse Trait::foo::<_> as foo9; note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ -- -------------- -- help: add missing generic arguments @@ -722,6 +726,7 @@ LL | reuse Trait::foo::, _, _, ()> as foo10; note: method defined here, with 1 lifetime parameter: `'bb` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ --- help: add missing lifetime argument @@ -740,6 +745,7 @@ LL | reuse Trait::foo::, _, _, ()> as foo10; note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ -- -------------- -- @@ -777,6 +783,7 @@ LL | reuse Trait::foo::, _, _, ()> as foo11; note: method defined here, with 1 lifetime parameter: `'bb` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ --- help: add missing lifetime argument @@ -795,6 +802,7 @@ LL | reuse Trait::foo::, _, _, ()> as foo11; note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ -- -------------- -- @@ -839,6 +847,7 @@ LL | reuse Trait::foo::<_, _, _> as foo15; note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ -- -------------- -- help: add missing generic argument @@ -1027,6 +1036,7 @@ LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ -- -------------- -- @@ -1047,6 +1057,7 @@ LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6 note: method defined here, with 1 lifetime parameter: `'bb` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ --- @@ -1061,6 +1072,7 @@ LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6 note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ -- -------------- -- @@ -1085,6 +1097,7 @@ LL | reuse Trait::<'static, 'static, _, _, _>::foo::<_> as foo9; note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ -- -------------- -- help: add missing generic arguments @@ -1113,6 +1126,7 @@ LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo:: note: method defined here, with 1 lifetime parameter: `'bb` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ --- help: add missing lifetime argument @@ -1131,6 +1145,7 @@ LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo:: note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` --> $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ -- -------------- -- @@ -1182,6 +1197,7 @@ LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo:: $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ --- help: add missing lifetime argument @@ -1200,6 +1216,7 @@ LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo:: $DIR/infers.rs:142:12 | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} | ^^^ -- -------------- -- diff --git a/tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr b/tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr index 931b61ef0ca85..17512f803d860 100644 --- a/tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr +++ b/tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr @@ -103,6 +103,7 @@ LL | reuse ::bar; note: associated function defined here, with 1 lifetime parameter: `'x` --> $DIR/trait-impl-wrong-args-count.rs:53:12 | +LL | trait Trait1 { LL | fn bar<'x: 'x, AA, BB, const NN: usize>() {} | ^^^ -- @@ -118,6 +119,7 @@ LL | reuse >::bar as bar1; note: associated function defined here, with 1 lifetime parameter: `'x` --> $DIR/trait-impl-wrong-args-count.rs:53:12 | +LL | trait Trait1 { LL | fn bar<'x: 'x, AA, BB, const NN: usize>() {} | ^^^ -- @@ -165,6 +167,7 @@ LL | reuse >::bar; note: associated function defined here, with 0 lifetime parameters --> $DIR/trait-impl-wrong-args-count.rs:89:12 | +LL | trait Trait1 { LL | fn bar() {} | ^^^ @@ -180,6 +183,7 @@ LL | reuse >::bar; note: associated function defined here, with 0 generic parameters --> $DIR/trait-impl-wrong-args-count.rs:89:12 | +LL | trait Trait1 { LL | fn bar() {} | ^^^ @@ -195,6 +199,7 @@ LL | reuse >::bar as bar1; note: associated function defined here, with 0 lifetime parameters --> $DIR/trait-impl-wrong-args-count.rs:89:12 | +LL | trait Trait1 { LL | fn bar() {} | ^^^ @@ -210,6 +215,7 @@ LL | reuse >::bar as bar1; note: associated function defined here, with 0 generic parameters --> $DIR/trait-impl-wrong-args-count.rs:89:12 | +LL | trait Trait1 { LL | fn bar() {} | ^^^ @@ -231,6 +237,8 @@ LL | reuse >::foo as bar3; note: associated function defined here, with at most 2 generic parameters: `X`, `Y` --> $DIR/trait-impl-wrong-args-count.rs:90:12 | +LL | trait Trait1 { +LL | fn bar() {} LL | fn foo() {} | ^^^ - - diff --git a/tests/ui/dropck/dropck-after-failed-type-lowering.stderr b/tests/ui/dropck/dropck-after-failed-type-lowering.stderr index 0922d2e4340e8..f6c9e7d314326 100644 --- a/tests/ui/dropck/dropck-after-failed-type-lowering.stderr +++ b/tests/ui/dropck/dropck-after-failed-type-lowering.stderr @@ -7,6 +7,7 @@ LL | h: Option<::C>, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/dropck-after-failed-type-lowering.rs:4:10 | +LL | trait B { LL | type C<'a>; | ^ -- help: add missing lifetime argument diff --git a/tests/ui/generic-associated-types/elided-in-expr-position.stderr b/tests/ui/generic-associated-types/elided-in-expr-position.stderr index 842b23bd49dd3..6880b7829d49b 100644 --- a/tests/ui/generic-associated-types/elided-in-expr-position.stderr +++ b/tests/ui/generic-associated-types/elided-in-expr-position.stderr @@ -7,6 +7,7 @@ LL | fn g(&self) -> Self::Assoc; note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/elided-in-expr-position.rs:4:10 | +LL | pub trait Trait { LL | type Assoc<'a> where Self: 'a; | ^^^^^ -- help: add missing lifetime argument @@ -23,6 +24,7 @@ LL | fn g(&self) -> Self::Assoc { note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/elided-in-expr-position.rs:4:10 | +LL | pub trait Trait { LL | type Assoc<'a> where Self: 'a; | ^^^^^ -- help: add missing lifetime argument diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr index 72c2bdc72a2f4..a719dabb9ed30 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr @@ -27,6 +27,7 @@ LL | fn foo<'a, T1: X>(t : T1) -> T1::Y<'a> { note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/gat-trait-path-missing-lifetime.rs:2:8 | +LL | trait X { LL | type Y<'a>; | ^ -- help: add missing lifetime argument @@ -43,6 +44,7 @@ LL | fn foo<'a, T1: X>(t : T1) -> T1::Y<'a> { note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/gat-trait-path-missing-lifetime.rs:2:8 | +LL | trait X { LL | type Y<'a>; | ^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr index fcfce28d26933..ee625dc4c79f5 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr @@ -38,6 +38,7 @@ LL | fn foo<'a>(arg: Box>) {} note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/gat-trait-path-parenthesised-args.rs:3:8 | +LL | trait X { LL | type Y<'a>; | ^ -- help: add missing lifetime argument @@ -56,6 +57,7 @@ LL | fn foo<'a>(arg: Box>) {} note: associated type defined here, with 0 generic parameters --> $DIR/gat-trait-path-parenthesised-args.rs:3:8 | +LL | trait X { LL | type Y<'a>; | ^ @@ -68,6 +70,7 @@ LL | fn bar<'a>(arg: Box>) {} note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/gat-trait-path-parenthesised-args.rs:3:8 | +LL | trait X { LL | type Y<'a>; | ^ -- help: add missing lifetime argument diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr index ed837f3475338..8250222473230 100644 --- a/tests/ui/generic-associated-types/issue-71176.stderr +++ b/tests/ui/generic-associated-types/issue-71176.stderr @@ -7,6 +7,7 @@ LL | inner: Box>, note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/issue-71176.rs:2:10 | +LL | trait Provider { LL | type A<'a>; | ^ -- help: add missing lifetime argument diff --git a/tests/ui/generic-associated-types/issue-76535.stderr b/tests/ui/generic-associated-types/issue-76535.stderr index 324f35e88293d..39dad6c70bf43 100644 --- a/tests/ui/generic-associated-types/issue-76535.stderr +++ b/tests/ui/generic-associated-types/issue-76535.stderr @@ -7,6 +7,7 @@ LL | let sub: Box> = Box::new(SuperStruc note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/issue-76535.rs:4:10 | +LL | pub trait SuperTrait { LL | type SubType<'a>: SubTrait where Self: 'a; | ^^^^^^^ -- help: add missing lifetime argument diff --git a/tests/ui/generic-associated-types/issue-78671.stderr b/tests/ui/generic-associated-types/issue-78671.stderr index 8b744622fc819..fa3c518630aad 100644 --- a/tests/ui/generic-associated-types/issue-78671.stderr +++ b/tests/ui/generic-associated-types/issue-78671.stderr @@ -7,6 +7,7 @@ LL | Box::new(Family) as &dyn CollectionFamily note: associated type defined here, with 1 generic parameter: `T` --> $DIR/issue-78671.rs:2:10 | +LL | trait CollectionFamily { LL | type Member; | ^^^^^^ - help: add missing generic argument diff --git a/tests/ui/generic-associated-types/issue-79422.stderr b/tests/ui/generic-associated-types/issue-79422.stderr index d22cc48e5290e..1e65609f960e4 100644 --- a/tests/ui/generic-associated-types/issue-79422.stderr +++ b/tests/ui/generic-associated-types/issue-79422.stderr @@ -7,6 +7,7 @@ LL | as Box>>; note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/issue-79422.rs:18:10 | +LL | trait MapLike { LL | type VRefCont<'a>: RefCont<'a, V> | ^^^^^^^^ -- help: add missing lifetime argument diff --git a/tests/ui/generic-associated-types/issue-79636-1.stderr b/tests/ui/generic-associated-types/issue-79636-1.stderr index fdcd5645f377a..d01b486cb62c8 100644 --- a/tests/ui/generic-associated-types/issue-79636-1.stderr +++ b/tests/ui/generic-associated-types/issue-79636-1.stderr @@ -7,6 +7,8 @@ LL | MInner: Monad>, note: associated type defined here, with 1 generic parameter: `B` --> $DIR/issue-79636-1.rs:3:10 | +LL | trait Monad { +LL | type Unwrapped; LL | type Wrapped; | ^^^^^^^ - help: add missing generic argument diff --git a/tests/ui/generic-associated-types/issue-79636-2.stderr b/tests/ui/generic-associated-types/issue-79636-2.stderr index a8b63f150797f..803b1230d3d01 100644 --- a/tests/ui/generic-associated-types/issue-79636-2.stderr +++ b/tests/ui/generic-associated-types/issue-79636-2.stderr @@ -7,6 +7,7 @@ LL | W: SomeTrait, note: associated type defined here, with 1 generic parameter: `A` --> $DIR/issue-79636-2.rs:2:10 | +LL | trait SomeTrait { LL | type Wrapped: SomeTrait; | ^^^^^^^ - help: add missing generic argument diff --git a/tests/ui/generic-associated-types/issue-80433.stderr b/tests/ui/generic-associated-types/issue-80433.stderr index 8ab6fdcb81573..0728e68f63bd1 100644 --- a/tests/ui/generic-associated-types/issue-80433.stderr +++ b/tests/ui/generic-associated-types/issue-80433.stderr @@ -18,6 +18,7 @@ LL | fn test_simpler<'a>(dst: &'a mut impl TestMut) note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/issue-80433.rs:7:10 | +LL | trait TestMut { LL | type Output<'a>; | ^^^^^^ -- help: add missing lifetime argument diff --git a/tests/ui/generic-associated-types/issue-81712-cyclic-traits.stderr b/tests/ui/generic-associated-types/issue-81712-cyclic-traits.stderr index 33c40f88f8728..25f2288723fa1 100644 --- a/tests/ui/generic-associated-types/issue-81712-cyclic-traits.stderr +++ b/tests/ui/generic-associated-types/issue-81712-cyclic-traits.stderr @@ -7,6 +7,7 @@ LL | type CType: C; note: associated type defined here, with 1 generic parameter: `T` --> $DIR/issue-81712-cyclic-traits.rs:11:10 | +LL | trait C { LL | type DType: D; | ^^^^^ - help: add missing generic argument @@ -23,6 +24,7 @@ LL | type CType: C; note: associated type defined here, with 1 generic parameter: `T` --> $DIR/issue-81712-cyclic-traits.rs:11:10 | +LL | trait C { LL | type DType: D; | ^^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/generic-associated-types/issue-81862.stderr b/tests/ui/generic-associated-types/issue-81862.stderr index 730dc8fffe856..d53609ee67d41 100644 --- a/tests/ui/generic-associated-types/issue-81862.stderr +++ b/tests/ui/generic-associated-types/issue-81862.stderr @@ -7,6 +7,7 @@ LL | fn next(&mut self) -> Option; note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/issue-81862.rs:2:10 | +LL | trait StreamingIterator { LL | type Item<'a>; | ^^^^ -- help: add missing lifetime argument diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.stderr b/tests/ui/generic-associated-types/missing_lifetime_args.stderr index 1a7a2e787a1a9..0aa860780869d 100644 --- a/tests/ui/generic-associated-types/missing_lifetime_args.stderr +++ b/tests/ui/generic-associated-types/missing_lifetime_args.stderr @@ -7,6 +7,7 @@ LL | fn foo<'c, 'd>(_arg: Box>) {} note: associated type defined here, with 2 lifetime parameters: `'a`, `'b` --> $DIR/missing_lifetime_args.rs:2:10 | +LL | trait X { LL | type Y<'a, 'b>; | ^ -- -- help: add missing lifetime arguments diff --git a/tests/ui/generic-associated-types/missing_lifetime_const.stderr b/tests/ui/generic-associated-types/missing_lifetime_const.stderr index ac09608640763..a68fa85d92bee 100644 --- a/tests/ui/generic-associated-types/missing_lifetime_const.stderr +++ b/tests/ui/generic-associated-types/missing_lifetime_const.stderr @@ -7,6 +7,7 @@ LL | let _: ::Assoc<3>; note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/missing_lifetime_const.rs:2:10 | +LL | trait Foo { LL | type Assoc<'a, const N: usize>; | ^^^^^ -- help: add missing lifetime argument diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind.stderr b/tests/ui/generic-associated-types/parameter_number_and_kind.stderr index 4a20cf55cae73..660f0d4692e05 100644 --- a/tests/ui/generic-associated-types/parameter_number_and_kind.stderr +++ b/tests/ui/generic-associated-types/parameter_number_and_kind.stderr @@ -9,6 +9,8 @@ LL | type FErr1 = Self::E<'static, 'static>; note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/parameter_number_and_kind.rs:8:10 | +LL | trait Foo { +... LL | type E<'a, T>; | ^ -- @@ -21,6 +23,8 @@ LL | type FErr1 = Self::E<'static, 'static>; note: associated type defined here, with 1 generic parameter: `T` --> $DIR/parameter_number_and_kind.rs:8:10 | +LL | trait Foo { +... LL | type E<'a, T>; | ^ - help: add missing generic argument @@ -39,6 +43,8 @@ LL | type FErr2 = Self::E<'static, T, u32>; note: associated type defined here, with 1 generic parameter: `T` --> $DIR/parameter_number_and_kind.rs:8:10 | +LL | trait Foo { +... LL | type E<'a, T>; | ^ - diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr index 682fa27ab5d65..486ae9ad2eb2b 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr +++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr @@ -7,6 +7,7 @@ LL | fn f2<'a>(arg : Box = &'a ()>>) {} note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/trait-path-type-error-once-implemented.rs:2:10 | +LL | trait X { LL | type Y<'a>; | ^ -- help: add missing lifetime argument @@ -25,6 +26,7 @@ LL | fn f2<'a>(arg : Box = &'a ()>>) {} note: associated type defined here, with 0 generic parameters --> $DIR/trait-path-type-error-once-implemented.rs:2:10 | +LL | trait X { LL | type Y<'a>; | ^ diff --git a/tests/ui/generics/bad-mid-path-type-params.stderr b/tests/ui/generics/bad-mid-path-type-params.stderr index de3c0289fc6e8..89cdb748edfa7 100644 --- a/tests/ui/generics/bad-mid-path-type-params.stderr +++ b/tests/ui/generics/bad-mid-path-type-params.stderr @@ -9,6 +9,7 @@ LL | let _ = S::new::(1, 1.0); note: associated function defined here, with 1 generic parameter: `U` --> $DIR/bad-mid-path-type-params.rs:6:8 | +LL | impl S { LL | fn new(x: T, _: U) -> S { | ^^^ - @@ -37,6 +38,7 @@ LL | let _: S2 = Trait::new::(1, 1.0); note: associated function defined here, with 1 generic parameter: `U` --> $DIR/bad-mid-path-type-params.rs:14:8 | +LL | trait Trait { LL | fn new(x: T, y: U) -> Self; | ^^^ - @@ -65,6 +67,7 @@ LL | let _: S2 = Trait::<'a,isize>::new::(1, 1.0); note: associated function defined here, with 1 generic parameter: `U` --> $DIR/bad-mid-path-type-params.rs:14:8 | +LL | trait Trait { LL | fn new(x: T, y: U) -> Self; | ^^^ - diff --git a/tests/ui/lifetimes/late-bound-lifetime-parameters-60622.stderr b/tests/ui/lifetimes/late-bound-lifetime-parameters-60622.stderr index 880513e02823b..bf6b1664c98fa 100644 --- a/tests/ui/lifetimes/late-bound-lifetime-parameters-60622.stderr +++ b/tests/ui/lifetimes/late-bound-lifetime-parameters-60622.stderr @@ -27,6 +27,7 @@ LL | b.a::<'_, T>(); note: method defined here, with 0 generic parameters --> $DIR/late-bound-lifetime-parameters-60622.rs:7:8 | +LL | impl Borked { LL | fn a(&self) {} | ^ diff --git a/tests/ui/lifetimes/missing-lifetime-in-alias.stderr b/tests/ui/lifetimes/missing-lifetime-in-alias.stderr index b868d4b15a1aa..21e5ae0dd09af 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-alias.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-alias.stderr @@ -53,6 +53,8 @@ LL | type C<'a, 'b> = as Trait>::Bar; note: associated type defined here, with 1 lifetime parameter: `'b` --> $DIR/missing-lifetime-in-alias.rs:4:10 | +LL | trait Trait<'a> { +... LL | type Bar<'b> | ^^^ -- help: add missing lifetime argument diff --git a/tests/ui/macros/repeated-macro-expansion-error.stderr b/tests/ui/macros/repeated-macro-expansion-error.stderr index e17540596e2b0..90547cfe1d432 100644 --- a/tests/ui/macros/repeated-macro-expansion-error.stderr +++ b/tests/ui/macros/repeated-macro-expansion-error.stderr @@ -14,6 +14,7 @@ LL | impl_add!(a b); note: associated function defined here, with 0 generic parameters --> $DIR/repeated-macro-expansion-error.rs:5:8 | +LL | impl S { LL | fn f() {} | ^ @@ -33,6 +34,7 @@ LL | impl_add!(a b); note: associated function defined here, with 0 generic parameters --> $DIR/repeated-macro-expansion-error.rs:5:8 | +LL | impl S { LL | fn f() {} | ^ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/methods/method-call-lifetime-args-fail.stderr b/tests/ui/methods/method-call-lifetime-args-fail.stderr index b251dd4d342f4..c767ac919ff8e 100644 --- a/tests/ui/methods/method-call-lifetime-args-fail.stderr +++ b/tests/ui/methods/method-call-lifetime-args-fail.stderr @@ -9,6 +9,8 @@ LL | S.early::<'static>(); note: method defined here, with 2 lifetime parameters: `'a`, `'b` --> $DIR/method-call-lifetime-args-fail.rs:6:8 | +LL | impl S { +... LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } | ^^^^^ -- -- help: add missing lifetime argument @@ -27,6 +29,8 @@ LL | S.early::<'static, 'static, 'static>(); note: method defined here, with 2 lifetime parameters: `'a`, `'b` --> $DIR/method-call-lifetime-args-fail.rs:6:8 | +LL | impl S { +... LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } | ^^^^^ -- -- @@ -209,6 +213,8 @@ LL | S::early::<'static>(S); note: method defined here, with 2 lifetime parameters: `'a`, `'b` --> $DIR/method-call-lifetime-args-fail.rs:6:8 | +LL | impl S { +... LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } | ^^^^^ -- -- help: add missing lifetime argument @@ -227,6 +233,8 @@ LL | S::early::<'static, 'static, 'static>(S); note: method defined here, with 2 lifetime parameters: `'a`, `'b` --> $DIR/method-call-lifetime-args-fail.rs:6:8 | +LL | impl S { +... LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } | ^^^^^ -- -- diff --git a/tests/ui/offload/check_config.fail.stderr b/tests/ui/offload/check_config.fail.stderr index 87df9d42bafd1..6f4ae31491d86 100644 --- a/tests/ui/offload/check_config.fail.stderr +++ b/tests/ui/offload/check_config.fail.stderr @@ -1,4 +1,4 @@ -error: using the offload feature requires -Z offload=.bc> +error: using the offload feature requires -Z offload=.ptx or .elf> error: using the offload feature requires -C lto=fat diff --git a/tests/ui/offload/check_config.rs b/tests/ui/offload/check_config.rs index 9865d36049a8f..d28d27d2c9d10 100644 --- a/tests/ui/offload/check_config.rs +++ b/tests/ui/offload/check_config.rs @@ -6,7 +6,7 @@ //@[pass] compile-flags: -Zunstable-options -Zoffload=Device -Clto=fat --emit=metadata //@[fail] compile-flags: -Clto=thin -//[fail]~? ERROR: using the offload feature requires -Z offload=.bc> +//[fail]~? ERROR: using the offload feature requires -Z offload=.ptx or .elf> //[fail]~? ERROR: using the offload feature requires -C lto=fat #![feature(gpu_offload)] diff --git a/tests/ui/offload/non_tuple_args.rs b/tests/ui/offload/non_tuple_args.rs index 44da33a808cb7..578aa956ecb53 100644 --- a/tests/ui/offload/non_tuple_args.rs +++ b/tests/ui/offload/non_tuple_args.rs @@ -1,4 +1,5 @@ //@ compile-flags: -Zunstable-options -Zoffload=Device -Clto=fat +//@ needs-offload #![feature(gpu_offload)] diff --git a/tests/ui/offload/region_by_ref.rs b/tests/ui/offload/region_by_ref.rs index 37ac1aa9c1b0a..2a4f7cc0b0563 100644 --- a/tests/ui/offload/region_by_ref.rs +++ b/tests/ui/offload/region_by_ref.rs @@ -1,6 +1,7 @@ //@ compile-flags: -Zunstable-options -Zoffload=Device -Clto=fat //@ edition: 2024 //@ aux-crate: offload_strategies=offload_strategies.rs +//@ needs-offload // This test ensures an error is emitted when a `Region` is nested inside another // type instead of being passed by value. @@ -9,6 +10,7 @@ #![feature(gpu_offload)] use core::offload::Region; + use offload_strategies::Dummy; fn kernel_shared(_region: &Region<'_, f32, Dummy>) {} diff --git a/tests/ui/offload/type_mismatch.rs b/tests/ui/offload/type_mismatch.rs index a75f8358b7359..47c89dac12b19 100644 --- a/tests/ui/offload/type_mismatch.rs +++ b/tests/ui/offload/type_mismatch.rs @@ -1,4 +1,5 @@ //@ compile-flags: -Zunstable-options -Zoffload=Device -Clto=fat +//@ needs-offload #![feature(core_intrinsics)] diff --git a/tests/ui/structs/struct-path-associated-type.stderr b/tests/ui/structs/struct-path-associated-type.stderr index 110362293ac32..991db6047683c 100644 --- a/tests/ui/structs/struct-path-associated-type.stderr +++ b/tests/ui/structs/struct-path-associated-type.stderr @@ -15,6 +15,7 @@ LL | let z = T::A:: {}; note: associated type defined here, with 0 generic parameters --> $DIR/struct-path-associated-type.rs:4:10 | +LL | trait Tr { LL | type A; | ^ @@ -41,6 +42,7 @@ LL | let z = T::A:: {}; note: associated type defined here, with 0 generic parameters --> $DIR/struct-path-associated-type.rs:4:10 | +LL | trait Tr { LL | type A; | ^ diff --git a/tests/ui/suggestions/issue-101421.stderr b/tests/ui/suggestions/issue-101421.stderr index 12b4c04c2a335..4e050015311f9 100644 --- a/tests/ui/suggestions/issue-101421.stderr +++ b/tests/ui/suggestions/issue-101421.stderr @@ -9,6 +9,7 @@ LL | ().f::<()>(()); note: method defined here, with 0 generic parameters --> $DIR/issue-101421.rs:2:8 | +LL | pub trait Ice { LL | fn f(&self, _: ()); | ^ diff --git a/tests/ui/suggestions/issue-104287.stderr b/tests/ui/suggestions/issue-104287.stderr index d728e6c3d8c19..bf0e5fcd979b5 100644 --- a/tests/ui/suggestions/issue-104287.stderr +++ b/tests/ui/suggestions/issue-104287.stderr @@ -9,6 +9,7 @@ LL | foo::<()>(x); note: method defined here, with 0 generic parameters --> $DIR/issue-104287.rs:6:8 | +LL | impl S { LL | fn foo(&self) {} | ^^^ diff --git a/tests/ui/suggestions/issue-85347.stderr b/tests/ui/suggestions/issue-85347.stderr index af77ddd35e32f..e95e7fc1b752e 100644 --- a/tests/ui/suggestions/issue-85347.stderr +++ b/tests/ui/suggestions/issue-85347.stderr @@ -7,6 +7,7 @@ LL | type Bar<'a>: Deref::Bar>; note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/issue-85347.rs:3:10 | +LL | trait Foo { LL | type Bar<'a>: Deref::Bar>; | ^^^ -- help: add missing lifetime argument @@ -35,6 +36,7 @@ LL | type Bar<'a>: Deref::Bar>; note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/issue-85347.rs:3:10 | +LL | trait Foo { LL | type Bar<'a>: Deref::Bar>; | ^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/suggestions/issue-89064.stderr b/tests/ui/suggestions/issue-89064.stderr index 457cd7982aaab..98325619584bd 100644 --- a/tests/ui/suggestions/issue-89064.stderr +++ b/tests/ui/suggestions/issue-89064.stderr @@ -7,6 +7,7 @@ LL | let _ = A::foo::(); note: associated function defined here, with 0 generic parameters --> $DIR/issue-89064.rs:4:8 | +LL | trait A { LL | fn foo() {} | ^^^ help: consider moving this generic argument to the `A` trait, which takes up to 1 argument @@ -29,6 +30,7 @@ LL | let _ = B::bar::(); note: associated function defined here, with 0 generic parameters --> $DIR/issue-89064.rs:8:8 | +LL | trait B { LL | fn bar() {} | ^^^ help: consider moving these generic arguments to the `B` trait, which takes up to 2 arguments @@ -53,6 +55,7 @@ LL | let _ = A::::foo::(); note: associated function defined here, with 0 generic parameters --> $DIR/issue-89064.rs:4:8 | +LL | trait A { LL | fn foo() {} | ^^^ diff --git a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr index 0819fa86a45de..ad09fbb5f4171 100644 --- a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr +++ b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr @@ -7,6 +7,7 @@ LL | 1.bar::(0); note: method defined here, with 0 generic parameters --> $DIR/move-generic-to-trait-in-method-with-params.rs:4:8 | +LL | trait Foo { LL | fn bar(&self, _: T); | ^^^ help: consider moving this generic argument to the `Foo` trait, which takes up to 1 argument diff --git a/tests/ui/target-feature/abi-relevant-target-modifier.baseline.stderr b/tests/ui/target-feature/abi-relevant-target-modifier.baseline.stderr new file mode 100644 index 0000000000000..fbf2ac5bff976 --- /dev/null +++ b/tests/ui/target-feature/abi-relevant-target-modifier.baseline.stderr @@ -0,0 +1,8 @@ +warning: mixing target features will cause an ABI mismatch in crate `abi_relevant_target_modifier` + | + = help: some target features modify the ABI so Rust crates compiled with different values for these target features cannot be used together safely + = help: the target feature atomics-32 is enabled in `using_atomics_32` but disabled in this crate + = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=target-feature` to silence this warning + +warning: 1 warning emitted + diff --git a/tests/ui/target-feature/abi-relevant-target-modifier.rs b/tests/ui/target-feature/abi-relevant-target-modifier.rs new file mode 100644 index 0000000000000..cb09064903ba2 --- /dev/null +++ b/tests/ui/target-feature/abi-relevant-target-modifier.rs @@ -0,0 +1,14 @@ +// Currently still just a warning. +//@ build-pass +//@ revisions: baseline allowed +//@ compile-flags: --crate-type=rlib --target=armv7-unknown-linux-gnueabihf +//@ needs-llvm-components: arm +//@[allowed] compile-flags: -Cunsafe-allow-abi-mismatch=target-feature +//@ aux-build: using-atomics-32.rs +//@ ignore-backends: gcc +#![feature(no_core)] +#![no_core] + +extern crate using_atomics_32; + +//[baseline]~? WARN mixing target features will cause an ABI mismatch diff --git a/tests/ui/target-feature/auxiliary/using-atomics-32.rs b/tests/ui/target-feature/auxiliary/using-atomics-32.rs new file mode 100644 index 0000000000000..33dd8ebeb6592 --- /dev/null +++ b/tests/ui/target-feature/auxiliary/using-atomics-32.rs @@ -0,0 +1,5 @@ +//@ compile-flags: --crate-type=rlib --target=armv7-unknown-linux-gnueabihf --emit=metadata +//@ needs-llvm-components: arm +//@ compile-flags: -Ctarget-feature=+atomics-32 +#![feature(no_core)] +#![no_core] diff --git a/tests/ui/traits/next-solver/cycles/rpitit-rtn-self-bound-cycle-issue-151307.rs b/tests/ui/traits/next-solver/cycles/rpitit-rtn-self-bound-cycle-issue-151307.rs new file mode 100644 index 0000000000000..bd04bdb817175 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/rpitit-rtn-self-bound-cycle-issue-151307.rs @@ -0,0 +1,19 @@ +//@ compile-flags: -Znext-solver +// Regression test for https://github.com/rust-lang/rust/issues/151307. +// This used to ICE. +#![feature(return_type_notation)] + +trait Trait { + fn foo() -> impl Copy {} +} + +impl Trait for () { + fn foo() -> impl Copy + //~^ ERROR cycle detected + where + Self::foo(..): Copy, + { + } +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/cycles/rpitit-rtn-self-bound-cycle-issue-151307.stderr b/tests/ui/traits/next-solver/cycles/rpitit-rtn-self-bound-cycle-issue-151307.stderr new file mode 100644 index 0000000000000..52a6090246435 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/rpitit-rtn-self-bound-cycle-issue-151307.stderr @@ -0,0 +1,29 @@ +error[E0391]: cycle detected when computing normalized predicates of `::foo` + --> $DIR/rpitit-rtn-self-bound-cycle-issue-151307.rs:11:5 + | +LL | / fn foo() -> impl Copy +LL | | +LL | | where +LL | | Self::foo(..): Copy, + | |____________________________^ + | +note: ...which requires computing type of `::foo::{anon_assoc#0}`... + --> $DIR/rpitit-rtn-self-bound-cycle-issue-151307.rs:11:17 + | +LL | fn foo() -> impl Copy + | ^^^^^^^^^ +note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process... + --> $DIR/rpitit-rtn-self-bound-cycle-issue-151307.rs:11:5 + | +LL | / fn foo() -> impl Copy +LL | | +LL | | where +LL | | Self::foo(..): Copy, + | |____________________________^ + = note: ...which again requires computing normalized predicates of `::foo`, completing the cycle + = note: cycle used when checking assoc item `::foo` is compatible with trait definition + = note: for more information, see and + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/traits/next-solver/normalize/checked-alias-variant-pattern-unsized-arg-issue-152990.rs b/tests/ui/traits/next-solver/normalize/checked-alias-variant-pattern-unsized-arg-issue-152990.rs new file mode 100644 index 0000000000000..dc67fef7fdae3 --- /dev/null +++ b/tests/ui/traits/next-solver/normalize/checked-alias-variant-pattern-unsized-arg-issue-152990.rs @@ -0,0 +1,23 @@ +//@ compile-flags: -Znext-solver +// Regression test for https://github.com/rust-lang/rust/issues/152990. +// This used to ICE. +#![feature(checked_type_aliases)] + +struct Inv; +enum Foo { + Bar, + Var(F), +} +type Supertype = Foo; +//~^ ERROR the size for values of type `(dyn Fn() + 'static)` cannot be known + +fn main() { + let x: Inv = todo!(); + match x { + Foo::Var(Supertype::Bar) => {} + //~^ ERROR mismatched types + //~| ERROR the size for values of type `(dyn Fn() + 'static)` cannot be known + //~| ERROR expected `Fn()` signature, found `Foo` + _ => {} + } +} diff --git a/tests/ui/traits/next-solver/normalize/checked-alias-variant-pattern-unsized-arg-issue-152990.stderr b/tests/ui/traits/next-solver/normalize/checked-alias-variant-pattern-unsized-arg-issue-152990.stderr new file mode 100644 index 0000000000000..e44b35692ea8c --- /dev/null +++ b/tests/ui/traits/next-solver/normalize/checked-alias-variant-pattern-unsized-arg-issue-152990.stderr @@ -0,0 +1,72 @@ +error[E0277]: the size for values of type `(dyn Fn() + 'static)` cannot be known at compilation time + --> $DIR/checked-alias-variant-pattern-unsized-arg-issue-152990.rs:11:1 + | +LL | type Supertype = Foo; + | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Fn() + 'static)` +note: required by an implicit `Sized` bound in `Foo` + --> $DIR/checked-alias-variant-pattern-unsized-arg-issue-152990.rs:7:10 + | +LL | enum Foo { + | ^ required by the implicit `Sized` requirement on this type parameter in `Foo` +help: you could relax the implicit `Sized` bound on `F` if it were used through indirection like `&F` or `Box` + --> $DIR/checked-alias-variant-pattern-unsized-arg-issue-152990.rs:7:10 + | +LL | enum Foo { + | ^ this could be changed to `F: ?Sized`... +LL | Bar, +LL | Var(F), + | - ...if indirection were used here: `Box` + +error[E0308]: mismatched types + --> $DIR/checked-alias-variant-pattern-unsized-arg-issue-152990.rs:17:9 + | +LL | match x { + | - this expression has type `Inv` +LL | Foo::Var(Supertype::Bar) => {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Inv`, found `Foo<_>` + | + = note: expected struct `Inv` + found enum `Foo<_>` + +error[E0277]: the size for values of type `(dyn Fn() + 'static)` cannot be known at compilation time + --> $DIR/checked-alias-variant-pattern-unsized-arg-issue-152990.rs:17:18 + | +LL | Foo::Var(Supertype::Bar) => {} + | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Fn() + 'static)` +note: required by a bound in `Foo::Bar` + --> $DIR/checked-alias-variant-pattern-unsized-arg-issue-152990.rs:7:10 + | +LL | enum Foo { + | ^ required by this bound in `Foo::Bar` +LL | Bar, + | + +error[E0277]: expected `Fn()` signature, found `Foo` + --> $DIR/checked-alias-variant-pattern-unsized-arg-issue-152990.rs:17:9 + | +LL | Foo::Var(Supertype::Bar) => {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Fn()` signature, found `Foo` + | +help: the trait `Fn()` is not implemented for `Foo` + --> $DIR/checked-alias-variant-pattern-unsized-arg-issue-152990.rs:7:1 + | +LL | enum Foo { + | ^^^^^^^^^^^^^^^^^ + = note: wrap the `Foo` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `Foo::Var` + --> $DIR/checked-alias-variant-pattern-unsized-arg-issue-152990.rs:7:13 + | +LL | enum Foo { + | ^^^^ required by this bound in `Foo::Var` +LL | Bar, +LL | Var(F), + | + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/opaques/recursive-opaque-validate-mir-issue-151297.rs b/tests/ui/traits/next-solver/opaques/recursive-opaque-validate-mir-issue-151297.rs new file mode 100644 index 0000000000000..2e82781ad38a8 --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/recursive-opaque-validate-mir-issue-151297.rs @@ -0,0 +1,34 @@ +//@ compile-flags: -Znext-solver -Zvalidate-mir +//~^ ERROR overflow evaluating the requirement `generator_sig::{opaque#0} == _` +// Regression test for https://github.com/rust-lang/rust/issues/151297. +// This used to ICE. +#![feature(coroutines, yield_expr)] + +trait Quux {} + +fn foo() -> impl Quux { //~ ERROR cannot resolve opaque type + struct Foo(T); + impl Quux for Foo {} + Foo(bar()) +} + +fn bar() -> impl Quux { //~ ERROR cannot resolve opaque type + struct Bar(T); + impl Quux for Bar {} + Bar(foo()) +} + +fn ptr() -> impl Sized { //~ ERROR cannot resolve opaque type + &generator_sig() as *const _ +} + +fn generator_sig() -> impl Sized { //~ ERROR cannot resolve opaque type + ptr() +} + +fn generator_hold() -> impl Sized { + #[coroutine] + || yield generator_sig() +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/opaques/recursive-opaque-validate-mir-issue-151297.stderr b/tests/ui/traits/next-solver/opaques/recursive-opaque-validate-mir-issue-151297.stderr new file mode 100644 index 0000000000000..af839d3933cce --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/recursive-opaque-validate-mir-issue-151297.stderr @@ -0,0 +1,52 @@ +error[E0720]: cannot resolve opaque type + --> $DIR/recursive-opaque-validate-mir-issue-151297.rs:9:13 + | +LL | fn foo() -> impl Quux { + | ^^^^^^^^^ recursive opaque type +... +LL | Foo(bar()) + | ---------- returning here with type `Foo` +... +LL | fn bar() -> impl Quux { + | --------- returning this type `Foo` + +error[E0720]: cannot resolve opaque type + --> $DIR/recursive-opaque-validate-mir-issue-151297.rs:15:13 + | +LL | fn foo() -> impl Quux { + | --------- returning this type `Bar` +... +LL | fn bar() -> impl Quux { + | ^^^^^^^^^ recursive opaque type +... +LL | Bar(foo()) + | ---------- returning here with type `Bar` + +error[E0720]: cannot resolve opaque type + --> $DIR/recursive-opaque-validate-mir-issue-151297.rs:21:13 + | +LL | fn ptr() -> impl Sized { + | ^^^^^^^^^^ recursive opaque type +LL | &generator_sig() as *const _ + | ---------------------------- returning here with type `*const impl Sized` +... +LL | fn generator_sig() -> impl Sized { + | ---------- returning this type `*const impl Sized` + +error[E0720]: cannot resolve opaque type + --> $DIR/recursive-opaque-validate-mir-issue-151297.rs:25:23 + | +LL | fn ptr() -> impl Sized { + | ---------- returning this opaque type `impl Sized` +... +LL | fn generator_sig() -> impl Sized { + | ^^^^^^^^^^ recursive opaque type +LL | ptr() + | ----- returning here with type `impl Sized` + +error[E0275]: overflow evaluating the requirement `generator_sig::{opaque#0} == _` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0275, E0720. +For more information about an error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/non_lifetime_binders/late-bound-assoc-type.stderr b/tests/ui/traits/non_lifetime_binders/late-bound-assoc-type.stderr index ecd8319099f28..f815fc3152377 100644 --- a/tests/ui/traits/non_lifetime_binders/late-bound-assoc-type.stderr +++ b/tests/ui/traits/non_lifetime_binders/late-bound-assoc-type.stderr @@ -29,6 +29,7 @@ LL | fn produce() -> impl for Trait<(), Assoc = impl Trait> { note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/late-bound-assoc-type.rs:8:10 | +LL | trait Trait { LL | type Assoc<'a> = i32; | ^^^^^ -- help: add missing lifetime argument @@ -45,6 +46,7 @@ LL | fn produce() -> impl for Trait<(), Assoc = impl Trait> { note: associated type defined here, with 1 lifetime parameter: `'a` --> $DIR/late-bound-assoc-type.rs:8:10 | +LL | trait Trait { LL | type Assoc<'a> = i32; | ^^^^^ -- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/traits/non_lifetime_binders/normalized-param-env-unconstrained-type-120033.stderr b/tests/ui/traits/non_lifetime_binders/normalized-param-env-unconstrained-type-120033.stderr index c95e6c68fc6a1..1c4c2d1719cef 100644 --- a/tests/ui/traits/non_lifetime_binders/normalized-param-env-unconstrained-type-120033.stderr +++ b/tests/ui/traits/non_lifetime_binders/normalized-param-env-unconstrained-type-120033.stderr @@ -13,6 +13,7 @@ LL | T1: for Foo>, note: associated type defined here, with 1 generic parameter: `K` --> $DIR/normalized-param-env-unconstrained-type-120033.rs:11:10 | +LL | pub trait Foo { LL | type Bar; | ^^^ - help: add missing generic argument @@ -29,6 +30,7 @@ LL | T1: for Foo>, note: associated type defined here, with 1 generic parameter: `K` --> $DIR/normalized-param-env-unconstrained-type-120033.rs:11:10 | +LL | pub trait Foo { LL | type Bar; | ^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/ufcs/ufcs-qpath-missing-params.stderr b/tests/ui/ufcs/ufcs-qpath-missing-params.stderr index 048cf96bcc8e8..48cedd10afd5e 100644 --- a/tests/ui/ufcs/ufcs-qpath-missing-params.stderr +++ b/tests/ui/ufcs/ufcs-qpath-missing-params.stderr @@ -41,6 +41,7 @@ LL | ::into_cow::("foo".to_string()); note: method defined here, with 0 generic parameters --> $DIR/ufcs-qpath-missing-params.rs:4:8 | +LL | pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { LL | fn into_cow(self) -> Cow<'a, B>; | ^^^^^^^^