diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index e56bc8ed7e82a..45c9495570ed2 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -26,7 +26,7 @@ use rustc_lint_defs::builtin::LINKER_INFO; use rustc_macros::Diagnostic; use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file}; use rustc_metadata::{ - EncodedMetadata, NativeLibSearchFallback, find_native_static_library, + EncodedMetadata, NativeLibSearchFallback, find_bundled_library, find_native_static_library, walk_native_lib_search_dirs, }; use rustc_middle::bug; @@ -396,8 +396,25 @@ fn link_rlib<'a>( .map(|obj| obj.file_name().unwrap().to_str().unwrap().to_string()) .collect(); + let native_lib_filenames: Vec> = crate_info + .used_libraries + .iter() + .map(|lib| { + find_bundled_library( + lib.name, + Some(lib.verbatim), + lib.kind, + lib.cfg.is_some(), + sess, + &crate_info.crate_types, + ) + }) + .collect(); + let metadata_link_file = if matches!(flavor, RlibFlavor::Normal) { - let metadata_link = rmeta_link::RmetaLink { rust_object_files }; + let native_lib_filenames: Vec> = + native_lib_filenames.iter().map(|f| f.map(|s| s.to_string())).collect(); + let metadata_link = rmeta_link::RmetaLink { rust_object_files, native_lib_filenames }; let metadata_link_data = metadata_link.encode(); let (wrapper, _) = create_wrapper_file(sess, rmeta_link::SECTION.to_string(), &metadata_link_data); @@ -480,12 +497,12 @@ fn link_rlib<'a>( // feature then we'll need to figure out how to record what objects were // loaded from the libraries found here and then encode that into the // metadata of the rlib we're generating somehow. - for lib in crate_info.used_libraries.iter() { + for (i, lib) in crate_info.used_libraries.iter().enumerate() { let NativeLibKind::Static { bundle: None | Some(true), .. } = lib.kind else { continue; }; if flavor == RlibFlavor::Normal - && let Some(filename) = lib.filename + && let Some(filename) = native_lib_filenames[i] { let path = find_native_static_library(filename.as_str(), true, sess); let src = read(path) @@ -599,11 +616,21 @@ fn link_staticlib( let lto = are_upstream_rust_objects_already_included(sess) && !ignored_for_lto(sess, crate_info, cnum); - let native_libs = crate_info.native_libraries[&cnum].iter(); - let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib)); - let relevant_libs: FxIndexSet<_> = relevant.filter_map(|lib| lib.filename).collect(); + let native_libs = &crate_info.native_libraries[&cnum]; + let bundled_filenames = + rmeta_link_cache.native_lib_filenames(&sess.target, path, native_libs); + let relevant_libs: FxIndexSet<_> = native_libs + .iter() + .enumerate() + .filter(|(_, lib)| relevant_lib(sess, lib)) + .filter_map(|(i, _)| bundled_filenames.get(i).copied().flatten()) + .collect(); - let bundled_libs: FxIndexSet<_> = native_libs.filter_map(|lib| lib.filename).collect(); + let bundled_libs: FxIndexSet<_> = native_libs + .iter() + .enumerate() + .filter_map(|(i, _)| bundled_filenames.get(i).copied().flatten()) + .collect(); ab.add_archive( path, AddArchiveKind::Rlib(rmeta_link_cache, &|fname: &str, entry_kind| { @@ -2804,6 +2831,7 @@ fn linker_with_args( cmd, sess, archive_builder_builder, + rmeta_link_cache, crate_info, tmpdir, link_output_kind, @@ -2826,6 +2854,7 @@ fn linker_with_args( cmd, sess, archive_builder_builder, + rmeta_link_cache, crate_info, tmpdir, link_output_kind, @@ -3125,6 +3154,7 @@ fn add_native_libs_from_crate( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, + rmeta_link_cache: &mut RmetaLinkCache, crate_info: &CrateInfo, tmpdir: &Path, bundled_libs: &FxIndexSet, @@ -3148,13 +3178,38 @@ fn add_native_libs_from_crate( .unwrap_or_else(|e| sess.dcx().emit_fatal(e)); } - let native_libs = match cnum { - LOCAL_CRATE => &crate_info.used_libraries, - _ => &crate_info.native_libraries[&cnum], + let (native_libs, bundled_filenames): (&Vec, Vec>) = match cnum { + LOCAL_CRATE => { + let libs = &crate_info.used_libraries; + let filenames = libs + .iter() + .map(|lib| { + find_bundled_library( + lib.name, + Some(lib.verbatim), + lib.kind, + lib.cfg.is_some(), + sess, + &crate_info.crate_types, + ) + }) + .collect(); + (libs, filenames) + } + _ => { + let native_libs = &crate_info.native_libraries[&cnum]; + let filenames = + if let Some(rlib_path) = crate_info.used_crate_source[&cnum].rlib.as_ref() { + rmeta_link_cache.native_lib_filenames(&sess.target, rlib_path, native_libs) + } else { + Vec::new() + }; + (native_libs, filenames) + } }; let mut last = (None, NativeLibKind::Unspecified, false); - for lib in native_libs { + for (i, lib) in native_libs.iter().enumerate() { if !relevant_lib(sess, lib) { continue; } @@ -3174,7 +3229,7 @@ fn add_native_libs_from_crate( let bundle = bundle.unwrap_or(true); let whole_archive = whole_archive == Some(true); if bundle && cnum != LOCAL_CRATE { - if let Some(filename) = lib.filename { + if let Some(filename) = bundled_filenames.get(i).copied().flatten() { // If rlib contains native libs as archives, they are unpacked to tmpdir. let path = tmpdir.join(filename.as_str()); cmd.link_staticlib_by_path(&path, whole_archive); @@ -3226,6 +3281,7 @@ fn add_local_native_libraries( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, + rmeta_link_cache: &mut RmetaLinkCache, crate_info: &CrateInfo, tmpdir: &Path, link_output_kind: LinkOutputKind, @@ -3237,6 +3293,7 @@ fn add_local_native_libraries( cmd, sess, archive_builder_builder, + rmeta_link_cache, crate_info, tmpdir, &Default::default(), @@ -3296,10 +3353,17 @@ fn add_upstream_rust_crates( match linkage { Linkage::Static | Linkage::IncludedFromDylib | Linkage::NotLinked => { if link_static_crate { - bundled_libs = crate_info.native_libraries[&cnum] - .iter() - .filter_map(|lib| lib.filename) - .collect(); + if let Some(rlib_path) = crate_info.used_crate_source[&cnum].rlib.as_ref() { + bundled_libs = rmeta_link_cache + .native_lib_filenames( + &sess.target, + rlib_path, + &crate_info.native_libraries[&cnum], + ) + .into_iter() + .flatten() + .collect(); + } add_static_crate( cmd, sess, @@ -3333,6 +3397,7 @@ fn add_upstream_rust_crates( cmd, sess, archive_builder_builder, + rmeta_link_cache, crate_info, tmpdir, &bundled_libs, @@ -3348,6 +3413,7 @@ fn add_upstream_native_libraries( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, + rmeta_link_cache: &mut RmetaLinkCache, crate_info: &CrateInfo, tmpdir: &Path, link_output_kind: LinkOutputKind, @@ -3371,6 +3437,7 @@ fn add_upstream_native_libraries( cmd, sess, archive_builder_builder, + rmeta_link_cache, crate_info, tmpdir, &Default::default(), diff --git a/compiler/rustc_codegen_ssa/src/back/rmeta_link.rs b/compiler/rustc_codegen_ssa/src/back/rmeta_link.rs index 58da783277dfe..69ec3788ac632 100644 --- a/compiler/rustc_codegen_ssa/src/back/rmeta_link.rs +++ b/compiler/rustc_codegen_ssa/src/back/rmeta_link.rs @@ -2,27 +2,38 @@ //! and potentially other data collected and used when building or linking a rlib. //! See . +use std::fs::File; use std::path::{Path, PathBuf}; use object::read::archive::ArchiveFile; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::memmap::Mmap; +use rustc_hir::attrs::NativeLibKind; use rustc_serialize::opaque::mem_encoder::MemEncoder; use rustc_serialize::opaque::{MAGIC_END_BYTES, MemDecoder}; use rustc_serialize::{Decodable, Encodable}; +use rustc_span::Symbol; +use rustc_target::spec::Target; +use tracing::debug; -use super::metadata::search_for_section; +use super::metadata::{get_metadata_xcoff, search_for_section}; +use crate::NativeLib; pub(crate) const FILENAME: &str = "lib.rmeta-link"; pub(crate) const SECTION: &str = ".rmeta-link"; pub struct RmetaLink { pub rust_object_files: Vec, + /// Positionally aligned with `native_libraries` in regular metadata: index `i` is the + /// bundled filename for native library `i`, or `None` if that library needs no bundling. + pub native_lib_filenames: Vec>, } impl RmetaLink { pub(crate) fn encode(&self) -> Vec { let mut encoder = MemEncoder::new(); self.rust_object_files.encode(&mut encoder); + self.native_lib_filenames.encode(&mut encoder); let mut data = encoder.finish(); data.extend_from_slice(MAGIC_END_BYTES); data @@ -31,7 +42,8 @@ impl RmetaLink { pub(crate) fn decode(data: &[u8]) -> Option { let mut decoder = MemDecoder::new(data, 0).ok()?; let rust_object_files = Vec::::decode(&mut decoder); - Some(RmetaLink { rust_object_files }) + let native_lib_filenames = Vec::>::decode(&mut decoder); + Some(RmetaLink { rust_object_files, native_lib_filenames }) } } @@ -69,4 +81,52 @@ impl RmetaLinkCache { ) -> Option<&RmetaLink> { self.cache.entry(rlib_path.to_path_buf()).or_insert_with(load).as_ref() } + + pub fn native_lib_filenames( + &mut self, + target: &Target, + rlib_path: &Path, + native_libs: &[NativeLib], + ) -> Vec> { + if !crate_may_have_bundled_libs(native_libs) { + return Vec::new(); + } + self.get_or_insert_with(rlib_path, || read_from_path(target, rlib_path)) + .map(|rl| { + rl.native_lib_filenames.iter().map(|f| f.as_deref().map(Symbol::intern)).collect() + }) + .unwrap_or_default() + } +} + +fn crate_may_have_bundled_libs(libs: &[NativeLib]) -> bool { + libs.iter() + .any(|lib| matches!(lib.kind, NativeLibKind::Static { bundle: Some(true) | None, .. })) +} + +// FIXME: this is mostly a copy-paste of `DefaultMetadataLoader::get_rlib_metadata`. +fn read_from_path(target: &Target, path: &Path) -> Option { + let Ok(file) = File::open(path) else { + debug!("failed to open rlib for rmeta-link: {}", path.display()); + return None; + }; + let Ok(mmap) = (unsafe { Mmap::map(file) }) else { + debug!("failed to mmap rlib for rmeta-link: {}", path.display()); + return None; + }; + + if target.is_like_aix { + let archive = ArchiveFile::parse(&*mmap).ok()?; + for entry in archive.members() { + let entry = entry.ok()?; + if entry.name() == FILENAME.as_bytes() { + let member_data = entry.data(&*mmap).ok()?; + let section_data = get_metadata_xcoff(path, member_data).ok()?; + return RmetaLink::decode(section_data); + } + } + return None; + } + + read_from_data(&mmap, path) } diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 3bb8b7de88c02..32d3887fbdf0b 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -216,7 +216,6 @@ bitflags::bitflags! { pub struct NativeLib { pub kind: NativeLibKind, pub name: Symbol, - pub filename: Option, pub cfg: Option, pub verbatim: bool, pub dll_imports: Vec, @@ -226,7 +225,6 @@ impl From<&cstore::NativeLib> for NativeLib { fn from(lib: &cstore::NativeLib) -> Self { NativeLib { kind: lib.kind, - filename: lib.filename, name: lib.name, cfg: lib.cfg.clone(), verbatim: lib.verbatim.unwrap_or(false), diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index f417dfba746f1..b002d7554b36e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -1,5 +1,6 @@ use itertools::Itertools as _; use rustc_abi::{self as abi, BackendRepr, FIRST_VARIANT}; +use rustc_index::IndexVec; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Mutability, Ty, TyCtxt}; @@ -15,6 +16,79 @@ use crate::traits::*; use crate::{MemFlags, base}; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { + fn try_codegen_const_aggregate_as_immediate( + &mut self, + bx: &mut Bx, + dest: PlaceRef<'tcx, Bx::Value>, + kind: &mir::AggregateKind<'tcx>, + operands: &IndexVec>, + ) -> bool { + // Keep this allowlist limited to aggregate kinds with direct codegen coverage. + // Extract the variant index at the same time so we can verify it against + // the layout below. Tuples always use `FIRST_VARIANT` (index 0); the + // `None` in the `Adt` arm excludes unions (which carry an active field). + let variant_index = match kind { + mir::AggregateKind::Tuple => FIRST_VARIANT, + mir::AggregateKind::Adt(_, variant_index, _, _, None) => *variant_index, + _ => return false, + }; + if !matches!(dest.layout.fields, abi::FieldsShape::Arbitrary { .. }) { + return false; + } + // `dest.layout` is the layout of the *overall* type, not a specific + // variant. When the layout is `Variants::Single { index: M }`, the + // field offsets and counts below all refer to variant M. If the MIR + // aggregate is constructing a different variant N (e.g. because N is + // uninhabited and the layout collapsed to M), using `dest.layout` + // directly would read the wrong field metadata. Bail out and let the + // normal codegen path handle it via `project_downcast`. + if !matches!(dest.layout.variants, abi::Variants::Single { index } if index == variant_index) + { + return false; + } + // Now that the variant indices are known to match, the operand count + // and the layout field count must agree. + debug_assert_eq!(operands.len(), dest.layout.fields.count()); + + let size = dest.layout.size.bytes(); + let llty = match size { + 1 => bx.cx().type_i8(), + 2 => bx.cx().type_i16(), + 4 => bx.cx().type_i32(), + 8 => bx.cx().type_i64(), + 16 => bx.cx().type_i128(), + _ => return false, + }; + + let mut value = 0u128; + for (field_idx, operand) in operands.iter_enumerated() { + let field_layout = dest.layout.field(bx.cx(), field_idx.as_usize()); + if field_layout.is_zst() { + continue; + } + let mir::Operand::Constant(constant) = operand else { + return false; + }; + let Some(field_value) = self.eval_mir_constant(constant).try_to_bits(field_layout.size) + else { + return false; + }; + + let field_size = field_layout.size.bytes(); + let field_offset = dest.layout.fields.offset(field_idx.as_usize()).bytes(); + debug_assert!(field_offset + field_size <= size); + let shift = match bx.tcx().data_layout.endian { + abi::Endian::Little => field_offset * 8, + abi::Endian::Big => (size - field_offset - field_size) * 8, + }; + value |= field_value << shift; + } + + let value = bx.cx().const_uint_big(llty, value); + bx.store_to_place(value, dest.val); + true + } + #[instrument(level = "trace", skip(self, bx))] pub(crate) fn codegen_rvalue( &mut self, @@ -179,6 +253,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::Aggregate(ref kind, ref operands) if !matches!(**kind, mir::AggregateKind::RawPtr(..)) => { + if self.try_codegen_const_aggregate_as_immediate(bx, dest, kind, operands) { + return; + } + let (variant_index, variant_dest, active_field_index) = match **kind { mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => { let variant_dest = dest.project_downcast(bx, variant_index); diff --git a/compiler/rustc_hir/src/weak_lang_items.rs b/compiler/rustc_hir/src/weak_lang_items.rs index f9d94bd505724..a2541089a530b 100644 --- a/compiler/rustc_hir/src/weak_lang_items.rs +++ b/compiler/rustc_hir/src/weak_lang_items.rs @@ -25,8 +25,6 @@ macro_rules! weak_lang_items { macro_rules! weak_only_lang_items { ($($item:ident,)*) => { - pub static WEAK_ONLY_LANG_ITEMS: &[LangItem] = &[$(LangItem::$item,)*]; - impl LangItem { pub fn is_weak_only(self) -> bool { matches!(self, $(LangItem::$item)|*) diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 4ff870b405e5a..ecc7b170818d2 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -34,44 +34,30 @@ pub(super) fn check_trait<'tcx>( impl_def_id: LocalDefId, impl_header: ty::ImplTraitHeader<'tcx>, ) -> Result<(), ErrorGuaranteed> { - let lang_items = tcx.lang_items(); - let checker = Checker { tcx, trait_def_id, impl_def_id, impl_header }; - checker.check(lang_items.drop_trait(), visit_implementation_of_drop)?; - checker.check(lang_items.async_drop_trait(), visit_implementation_of_drop)?; - checker.check(lang_items.copy_trait(), visit_implementation_of_copy)?; - checker.check(lang_items.unpin_trait(), visit_implementation_of_unpin)?; - checker.check(lang_items.const_param_ty_trait(), |checker| { - visit_implementation_of_const_param_ty(checker) - })?; - checker.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized)?; - checker.check(lang_items.reborrow(), visit_implementation_of_reborrow)?; - checker.check(lang_items.coerce_shared(), visit_implementation_of_coerce_shared)?; - checker - .check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn)?; - checker.check( - lang_items.coerce_pointee_validated_trait(), - visit_implementation_of_coerce_pointee_validity, - )?; - Ok(()) + let checker = Checker { tcx, impl_def_id, impl_header }; + match tcx.as_lang_item(trait_def_id) { + Some(LangItem::Drop) => visit_implementation_of_drop(&checker), + Some(LangItem::AsyncDrop) => visit_implementation_of_drop(&checker), + Some(LangItem::Copy) => visit_implementation_of_copy(&checker), + Some(LangItem::Unpin) => visit_implementation_of_unpin(&checker), + Some(LangItem::ConstParamTy) => visit_implementation_of_const_param_ty(&checker), + Some(LangItem::CoerceUnsized) => visit_implementation_of_coerce_unsized(&checker), + Some(LangItem::Reborrow) => visit_implementation_of_reborrow(&checker), + Some(LangItem::CoerceShared) => visit_implementation_of_coerce_shared(&checker), + Some(LangItem::DispatchFromDyn) => visit_implementation_of_dispatch_from_dyn(&checker), + Some(LangItem::CoercePointeeValidated) => { + visit_implementation_of_coerce_pointee_validity(&checker) + } + _ => Ok(()), + } } struct Checker<'tcx> { tcx: TyCtxt<'tcx>, - trait_def_id: DefId, impl_def_id: LocalDefId, impl_header: ty::ImplTraitHeader<'tcx>, } -impl<'tcx> Checker<'tcx> { - fn check( - &self, - trait_def_id: Option, - f: impl FnOnce(&Self) -> Result<(), ErrorGuaranteed>, - ) -> Result<(), ErrorGuaranteed> { - if Some(self.trait_def_id) == trait_def_id { f(self) } else { Ok(()) } - } -} - fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { let tcx = checker.tcx; let impl_did = checker.impl_def_id; diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 9ef9422a9e5a0..0a22f468d974e 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -30,7 +30,7 @@ pub mod locator; pub use fs::{METADATA_FILENAME, emit_wrapper_file}; pub use host_dylib::{DylibError, load_symbol_from_dylib}; pub use native_libs::{ - NativeLibSearchFallback, find_native_static_library, try_find_native_dynamic_library, - try_find_native_static_library, walk_native_lib_search_dirs, + NativeLibSearchFallback, find_bundled_library, find_native_static_library, + try_find_native_dynamic_library, try_find_native_static_library, walk_native_lib_search_dirs, }; pub use rmeta::{EncodedMetadata, METADATA_HEADER, ProcMacroKind, encode_metadata, rendered_const}; diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index b2cfc2f079e89..796538963ec3d 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -168,16 +168,16 @@ pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) -> }) } -fn find_bundled_library( +pub fn find_bundled_library( name: Symbol, verbatim: Option, kind: NativeLibKind, has_cfg: bool, - tcx: TyCtxt<'_>, + sess: &Session, + crate_types: &[CrateType], ) -> Option { - let sess = tcx.sess; if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive, .. } = kind - && tcx.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::StaticLib)) + && crate_types.iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::StaticLib)) && (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true)) { let verbatim = verbatim.unwrap_or(false); @@ -273,16 +273,8 @@ impl<'tcx> Collector<'tcx> { } }; - let filename = find_bundled_library( - attr.name, - attr.verbatim, - attr.kind, - attr.cfg.is_some(), - self.tcx, - ); self.libs.push(NativeLib { name: attr.name, - filename, kind: attr.kind, cfg: attr.cfg.clone(), foreign_module: Some(def_id.to_def_id()), @@ -364,16 +356,8 @@ impl<'tcx> Collector<'tcx> { // Add if not found let new_name: Option<&str> = passed_lib.new_name.as_deref(); let name = Symbol::intern(new_name.unwrap_or(&passed_lib.name)); - let filename = find_bundled_library( - name, - passed_lib.verbatim, - passed_lib.kind, - false, - self.tcx, - ); self.libs.push(NativeLib { name, - filename, kind: passed_lib.kind, cfg: None, foreign_module: None, 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 db1a8228c43cb..5dd42b8f1154b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -1095,8 +1095,8 @@ where if let ty::Alias(is_rigid, alias_ty) = ty.kind() && let Some(opaque_ty) = alias_ty.try_to_opaque() { - debug_assert_eq!(is_rigid, ty::IsRigid::No); if opaque_ty == self.opaque_ty { + debug_assert_eq!(is_rigid, ty::IsRigid::No); return self.self_ty; } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index c35dc02fb1de1..974577fd89a54 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -31,7 +31,7 @@ use tracing::debug; use crate::Namespace::{MacroNS, TypeNS, ValueNS}; use crate::def_collector::DefCollector; -use crate::error_helper::{OnUnknownData, StructCtor}; +use crate::diagnostics::impls::{OnUnknownData, StructCtor}; use crate::imports::{ImportData, ImportKind}; use crate::macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef}; use crate::ref_mut::CmCell; diff --git a/compiler/rustc_resolve/src/error_helper.rs b/compiler/rustc_resolve/src/diagnostics/impls.rs similarity index 100% rename from compiler/rustc_resolve/src/error_helper.rs rename to compiler/rustc_resolve/src/diagnostics/impls.rs diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics/mod.rs similarity index 99% rename from compiler/rustc_resolve/src/diagnostics.rs rename to compiler/rustc_resolve/src/diagnostics/mod.rs index 22cc6a581f19a..94616f1c679ea 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics/mod.rs @@ -10,6 +10,8 @@ use rustc_span::{Ident, Span, Spanned, Symbol}; use crate::Res; use crate::late::PatternSource; +pub(crate) mod impls; + #[derive(Diagnostic)] #[diag("can't use {$is_self -> [true] `Self` diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index e20c86d65af3f..8f051cf02d41c 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -125,26 +125,42 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { fn set_bindings_effective_visibilities(&mut self, module_id: LocalDefId) { let module = self.r.expect_module(module_id.to_def_id()); for (_, name_resolution) in self.r.resolutions(module).borrow().iter() { - let Some(mut decl) = name_resolution.borrow().best_decl() else { + let Some(decl) = name_resolution.borrow().best_decl() else { continue; }; - // Set the given effective visibility level to `Level::Direct` and - // sets the rest of the `use` chain to `Level::Reexported` until - // we hit the actual exported item. - let priv_vis = |this: &Self, parent_id, decl| match parent_id { - ParentId::Def(_) => this.current_private_vis, - ParentId::Import(_) => this.r.private_vis_decl(decl), - }; - let mut parent_id = ParentId::Def(module_id); - while let DeclKind::Import { source_decl, .. } = decl.kind { - self.update_import(decl, parent_id, priv_vis(self, parent_id, decl)); - parent_id = ParentId::Import(decl); - decl = source_decl; - } - if let Some(def_id) = decl.res().opt_def_id().and_then(|id| id.as_local()) { - let priv_vis = priv_vis(self, parent_id, decl); - self.update_def(def_id, decl.vis().expect_local(), parent_id, priv_vis); + self.update_decl_chain(decl, ParentId::Def(module_id)); + } + } + + /// Update effective visibilities for the whole reexport chain of a declaration. + /// Set the given effective visibility level to `Level::Direct` and + /// sets the rest of the `use` chain to `Level::Reexported` until + /// we hit the actual exported item. + fn update_decl_chain(&mut self, mut decl: Decl<'ra>, mut parent_id: ParentId<'ra>) { + let priv_vis = |this: &Self, parent_id, decl| match parent_id { + ParentId::Def(_) => this.current_private_vis, + ParentId::Import(_) => this.r.private_vis_decl(decl), + }; + while let DeclKind::Import { source_decl, .. } = decl.kind { + self.update_import(decl, parent_id, priv_vis(self, parent_id, decl)); + if let Some(max_vis_decl) = decl.ambiguity_vis_max.get() { + // The name is exported with the visibility of the most visible declaration + // in its ambiguous glob set (see `DeclData::vis`), so everything on that + // declaration's reexport chain, including the final item, must get its + // effective visibility from that declaration as well. Otherwise the item + // would be considered unreachable by dead code analysis and metadata + // encoding despite being exported (see the regression test + // `ambiguous-import-visibility-globglob-mir.rs`). + // This also avoids the most visible import in an ambiguous glob set + // being reported as unused. + self.update_decl_chain(max_vis_decl, parent_id); } + parent_id = ParentId::Import(decl); + decl = source_decl; + } + if let Some(def_id) = decl.res().opt_def_id().and_then(|id| id.as_local()) { + let priv_vis = priv_vis(self, parent_id, decl); + self.update_def(def_id, decl.vis().expect_local(), parent_id, priv_vis); } } @@ -194,10 +210,6 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { parent_id.level(), tcx, ); - if let Some(max_vis_decl) = decl.ambiguity_vis_max.get() { - // Avoid the most visible import in an ambiguous glob set being reported as unused. - self.update_import(max_vis_decl, parent_id, priv_vis); - } } fn update_def( diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 379ae992c9a6e..db7c95fbd511e 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -25,13 +25,13 @@ use rustc_span::{Ident, Span, Symbol, kw, sym}; use tracing::debug; use crate::Namespace::{self, *}; +use crate::diagnostics::impls::{OnUnknownData, Suggestion}; use crate::diagnostics::{ self, CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate, CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates, ConsiderAddingMacroExport, ConsiderMarkingAsPub, ConsiderMarkingAsPubCrate, }; -use crate::error_helper::{OnUnknownData, Suggestion}; use crate::ref_mut::{CmCell, CmRefCell}; use crate::{ AmbiguityError, BindingKey, CmResolver, Decl, DeclData, DeclKind, Determinacy, Finalize, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 668278f13d9cf..4e901cd76b92e 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -32,7 +32,7 @@ use thin_vec::{ThinVec, thin_vec}; use tracing::debug; use super::NoConstantGenericsReason; -use crate::error_helper::{ImportSuggestion, LabelSuggestion, TypoSuggestion}; +use crate::diagnostics::impls::{ImportSuggestion, LabelSuggestion, TypoSuggestion}; use crate::late::{ AliasPossibility, LateResolutionVisitor, LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet, QSelf, RibKind, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 911350665ed32..56e107c0c3369 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -29,7 +29,6 @@ use std::{fmt, mem}; use diagnostics::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; use effective_visibilities::EffectiveVisibilitiesVisitor; -use error_helper::{ImportSuggestion, LabelSuggestion, StructCtor, Suggestion}; use hygiene::Macros20NormalizedSyntaxContext; use imports::{Import, ImportData, ImportKind, NameResolution, PendingDecl}; use late::{ @@ -77,7 +76,9 @@ use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; -use crate::error_helper::OnUnknownData; +use crate::diagnostics::impls::{ + ImportSuggestion, LabelSuggestion, OnUnknownData, StructCtor, Suggestion, +}; use crate::imports::NameResolutionRef; use crate::ref_mut::{CmCell, CmRefCell}; @@ -86,7 +87,6 @@ mod check_unused; mod def_collector; mod diagnostics; mod effective_visibilities; -mod error_helper; mod ident; mod imports; mod late; diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 94237132bd393..c2b517824a058 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -68,8 +68,6 @@ pub enum LinkagePreference { pub struct NativeLib { pub kind: NativeLibKind, pub name: Symbol, - /// If packed_bundled_libs enabled, actual filename of library is stored. - pub filename: Option, pub cfg: Option, pub foreign_module: Option, pub verbatim: Option, diff --git a/tests/codegen-llvm/aggregate-padding-zero.rs b/tests/codegen-llvm/aggregate-padding-zero.rs new file mode 100644 index 0000000000000..8455b1d8583a5 --- /dev/null +++ b/tests/codegen-llvm/aggregate-padding-zero.rs @@ -0,0 +1,244 @@ +//@ add-minicore +//@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes -Z merge-functions=disabled -Z randomize-layout=no +//@ revisions: powerpc64 x86_64 +//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu +//@[powerpc64] needs-llvm-components: powerpc +//@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu +//@[x86_64] needs-llvm-components: x86 + +// Regression test for . +// +// These cases specifically exercise direct codegen of small non-zero constant +// aggregates as a single integer store. They are chosen so they fail without +// `try_codegen_const_aggregate_as_immediate`. + +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![no_core] + +extern crate minicore; + +use minicore::*; + +#[inline(always)] +unsafe fn ptr_write(dest: *mut T, value: T) { + *dest = value; +} + +trait MaybeUninitExt { + fn as_mut_ptr(&mut self) -> *mut T; + fn write(&mut self, value: T); +} + +impl MaybeUninitExt for MaybeUninit { + fn as_mut_ptr(&mut self) -> *mut T { + self as *mut _ as *mut T + } + + fn write(&mut self, value: T) { + unsafe { + ptr_write(self.as_mut_ptr(), value); + } + } +} + +// Inner padding between b (offset 2, size 1) and c (offset 4, size 4). +#[repr(C)] +pub struct InnerPadded { + a: u16, + b: u8, + c: u32, +} + +#[repr(transparent)] +pub struct Nested1(InnerPadded); + +#[repr(transparent)] +pub struct Nested2(Nested1); + +// PR 157690's original ptr::write entry point, checked against the current +// aggregate-immediate codegen shape. +// CHECK-LABEL: @via_ptr_write( +#[no_mangle] +pub fn via_ptr_write(dest: &mut MaybeUninit) { + let val = InnerPadded { a: 0, b: 0, c: 0 }; + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // CHECK-NEXT: store i64 0, ptr %val, align 4 + // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %val, i64 8, i1 false) + unsafe { + ptr_write(dest.as_mut_ptr(), val); + } +} + +// PR 157690's original MaybeUninit::write entry point. +// CHECK-LABEL: @via_maybe_uninit_write( +#[no_mangle] +pub fn via_maybe_uninit_write(dest: &mut MaybeUninit) { + let val = InnerPadded { a: 0, b: 0, c: 0 }; + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // CHECK-NEXT: store i64 0, ptr %val, align 4 + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %{{.*}}, i64 8, i1 false) + dest.write(val); +} + +// Constant non-zero initialization: emitted as a single store including zero padding. +// CHECK-LABEL: @const_init_non_zero( +#[no_mangle] +pub fn const_init_non_zero(dest: *mut InnerPadded) { + let val = InnerPadded { a: 0, b: 1, c: 0 }; + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // x86_64-NEXT: store i64 65536, ptr %val, align 4 + // powerpc64-NEXT: store i64 1099511627776, ptr %val, align 4 + // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %val, i64 8, i1 false) + unsafe { + ptr_write(dest, val); + } +} + +// From issue #157373: nesting wrapper structs used to change the lowering +// shape enough that LLVM would sometimes find the wide store only in the +// nested case. +// CHECK-LABEL: @bad( +#[no_mangle] +pub fn bad(a: &mut InnerPadded) { + let x = InnerPadded { a: 0, b: 1, c: 0 }; + // x86_64: store i64 65536, ptr %x, align 4 + // powerpc64: store i64 1099511627776, ptr %x, align 4 + *a = x; +} + +// CHECK-LABEL: @good( +#[no_mangle] +pub fn good(a: &mut Nested2) { + let x = InnerPadded { a: 0, b: 1, c: 0 }; + // x86_64: store i64 65536, ptr %x, align 4 + // powerpc64: store i64 1099511627776, ptr %x, align 4 + *a = Nested2(Nested1(x)); +} + +// The same direct constant aggregate packing should apply through ptr::write on MaybeUninit. +// CHECK-LABEL: @via_ptr_write_non_zero( +#[no_mangle] +pub fn via_ptr_write_non_zero(dest: &mut MaybeUninit) { + let val = InnerPadded { a: 0, b: 1, c: 0 }; + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // x86_64-NEXT: store i64 65536, ptr %val, align 4 + // powerpc64-NEXT: store i64 1099511627776, ptr %val, align 4 + // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %val, i64 8, i1 false) + unsafe { + ptr_write(dest.as_mut_ptr(), val); + } +} + +// The same direct constant aggregate packing should apply through MaybeUninit::write. +// CHECK-LABEL: @via_maybe_uninit_write_non_zero( +#[no_mangle] +pub fn via_maybe_uninit_write_non_zero(dest: &mut MaybeUninit) { + let val = InnerPadded { a: 0, b: 1, c: 0 }; + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // x86_64-NEXT: store i64 65536, ptr %val, align 4 + // powerpc64-NEXT: store i64 1099511627776, ptr %val, align 4 + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %{{.*}}, i64 8, i1 false) + dest.write(val); +} + +// CHECK-LABEL: @bad_non_zero( +#[no_mangle] +pub fn bad_non_zero(a: &mut InnerPadded) { + let x = InnerPadded { a: 0, b: 1, c: 0 }; + // CHECK: %x = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %x) + // x86_64-NEXT: store i64 65536, ptr %x, align 4 + // powerpc64-NEXT: store i64 1099511627776, ptr %x, align 4 + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 %x, i64 8, i1 false) + *a = x; +} + +// CHECK-LABEL: @good_non_zero( +#[no_mangle] +pub fn good_non_zero(a: &mut Nested2) { + let x = InnerPadded { a: 0, b: 1, c: 0 }; + // CHECK: %x = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %x) + // x86_64-NEXT: store i64 65536, ptr %x, align 4 + // powerpc64-NEXT: store i64 1099511627776, ptr %x, align 4 + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 %{{.*}}, i64 8, i1 false) + *a = Nested2(Nested1(x)); +} + +// Trailing padding only (no inter-field padding): a (offset 0, size 4), +// b (offset 4, size 2), c (offset 6, size 1), trailing pad (offset 7, size 1). +#[repr(C)] +pub struct TailOnly { + a: u32, + b: u16, + c: u8, +} + +type TupleTailOnly = (u32, u16, u8); + +// PR 157690's trailing-padding-only entry point. +// CHECK-LABEL: @tail_only_write( +#[no_mangle] +pub fn tail_only_write(dest: &mut MaybeUninit) { + let val = TailOnly { a: 0, b: 0, c: 0 }; + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // CHECK-NEXT: store i64 0, ptr %val, align 4 + // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %val, i64 8, i1 false) + unsafe { + ptr_write(dest.as_mut_ptr(), val); + } +} + +// Tuple aggregates should use the same const-packing path as structs when the +// whole tuple is constant and small enough to fit in an integer store. +// CHECK-LABEL: @tuple_tail_only_non_zero( +#[no_mangle] +pub fn tuple_tail_only_non_zero(dest: *mut TupleTailOnly) { + let val: TupleTailOnly = (0, 1, 0); + // CHECK: %val = alloca [8 x i8], align 4 + // CHECK-NEXT: call void @llvm.lifetime.start.p0({{(i64 8, )?}}ptr %val) + // x86_64-NEXT: store i64 4294967296, ptr %val, align 4 + // powerpc64-NEXT: store i64 65536, ptr %val, align 4 + // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %val, i64 8, i1 false) + unsafe { + ptr_write(dest, val); + } +} + +// Regression test for the debug assertion failure in +// `try_codegen_const_aggregate_as_immediate` when the MIR aggregate's +// variant index doesn't match the layout's `Variants::Single { index }`. +// +// When `Data(Void)` is uninhabited, the layout of `E` collapses to +// `Variants::Single { index: 0 }` (only `Empty`). But generic code +// monomorphized with `T = Void` still contains an aggregate for `Data(x)` +// with 1 operand. The optimization must bail out gracefully instead of +// asserting `operands.len() == dest.layout.fields.count()` (1 == 0). +// +// See . +enum Void {} + +enum E { + Empty, + Data(T), +} + +#[inline(never)] +fn make_data(x: T) -> E { + E::Data(x) +} + +// Force codegen of `make_data::`. Without the variant index check, +// this triggers: assertion `left == right` failed (left: 1, right: 0). +// CHECK-LABEL: @force_variant_mismatch( +#[no_mangle] +pub fn force_variant_mismatch() -> fn(Void) -> E { + make_data:: +} diff --git a/tests/codegen-llvm/issues/result-is-ok-unwrap.rs b/tests/codegen-llvm/issues/result-is-ok-unwrap.rs new file mode 100644 index 0000000000000..ffcbb0ae142d9 --- /dev/null +++ b/tests/codegen-llvm/issues/result-is-ok-unwrap.rs @@ -0,0 +1,20 @@ +// Checking `Result::is_ok()` should make a following `unwrap()` branch-free. + +//@ compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +use std::hint::black_box; + +// CHECK-LABEL: @unwrap_after_is_ok +#[no_mangle] +pub fn unwrap_after_is_ok(arg: Result) { + // CHECK-NOT: unwrap_failed + // CHECK-NOT: panic + if arg.is_ok() { + let value = arg.unwrap(); + if value == 42 { + black_box(value); + } + } +} diff --git a/tests/ui/issues/issue-35139.rs b/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.rs similarity index 85% rename from tests/ui/issues/issue-35139.rs rename to tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.rs index e462f35437358..bce0a3729a820 100644 --- a/tests/ui/issues/issue-35139.rs +++ b/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.rs @@ -1,3 +1,5 @@ +//! Regression test for . + use std::fmt; pub trait MethodType { diff --git a/tests/ui/issues/issue-35139.stderr b/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.stderr similarity index 89% rename from tests/ui/issues/issue-35139.stderr rename to tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.stderr index 4568b9b70f412..73663e85ef37c 100644 --- a/tests/ui/issues/issue-35139.stderr +++ b/tests/ui/associated-types/unconstrained-dyn-assoc-type-lifetime.stderr @@ -1,5 +1,5 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-35139.rs:9:6 + --> $DIR/unconstrained-dyn-assoc-type-lifetime.rs:11:6 | LL | impl<'a> MethodType for MTFn { | ^^ unconstrained lifetime parameter diff --git a/tests/ui/issues/issue-34334.rs b/tests/ui/binding/tuple-binder-on-err-ty.rs similarity index 64% rename from tests/ui/issues/issue-34334.rs rename to tests/ui/binding/tuple-binder-on-err-ty.rs index 51486bc40de0c..3357dd42f4e35 100644 --- a/tests/ui/issues/issue-34334.rs +++ b/tests/ui/binding/tuple-binder-on-err-ty.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Test tuple pattern syntax doesn't ICE on erroneous type. + fn main () { let sr: Vec<(u32, _, _) = vec![]; //~^ ERROR expected one of diff --git a/tests/ui/issues/issue-34334.stderr b/tests/ui/binding/tuple-binder-on-err-ty.stderr similarity index 93% rename from tests/ui/issues/issue-34334.stderr rename to tests/ui/binding/tuple-binder-on-err-ty.stderr index 6bf6732311fcf..f8f9cd73035d6 100644 --- a/tests/ui/issues/issue-34334.stderr +++ b/tests/ui/binding/tuple-binder-on-err-ty.stderr @@ -1,5 +1,5 @@ error: expected one of `,`, `:`, or `>`, found `=` - --> $DIR/issue-34334.rs:2:29 + --> $DIR/tuple-binder-on-err-ty.rs:5:29 | LL | let sr: Vec<(u32, _, _) = vec![]; | - ^ expected one of `,`, `:`, or `>` @@ -12,7 +12,7 @@ LL | let sr: Vec<(u32, _, _)> = vec![]; | + error[E0277]: a value of type `Vec<(u32, _, _)>` cannot be built from an iterator over elements of type `()` - --> $DIR/issue-34334.rs:5:87 + --> $DIR/tuple-binder-on-err-ty.rs:8:87 | LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect(); | ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator` @@ -22,7 +22,7 @@ help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL = help: for that trait implementation, expected `(u32, _, _)`, found `()` note: the method call chain might not have had the expected associated types - --> $DIR/issue-34334.rs:5:43 + --> $DIR/tuple-binder-on-err-ty.rs:8:43 | LL | let sr: Vec<(u32, _, _) = vec![]; | ------ this expression has type `Vec<(_, _, _)>` diff --git a/tests/ui/issues/issue-36474.rs b/tests/ui/codegen/slice-iter-enumerate-opt.rs similarity index 75% rename from tests/ui/issues/issue-36474.rs rename to tests/ui/codegen/slice-iter-enumerate-opt.rs index ddfa1829e3afc..21cb530953eaf 100644 --- a/tests/ui/issues/issue-36474.rs +++ b/tests/ui/codegen/slice-iter-enumerate-opt.rs @@ -1,4 +1,8 @@ +//! Regression test for . +//! This used to trigger LLVM assertion when compiled with opt level 3. +//@ compile-flags: -Copt-level=3 //@ run-pass + fn main() { remove_axis(&3, 0); } diff --git a/tests/ui/issues/issue-3559.rs b/tests/ui/collections/hashmap/hashmap-debug-format.rs similarity index 81% rename from tests/ui/issues/issue-3559.rs rename to tests/ui/collections/hashmap/hashmap-debug-format.rs index ffb937cf5d253..97e81db94c49c 100644 --- a/tests/ui/issues/issue-3559.rs +++ b/tests/ui/collections/hashmap/hashmap-debug-format.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! Test hashmap debug format doesn't ICE. //@ run-pass + use std::collections::HashMap; fn check_strs(actual: &str, expected: &str) -> bool { diff --git a/tests/ui/derived-errors/no-spurious-unconstrained-param.rs b/tests/ui/derived-errors/no-spurious-unconstrained-param.rs new file mode 100644 index 0000000000000..d56245a6ac83c --- /dev/null +++ b/tests/ui/derived-errors/no-spurious-unconstrained-param.rs @@ -0,0 +1,16 @@ +//! Regression test for . +//! Previously, in addition to the real cause of the problem as seen below, +//! the compiler would tell the user: +//! +//! ``` +//! error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or +//! predicates +//! ``` +//! +//! With this test, we check that only the relevant error is emitted. + +trait Foo {} + +impl Foo for Bar {} //~ ERROR cannot find type `Bar` in this scope + +fn main() {} diff --git a/tests/ui/issues/issue-36836.stderr b/tests/ui/derived-errors/no-spurious-unconstrained-param.stderr similarity index 82% rename from tests/ui/issues/issue-36836.stderr rename to tests/ui/derived-errors/no-spurious-unconstrained-param.stderr index 2d9a97df90520..0dde8afbc1c00 100644 --- a/tests/ui/issues/issue-36836.stderr +++ b/tests/ui/derived-errors/no-spurious-unconstrained-param.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find type `Bar` in this scope - --> $DIR/issue-36836.rs:13:17 + --> $DIR/no-spurious-unconstrained-param.rs:14:17 | LL | impl Foo for Bar {} | ^^^ not found in this scope diff --git a/tests/ui/errors/error-count.rs b/tests/ui/errors/error-count.rs new file mode 100644 index 0000000000000..08eb56bc2040d --- /dev/null +++ b/tests/ui/errors/error-count.rs @@ -0,0 +1,9 @@ +//! Regression test for . +//! Test rustc emits right error count. +//! (this used to return `aborting due to 2 previous errors`) + +fn main() { + a; //~ ERROR cannot find value `a` + "".lorem; //~ ERROR no field + "".ipsum; //~ ERROR no field +} diff --git a/tests/ui/issues/issue-33525.stderr b/tests/ui/errors/error-count.stderr similarity index 84% rename from tests/ui/issues/issue-33525.stderr rename to tests/ui/errors/error-count.stderr index ee9f4d4c3016d..e53c2c5882c47 100644 --- a/tests/ui/issues/issue-33525.stderr +++ b/tests/ui/errors/error-count.stderr @@ -1,17 +1,17 @@ error[E0425]: cannot find value `a` in this scope - --> $DIR/issue-33525.rs:2:5 + --> $DIR/error-count.rs:6:5 | LL | a; | ^ not found in this scope error[E0609]: no field `lorem` on type `&'static str` - --> $DIR/issue-33525.rs:3:8 + --> $DIR/error-count.rs:7:8 | LL | "".lorem; | ^^^^^ unknown field error[E0609]: no field `ipsum` on type `&'static str` - --> $DIR/issue-33525.rs:4:8 + --> $DIR/error-count.rs:8:8 | LL | "".ipsum; | ^^^^^ unknown field diff --git a/tests/ui/issues/issue-34373.rs b/tests/ui/generics/cyclic-default-type-param-via-alias.rs similarity index 64% rename from tests/ui/issues/issue-34373.rs rename to tests/ui/generics/cyclic-default-type-param-via-alias.rs index 02e1048e5a330..ae83dfc7c6f74 100644 --- a/tests/ui/issues/issue-34373.rs +++ b/tests/ui/generics/cyclic-default-type-param-via-alias.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Test cyclic default type param through alias doesn't ICE. + #![allow(warnings)] //@ ignore-parallel-frontend query cycle trait Trait { diff --git a/tests/ui/issues/issue-34373.stderr b/tests/ui/generics/cyclic-default-type-param-via-alias.stderr similarity index 82% rename from tests/ui/issues/issue-34373.stderr rename to tests/ui/generics/cyclic-default-type-param-via-alias.stderr index 9f85e4d5e5a93..4d05d45286529 100644 --- a/tests/ui/issues/issue-34373.stderr +++ b/tests/ui/generics/cyclic-default-type-param-via-alias.stderr @@ -1,17 +1,17 @@ error[E0391]: cycle detected when computing type of `Foo::T` - --> $DIR/issue-34373.rs:7:34 + --> $DIR/cyclic-default-type-param-via-alias.rs:10:34 | LL | pub struct Foo>>; | ^^^^^^^^^^ | note: ...which requires expanding type alias `DefaultFoo`... - --> $DIR/issue-34373.rs:9:19 + --> $DIR/cyclic-default-type-param-via-alias.rs:12:19 | LL | type DefaultFoo = Foo; | ^^^ = note: ...which again requires computing type of `Foo::T`, completing the cycle note: cycle used when checking that `Foo` is well-formed - --> $DIR/issue-34373.rs:7:1 + --> $DIR/cyclic-default-type-param-via-alias.rs:10:1 | LL | pub struct Foo>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-36299.rs b/tests/ui/generics/unused-type-and-lifetime-param.rs similarity index 54% rename from tests/ui/issues/issue-36299.rs rename to tests/ui/generics/unused-type-and-lifetime-param.rs index 7b68420b71cb2..0ad7b087ceeee 100644 --- a/tests/ui/issues/issue-36299.rs +++ b/tests/ui/generics/unused-type-and-lifetime-param.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! This used to ICE. + struct Foo<'a, A> {} //~^ ERROR parameter `'a` is never used //~| ERROR parameter `A` is never used diff --git a/tests/ui/issues/issue-36299.stderr b/tests/ui/generics/unused-type-and-lifetime-param.stderr similarity index 86% rename from tests/ui/issues/issue-36299.stderr rename to tests/ui/generics/unused-type-and-lifetime-param.stderr index 29e8d7ca59a24..d21c44ec1fc87 100644 --- a/tests/ui/issues/issue-36299.stderr +++ b/tests/ui/generics/unused-type-and-lifetime-param.stderr @@ -1,5 +1,5 @@ error[E0392]: lifetime parameter `'a` is never used - --> $DIR/issue-36299.rs:1:12 + --> $DIR/unused-type-and-lifetime-param.rs:4:12 | LL | struct Foo<'a, A> {} | ^^ unused lifetime parameter @@ -7,7 +7,7 @@ LL | struct Foo<'a, A> {} = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` error[E0392]: type parameter `A` is never used - --> $DIR/issue-36299.rs:1:16 + --> $DIR/unused-type-and-lifetime-param.rs:4:16 | LL | struct Foo<'a, A> {} | ^ unused type parameter diff --git a/tests/ui/issues/issue-35570.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.rs similarity index 74% rename from tests/ui/issues/issue-35570.rs rename to tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.rs index a2b0222d4f395..da83fe0a7ba04 100644 --- a/tests/ui/issues/issue-35570.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.rs @@ -1,3 +1,7 @@ +//! Regression test for . +//! Test associated type projection under `for<'a>` binder in the return +//! type of fn parameter and inside trait object doesn't ICE. + use std::mem; trait Trait1 {} diff --git a/tests/ui/issues/issue-35570.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.stderr similarity index 80% rename from tests/ui/issues/issue-35570.stderr rename to tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.stderr index b39b15fdf4b10..2aeca47b2ebb9 100644 --- a/tests/ui/issues/issue-35570.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/assoc-type-projection-in-dyn-and-fn.stderr @@ -1,23 +1,23 @@ error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied - --> $DIR/issue-35570.rs:8:40 + --> $DIR/assoc-type-projection-in-dyn-and-fn.rs:12:40 | LL | fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/issue-35570.rs:4:1 + --> $DIR/assoc-type-projection-in-dyn-and-fn.rs:8:1 | LL | trait Trait2<'a> { | ^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied - --> $DIR/issue-35570.rs:8:16 + --> $DIR/assoc-type-projection-in-dyn-and-fn.rs:12:16 | LL | fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/issue-35570.rs:4:1 + --> $DIR/assoc-type-projection-in-dyn-and-fn.rs:8:1 | LL | trait Trait2<'a> { | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/imports/ambiguous-import-visibility-globglob-mir.rs b/tests/ui/imports/ambiguous-import-visibility-globglob-mir.rs new file mode 100644 index 0000000000000..a411e2cc4394d --- /dev/null +++ b/tests/ui/imports/ambiguous-import-visibility-globglob-mir.rs @@ -0,0 +1,20 @@ +// Regression test for the 1.96 -> 1.97 stable-to-stable regression: an item exported +// only through a public glob, and also glob-imported with restricted visibility through +// a private facade, lost its exported effective visibility. The defining crate then +// skipped encoding its optimized MIR (and warned dead_code) while name resolution still +// exported the item and it remained `cross_crate_inlinable`, so downstream crates failed +// with "missing optimized MIR". The dead_code half is checked by `#![deny(dead_code)]` +// in the auxiliary crate itself. + +//@ build-pass +//@ aux-build:ambiguous-import-visibility-globglob-mir.rs + +extern crate ambiguous_import_visibility_globglob_mir as dep; + +pub fn call_f() -> u32 { + dep::f() +} + +fn main() { + call_f(); +} diff --git a/tests/ui/imports/ambiguous-import-visibility-globglob-reachable.rs b/tests/ui/imports/ambiguous-import-visibility-globglob-reachable.rs new file mode 100644 index 0000000000000..1a533b1d4ee21 --- /dev/null +++ b/tests/ui/imports/ambiguous-import-visibility-globglob-reachable.rs @@ -0,0 +1,26 @@ +// Regression test for the 1.96 -> 1.97 stable-to-stable regression: an item exported +// only through a public glob, and also glob-imported with restricted visibility through +// a private facade, lost its exported effective visibility while name resolution still +// exported it. Downstream: spurious dead_code in this crate, "missing optimized MIR" in +// dependent crates (see ambiguous-import-visibility-globglob-mir.rs). The public glob +// declaration must drive the effective visibility of the whole reexport chain. + +#![feature(rustc_attrs)] +#![allow(internal_features)] +#![deny(dead_code)] + +mod inner { + #[rustc_effective_visibility] + pub fn f() {} //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub +} + +mod facade { + #[allow(unused_imports)] + pub(crate) use super::inner::f; +} + +#[allow(unused_imports)] +use facade::*; +pub use inner::*; + +fn main() {} diff --git a/tests/ui/imports/ambiguous-import-visibility-globglob-reachable.stderr b/tests/ui/imports/ambiguous-import-visibility-globglob-reachable.stderr new file mode 100644 index 0000000000000..c27e6a2ac807b --- /dev/null +++ b/tests/ui/imports/ambiguous-import-visibility-globglob-reachable.stderr @@ -0,0 +1,8 @@ +error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub + --> $DIR/ambiguous-import-visibility-globglob-reachable.rs:14:5 + | +LL | pub fn f() {} + | ^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/imports/auxiliary/ambiguous-import-visibility-globglob-mir.rs b/tests/ui/imports/auxiliary/ambiguous-import-visibility-globglob-mir.rs new file mode 100644 index 0000000000000..a1e125bd55637 --- /dev/null +++ b/tests/ui/imports/auxiliary/ambiguous-import-visibility-globglob-mir.rs @@ -0,0 +1,19 @@ +// An item exported only through a public glob, while also glob-imported into the +// same module through a facade with restricted visibility. The restricted duplicate +// must not make `f` unreachable: its optimized MIR must still be encoded for +// downstream crates (it is `cross_crate_inlinable`). + +mod inner { + pub fn f() -> u32 { + 42 + } +} + +mod facade { + #[allow(unused_imports)] + pub(crate) use super::inner::f; +} + +#[allow(unused_imports)] +use facade::*; +pub use inner::*; diff --git a/tests/ui/issues/issue-33504.rs b/tests/ui/issues/issue-33504.rs deleted file mode 100644 index 89cc06ede5e48..0000000000000 --- a/tests/ui/issues/issue-33504.rs +++ /dev/null @@ -1,9 +0,0 @@ -// Shadowing a unit-like enum in a closure - -struct Test; - -fn main() { - || { - let Test = 1; //~ ERROR mismatched types - }; -} diff --git a/tests/ui/issues/issue-33525.rs b/tests/ui/issues/issue-33525.rs deleted file mode 100644 index 74f21eff20f69..0000000000000 --- a/tests/ui/issues/issue-33525.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - a; //~ ERROR cannot find value `a` - "".lorem; //~ ERROR no field - "".ipsum; //~ ERROR no field -} diff --git a/tests/ui/issues/issue-34751.rs b/tests/ui/issues/issue-34751.rs deleted file mode 100644 index 1e842049b14c1..0000000000000 --- a/tests/ui/issues/issue-34751.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ check-pass -#![allow(dead_code)] -// #34751 ICE: 'rustc' panicked at 'assertion failed: !substs.has_regions_escaping_depth(0)' - -#[allow(dead_code)] - -use std::marker::PhantomData; - -fn f<'a>(PhantomData::<&'a u8>: PhantomData<&'a u8>) {} - -fn main() {} diff --git a/tests/ui/issues/issue-36816.rs b/tests/ui/issues/issue-36816.rs deleted file mode 100644 index d15a9c7abe15b..0000000000000 --- a/tests/ui/issues/issue-36816.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass -macro_rules! m { () => { 1 } } -macro_rules! n { () => { 1 + m!() } } - -fn main() { - let _: [u32; n!()] = [0, 0]; -} diff --git a/tests/ui/issues/issue-36836.rs b/tests/ui/issues/issue-36836.rs deleted file mode 100644 index 99c56213153e4..0000000000000 --- a/tests/ui/issues/issue-36836.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Previously, in addition to the real cause of the problem as seen below, -// the compiler would tell the user: -// -// ``` -// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or -// predicates -// ``` -// -// With this test, we check that only the relevant error is emitted. - -trait Foo {} - -impl Foo for Bar {} //~ ERROR cannot find type `Bar` in this scope - -fn main() {} diff --git a/tests/ui/issues/issue-33941.current.stderr b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.current.stderr similarity index 88% rename from tests/ui/issues/issue-33941.current.stderr rename to tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.current.stderr index d653bbd327427..9ceacdc7bfbdd 100644 --- a/tests/ui/issues/issue-33941.current.stderr +++ b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.current.stderr @@ -1,5 +1,5 @@ error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` - --> $DIR/issue-33941.rs:9:36 + --> $DIR/cloned-hashmap-iter-type-mismatch-diag.rs:12:36 | LL | for _ in HashMap::new().iter().cloned() {} | ^^^^^^ expected `&_`, found `(&_, &_)` @@ -7,7 +7,7 @@ LL | for _ in HashMap::new().iter().cloned() {} = note: expected reference `&_` found tuple `(&_, &_)` note: the method call chain might not have had the expected associated types - --> $DIR/issue-33941.rs:9:29 + --> $DIR/cloned-hashmap-iter-type-mismatch-diag.rs:12:29 | LL | for _ in HashMap::new().iter().cloned() {} | -------------- ^^^^^^ `Iterator::Item` is `(&_, &_)` here @@ -17,7 +17,7 @@ note: required by a bound in `cloned` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` - --> $DIR/issue-33941.rs:9:14 + --> $DIR/cloned-hashmap-iter-type-mismatch-diag.rs:12:14 | LL | for _ in HashMap::new().iter().cloned() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `(&_, &_)` diff --git a/tests/ui/issues/issue-33941.next.stderr b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.next.stderr similarity index 88% rename from tests/ui/issues/issue-33941.next.stderr rename to tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.next.stderr index d653bbd327427..9ceacdc7bfbdd 100644 --- a/tests/ui/issues/issue-33941.next.stderr +++ b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.next.stderr @@ -1,5 +1,5 @@ error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` - --> $DIR/issue-33941.rs:9:36 + --> $DIR/cloned-hashmap-iter-type-mismatch-diag.rs:12:36 | LL | for _ in HashMap::new().iter().cloned() {} | ^^^^^^ expected `&_`, found `(&_, &_)` @@ -7,7 +7,7 @@ LL | for _ in HashMap::new().iter().cloned() {} = note: expected reference `&_` found tuple `(&_, &_)` note: the method call chain might not have had the expected associated types - --> $DIR/issue-33941.rs:9:29 + --> $DIR/cloned-hashmap-iter-type-mismatch-diag.rs:12:29 | LL | for _ in HashMap::new().iter().cloned() {} | -------------- ^^^^^^ `Iterator::Item` is `(&_, &_)` here @@ -17,7 +17,7 @@ note: required by a bound in `cloned` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` - --> $DIR/issue-33941.rs:9:14 + --> $DIR/cloned-hashmap-iter-type-mismatch-diag.rs:12:14 | LL | for _ in HashMap::new().iter().cloned() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `(&_, &_)` diff --git a/tests/ui/issues/issue-33941.rs b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.rs similarity index 77% rename from tests/ui/issues/issue-33941.rs rename to tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.rs index e49efc3bfd496..de402fbb7fba5 100644 --- a/tests/ui/issues/issue-33941.rs +++ b/tests/ui/iterators/cloned-hashmap-iter-type-mismatch-diag.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Test iterator type mismatch prints pretty error message. +//! This used to emit many duplicated, unhelpful error messages. //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver diff --git a/tests/ui/lifetimes/lifetime-in-unit-struct-pattern.rs b/tests/ui/lifetimes/lifetime-in-unit-struct-pattern.rs new file mode 100644 index 0000000000000..b9eebc8dac0f2 --- /dev/null +++ b/tests/ui/lifetimes/lifetime-in-unit-struct-pattern.rs @@ -0,0 +1,12 @@ +//! Regression test for . +//! This used to ICE with +//! `assertion failed: !substs.has_regions_escaping_depth(0)`. +//@ check-pass + +#![allow(dead_code)] + +use std::marker::PhantomData; + +fn f<'a>(PhantomData::<&'a u8>: PhantomData<&'a u8>) {} + +fn main() {} diff --git a/tests/ui/issues/issue-36744-bitcast-args-if-needed.rs b/tests/ui/lifetimes/lifetime-param-in-fn-coercion.rs similarity index 55% rename from tests/ui/issues/issue-36744-bitcast-args-if-needed.rs rename to tests/ui/lifetimes/lifetime-param-in-fn-coercion.rs index 8fcd0c3f41c9a..7f8af7e6b49d4 100644 --- a/tests/ui/issues/issue-36744-bitcast-args-if-needed.rs +++ b/tests/ui/lifetimes/lifetime-param-in-fn-coercion.rs @@ -1,7 +1,8 @@ +//! Regression test for . +//! This tests for an ICE (and, if ignored, subsequent LLVM abort) when +//! a lifetime-parametric fn is passed into a context whose expected +//! type has a differing lifetime parameterization. //@ run-pass -// This tests for an ICE (and, if ignored, subsequent LLVM abort) when -// a lifetime-parametric fn is passed into a context whose expected -// type has a differing lifetime parameterization. struct A<'a> { _a: &'a i32, diff --git a/tests/ui/macros/macro-in-array-len-expr.rs b/tests/ui/macros/macro-in-array-len-expr.rs new file mode 100644 index 0000000000000..272ee7f90cecc --- /dev/null +++ b/tests/ui/macros/macro-in-array-len-expr.rs @@ -0,0 +1,10 @@ +//! Regression test for . +//! Macro invocation in len position in arrays used to ICE. +//@ run-pass + +macro_rules! m { () => { 1 } } +macro_rules! n { () => { 1 + m!() } } + +fn main() { + let _: [u32; n!()] = [0, 0]; +} diff --git a/tests/ui/issues/issue-3574.rs b/tests/ui/match/match-borrowed-str.rs similarity index 60% rename from tests/ui/issues/issue-3574.rs rename to tests/ui/match/match-borrowed-str.rs index 36c1e2ad93ee8..48597ed2c18f1 100644 --- a/tests/ui/issues/issue-3574.rs +++ b/tests/ui/match/match-borrowed-str.rs @@ -1,6 +1,6 @@ +//! Regression test for . +//! Test pattern-matching on `&str` doesn't ICE. //@ run-pass -// rustc --test match_borrowed_str.rs.rs && ./match_borrowed_str.rs - fn compare(x: &str, y: &str) -> bool { match x { diff --git a/tests/ui/issues/issue-35423.rs b/tests/ui/match/range-arm-and-ref-arm.rs similarity index 70% rename from tests/ui/issues/issue-35423.rs rename to tests/ui/match/range-arm-and-ref-arm.rs index c43d35fea7837..d5a797aa1aaeb 100644 --- a/tests/ui/issues/issue-35423.rs +++ b/tests/ui/match/range-arm-and-ref-arm.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! This used to ICE. //@ run-pass + fn main () { let x = 4; match x { diff --git a/tests/ui/shadowed/shadow-unit-struct-in-closure.rs b/tests/ui/shadowed/shadow-unit-struct-in-closure.rs new file mode 100644 index 0000000000000..355c5f3c9f8d7 --- /dev/null +++ b/tests/ui/shadowed/shadow-unit-struct-in-closure.rs @@ -0,0 +1,10 @@ +//! Regression test for . +//! Test shadowing a unit-like struct in a closure doesn't cause ICE. + +struct Test; + +fn main() { + || { + let Test = 1; //~ ERROR mismatched types + }; +} diff --git a/tests/ui/issues/issue-33504.stderr b/tests/ui/shadowed/shadow-unit-struct-in-closure.stderr similarity index 91% rename from tests/ui/issues/issue-33504.stderr rename to tests/ui/shadowed/shadow-unit-struct-in-closure.stderr index e5a2eea751d0e..44845135c1deb 100644 --- a/tests/ui/issues/issue-33504.stderr +++ b/tests/ui/shadowed/shadow-unit-struct-in-closure.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-33504.rs:7:13 + --> $DIR/shadow-unit-struct-in-closure.rs:8:13 | LL | struct Test; | ----------- unit struct defined here diff --git a/tests/ui/issues/issue-3447.rs b/tests/ui/structs-enums/generic-recursive-list-struct.rs similarity index 84% rename from tests/ui/issues/issue-3447.rs rename to tests/ui/structs-enums/generic-recursive-list-struct.rs index ab844b0bb9061..f91cffecaa675 100644 --- a/tests/ui/issues/issue-3447.rs +++ b/tests/ui/structs-enums/generic-recursive-list-struct.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! This used to overflow stack. //@ run-pass + #![allow(dead_code)] #![allow(non_snake_case)] #![allow(non_camel_case_types)] diff --git a/tests/ui/issues/issue-35976.rs b/tests/ui/suggestions/trait-object-import-suggestion-on-method.rs similarity index 73% rename from tests/ui/issues/issue-35976.rs rename to tests/ui/suggestions/trait-object-import-suggestion-on-method.rs index 03d4a187f5557..d3600188e822d 100644 --- a/tests/ui/issues/issue-35976.rs +++ b/tests/ui/suggestions/trait-object-import-suggestion-on-method.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! This used to emit spurious `Sized` bound unsatisfied error when trait +//! was not imported, instead of suggestion to import it. //@ edition:2015 //@ revisions: imported unimported //@[imported] check-pass diff --git a/tests/ui/issues/issue-35976.unimported.stderr b/tests/ui/suggestions/trait-object-import-suggestion-on-method.unimported.stderr similarity index 87% rename from tests/ui/issues/issue-35976.unimported.stderr rename to tests/ui/suggestions/trait-object-import-suggestion-on-method.unimported.stderr index db2973d902efb..5f5e4b7f47294 100644 --- a/tests/ui/issues/issue-35976.unimported.stderr +++ b/tests/ui/suggestions/trait-object-import-suggestion-on-method.unimported.stderr @@ -1,5 +1,5 @@ error: the `wait` method cannot be invoked on a trait object - --> $DIR/issue-35976.rs:21:9 + --> $DIR/trait-object-import-suggestion-on-method.rs:24:9 | LL | fn wait(&self) where Self: Sized; | ----- this has a `Sized` requirement diff --git a/tests/ui/issues/issue-33770.rs b/tests/ui/threads-sendsync/no-double-lock-same-thread.rs similarity index 84% rename from tests/ui/issues/issue-33770.rs rename to tests/ui/threads-sendsync/no-double-lock-same-thread.rs index 814e8f371765e..278ff0242950e 100644 --- a/tests/ui/issues/issue-33770.rs +++ b/tests/ui/threads-sendsync/no-double-lock-same-thread.rs @@ -1,3 +1,13 @@ +//! Regression test for . +//! Ensure both `Mutex` and `RwLock` cannot be locked twice on same +//! thread. +//! +//! This was possible as mutexes were initialized with `PTHREAD_MUTEX_DEFAULT` +//! for which attempt to relock from the same thread is considered undefined +//! behaviour, and during glibc's lock-elision transaction lock appeared +//! unlocked, which allowed to lock it again from the same thread. +//! +//! This resulted in ability to aquire 2 mutable references at the same time. //@ run-pass //@ needs-subprocess diff --git a/tests/ui/traits/next-solver/opaques/dont-ice-replacing-non-rigid-opaque.rs b/tests/ui/traits/next-solver/opaques/dont-ice-replacing-non-rigid-opaque.rs new file mode 100644 index 0000000000000..69c53efa14c5c --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/dont-ice-replacing-non-rigid-opaque.rs @@ -0,0 +1,25 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// Regression test for #158784 +// +// We should assert that only opaque types that is to be replaced +// are non-rigid. We can have rigid opaque types elsewhere. + +#![feature(type_alias_impl_trait)] +type Rigid = impl Sized; +#[define_opaque(Rigid)] +fn define_rigid() -> Rigid {} + +type MyIter = impl Iterator; + +#[define_opaque(MyIter)] +fn define_my_iter(a: T) -> MyIter { + if false { + // `Rigid` being rigid is totally fine here. + let _: MyIter = std::iter::once(define_rigid()); + } + std::iter::once(a) +} + +fn main() {} diff --git a/tests/ui/issues/issue-34503.rs b/tests/ui/where-clauses/obligation-error-propagation.rs similarity index 59% rename from tests/ui/issues/issue-34503.rs rename to tests/ui/where-clauses/obligation-error-propagation.rs index 68d84bae3d859..501d89e6162d4 100644 --- a/tests/ui/issues/issue-34503.rs +++ b/tests/ui/where-clauses/obligation-error-propagation.rs @@ -1,4 +1,8 @@ +//! Regression test for . +//! `(T, Option)` falsly marked Option as proved when T failed, +//! this made use of invalid Option bound possible anywhere. //@ run-pass + fn main() { struct X; trait Foo { diff --git a/tests/ui/issues/issue-34503.stderr b/tests/ui/where-clauses/obligation-error-propagation.stderr similarity index 88% rename from tests/ui/issues/issue-34503.stderr rename to tests/ui/where-clauses/obligation-error-propagation.stderr index 1877e20bbc14d..a796002caf951 100644 --- a/tests/ui/issues/issue-34503.stderr +++ b/tests/ui/where-clauses/obligation-error-propagation.stderr @@ -1,5 +1,5 @@ warning: methods `foo` and `bar` are never used - --> $DIR/issue-34503.rs:5:12 + --> $DIR/obligation-error-propagation.rs:9:12 | LL | trait Foo { | --- methods in this trait