From 9de1d7c10d4732068d43219253fa8ceccd675754 Mon Sep 17 00:00:00 2001 From: Ibraheem Ahmed Date: Thu, 21 Jul 2022 22:49:08 -0400 Subject: [PATCH 01/16] document memory orderings of `thread::{park, unpark}` --- library/std/src/thread/mod.rs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index d28c7b58b20..32453b4d4a3 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -845,7 +845,7 @@ pub fn sleep(dur: Duration) { /// A call to `park` does not guarantee that the thread will remain parked /// forever, and callers should be prepared for this possibility. /// -/// # park and unpark +/// # `park` and `unpark` /// /// Every thread is equipped with some basic low-level blocking support, via the /// [`thread::park`][`park`] function and [`thread::Thread::unpark`][`unpark`] @@ -866,14 +866,6 @@ pub fn sleep(dur: Duration) { /// if it wasn't already. Because the token is initially absent, [`unpark`] /// followed by [`park`] will result in the second call returning immediately. /// -/// In other words, each [`Thread`] acts a bit like a spinlock that can be -/// locked and unlocked using `park` and `unpark`. -/// -/// Notice that being unblocked does not imply any synchronization with someone -/// that unparked this thread, it could also be spurious. -/// For example, it would be a valid, but inefficient, implementation to make both [`park`] and -/// [`unpark`] return immediately without doing anything. -/// /// The API is typically used by acquiring a handle to the current thread, /// placing that handle in a shared data structure so that other threads can /// find it, and then `park`ing in a loop. When some desired condition is met, another @@ -887,6 +879,23 @@ pub fn sleep(dur: Duration) { /// /// * It can be implemented very efficiently on many platforms. /// +/// # Memory Orderings +/// +/// Calls to `park` _synchronize-with_ calls to `unpark`, meaning that memory +/// operations performed before a call to `unpark` are made visible to the thread that +/// consumes the token and returns from `park`. Note that all `park` and `unpark` +/// operations for a given thread form a total order and `park` synchronizes-with +/// _all_ prior `unpark` operations. +/// +/// In atomic ordering terms, `unpark` performs a `Release` operation and `park` +/// performs the corresponding `Acquire` operation. Calls to `unpark` for the same +/// thread form a [release sequence]. +/// +/// Notice that being unblocked does not imply any synchronization with someone that +/// unparked this thread, it could also be spurious. For example, it would be a valid, +/// but inefficient, implementation to make both park and unpark return immediately +/// without doing anything. +/// /// # Examples /// /// ``` @@ -926,6 +935,7 @@ pub fn sleep(dur: Duration) { /// /// [`unpark`]: Thread::unpark /// [`thread::park_timeout`]: park_timeout +/// [release sequence]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release_sequence #[stable(feature = "rust1", since = "1.0.0")] pub fn park() { // SAFETY: park_timeout is called on the parker owned by this thread. From 1bae661dbc0b9fd3397e0df00b176bf13f346cff Mon Sep 17 00:00:00 2001 From: Ibraheem Ahmed Date: Wed, 5 Oct 2022 16:33:04 -0400 Subject: [PATCH 02/16] tidy Co-authored-by: yvt --- library/std/src/thread/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 32453b4d4a3..afa4e2fb168 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -880,7 +880,7 @@ pub fn sleep(dur: Duration) { /// * It can be implemented very efficiently on many platforms. /// /// # Memory Orderings -/// +/// /// Calls to `park` _synchronize-with_ calls to `unpark`, meaning that memory /// operations performed before a call to `unpark` are made visible to the thread that /// consumes the token and returns from `park`. Note that all `park` and `unpark` @@ -890,7 +890,7 @@ pub fn sleep(dur: Duration) { /// In atomic ordering terms, `unpark` performs a `Release` operation and `park` /// performs the corresponding `Acquire` operation. Calls to `unpark` for the same /// thread form a [release sequence]. -/// +/// /// Notice that being unblocked does not imply any synchronization with someone that /// unparked this thread, it could also be spurious. For example, it would be a valid, /// but inefficient, implementation to make both park and unpark return immediately From 6e8a0136f1d5d9e7e2f7d6bf1f599975f8c0c4c2 Mon Sep 17 00:00:00 2001 From: Ibraheem Ahmed Date: Sun, 1 Jan 2023 14:34:22 -0500 Subject: [PATCH 03/16] improve wording of `thread::park` docs --- library/std/src/thread/mod.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index afa4e2fb168..07662e90c52 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -891,10 +891,9 @@ pub fn sleep(dur: Duration) { /// performs the corresponding `Acquire` operation. Calls to `unpark` for the same /// thread form a [release sequence]. /// -/// Notice that being unblocked does not imply any synchronization with someone that -/// unparked this thread, it could also be spurious. For example, it would be a valid, -/// but inefficient, implementation to make both park and unpark return immediately -/// without doing anything. +/// Note that being unblocked does not imply synchronization with a call to `unpark`, +/// the wakeup could also be spurious. For example, a valid, but inefficient, +/// implementation could have `park` and `unpark` return immediately without doing anything. /// /// # Examples /// From e9868ef8df9817802a0aaf0695e83c1e45783842 Mon Sep 17 00:00:00 2001 From: Ibraheem Ahmed Date: Tue, 11 Apr 2023 13:20:41 -0400 Subject: [PATCH 04/16] clarify wording around spurious wakeups from `thread::park` --- library/std/src/thread/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 07662e90c52..0f8b9c76688 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -891,8 +891,8 @@ pub fn sleep(dur: Duration) { /// performs the corresponding `Acquire` operation. Calls to `unpark` for the same /// thread form a [release sequence]. /// -/// Note that being unblocked does not imply synchronization with a call to `unpark`, -/// the wakeup could also be spurious. For example, a valid, but inefficient, +/// Note that being unblocked does not imply a call was made to `unpark`, because +/// wakeups can also be spurious. For example, a valid, but inefficient, /// implementation could have `park` and `unpark` return immediately without doing anything. /// /// # Examples From bc20a8e01a6c480c98f0155252b3cce57d338096 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 19 Jun 2023 21:17:39 +0200 Subject: [PATCH 05/16] Add `Item::def_id` helper --- src/librustdoc/clean/types.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index fc5f03568a9..5f5cade67a2 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -358,15 +358,15 @@ fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool { impl Item { pub(crate) fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option { - self.item_id.as_def_id().and_then(|did| tcx.lookup_stability(did)) + self.def_id().and_then(|did| tcx.lookup_stability(did)) } pub(crate) fn const_stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option { - self.item_id.as_def_id().and_then(|did| tcx.lookup_const_stability(did)) + self.def_id().and_then(|did| tcx.lookup_const_stability(did)) } pub(crate) fn deprecation(&self, tcx: TyCtxt<'_>) -> Option { - self.item_id.as_def_id().and_then(|did| tcx.lookup_deprecation(did)) + self.def_id().and_then(|did| tcx.lookup_deprecation(did)) } pub(crate) fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool { @@ -391,7 +391,7 @@ impl Item { panic!("blanket impl item has non-blanket ID") } } - _ => self.item_id.as_def_id().map(|did| rustc_span(did, tcx)), + _ => self.def_id().map(|did| rustc_span(did, tcx)), } } @@ -501,7 +501,7 @@ impl Item { } pub(crate) fn is_crate(&self) -> bool { - self.is_mod() && self.item_id.as_def_id().map_or(false, |did| did.is_crate_root()) + self.is_mod() && self.def_id().map_or(false, |did| did.is_crate_root()) } pub(crate) fn is_mod(&self) -> bool { self.type_() == ItemType::Module @@ -638,11 +638,11 @@ impl Item { } let header = match *self.kind { ItemKind::ForeignFunctionItem(_) => { - let def_id = self.item_id.as_def_id().unwrap(); + let def_id = self.def_id().unwrap(); let abi = tcx.fn_sig(def_id).skip_binder().abi(); hir::FnHeader { unsafety: if abi == Abi::RustIntrinsic { - intrinsic_operation_unsafety(tcx, self.item_id.as_def_id().unwrap()) + intrinsic_operation_unsafety(tcx, self.def_id().unwrap()) } else { hir::Unsafety::Unsafe }, @@ -659,7 +659,7 @@ impl Item { } } ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) | ItemKind::TyMethodItem(_) => { - let def_id = self.item_id.as_def_id().unwrap(); + let def_id = self.def_id().unwrap(); build_fn_header(def_id, tcx, tcx.asyncness(def_id)) } _ => return None, @@ -738,7 +738,7 @@ impl Item { } }) .collect(); - if let Some(def_id) = self.item_id.as_def_id() && + if let Some(def_id) = self.def_id() && !def_id.is_local() && // This check is needed because `adt_def` will panic if not a compatible type otherwise... matches!(self.type_(), ItemType::Struct | ItemType::Enum | ItemType::Union) @@ -787,6 +787,10 @@ impl Item { pub fn is_doc_hidden(&self) -> bool { self.attrs.is_doc_hidden() } + + pub fn def_id(&self) -> Option { + self.item_id.as_def_id() + } } #[derive(Clone, Debug)] From db95734b9d41e00c17bb934b96ffd8cb660a2248 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 19 Jun 2023 21:17:57 +0200 Subject: [PATCH 06/16] Fix invalid creation of files in rustdoc --- src/librustdoc/formats/cache.rs | 5 ++++ src/librustdoc/html/render/context.rs | 41 ++++++++++++++++++++++----- src/librustdoc/visit_ast.rs | 7 +++-- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 8aaad8bce1b..dac762e9ff9 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -121,6 +121,11 @@ pub(crate) struct Cache { pub(crate) intra_doc_links: FxHashMap>, /// Cfg that have been hidden via #![doc(cfg_hide(...))] pub(crate) hidden_cfg: FxHashSet, + + /// Contains the list of `DefId`s which have been inlined. It is used when generating files + /// to check if a stripped item should get its file generated or not: if it's inside a + /// `#[doc(hidden)]` item or a private one and not inlined, it shouldn't get a file. + pub(crate) inlined_items: DefIdSet, } /// This struct is used to wrap the `cache` and `tcx` in order to run `DocFolder`. diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 56af257fd5e..4c476263635 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -73,6 +73,8 @@ pub(crate) struct Context<'tcx> { pub(crate) include_sources: bool, /// Collection of all types with notable traits referenced in the current module. pub(crate) types_with_notable_traits: FxHashSet, + /// Field used during rendering, to know if we're inside an inlined item. + pub(crate) is_inside_inlined_module: bool, } // `Context` is cloned a lot, so we don't want the size to grow unexpectedly. @@ -171,6 +173,19 @@ impl<'tcx> Context<'tcx> { } fn render_item(&mut self, it: &clean::Item, is_module: bool) -> String { + let mut render_redirect_pages = self.render_redirect_pages; + // If the item is stripped but inlined, links won't point to the item so no need to generate + // a file for it. + if it.is_stripped() && + let Some(def_id) = it.def_id() && + def_id.is_local() + { + if self.is_inside_inlined_module || self.shared.cache.inlined_items.contains(&def_id) { + // For now we're forced to generate a redirect page for stripped items until + // `record_extern_fqn` correctly points to external items. + render_redirect_pages = true; + } + } let mut title = String::new(); if !is_module { title.push_str(it.name.unwrap().as_str()); @@ -205,7 +220,7 @@ impl<'tcx> Context<'tcx> { tyname.as_str() }; - if !self.render_redirect_pages { + if !render_redirect_pages { let clone_shared = Rc::clone(&self.shared); let page = layout::Page { css_class: tyname_s, @@ -545,6 +560,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { shared: Rc::new(scx), include_sources, types_with_notable_traits: FxHashSet::default(), + is_inside_inlined_module: false, }; if emit_crate { @@ -574,6 +590,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { shared: Rc::clone(&self.shared), include_sources: self.include_sources, types_with_notable_traits: FxHashSet::default(), + is_inside_inlined_module: self.is_inside_inlined_module, } } @@ -768,12 +785,22 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { info!("Recursing into {}", self.dst.display()); - let buf = self.render_item(item, true); - // buf will be empty if the module is stripped and there is no redirect for it - if !buf.is_empty() { - self.shared.ensure_dir(&self.dst)?; - let joint_dst = self.dst.join("index.html"); - self.shared.fs.write(joint_dst, buf)?; + if !item.is_stripped() { + let buf = self.render_item(item, true); + // buf will be empty if the module is stripped and there is no redirect for it + if !buf.is_empty() { + self.shared.ensure_dir(&self.dst)?; + let joint_dst = self.dst.join("index.html"); + self.shared.fs.write(joint_dst, buf)?; + } + } + if !self.is_inside_inlined_module { + if let Some(def_id) = item.def_id() && self.cache().inlined_items.contains(&def_id) { + self.is_inside_inlined_module = true; + } + } else if item.is_doc_hidden() { + // We're not inside an inlined module anymore since this one cannot be re-exported. + self.is_inside_inlined_module = false; } // Render sidebar-items.js used throughout this module. diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 22c8cc09243..fcf591a9328 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -313,7 +313,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { return false; } - let ret = match tcx.hir().get_by_def_id(res_did) { + let inlined = match tcx.hir().get_by_def_id(res_did) { // Bang macros are handled a bit on their because of how they are handled by the // compiler. If they have `#[doc(hidden)]` and the re-export doesn't have // `#[doc(inline)]`, then we don't inline it. @@ -344,7 +344,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { _ => false, }; self.view_item_stack.remove(&res_did); - ret + if inlined { + self.cx.cache.inlined_items.insert(res_did.to_def_id()); + } + inlined } /// Returns `true` if the item is visible, meaning it's not `#[doc(hidden)]` or private. From bf27f12d941b2aea125bd629c1f30feaacf41cc6 Mon Sep 17 00:00:00 2001 From: Ibraheem Ahmed Date: Tue, 20 Jun 2023 20:05:31 -0400 Subject: [PATCH 07/16] relaxed orderings in `thread::park` example --- library/std/src/thread/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 0f8b9c76688..e9d94ba425a 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -893,7 +893,8 @@ pub fn sleep(dur: Duration) { /// /// Note that being unblocked does not imply a call was made to `unpark`, because /// wakeups can also be spurious. For example, a valid, but inefficient, -/// implementation could have `park` and `unpark` return immediately without doing anything. +/// implementation could have `park` and `unpark` return immediately without doing anything, +/// making *all* wakeups spurious. /// /// # Examples /// @@ -908,7 +909,7 @@ pub fn sleep(dur: Duration) { /// let parked_thread = thread::spawn(move || { /// // We want to wait until the flag is set. We *could* just spin, but using /// // park/unpark is more efficient. -/// while !flag2.load(Ordering::Acquire) { +/// while !flag2.load(Ordering::Relaxed) { /// println!("Parking thread"); /// thread::park(); /// // We *could* get here spuriously, i.e., way before the 10ms below are over! @@ -925,7 +926,7 @@ pub fn sleep(dur: Duration) { /// // There is no race condition here, if `unpark` /// // happens first, `park` will return immediately. /// // Hence there is no risk of a deadlock. -/// flag.store(true, Ordering::Release); +/// flag.store(true, Ordering::Relaxed); /// println!("Unpark the thread"); /// parked_thread.thread().unpark(); /// From 7201271fe8f8499eed8f20b282aca508ea53f855 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Wed, 21 Jun 2023 01:06:48 +0100 Subject: [PATCH 08/16] Fix typo in `eprintln` docs --- library/std/src/macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index fcc5cfafd80..ba1b8cbfa56 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -154,7 +154,7 @@ macro_rules! println { /// /// Panics if writing to `io::stderr` fails. /// -/// Writing to non-blocking stdout can cause an error, which will lead +/// Writing to non-blocking stderr can cause an error, which will lead /// this macro to panic. /// /// # Examples @@ -189,7 +189,7 @@ macro_rules! eprint { /// /// Panics if writing to `io::stderr` fails. /// -/// Writing to non-blocking stdout can cause an error, which will lead +/// Writing to non-blocking stderr can cause an error, which will lead /// this macro to panic. /// /// # Examples From 81e37743a506b2cf0aff1bb6c0cdd3d22699776f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Jun 2023 10:25:25 +0000 Subject: [PATCH 09/16] Make queries traceable again --- compiler/rustc_query_impl/src/plumbing.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 244f0e84b43..cb0df1d1b82 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -531,6 +531,8 @@ macro_rules! define_queries { key: queries::$name::Key<'tcx>, mode: QueryMode, ) -> Option>> { + #[cfg(debug_assertions)] + let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered(); get_query_incr( QueryType::config(tcx), QueryCtxt::new(tcx), @@ -571,10 +573,16 @@ macro_rules! define_queries { cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key), execute_query: |tcx, key| erase(tcx.$name(key)), compute: |tcx, key| { + #[cfg(debug_assertions)] + let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered(); __rust_begin_short_backtrace(|| queries::$name::provided_to_erased( tcx, - call_provider!([$($modifiers)*][tcx, $name, key]) + { + let ret = call_provider!([$($modifiers)*][tcx, $name, key]); + tracing::trace!(?ret); + ret + } ) ) }, From 3acb1d2b9b5f0ab85cb787250326c0571503f78c Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 21 Jun 2023 12:43:22 +0200 Subject: [PATCH 10/16] "Memory Orderings" -> "Memory Ordering" Co-authored-by: yvt --- library/std/src/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index e9d94ba425a..b9b14b2dc5f 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -879,7 +879,7 @@ pub fn sleep(dur: Duration) { /// /// * It can be implemented very efficiently on many platforms. /// -/// # Memory Orderings +/// # Memory Ordering /// /// Calls to `park` _synchronize-with_ calls to `unpark`, meaning that memory /// operations performed before a call to `unpark` are made visible to the thread that From 91aef00e51d9f7500b8d76bce0917138ffa00d2f Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 21 Jun 2023 16:54:54 +0530 Subject: [PATCH 11/16] Fix msg passed to span_bug --- compiler/rustc_expand/src/mbe/macro_rules.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index ee9616a0f0a..4a8a14994ff 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -535,7 +535,7 @@ pub fn compile_declarative_macro( .pop() .unwrap(); } - sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs") + sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs") }) .collect::>(), _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs"), From 60ec8405eb03bb3da43e11a5415968d8d8852120 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 19 Jun 2023 13:50:22 +0200 Subject: [PATCH 12/16] Add `lazy_type_alias` feature gate --- compiler/rustc_feature/src/active.rs | 2 ++ compiler/rustc_hir_analysis/src/astconv/mod.rs | 2 +- compiler/rustc_span/src/symbol.rs | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 4c53f9d8369..34c0e5009d3 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -440,6 +440,8 @@ declare_features! ( (active, intra_doc_pointers, "1.51.0", Some(80896), None), // Allows setting the threshold for the `large_assignments` lint. (active, large_assignments, "1.52.0", Some(83518), None), + /// Allow to have type alias types for inter-crate use. + (active, lazy_type_alias, "CURRENT_RUSTC_VERSION", Some(112792), None), /// Allows `if/while p && let q = r && ...` chains. (active, let_chains, "1.37.0", Some(53667), None), /// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check. diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 621569ab321..7a83447786c 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -896,7 +896,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let ty = self.tcx().at(span).type_of(did); if matches!(self.tcx().def_kind(did), DefKind::TyAlias) - && ty.skip_binder().has_opaque_types() + && (ty.skip_binder().has_opaque_types() || self.tcx().features().lazy_type_alias) { // Type aliases referring to types that contain opaque types (but aren't just directly // referencing a single opaque type) get encoded as a type alias that normalization will diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 388b904d197..d8c04f72060 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -870,6 +870,7 @@ symbols! { large_assignments, lateout, lazy_normalization_consts, + lazy_type_alias, le, len, let_chains, From 1af48beed74e9ab652a05c8fe267541ae652eaf6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 19 Jun 2023 15:05:46 +0200 Subject: [PATCH 13/16] Add rustdoc tests for `lazy_type_alias` --- tests/rustdoc/alias-reexport.rs | 18 ++++++++++++++++++ tests/rustdoc/alias-reexport2.rs | 16 ++++++++++++++++ tests/rustdoc/auxiliary/alias-reexport.rs | 3 +++ tests/rustdoc/auxiliary/alias-reexport2.rs | 12 ++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 tests/rustdoc/alias-reexport.rs create mode 100644 tests/rustdoc/alias-reexport2.rs create mode 100644 tests/rustdoc/auxiliary/alias-reexport.rs create mode 100644 tests/rustdoc/auxiliary/alias-reexport2.rs diff --git a/tests/rustdoc/alias-reexport.rs b/tests/rustdoc/alias-reexport.rs new file mode 100644 index 00000000000..029891197fc --- /dev/null +++ b/tests/rustdoc/alias-reexport.rs @@ -0,0 +1,18 @@ +// aux-build:alias-reexport.rs +// aux-build:alias-reexport2.rs + +#![crate_name = "foo"] +#![feature(lazy_type_alias)] + +extern crate alias_reexport2; + +// @has 'foo/reexport/fn.foo.html' +// FIXME: should be 'pub fn foo() -> Reexport' +// @has - '//*[@class="rust item-decl"]' 'pub fn foo() -> u8' +// @has 'foo/reexport/fn.foo2.html' +// FIXME: should be 'pub fn foo2() -> Result' +// @has - '//*[@class="rust item-decl"]' 'pub fn foo2() -> Result' +// @has 'foo/reexport/type.Reexported.html' +// @has - '//*[@class="rust item-decl"]' 'pub type Reexported = u8;' +#[doc(inline)] +pub use alias_reexport2 as reexport; diff --git a/tests/rustdoc/alias-reexport2.rs b/tests/rustdoc/alias-reexport2.rs new file mode 100644 index 00000000000..85d3cdad962 --- /dev/null +++ b/tests/rustdoc/alias-reexport2.rs @@ -0,0 +1,16 @@ +// gate-test-lazy_type_alias +// aux-build:alias-reexport.rs + +#![crate_name = "foo"] +#![feature(lazy_type_alias)] + +extern crate alias_reexport; + +use alias_reexport::Reexported; + +// @has 'foo/fn.foo.html' +// @has - '//*[@class="rust item-decl"]' 'pub fn foo() -> Reexported' +pub fn foo() -> Reexported { 0 } +// @has 'foo/fn.foo2.html' +// @has - '//*[@class="rust item-decl"]' 'pub fn foo2() -> Result' +pub fn foo2() -> Result { Ok(0) } diff --git a/tests/rustdoc/auxiliary/alias-reexport.rs b/tests/rustdoc/auxiliary/alias-reexport.rs new file mode 100644 index 00000000000..14fafc02d36 --- /dev/null +++ b/tests/rustdoc/auxiliary/alias-reexport.rs @@ -0,0 +1,3 @@ +#![feature(lazy_type_alias)] + +pub type Reexported = u8; diff --git a/tests/rustdoc/auxiliary/alias-reexport2.rs b/tests/rustdoc/auxiliary/alias-reexport2.rs new file mode 100644 index 00000000000..9f6910572ad --- /dev/null +++ b/tests/rustdoc/auxiliary/alias-reexport2.rs @@ -0,0 +1,12 @@ +#![feature(lazy_type_alias)] + +extern crate alias_reexport; + +pub use alias_reexport::Reexported; + +// @has 'foo/fn.foo.html' +// @has - '//*[@class="docblock item-decl"]' 'pub fn foo() -> Reexported' +pub fn foo() -> Reexported { 0 } +// @has 'foo/fn.foo2.html' +// @has - '//*[@class="docblock item-decl"]' 'pub fn foo2() -> Result' +pub fn foo2() -> Result { Ok(0) } From e3e65d1e14c6372af860233b237475ebd3078b34 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Wed, 21 Jun 2023 13:30:02 +0100 Subject: [PATCH 14/16] Revert 'Rename profile=user to profile=dist' This reverts commit a45fc9465204c9fb8c6792e74e3ed10959e46001 --- src/bootstrap/setup.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index e13f3f0bd5e..7eb70de91f8 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -20,7 +20,7 @@ pub enum Profile { Codegen, Library, Tools, - Dist, + User, None, } @@ -43,7 +43,7 @@ impl Profile { pub fn all() -> impl Iterator { use Profile::*; // N.B. these are ordered by how they are displayed, not alphabetically - [Library, Compiler, Codegen, Tools, Dist, None].iter().copied() + [Library, Compiler, Codegen, Tools, User, None].iter().copied() } pub fn purpose(&self) -> String { @@ -53,7 +53,7 @@ impl Profile { Compiler => "Contribute to the compiler itself", Codegen => "Contribute to the compiler, and also modify LLVM or codegen", Tools => "Contribute to tools which depend on the compiler, but do not modify it directly (e.g. rustdoc, clippy, miri)", - Dist => "Install Rust from source", + User => "Install Rust from source", None => "Do not modify `config.toml`" } .to_string() @@ -73,7 +73,7 @@ impl Profile { Profile::Codegen => "codegen", Profile::Library => "library", Profile::Tools => "tools", - Profile::Dist => "dist", + Profile::User => "user", Profile::None => "none", } } @@ -87,7 +87,7 @@ impl FromStr for Profile { "lib" | "library" => Ok(Profile::Library), "compiler" => Ok(Profile::Compiler), "llvm" | "codegen" => Ok(Profile::Codegen), - "maintainer" | "dist" => Ok(Profile::Dist), + "maintainer" | "user" => Ok(Profile::User), "tools" | "tool" | "rustdoc" | "clippy" | "miri" | "rustfmt" | "rls" => { Ok(Profile::Tools) } @@ -160,7 +160,7 @@ pub fn setup(config: &Config, profile: Profile) { "test src/tools/rustfmt", ], Profile::Library => &["check", "build", "test library/std", "doc"], - Profile::Dist => &["dist", "build"], + Profile::User => &["dist", "build"], }; println!(); @@ -170,7 +170,7 @@ pub fn setup(config: &Config, profile: Profile) { println!("- `x.py {}`", cmd); } - if profile != Profile::Dist { + if profile != Profile::User { println!( "For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html" ); From 3ad595a31610b5094f66fa2855bde1f898a5d1f5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 19 Jun 2023 21:18:11 +0200 Subject: [PATCH 15/16] Add tests for invalid files generation --- tests/rustdoc/files-creation-hidden.rs | 23 +++++++++++++ tests/rustdoc/files-creation-private.rs | 18 ++++++++++ ...sue-111064-reexport-trait-from-hidden-2.rs | 8 ++--- tests/rustdoc/issue-111249-file-creation.rs | 34 +++++++++++++++++++ tests/rustdoc/redirect.rs | 2 ++ 5 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 tests/rustdoc/files-creation-hidden.rs create mode 100644 tests/rustdoc/files-creation-private.rs create mode 100644 tests/rustdoc/issue-111249-file-creation.rs diff --git a/tests/rustdoc/files-creation-hidden.rs b/tests/rustdoc/files-creation-hidden.rs new file mode 100644 index 00000000000..bcabbfc91e8 --- /dev/null +++ b/tests/rustdoc/files-creation-hidden.rs @@ -0,0 +1,23 @@ +#![crate_name="foo"] + +// @!has "foo/struct.Foo.html" +#[doc(hidden)] +pub struct Foo; + +// @!has "foo/struct.Bar.html" +pub use crate::Foo as Bar; + +// @!has "foo/struct.Baz.html" +#[doc(hidden)] +pub use crate::Foo as Baz; + +// @!has "foo/foo/index.html" +#[doc(hidden)] +pub mod foo {} + +// @!has "foo/bar/index.html" +pub use crate::foo as bar; + +// @!has "foo/baz/index.html" +#[doc(hidden)] +pub use crate::foo as baz; diff --git a/tests/rustdoc/files-creation-private.rs b/tests/rustdoc/files-creation-private.rs new file mode 100644 index 00000000000..ca2327e0f91 --- /dev/null +++ b/tests/rustdoc/files-creation-private.rs @@ -0,0 +1,18 @@ +#![crate_name="foo"] + +// @!has "foo/priv/index.html" +// @!has "foo/priv/struct.Foo.html" +mod private { + pub struct Foo; +} + +// @has "foo/struct.Bar.html" +pub use crate::private::Foo as Bar; + +// @!has "foo/foo/index.html" +mod foo { + pub mod subfoo {} +} + +// @has "foo/bar/index.html" +pub use crate::foo::subfoo as bar; diff --git a/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs b/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs index 8e1029a1ca3..d6832bb7a09 100644 --- a/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs +++ b/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs @@ -3,10 +3,10 @@ #![crate_name = "foo"] // @!has 'foo/hidden/index.html' -// FIXME: add missing `@` for the two next tests once issue is fixed! -// To be done in . -// !has 'foo/hidden/inner/index.html' -// !has 'foo/hidden/inner/trait.Foo.html' +// @!has 'foo/hidden/inner/index.html' +// FIXME: Should be `@!has`: https://github.com/rust-lang/rust/issues/111249 +// @has 'foo/hidden/inner/trait.Foo.html' +// @matchesraw - '' #[doc(hidden)] pub mod hidden { pub mod inner { diff --git a/tests/rustdoc/issue-111249-file-creation.rs b/tests/rustdoc/issue-111249-file-creation.rs new file mode 100644 index 00000000000..d2042b231e4 --- /dev/null +++ b/tests/rustdoc/issue-111249-file-creation.rs @@ -0,0 +1,34 @@ +#![crate_name = "foo"] +#![feature(no_core)] +#![no_core] + +// The following five should not fail! +// @!has 'foo/hidden/index.html' +// @!has 'foo/hidden/inner/index.html' +// FIXME: Should be `@!has`: https://github.com/rust-lang/rust/issues/111249 +// @has 'foo/hidden/inner/trait.Foo.html' +// @matchesraw - '' +// @!has 'foo/hidden/inner/inner_hidden/index.html' +// @!has 'foo/hidden/inner/inner_hidden/trait.HiddenFoo.html' +#[doc(hidden)] +pub mod hidden { + pub mod inner { + pub trait Foo {} + + #[doc(hidden)] + pub mod inner_hidden { + pub trait HiddenFoo {} + } + } +} + +// @has 'foo/visible/index.html' +// @has 'foo/visible/trait.Foo.html' +#[doc(inline)] +pub use hidden::inner as visible; + +// @has 'foo/struct.Bar.html' +// @count - '//*[@id="impl-Foo-for-Bar"]' 1 +pub struct Bar; + +impl visible::Foo for Bar {} diff --git a/tests/rustdoc/redirect.rs b/tests/rustdoc/redirect.rs index 5b7a76e1a77..4fb81c23d39 100644 --- a/tests/rustdoc/redirect.rs +++ b/tests/rustdoc/redirect.rs @@ -10,7 +10,9 @@ pub trait Foo {} // @has - '//code' 'pub use reexp_stripped::Bar' // @has - '//code/a' 'Bar' // @has - '//a[@href="../reexp_stripped/hidden/struct.Bar.html"]' 'Bar' +// FIXME: Should be `@!has`: https://github.com/rust-lang/rust/issues/111249 // @has reexp_stripped/hidden/struct.Bar.html +// @matchesraw - '' // @has 'reexp_stripped/struct.Bar.html' // @has - '//a[@href="struct.Bar.html"]' 'Bar' #[doc(no_inline)] From 53761e12226b03e742ae3c4b6e0d7716ad38b18f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 21 Jun 2023 13:37:17 +0200 Subject: [PATCH 16/16] Correctly handle Weak type aliases in rustdoc --- src/librustdoc/clean/mod.rs | 21 +++++++++++++++++---- tests/rustdoc/alias-reexport.rs | 6 ++---- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 851002d5e79..67d433dd0ad 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2024,8 +2024,8 @@ pub(crate) fn clean_middle_ty<'tcx>( Tuple(t.iter().map(|t| clean_middle_ty(bound_ty.rebind(t), cx, None, None)).collect()) } - ty::Alias(ty::Projection, ref data) => { - clean_projection(bound_ty.rebind(*data), cx, parent_def_id) + ty::Alias(ty::Projection, data) => { + clean_projection(bound_ty.rebind(data), cx, parent_def_id) } ty::Alias(ty::Inherent, alias_ty) => { @@ -2053,8 +2053,21 @@ pub(crate) fn clean_middle_ty<'tcx>( } ty::Alias(ty::Weak, data) => { - let ty = cx.tcx.type_of(data.def_id).subst(cx.tcx, data.substs); - clean_middle_ty(bound_ty.rebind(ty), cx, None, None) + if cx.tcx.features().lazy_type_alias { + // Weak type alias `data` represents the `type X` in `type X = Y`. If we need `Y`, + // we need to use `type_of`. + let path = external_path( + cx, + data.def_id, + false, + ThinVec::new(), + bound_ty.rebind(data.substs), + ); + Type::Path { path } + } else { + let ty = cx.tcx.type_of(data.def_id).subst(cx.tcx, data.substs); + clean_middle_ty(bound_ty.rebind(ty), cx, None, None) + } } ty::Param(ref p) => { diff --git a/tests/rustdoc/alias-reexport.rs b/tests/rustdoc/alias-reexport.rs index 029891197fc..a2a8e651caf 100644 --- a/tests/rustdoc/alias-reexport.rs +++ b/tests/rustdoc/alias-reexport.rs @@ -7,11 +7,9 @@ extern crate alias_reexport2; // @has 'foo/reexport/fn.foo.html' -// FIXME: should be 'pub fn foo() -> Reexport' -// @has - '//*[@class="rust item-decl"]' 'pub fn foo() -> u8' +// @has - '//*[@class="rust item-decl"]' 'pub fn foo() -> Reexported' // @has 'foo/reexport/fn.foo2.html' -// FIXME: should be 'pub fn foo2() -> Result' -// @has - '//*[@class="rust item-decl"]' 'pub fn foo2() -> Result' +// @has - '//*[@class="rust item-decl"]' 'pub fn foo2() -> Result' // @has 'foo/reexport/type.Reexported.html' // @has - '//*[@class="rust item-decl"]' 'pub type Reexported = u8;' #[doc(inline)]