diff options
60 files changed, 368 insertions, 339 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 4ac7bea03eb..6fe8527ada6 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -270,10 +270,9 @@ pub fn each_linked_rlib( /// Create an 'rlib'. /// -/// An rlib in its current incarnation is essentially a renamed .a file. The rlib primarily contains -/// the object file of the crate, but it also contains all of the object files from native -/// libraries. This is done by unzipping native libraries and inserting all of the contents into -/// this archive. +/// An rlib in its current incarnation is essentially a renamed .a file (with "dummy" object files). +/// The rlib primarily contains the object file of the crate, but it also some of the object files +/// from native libraries. fn link_rlib<'a>( sess: &'a Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, @@ -347,44 +346,23 @@ fn link_rlib<'a>( // loaded from the libraries found here and then encode that into the // metadata of the rlib we're generating somehow. for lib in codegen_results.crate_info.used_libraries.iter() { - match lib.kind { - NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) } - if flavor == RlibFlavor::Normal && sess.opts.unstable_opts.packed_bundled_libs => {} - NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) } - if flavor == RlibFlavor::Normal => - { - // Don't allow mixing +bundle with +whole_archive since an rlib may contain - // multiple native libs, some of which are +whole-archive and some of which are - // -whole-archive and it isn't clear how we can currently handle such a - // situation correctly. - // See https://github.com/rust-lang/rust/issues/88085#issuecomment-901050897 - sess.emit_err(errors::IncompatibleLinkingModifiers); - } - NativeLibKind::Static { bundle: None | Some(true), .. } => {} - NativeLibKind::Static { bundle: Some(false), .. } - | NativeLibKind::Dylib { .. } - | NativeLibKind::Framework { .. } - | NativeLibKind::RawDylib - | NativeLibKind::LinkArg - | NativeLibKind::Unspecified => continue, - } - if let Some(name) = lib.name { - let location = + let NativeLibKind::Static { bundle: None | Some(true), whole_archive } = lib.kind else { + continue; + }; + if whole_archive == Some(true) && !codegen_results.crate_info.feature_packed_bundled_libs { + sess.emit_err(errors::IncompatibleLinkingModifiers); + } + if flavor == RlibFlavor::Normal && let Some(filename) = lib.filename { + let path = find_native_static_library(filename.as_str(), true, &lib_search_paths, sess); + let src = read(path).map_err(|e| sess.emit_fatal(errors::ReadFileError {message: e }))?; + let (data, _) = create_wrapper_file(sess, b".bundled_lib".to_vec(), &src); + let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str()); + packed_bundled_libs.push(wrapper_file); + } else if let Some(name) = lib.name { + let path = find_native_static_library(name.as_str(), lib.verbatim, &lib_search_paths, sess); - if sess.opts.unstable_opts.packed_bundled_libs && flavor == RlibFlavor::Normal { - let filename = lib.filename.unwrap(); - let lib_path = - find_native_static_library(filename.as_str(), true, &lib_search_paths, sess); - let src = read(lib_path) - .map_err(|e| sess.emit_fatal(errors::ReadFileError { message: e }))?; - let (data, _) = create_wrapper_file(sess, b".bundled_lib".to_vec(), &src); - let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str()); - packed_bundled_libs.push(wrapper_file); - continue; - } - ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|error| { - sess.emit_fatal(errors::AddNativeLibrary { library_path: location, error }); - }); + ab.add_archive(&path, Box::new(|_| false)).unwrap_or_else(|error| { + sess.emit_fatal(errors::AddNativeLibrary { library_path: path, error })}); } } @@ -516,36 +494,14 @@ fn link_staticlib<'a>( &codegen_results.crate_info, Some(CrateType::Staticlib), &mut |cnum, path| { - let name = codegen_results.crate_info.crate_name[&cnum]; - let native_libs = &codegen_results.crate_info.native_libraries[&cnum]; - - // Here when we include the rlib into our staticlib we need to make a - // decision whether to include the extra object files along the way. - // These extra object files come from statically included native - // libraries, but they may be cfg'd away with #[link(cfg(..))]. - // - // This unstable feature, though, only needs liblibc to work. The only - // use case there is where musl is statically included in liblibc.rlib, - // so if we don't want the included version we just need to skip it. As - // a result the logic here is that if *any* linked library is cfg'd away - // we just skip all object files. - // - // Clearly this is not sufficient for a general purpose feature, and - // we'd want to read from the library's metadata to determine which - // object files come from where and selectively skip them. - let skip_object_files = native_libs.iter().any(|lib| { - matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. }) - && !relevant_lib(sess, lib) - }); - let lto = are_upstream_rust_objects_already_included(sess) && !ignored_for_lto(sess, &codegen_results.crate_info, cnum); - // Ignoring obj file starting with the crate name - // as simple comparison is not enough - there - // might be also an extra name suffix - let obj_start = name.as_str().to_owned(); + let native_libs = codegen_results.crate_info.native_libraries[&cnum].iter(); + let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, &lib)); + let relevant_libs: FxHashSet<_> = relevant.filter_map(|lib| lib.filename).collect(); + let bundled_libs: FxHashSet<_> = native_libs.filter_map(|lib| lib.filename).collect(); ab.add_archive( path, Box::new(move |fname: &str| { @@ -559,20 +515,25 @@ fn link_staticlib<'a>( return true; } - // Otherwise if this is *not* a rust object and we're skipping - // objects then skip this file - if skip_object_files - && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) - { + // Skip objects for bundled libs. + if bundled_libs.contains(&Symbol::intern(fname)) { return true; } - // ok, don't skip this false }), ) .unwrap(); + archive_builder_builder + .extract_bundled_libs(path, tempdir.as_ref(), &relevant_libs) + .unwrap_or_else(|e| sess.emit_fatal(e)); + for filename in relevant_libs { + let joined = tempdir.as_ref().join(filename.as_str()); + let path = joined.as_path(); + ab.add_archive(path, Box::new(|_| false)).unwrap(); + } + all_native_libs .extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned()); }, @@ -2590,18 +2551,8 @@ fn add_static_crate<'a>( cmd.link_rlib(&fix_windows_verbatim_for_gcc(path)); }; - // See the comment above in `link_staticlib` and `link_rlib` for why if - // there's a static library that's not relevant we skip all object - // files. - let native_libs = &codegen_results.crate_info.native_libraries[&cnum]; - let skip_native = native_libs.iter().any(|lib| { - matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. }) - && !relevant_lib(sess, lib) - }); - - if (!are_upstream_rust_objects_already_included(sess) - || ignored_for_lto(sess, &codegen_results.crate_info, cnum)) - && !skip_native + if !are_upstream_rust_objects_already_included(sess) + || ignored_for_lto(sess, &codegen_results.crate_info, cnum) { link_upstream(cratepath); return; @@ -2632,17 +2583,13 @@ fn add_static_crate<'a>( let is_rust_object = canonical.starts_with(&canonical_name) && looks_like_rust_object_file(&f); - // If we've been requested to skip all native object files - // (those not generated by the rust compiler) then we can skip - // this file. See above for why we may want to do this. - let skip_because_cfg_say_so = skip_native && !is_rust_object; - // If we're performing LTO and this is a rust-generated object // file, then we don't need the object file as it's part of the // LTO module. Note that `#![no_builtins]` is excluded from LTO, // though, so we let that object file slide. - let skip_because_lto = - upstream_rust_objects_already_included && is_rust_object && is_builtins; + if upstream_rust_objects_already_included && is_rust_object && is_builtins { + return true; + } // We skip native libraries because: // 1. This native libraries won't be used from the generated rlib, @@ -2653,10 +2600,6 @@ fn add_static_crate<'a>( return true; } - if skip_because_cfg_say_so || skip_because_lto { - return true; - } - false }), ) { diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 02b502d948c..de2727c8a5d 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -858,6 +858,7 @@ impl CrateInfo { dependency_formats: tcx.dependency_formats(()).clone(), windows_subsystem, natvis_debugger_visualizers: Default::default(), + feature_packed_bundled_libs: tcx.features().packed_bundled_libs, }; let crates = tcx.crates(()); diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 0e6596d4ba7..d5530c47680 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -159,6 +159,7 @@ pub struct CrateInfo { pub dependency_formats: Lrc<Dependencies>, pub windows_subsystem: Option<String>, pub natvis_debugger_visualizers: BTreeSet<DebuggerVisualizerFile>, + pub feature_packed_bundled_libs: bool, // unstable feature flag. } #[derive(Encodable, Decodable)] diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 4924105128d..8fe5f8d50ab 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -22,7 +22,7 @@ codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files w codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error} -codegen_ssa_incompatible_linking_modifiers = the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs +codegen_ssa_incompatible_linking_modifiers = link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error} diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 323f5a368fc..21d211eefbe 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -164,6 +164,8 @@ declare_features! ( (active, multiple_supertrait_upcastable, "CURRENT_RUSTC_VERSION", None, None), /// Allows using `#[omit_gdb_pretty_printer_section]`. (active, omit_gdb_pretty_printer_section, "1.5.0", None, None), + /// Allows using `+bundled,+whole-archive` native libs. + (active, packed_bundled_libs, "1.67.0", None, None), /// Allows using `#[prelude_import]` on glob `use` items. (active, prelude_import, "1.2.0", None, None), /// Used to identify crates that contain the profiler runtime. diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index e263fc74835..a8514c69d1c 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -49,20 +49,21 @@ fn find_bundled_library( name: Option<Symbol>, verbatim: Option<bool>, kind: NativeLibKind, + has_cfg: bool, sess: &Session, ) -> Option<Symbol> { - if sess.opts.unstable_opts.packed_bundled_libs && - sess.crate_types().iter().any(|ct| ct == &CrateType::Rlib || ct == &CrateType::Staticlib) && - let NativeLibKind::Static { bundle: Some(true) | None, .. } = kind { - find_native_static_library( - name.unwrap().as_str(), - verbatim.unwrap_or(false), - &sess.target_filesearch(PathKind::Native).search_path_dirs(), - sess, - ).file_name().and_then(|s| s.to_str()).map(Symbol::intern) - } else { - None + if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind + && sess.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); + let search_paths = &sess.target_filesearch(PathKind::Native).search_path_dirs(); + return find_native_static_library(name.unwrap().as_str(), verbatim, search_paths, sess) + .file_name() + .and_then(|s| s.to_str()) + .map(Symbol::intern); } + None } pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> { @@ -385,7 +386,7 @@ impl<'tcx> Collector<'tcx> { let name = name.map(|(name, _)| name); let kind = kind.unwrap_or(NativeLibKind::Unspecified); - let filename = find_bundled_library(name, verbatim, kind, sess); + let filename = find_bundled_library(name, verbatim, kind, cfg.is_some(), sess); self.libs.push(NativeLib { name, filename, @@ -475,7 +476,7 @@ impl<'tcx> Collector<'tcx> { let name = Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name))); let sess = self.tcx.sess; let filename = - find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, sess); + find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, false, sess); self.libs.push(NativeLib { name, filename, diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index e4bb3ce3d5a..dc02fd53ed0 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -8,7 +8,7 @@ use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::{self, layout::TyAndLayout, Ty, TyCtxt}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::hir_id::{HirId, OwnerId}; -use rustc_query_system::query::{DefaultCacheSelector, VecCacheSelector}; +use rustc_query_system::query::{DefaultCacheSelector, SingleCacheSelector, VecCacheSelector}; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -45,7 +45,7 @@ pub trait Key: Sized { } impl Key for () { - type CacheSelector = DefaultCacheSelector<Self>; + type CacheSelector = SingleCacheSelector; #[inline(always)] fn query_crate_is_local(&self) -> bool { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 7ba531fba78..e9a10f483e5 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -22,7 +22,6 @@ use rustc_target::spec::abi::Abi; use smallvec::SmallVec; use std::cell::Cell; -use std::char; use std::collections::BTreeMap; use std::fmt::{self, Write as _}; use std::iter; diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 26acd406ed8..30d8511153a 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -318,6 +318,8 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { // ConstProp will pick up the pieces and replace them by actual constants. StatementKind::Assign(box (place, Rvalue::Use(Operand::Constant(_)))) => { if let Some(final_locals) = self.replacements.place_fragments(place) { + // Put the deaggregated statements *after* the original one. + let location = location.successor_within_block(); for (field, ty, new_local) in final_locals { let rplace = self.tcx.mk_place_field(place, field, ty); let rvalue = Rvalue::Use(Operand::Move(rplace)); diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 9f875b43731..c9dd75e4d55 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sharded; #[cfg(parallel_compiler)] use rustc_data_structures::sharded::Sharded; -#[cfg(not(parallel_compiler))] use rustc_data_structures::sync::Lock; use rustc_data_structures::sync::WorkerLocal; use rustc_index::vec::{Idx, IndexVec}; @@ -117,6 +116,52 @@ where } } +pub struct SingleCacheSelector; + +impl<'tcx, V: 'tcx> CacheSelector<'tcx, V> for SingleCacheSelector { + type Cache = SingleCache<V> + where + V: Copy; + type ArenaCache = ArenaCache<'tcx, (), V>; +} + +pub struct SingleCache<V> { + cache: Lock<Option<(V, DepNodeIndex)>>, +} + +impl<V> Default for SingleCache<V> { + fn default() -> Self { + SingleCache { cache: Lock::new(None) } + } +} + +impl<V: Copy + Debug> QueryStorage for SingleCache<V> { + type Value = V; + type Stored = V; +} + +impl<V> QueryCache for SingleCache<V> +where + V: Copy + Debug, +{ + type Key = (); + + #[inline(always)] + fn lookup(&self, _key: &()) -> Option<(V, DepNodeIndex)> { + *self.cache.lock() + } + + #[inline] + fn complete(&self, _key: (), value: V, index: DepNodeIndex) -> Self::Stored { + *self.cache.lock() = Some((value.clone(), index)); + value + } + + fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { + self.cache.lock().as_ref().map(|value| f(&(), &value.0, value.1)); + } +} + pub struct ArenaCache<'tcx, K, V> { arena: WorkerLocal<TypedArena<(V, DepNodeIndex)>>, #[cfg(parallel_compiler)] diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index d308af19207..6c0ee2bc2f6 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -8,7 +8,8 @@ pub use self::job::{print_query_stack, QueryInfo, QueryJob, QueryJobId, QueryJob mod caches; pub use self::caches::{ - CacheSelector, DefaultCacheSelector, QueryCache, QueryStorage, VecCacheSelector, + CacheSelector, DefaultCacheSelector, QueryCache, QueryStorage, SingleCacheSelector, + VecCacheSelector, }; mod config; diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index fe6ac80fde6..be1ff8559cf 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -156,7 +156,7 @@ pub struct Session { /// `-C metadata` arguments passed to the compiler. Its value forms a unique /// global identifier for the crate. It is used to allow multiple crates /// with the same name to coexist. See the - /// `rustc_codegen_llvm::back::symbol_names` module for more information. + /// `rustc_symbol_mangling` crate for more information. pub stable_crate_id: OnceCell<StableCrateId>, features: OnceCell<rustc_feature::Features>, diff --git a/compiler/rustc_span/src/lev_distance/tests.rs b/compiler/rustc_span/src/lev_distance/tests.rs index b17d6588c9f..ed03b22c61f 100644 --- a/compiler/rustc_span/src/lev_distance/tests.rs +++ b/compiler/rustc_span/src/lev_distance/tests.rs @@ -2,9 +2,8 @@ use super::*; #[test] fn test_lev_distance() { - use std::char::{from_u32, MAX}; // Test bytelength agnosticity - for c in (0..MAX as u32).filter_map(from_u32).map(|i| i.to_string()) { + for c in (0..char::MAX as u32).filter_map(char::from_u32).map(|i| i.to_string()) { assert_eq!(lev_distance(&c[..], &c[..], usize::MAX), Some(0)); } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1ced75cccbb..ef417d3e0a7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1049,6 +1049,7 @@ symbols! { overlapping_marker_traits, owned_box, packed, + packed_bundled_libs, panic, panic_2015, panic_2021, diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index 11bd4c4dc1b..f99395c72aa 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -991,12 +991,6 @@ impl IntoStringError { pub fn utf8_error(&self) -> Utf8Error { self.error } - - #[doc(hidden)] - #[unstable(feature = "cstr_internals", issue = "none")] - pub fn __source(&self) -> &Utf8Error { - &self.error - } } impl IntoStringError { @@ -1141,6 +1135,6 @@ impl core::error::Error for IntoStringError { } fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - Some(self.__source()) + Some(&self.error) } } diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 75659188515..2b843647dd5 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -42,8 +42,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -#[cfg(not(no_global_oom_handling))] -use core::char::{decode_utf16, REPLACEMENT_CHARACTER}; use core::error::Error; use core::fmt; use core::hash; @@ -683,7 +681,7 @@ impl String { // This isn't done via collect::<Result<_, _>>() for performance reasons. // FIXME: the function can be simplified again when #48994 is closed. let mut ret = String::with_capacity(v.len()); - for c in decode_utf16(v.iter().cloned()) { + for c in char::decode_utf16(v.iter().cloned()) { if let Ok(c) = c { ret.push(c); } else { @@ -722,7 +720,9 @@ impl String { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn from_utf16_lossy(v: &[u16]) -> String { - decode_utf16(v.iter().cloned()).map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)).collect() + char::decode_utf16(v.iter().cloned()) + .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER)) + .collect() } /// Decomposes a `String` into its raw components. diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 2825e0bbb43..5decd7d5a65 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -131,7 +131,8 @@ pub struct TryFromSliceError(()); impl fmt::Display for TryFromSliceError { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self.__description(), f) + #[allow(deprecated)] + self.description().fmt(f) } } @@ -139,20 +140,6 @@ impl fmt::Display for TryFromSliceError { impl Error for TryFromSliceError { #[allow(deprecated)] fn description(&self) -> &str { - self.__description() - } -} - -impl TryFromSliceError { - #[unstable( - feature = "array_error_internals", - reason = "available through Error trait and this method should not \ - be exposed publicly", - issue = "none" - )] - #[inline] - #[doc(hidden)] - pub fn __description(&self) -> &str { "could not convert slice to array" } } diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index f1a51a550f5..136bbcb8b21 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -2,6 +2,7 @@ use crate::char::TryFromCharError; use crate::convert::TryFrom; +use crate::error::Error; use crate::fmt; use crate::mem::transmute; use crate::str::FromStr; @@ -150,14 +151,16 @@ pub struct ParseCharError { kind: CharErrorKind, } -impl ParseCharError { - #[unstable( - feature = "char_error_internals", - reason = "this method should not be available publicly", - issue = "none" - )] - #[doc(hidden)] - pub fn __description(&self) -> &str { +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +enum CharErrorKind { + EmptyString, + TooManyChars, +} + +#[stable(feature = "char_from_str", since = "1.20.0")] +impl Error for ParseCharError { + #[allow(deprecated)] + fn description(&self) -> &str { match self.kind { CharErrorKind::EmptyString => "cannot parse char from empty string", CharErrorKind::TooManyChars => "too many characters in string", @@ -165,16 +168,11 @@ impl ParseCharError { } } -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -enum CharErrorKind { - EmptyString, - TooManyChars, -} - #[stable(feature = "char_from_str", since = "1.20.0")] impl fmt::Display for ParseCharError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.__description().fmt(f) + #[allow(deprecated)] + self.description().fmt(f) } } diff --git a/library/core/src/char/decode.rs b/library/core/src/char/decode.rs index eeb08803040..dbfe251f2bb 100644 --- a/library/core/src/char/decode.rs +++ b/library/core/src/char/decode.rs @@ -3,8 +3,6 @@ use crate::error::Error; use crate::fmt; -use super::from_u32_unchecked; - /// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s. /// /// This `struct` is created by the [`decode_utf16`] method on [`char`]. See its @@ -49,7 +47,7 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> { if !u.is_utf16_surrogate() { // SAFETY: not a surrogate - Some(Ok(unsafe { from_u32_unchecked(u as u32) })) + Some(Ok(unsafe { char::from_u32_unchecked(u as u32) })) } else if u >= 0xDC00 { // a trailing surrogate Some(Err(DecodeUtf16Error { code: u })) @@ -69,7 +67,7 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> { // all ok, so lets decode it. let c = (((u & 0x3ff) as u32) << 10 | (u2 & 0x3ff) as u32) + 0x1_0000; // SAFETY: we checked that it's a legal unicode value - Some(Ok(unsafe { from_u32_unchecked(c) })) + Some(Ok(unsafe { char::from_u32_unchecked(c) })) } } diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 3e7383b4cd1..9bc97ea0bff 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -53,15 +53,13 @@ impl char { /// Basic usage: /// /// ``` - /// use std::char::decode_utf16; - /// /// // 𝄞mus<invalid>ic<invalid> /// let v = [ /// 0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834, /// ]; /// /// assert_eq!( - /// decode_utf16(v) + /// char::decode_utf16(v) /// .map(|r| r.map_err(|e| e.unpaired_surrogate())) /// .collect::<Vec<_>>(), /// vec![ @@ -77,16 +75,14 @@ impl char { /// A lossy decoder can be obtained by replacing `Err` results with the replacement character: /// /// ``` - /// use std::char::{decode_utf16, REPLACEMENT_CHARACTER}; - /// /// // 𝄞mus<invalid>ic<invalid> /// let v = [ /// 0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834, /// ]; /// /// assert_eq!( - /// decode_utf16(v) - /// .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)) + /// char::decode_utf16(v) + /// .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER)) /// .collect::<String>(), /// "𝄞mus�ic�" /// ); @@ -123,8 +119,6 @@ impl char { /// Basic usage: /// /// ``` - /// use std::char; - /// /// let c = char::from_u32(0x2764); /// /// assert_eq!(Some('❤'), c); @@ -133,8 +127,6 @@ impl char { /// Returning `None` when the input is not a valid `char`: /// /// ``` - /// use std::char; - /// /// let c = char::from_u32(0x110000); /// /// assert_eq!(None, c); @@ -176,8 +168,6 @@ impl char { /// Basic usage: /// /// ``` - /// use std::char; - /// /// let c = unsafe { char::from_u32_unchecked(0x2764) }; /// /// assert_eq!('❤', c); @@ -210,8 +200,6 @@ impl char { /// Basic usage: /// /// ``` - /// use std::char; - /// /// let c = char::from_digit(4, 10); /// /// assert_eq!(Some('4'), c); @@ -225,8 +213,6 @@ impl char { /// Returning `None` when the input is not a digit: /// /// ``` - /// use std::char; - /// /// let c = char::from_digit(20, 10); /// /// assert_eq!(None, c); @@ -235,8 +221,6 @@ impl char { /// Passing a large radix, causing a panic: /// /// ```should_panic - /// use std::char; - /// /// // this panics /// let _c = char::from_digit(1, 37); /// ``` @@ -1786,7 +1770,7 @@ pub fn encode_utf16_raw(mut code: u32, dst: &mut [u16]) -> &mut [u16] { } else { panic!( "encode_utf16: need {} units to encode U+{:X}, but the buffer has {}", - from_u32_unchecked(code).len_utf16(), + char::from_u32_unchecked(code).len_utf16(), code, dst.len(), ) diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs index af98059cf42..8ec78e88733 100644 --- a/library/core/src/char/mod.rs +++ b/library/core/src/char/mod.rs @@ -189,7 +189,7 @@ impl Iterator for EscapeUnicode { } EscapeUnicodeState::Value => { let hex_digit = ((self.c as u32) >> (self.hex_digit_idx * 4)) & 0xf; - let c = from_digit(hex_digit, 16).unwrap(); + let c = char::from_digit(hex_digit, 16).unwrap(); if self.hex_digit_idx == 0 { self.state = EscapeUnicodeState::RightBrace; } else { diff --git a/library/core/src/error.rs b/library/core/src/error.rs index e11a5e99184..571bc4bcfd1 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -486,25 +486,9 @@ impl Error for crate::char::CharTryFromError { } } -#[stable(feature = "char_from_str", since = "1.20.0")] -impl Error for crate::char::ParseCharError { - #[allow(deprecated)] - fn description(&self) -> &str { - self.__description() - } -} - #[stable(feature = "duration_checked_float", since = "1.66.0")] impl Error for crate::time::TryFromFloatSecsError {} -#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")] -impl Error for crate::ffi::FromBytesWithNulError { - #[allow(deprecated)] - fn description(&self) -> &str { - self.__description() - } -} - #[stable(feature = "cstr_from_bytes_until_nul", since = "CURRENT_RUSTC_VERSION")] impl Error for crate::ffi::FromBytesUntilNulError {} diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 82e5fa75ded..cd00fd0daf9 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -1,4 +1,5 @@ use crate::cmp::Ordering; +use crate::error::Error; use crate::ffi::c_char; use crate::fmt; use crate::intrinsics; @@ -129,10 +130,12 @@ impl FromBytesWithNulError { const fn not_nul_terminated() -> FromBytesWithNulError { FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated } } +} - #[doc(hidden)] - #[unstable(feature = "cstr_internals", issue = "none")] - pub fn __description(&self) -> &str { +#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")] +impl Error for FromBytesWithNulError { + #[allow(deprecated)] + fn description(&self) -> &str { match self.kind { FromBytesWithNulErrorKind::InteriorNul(..) => { "data provided contains an interior nul byte" @@ -180,7 +183,7 @@ impl Default for &CStr { impl fmt::Display for FromBytesWithNulError { #[allow(deprecated, deprecated_in_future)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.__description())?; + f.write_str(self.description())?; if let FromBytesWithNulErrorKind::InteriorNul(pos) = self.kind { write!(f, " at byte pos {pos}")?; } diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index b5739f2f3c0..78e27d73065 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -1,4 +1,3 @@ -use crate::char; use crate::convert::TryFrom; use crate::mem; use crate::ops::{self, Try}; diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index e11bca5962a..07a7d45c7eb 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -871,7 +871,10 @@ pub trait Destruct {} #[rustc_deny_explicit_impl] pub trait Tuple {} -/// A marker for things +/// A marker for pointer-like types. +/// +/// All types that have the same size and alignment as a `usize` or +/// `*const ()` automatically implement this trait. #[unstable(feature = "pointer_like_trait", issue = "none")] #[cfg_attr(bootstrap, lang = "pointer_sized")] #[cfg_attr(not(bootstrap), lang = "pointer_like")] diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index a888ced49b3..f8d493e8b62 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -75,6 +75,7 @@ issue = "none" )] +use crate::error::Error; use crate::fmt; use crate::str::FromStr; @@ -182,15 +183,10 @@ enum FloatErrorKind { Invalid, } -impl ParseFloatError { - #[unstable( - feature = "int_error_internals", - reason = "available through Error trait and this method should \ - not be exposed publicly", - issue = "none" - )] - #[doc(hidden)] - pub fn __description(&self) -> &str { +#[stable(feature = "rust1", since = "1.0.0")] +impl Error for ParseFloatError { + #[allow(deprecated)] + fn description(&self) -> &str { match self.kind { FloatErrorKind::Empty => "cannot parse float from empty string", FloatErrorKind::Invalid => "invalid float literal", @@ -201,7 +197,8 @@ impl ParseFloatError { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for ParseFloatError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.__description().fmt(f) + #[allow(deprecated)] + self.description().fmt(f) } } diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index 768dd87816d..1bae4efe7d9 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -9,23 +9,19 @@ use crate::fmt; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct TryFromIntError(pub(crate) ()); -impl TryFromIntError { - #[unstable( - feature = "int_error_internals", - reason = "available through Error trait and this method should \ - not be exposed publicly", - issue = "none" - )] - #[doc(hidden)] - pub fn __description(&self) -> &str { - "out of range integral type conversion attempted" +#[stable(feature = "try_from", since = "1.34.0")] +impl fmt::Display for TryFromIntError { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + #[allow(deprecated)] + self.description().fmt(fmt) } } #[stable(feature = "try_from", since = "1.34.0")] -impl fmt::Display for TryFromIntError { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - self.__description().fmt(fmt) +impl Error for TryFromIntError { + #[allow(deprecated)] + fn description(&self) -> &str { + "out of range integral type conversion attempted" } } @@ -121,28 +117,13 @@ impl ParseIntError { pub fn kind(&self) -> &IntErrorKind { &self.kind } - #[unstable( - feature = "int_error_internals", - reason = "available through Error trait and this method should \ - not be exposed publicly", - issue = "none" - )] - #[doc(hidden)] - pub fn __description(&self) -> &str { - match self.kind { - IntErrorKind::Empty => "cannot parse integer from empty string", - IntErrorKind::InvalidDigit => "invalid digit found in string", - IntErrorKind::PosOverflow => "number too large to fit in target type", - IntErrorKind::NegOverflow => "number too small to fit in target type", - IntErrorKind::Zero => "number would be zero for non-zero type", - } - } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for ParseIntError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.__description().fmt(f) + #[allow(deprecated)] + self.description().fmt(f) } } @@ -150,14 +131,12 @@ impl fmt::Display for ParseIntError { impl Error for ParseIntError { #[allow(deprecated)] fn description(&self) -> &str { - self.__description() - } -} - -#[stable(feature = "try_from", since = "1.34.0")] -impl Error for TryFromIntError { - #[allow(deprecated)] - fn description(&self) -> &str { - self.__description() + match self.kind { + IntErrorKind::Empty => "cannot parse integer from empty string", + IntErrorKind::InvalidDigit => "invalid digit found in string", + IntErrorKind::PosOverflow => "number too large to fit in target type", + IntErrorKind::NegOverflow => "number too small to fit in target type", + IntErrorKind::Zero => "number would be zero for non-zero type", + } } } diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index ac7f579ebb5..0497416745f 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -9,9 +9,6 @@ use crate::mem; use crate::ops::{Add, Mul, Sub}; use crate::str::FromStr; -#[cfg(not(no_fp_fmt_parse))] -use crate::error::Error; - // Used because the `?` operator is not allowed in a const context. macro_rules! try_opt { ($e:expr) => { @@ -61,15 +58,6 @@ pub use wrapping::Wrapping; #[cfg(not(no_fp_fmt_parse))] pub use dec2flt::ParseFloatError; -#[cfg(not(no_fp_fmt_parse))] -#[stable(feature = "rust1", since = "1.0.0")] -impl Error for ParseFloatError { - #[allow(deprecated)] - fn description(&self) -> &str { - self.__description() - } -} - #[stable(feature = "rust1", since = "1.0.0")] pub use error::ParseIntError; diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs index 2181f9a8118..8f02a446670 100644 --- a/library/core/src/slice/sort.rs +++ b/library/core/src/slice/sort.rs @@ -198,8 +198,11 @@ where } // Choose the greater child. - if child + 1 < v.len() && is_less(&v[child], &v[child + 1]) { - child += 1; + if child + 1 < v.len() { + // We need a branch to be sure not to out-of-bounds index, + // but it's highly predictable. The comparison, however, + // is better done branchless, especially for primitives. + child += is_less(&v[child], &v[child + 1]) as usize; } // Stop if the invariant holds at `node`. diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs index d969475aa48..95c682f42d0 100644 --- a/library/core/src/str/iter.rs +++ b/library/core/src/str/iter.rs @@ -1,6 +1,6 @@ //! Iterators for `str` methods. -use crate::char; +use crate::char as char_mod; use crate::fmt::{self, Write}; use crate::iter::{Chain, FlatMap, Flatten}; use crate::iter::{Copied, Filter, FusedIterator, Map, TrustedLen}; @@ -1455,8 +1455,8 @@ impl FusedIterator for EncodeUtf16<'_> {} #[derive(Clone, Debug)] pub struct EscapeDebug<'a> { pub(super) inner: Chain< - Flatten<option::IntoIter<char::EscapeDebug>>, - FlatMap<Chars<'a>, char::EscapeDebug, CharEscapeDebugContinue>, + Flatten<option::IntoIter<char_mod::EscapeDebug>>, + FlatMap<Chars<'a>, char_mod::EscapeDebug, CharEscapeDebugContinue>, >, } @@ -1464,14 +1464,14 @@ pub struct EscapeDebug<'a> { #[stable(feature = "str_escape", since = "1.34.0")] #[derive(Clone, Debug)] pub struct EscapeDefault<'a> { - pub(super) inner: FlatMap<Chars<'a>, char::EscapeDefault, CharEscapeDefault>, + pub(super) inner: FlatMap<Chars<'a>, char_mod::EscapeDefault, CharEscapeDefault>, } /// The return type of [`str::escape_unicode`]. #[stable(feature = "str_escape", since = "1.34.0")] #[derive(Clone, Debug)] pub struct EscapeUnicode<'a> { - pub(super) inner: FlatMap<Chars<'a>, char::EscapeUnicode, CharEscapeUnicode>, + pub(super) inner: FlatMap<Chars<'a>, char_mod::EscapeUnicode, CharEscapeUnicode>, } macro_rules! escape_types_impls { diff --git a/library/core/tests/iter/range.rs b/library/core/tests/iter/range.rs index 84498a8eae5..0f91ffe2dfc 100644 --- a/library/core/tests/iter/range.rs +++ b/library/core/tests/iter/range.rs @@ -26,7 +26,6 @@ fn test_range() { #[test] fn test_char_range() { - use std::char; // Miri is too slow let from = if cfg!(miri) { char::from_u32(0xD800 - 10).unwrap() } else { '\0' }; let to = if cfg!(miri) { char::from_u32(0xDFFF + 10).unwrap() } else { char::MAX }; diff --git a/library/proc_macro/src/bridge/rpc.rs b/library/proc_macro/src/bridge/rpc.rs index e9d7a46c06f..5b1bfb30983 100644 --- a/library/proc_macro/src/bridge/rpc.rs +++ b/library/proc_macro/src/bridge/rpc.rs @@ -1,7 +1,6 @@ //! Serialization for client-server communication. use std::any::Any; -use std::char; use std::io::Write; use std::num::NonZeroU32; use std::str; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index cd9f74820ae..363a2667174 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -273,12 +273,9 @@ #![feature(utf8_chunks)] // // Library features (core): -#![feature(array_error_internals)] #![feature(atomic_mut_ptr)] -#![feature(char_error_internals)] #![feature(char_internals)] #![feature(core_intrinsics)] -#![feature(cstr_internals)] #![feature(duration_constants)] #![feature(error_generic_member_access)] #![feature(error_in_core)] @@ -290,7 +287,6 @@ #![feature(float_next_up_down)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] -#![feature(int_error_internals)] #![feature(is_some_and)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_write_slice)] diff --git a/library/std/src/sys/windows/stdio.rs b/library/std/src/sys/windows/stdio.rs index 70c9b14a08f..c2cd48470bd 100644 --- a/library/std/src/sys/windows/stdio.rs +++ b/library/std/src/sys/windows/stdio.rs @@ -1,6 +1,5 @@ #![unstable(issue = "none", feature = "windows_stdio")] -use crate::char::decode_utf16; use crate::cmp; use crate::io; use crate::mem::MaybeUninit; @@ -369,7 +368,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit<u16>]) -> io::Result<usiz #[allow(unused)] fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> { let mut written = 0; - for chr in decode_utf16(utf16.iter().cloned()) { + for chr in char::decode_utf16(utf16.iter().cloned()) { match chr { Ok(chr) => { chr.encode_utf8(&mut utf8[written..]); diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index dd53767d452..e202d17e1c2 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -18,10 +18,10 @@ #[cfg(test)] mod tests; +use core::char::{encode_utf16_raw, encode_utf8_raw}; use core::str::next_code_point; use crate::borrow::Cow; -use crate::char; use crate::collections::TryReserveError; use crate::fmt; use crate::hash::{Hash, Hasher}; @@ -235,7 +235,7 @@ impl Wtf8Buf { /// This does **not** include the WTF-8 concatenation check or `is_known_utf8` check. fn push_code_point_unchecked(&mut self, code_point: CodePoint) { let mut bytes = [0; 4]; - let bytes = char::encode_utf8_raw(code_point.value, &mut bytes); + let bytes = encode_utf8_raw(code_point.value, &mut bytes); self.bytes.extend_from_slice(bytes) } @@ -939,7 +939,7 @@ impl<'a> Iterator for EncodeWide<'a> { let mut buf = [0; 2]; self.code_points.next().map(|code_point| { - let n = char::encode_utf16_raw(code_point.value, &mut buf).len(); + let n = encode_utf16_raw(code_point.value, &mut buf).len(); if n == 2 { self.extra = buf[1]; } diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index 6dcba117c24..d6592d2d771 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -181,8 +181,7 @@ impl Config { // appear to have this (even when `../lib` is redundant). // NOTE: there are only two paths here, delimited by a `:` let mut entries = OsString::from("$ORIGIN/../lib:"); - entries.push(t!(fs::canonicalize(nix_deps_dir))); - entries.push("/lib"); + entries.push(t!(fs::canonicalize(nix_deps_dir)).join("lib")); entries }; patchelf.args(&[OsString::from("--set-rpath"), rpath_entries]); @@ -370,6 +369,13 @@ impl Config { if self.should_fix_bins_and_dylibs() { self.fix_bin_or_dylib(&bin_root.join("bin").join("rustfmt")); self.fix_bin_or_dylib(&bin_root.join("bin").join("cargo-fmt")); + let lib_dir = bin_root.join("lib"); + for lib in t!(fs::read_dir(&lib_dir), lib_dir.display().to_string()) { + let lib = t!(lib); + if lib.path().extension() == Some(OsStr::new("so")) { + self.fix_bin_or_dylib(&lib.path()); + } + } } self.create(&rustfmt_stamp, &channel); diff --git a/src/doc/unstable-book/src/library-features/char-error-internals.md b/src/doc/unstable-book/src/library-features/char-error-internals.md deleted file mode 100644 index 8013b4988e1..00000000000 --- a/src/doc/unstable-book/src/library-features/char-error-internals.md +++ /dev/null @@ -1,5 +0,0 @@ -# `char_error_internals` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/int-error-internals.md b/src/doc/unstable-book/src/library-features/int-error-internals.md deleted file mode 100644 index 402e4fa5ef6..00000000000 --- a/src/doc/unstable-book/src/library-features/int-error-internals.md +++ /dev/null @@ -1,5 +0,0 @@ -# `int_error_internals` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index d85749cadbd..a26c25c9782 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -27,13 +27,11 @@ use crate::clean::inline::build_external_trait; use crate::clean::{self, ItemId}; use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions}; use crate::formats::cache::Cache; -use crate::passes::collect_intra_doc_links::PreprocessedMarkdownLink; use crate::passes::{self, Condition::*}; pub(crate) use rustc_session::config::{Input, Options, UnstableOptions}; pub(crate) struct ResolverCaches { - pub(crate) markdown_links: Option<FxHashMap<String, Vec<PreprocessedMarkdownLink>>>, pub(crate) all_trait_impls: Option<Vec<DefId>>, pub(crate) all_macro_rules: FxHashMap<Symbol, Res<NodeId>>, pub(crate) extern_doc_reachable: DefIdSet, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 8f401a2fc1d..33180439393 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1176,14 +1176,23 @@ pub(crate) fn short_markdown_summary(markdown: &str, link_names: &[RenderedLink] /// - Headings, links, and formatting are stripped. /// - Inline code is rendered as-is, surrounded by backticks. /// - HTML and code blocks are ignored. -pub(crate) fn plain_text_summary(md: &str) -> String { +pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> String { if md.is_empty() { return String::new(); } let mut s = String::with_capacity(md.len() * 3 / 2); - for event in Parser::new_ext(md, summary_opts()) { + let mut replacer = |broken_link: BrokenLink<'_>| { + link_names + .iter() + .find(|link| link.original_text.as_str() == &*broken_link.reference) + .map(|link| (link.href.as_str().into(), link.new_text.as_str().into())) + }; + + let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer)); + + for event in p { match &event { Event::Text(text) => s.push_str(text), Event::Code(code) => { diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index 5878c58264e..e05635a0207 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -249,7 +249,7 @@ fn test_short_markdown_summary() { #[test] fn test_plain_text_summary() { fn t(input: &str, expect: &str) { - let output = plain_text_summary(input); + let output = plain_text_summary(input, &[]); assert_eq!(output, expect, "original: {}", input); } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 1216a8d71c8..6762fba9275 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -182,7 +182,10 @@ impl<'tcx> Context<'tcx> { }; title.push_str(" - Rust"); let tyname = it.type_(); - let desc = it.doc_value().as_ref().map(|doc| plain_text_summary(doc)); + let desc = it + .doc_value() + .as_ref() + .map(|doc| plain_text_summary(doc, &it.link_names(&self.cache()))); let desc = if let Some(desc) = desc { desc } else if it.is_crate() { diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 251e806c2d9..ea1875d8e27 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -142,13 +142,11 @@ function initSearch(rawSearchIndex) { } function itemTypeFromName(typename) { - for (let i = 0, len = itemTypes.length; i < len; ++i) { - if (itemTypes[i] === typename) { - return i; - } + const index = itemTypes.findIndex(i => i === typename); + if (index < 0) { + throw new Error("Unknown type filter `" + typename + "`"); } - - throw new Error("Unknown type filter `" + typename + "`"); + return index; } /** diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 62e190b4bd8..779cbaa6802 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -807,22 +807,12 @@ impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> { // NOTE: if there are links that start in one crate and end in another, this will not resolve them. // This is a degenerate case and it's not supported by rustdoc. let parent_node = parent_module.or(parent_node); - let mut tmp_links = self - .cx - .resolver_caches - .markdown_links - .take() - .expect("`markdown_links` are already borrowed"); - if !tmp_links.contains_key(&doc) { - tmp_links.insert(doc.clone(), preprocessed_markdown_links(&doc)); - } - for md_link in &tmp_links[&doc] { - let link = self.resolve_link(item, &doc, parent_node, md_link); + for md_link in preprocessed_markdown_links(&doc) { + let link = self.resolve_link(item, &doc, parent_node, &md_link); if let Some(link) = link { self.cx.cache.intra_doc_links.entry(item.item_id).or_default().push(link); } } - self.cx.resolver_caches.markdown_links = Some(tmp_links); } if item.is_mod() { diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs index 75c3380ee9b..ec449e94ce5 100644 --- a/src/librustdoc/passes/collect_intra_doc_links/early.rs +++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs @@ -24,7 +24,6 @@ pub(crate) fn early_resolve_intra_doc_links( link_resolver.process_extern_impls(); ResolverCaches { - markdown_links: Some(Default::default()), all_trait_impls: Some(link_resolver.all_trait_impls), all_macro_rules: link_resolver.all_macro_rules, extern_doc_reachable: link_resolver.extern_doc_reachable, diff --git a/tests/mir-opt/sroa.constant.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.constant.ScalarReplacementOfAggregates.diff new file mode 100644 index 00000000000..9e33215f2b5 --- /dev/null +++ b/tests/mir-opt/sroa.constant.ScalarReplacementOfAggregates.diff @@ -0,0 +1,46 @@ +- // MIR for `constant` before ScalarReplacementOfAggregates ++ // MIR for `constant` after ScalarReplacementOfAggregates + + fn constant() -> () { + let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:15: +0:15 + let _1: (usize, u8); // in scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ let _4: usize; // in scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ let _5: u8; // in scope 0 at $DIR/sroa.rs:+2:9: +2:10 + scope 1 { +- debug y => _1; // in scope 1 at $DIR/sroa.rs:+2:9: +2:10 ++ debug y => (usize, u8){ .0 => _4, .1 => _5, }; // in scope 1 at $DIR/sroa.rs:+2:9: +2:10 + let _2: usize; // in scope 1 at $DIR/sroa.rs:+3:9: +3:10 + scope 2 { + debug t => _2; // in scope 2 at $DIR/sroa.rs:+3:9: +3:10 + let _3: u8; // in scope 2 at $DIR/sroa.rs:+4:9: +4:10 + scope 3 { + debug u => _3; // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 + } + } + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ nop; // scope 0 at $DIR/sroa.rs:+2:9: +2:10 + _1 = const _; // scope 0 at $DIR/sroa.rs:+2:13: +2:14 ++ _4 = move (_1.0: usize); // scope 1 at $DIR/sroa.rs:+3:9: +3:10 ++ _5 = move (_1.1: u8); // scope 1 at $DIR/sroa.rs:+3:9: +3:10 + StorageLive(_2); // scope 1 at $DIR/sroa.rs:+3:9: +3:10 +- _2 = (_1.0: usize); // scope 1 at $DIR/sroa.rs:+3:13: +3:16 ++ _2 = _4; // scope 1 at $DIR/sroa.rs:+3:13: +3:16 + StorageLive(_3); // scope 2 at $DIR/sroa.rs:+4:9: +4:10 +- _3 = (_1.1: u8); // scope 2 at $DIR/sroa.rs:+4:13: +4:16 ++ _3 = _5; // scope 2 at $DIR/sroa.rs:+4:13: +4:16 + _0 = const (); // scope 0 at $DIR/sroa.rs:+0:15: +5:2 + StorageDead(_3); // scope 2 at $DIR/sroa.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/sroa.rs:+5:1: +5:2 +- StorageDead(_1); // scope 0 at $DIR/sroa.rs:+5:1: +5:2 ++ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+5:1: +5:2 ++ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+5:1: +5:2 ++ nop; // scope 0 at $DIR/sroa.rs:+5:1: +5:2 + return; // scope 0 at $DIR/sroa.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/sroa.rs b/tests/mir-opt/sroa.rs index 471aac9f9d8..b69de2e124e 100644 --- a/tests/mir-opt/sroa.rs +++ b/tests/mir-opt/sroa.rs @@ -87,6 +87,13 @@ fn ref_copies(x: &Foo) { let u = y.c; } +fn constant() { + const U: (usize, u8) = (5, 9); + let y = U; + let t = y.0; + let u = y.1; +} + fn main() { dropping(); enums(5); @@ -96,6 +103,7 @@ fn main() { escaping(); copies(Foo { a: 5, b: (), c: "a", d: Some(-4) }); ref_copies(&Foo { a: 5, b: (), c: "a", d: Some(-4) }); + constant(); } // EMIT_MIR sroa.dropping.ScalarReplacementOfAggregates.diff @@ -106,3 +114,4 @@ fn main() { // EMIT_MIR sroa.escaping.ScalarReplacementOfAggregates.diff // EMIT_MIR sroa.copies.ScalarReplacementOfAggregates.diff // EMIT_MIR sroa.ref_copies.ScalarReplacementOfAggregates.diff +// EMIT_MIR sroa.constant.ScalarReplacementOfAggregates.diff diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile new file mode 100644 index 00000000000..62dc1b5f606 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile @@ -0,0 +1,35 @@ +-include ../../run-make-fulldeps/tools.mk + +# ignore-cross-compile +# only-linux + +# Make sure -Zpacked_bundled_libs-like behavior activates with whole-archive. + +# We're using the llvm-nm instead of the system nm to ensure it is compatible +# with the LLVM bitcode generated by rustc. +NM = "$(LLVM_BIN_DIR)"/llvm-nm + +all: $(call NATIVE_STATICLIB,native_dep_1) $(call NATIVE_STATICLIB,native_dep_2) $(call NATIVE_STATICLIB,native_dep_3) $(call NATIVE_STATICLIB,native_dep_4) + # test cfg with packed bundle + $(RUSTC) rust_dep_cfg.rs --crate-type=rlib -Zpacked_bundled_libs + $(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep_cfg.rlib --crate-type=staticlib --cfg should_add + $(AR) t $(TMPDIR)/librust_dep_cfg.rlib | $(CGREP) -e "libnative_dep_1.a" + $(AR) t $(TMPDIR)/librust_dep_cfg.rlib | $(CGREP) -e "libnative_dep_2.a" + $(AR) t $(TMPDIR)/libmain.a | $(CGREP) -e "libnative_dep_1.o" + $(AR) t $(TMPDIR)/libmain.a | $(CGREP) -ev "libnative_dep_2.o" + + + # test bundle with whole_archive + $(RUSTC) rust_dep.rs --crate-type=rlib + $(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) -e "native_dep_1" + $(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) -e "native_dep_3" + $(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) -ev "native_dep_2" + $(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) -ev "native_dep_4" + + # Make sure compiler doesn't use files, that it shouldn't know about. + rm $(TMPDIR)/libnative_dep_1.a + rm $(TMPDIR)/libnative_dep_3.a + + $(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep.rlib --print link-args > $(TMPDIR)/link_args + cat $(TMPDIR)/link_args | $(CGREP) -ev "native_dep_3" + cat $(TMPDIR)/link_args | $(CGREP) -e "--whole-archive.*native_dep_1.*--whole-archive.*lnative_dep_2.*no-whole-archive.*lnative_dep_4" diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/main.rs b/tests/run-make/rlib-format-packed-bundled-libs-3/main.rs new file mode 100644 index 00000000000..8d2b8a2859c --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/main.rs @@ -0,0 +1,5 @@ +extern crate rust_dep; + +pub fn main() { + rust_dep::rust_dep(); +} diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_1.c b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_1.c new file mode 100644 index 00000000000..07be8562c92 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_1.c @@ -0,0 +1 @@ +int native_f1() { return 1; } diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_2.c b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_2.c new file mode 100644 index 00000000000..a1b94e40dc0 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_2.c @@ -0,0 +1 @@ +int native_f2() { return 2; } diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_3.c b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_3.c new file mode 100644 index 00000000000..f81f397a4b1 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_3.c @@ -0,0 +1 @@ +int native_f3() { return 3; } diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_4.c b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_4.c new file mode 100644 index 00000000000..14d41d60b1f --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_4.c @@ -0,0 +1 @@ +int native_f4() { return 4; } diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs new file mode 100644 index 00000000000..abd846b6862 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs @@ -0,0 +1,16 @@ +#![feature(packed_bundled_libs)] + +#[link(name = "native_dep_1", kind = "static", modifiers = "+whole-archive,+bundle")] +extern "C" {} + +#[link(name = "native_dep_2", kind = "static", modifiers = "+whole-archive,-bundle")] +extern "C" {} + +#[link(name = "native_dep_3", kind = "static", modifiers = "+bundle")] +extern "C" {} + +#[link(name = "native_dep_4", kind = "static", modifiers = "-bundle")] +extern "C" {} + +#[no_mangle] +pub fn rust_dep() {} diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep_cfg.rs b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep_cfg.rs new file mode 100644 index 00000000000..506ca62a8a6 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep_cfg.rs @@ -0,0 +1,10 @@ +#![feature(link_cfg)] + +#[link(name = "native_dep_1", kind = "static", cfg(should_add))] +extern "C" {} + +#[link(name = "native_dep_2", kind = "static", cfg(should_not_add))] +extern "C" {} + +#[no_mangle] +pub fn rust_dep() {} diff --git a/tests/rustdoc/description.rs b/tests/rustdoc/description.rs index 05ec4282208..43cd59ebd09 100644 --- a/tests/rustdoc/description.rs +++ b/tests/rustdoc/description.rs @@ -22,3 +22,9 @@ pub mod foo_mod { // 'Only paragraph.' /// Only paragraph. pub fn foo_fn() {} + +// @has 'foo/fn.bar_fn.html' '//meta[@name="description"]/@content' \ +// 'Description with intra-doc link to foo_fn and [nonexistent_item] and foo_fn.' +#[allow(rustdoc::broken_intra_doc_links)] +/// Description with intra-doc link to [foo_fn] and [nonexistent_item] and [foo_fn](self::foo_fn). +pub fn bar_fn() {} diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs index 066048795c8..0ccd441cc64 100644 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs +++ b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs @@ -1,8 +1,11 @@ -// compile-flags: -Zunstable-options --crate-type rlib +// gate-test-packed_bundled_libs + +// ignore-wasm32-bare +// compile-flags: --crate-type rlib +// error-pattern: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs // build-fail -// error-pattern: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs -#[link(name = "mylib", kind = "static", modifiers = "+bundle,+whole-archive")] -extern "C" { } +#[link(name = "rust_test_helpers", kind = "static", modifiers = "+bundle,+whole-archive")] +extern "C" {} -fn main() { } +fn main() {} diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr index 246efb8d627..8a9fed740b0 100644 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr +++ b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr @@ -1,6 +1,4 @@ -error: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs +error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs -error: could not find native static library `mylib`, perhaps an -L flag is missing? - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs index 1d0768d99cf..18d4b52a34c 100644 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs +++ b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs @@ -1,7 +1,8 @@ -// Mixing +bundle and +whole-archive is not allowed +// gate-test-packed_bundled_libs -// compile-flags: -l static:+bundle,+whole-archive=mylib -Zunstable-options --crate-type rlib +// ignore-wasm32-bare +// compile-flags: -l static:+bundle,+whole-archive=rust_test_helpers --crate-type rlib +// error-pattern: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs // build-fail -// error-pattern: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs -fn main() { } +fn main() {} diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr index 246efb8d627..8a9fed740b0 100644 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr +++ b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr @@ -1,6 +1,4 @@ -error: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs +error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs -error: could not find native static library `mylib`, perhaps an -L flag is missing? - -error: aborting due to 2 previous errors +error: aborting due to previous error |
