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"), diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 20a33e7fb36..93f968aa851 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -442,6 +442,8 @@ pub fn set(&self, features: &mut Features, span: Span) { (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 12f66779522..41a6d94b278 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -896,7 +896,7 @@ fn ast_path_to_ty( 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_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 @@ pub fn __rust_end_short_backtrace<'tcx>( 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 @@ pub fn dynamic_query<'tcx>() -> DynamicQuery<'tcx, queries::$name::Storage<'tcx> 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 + } ) ) }, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index f15d2c22da4..c71ed2097b8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -871,6 +871,7 @@ large_assignments, lateout, lazy_normalization_consts, + lazy_type_alias, le, len, let_chains, 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 diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 1230bb5deed..e4581c2de78 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -889,7 +889,7 @@ fn drop(&mut self) { /// it is guaranteed that this function will not panic (it may abort the /// process if the implementation encounters some rare errors). /// -/// # 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`] @@ -910,14 +910,6 @@ fn drop(&mut self) { /// 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 @@ -931,6 +923,23 @@ fn drop(&mut self) { /// /// * It can be implemented very efficiently on many platforms. /// +/// # 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 +/// 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]. +/// +/// 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, +/// making *all* wakeups spurious. +/// /// # Examples /// /// ``` @@ -944,7 +953,7 @@ fn drop(&mut self) { /// 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! @@ -961,7 +970,7 @@ fn drop(&mut self) { /// // 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(); /// @@ -970,6 +979,7 @@ fn drop(&mut self) { /// /// [`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() { let guard = PanicGuard; 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 @@ fn include_path(&self, src_path: &Path) -> PathBuf { 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 @@ pub fn purpose(&self) -> String { 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 @@ pub fn as_str(&self) -> &'static str { Profile::Codegen => "codegen", Profile::Library => "library", Profile::Tools => "tools", - Profile::Dist => "dist", + Profile::User => "user", Profile::None => "none", } } @@ -87,7 +87,7 @@ fn from_str(s: &str) -> Result { "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" ); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 162fc831ad2..9a815694e1b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2023,8 +2023,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) => { @@ -2052,8 +2052,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/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 @@ pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Option { 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 @@ pub(crate) fn link_names(&self, cache: &Cache) -> Vec { } 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 @@ fn build_fn_header( } 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 @@ fn build_fn_header( } } 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 @@ pub(crate) fn attributes(&self, tcx: TyCtxt<'_>, keep_as_is: bool) -> Vec, keep_as_is: bool) -> Vec bool { self.attrs.is_doc_hidden() } + + pub fn def_id(&self) -> Option { + self.item_id.as_def_id() + } } #[derive(Clone, Debug)] 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 @@ pub(super) fn root_path(&self) -> String { } 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 @@ fn render_item(&mut self, it: &clean::Item, is_module: bool) -> String { 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 @@ fn init( shared: Rc::new(scx), include_sources, types_with_notable_traits: FxHashSet::default(), + is_inside_inlined_module: false, }; if emit_crate { @@ -574,6 +590,7 @@ fn make_child_renderer(&self) -> Self { 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 @@ fn mod_item_in(&mut self, item: &clean::Item) -> Result<(), Error> { 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 @@ fn maybe_inline_local( 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 @@ fn maybe_inline_local( _ => 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. diff --git a/tests/rustdoc/alias-reexport.rs b/tests/rustdoc/alias-reexport.rs new file mode 100644 index 00000000000..a2a8e651caf --- /dev/null +++ b/tests/rustdoc/alias-reexport.rs @@ -0,0 +1,16 @@ +// 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' +// @has - '//*[@class="rust item-decl"]' 'pub fn foo() -> Reexported' +// @has 'foo/reexport/fn.foo2.html' +// @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) } 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)]