mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Auto merge of #112890 - GuillaumeGomez:rollup-7e01q69, r=GuillaumeGomez
Rollup of 7 pull requests Successful merges: - #99587 (Document memory orderings of `thread::{park, unpark}`) - #112836 ([rustdoc] partially fix invalid files creation) - #112853 (Add `lazy_type_alias` feature gate) - #112863 (Fix copy-paste typo in `eprint(ln)` docs) - #112883 (Make queries traceable again) - #112885 (Fix msg passed to span_bug) - #112886 (Revert 'Rename profile=user to profile=dist') r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
536635c89b
@ -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::<Vec<mbe::TokenTree>>(),
|
||||
_ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs"),
|
||||
|
@ -442,6 +442,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.
|
||||
|
@ -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
|
||||
|
@ -531,6 +531,8 @@ macro_rules! define_queries {
|
||||
key: queries::$name::Key<'tcx>,
|
||||
mode: QueryMode,
|
||||
) -> Option<Erase<queries::$name::Value<'tcx>>> {
|
||||
#[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
|
||||
}
|
||||
)
|
||||
)
|
||||
},
|
||||
|
@ -871,6 +871,7 @@ symbols! {
|
||||
large_assignments,
|
||||
lateout,
|
||||
lazy_normalization_consts,
|
||||
lazy_type_alias,
|
||||
le,
|
||||
len,
|
||||
let_chains,
|
||||
|
@ -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
|
||||
|
@ -889,7 +889,7 @@ impl Drop for PanicGuard {
|
||||
/// 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 @@ impl Drop for PanicGuard {
|
||||
/// 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 @@ impl Drop for PanicGuard {
|
||||
///
|
||||
/// * 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 @@ impl Drop for PanicGuard {
|
||||
/// 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 @@ impl Drop for PanicGuard {
|
||||
/// // 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 @@ impl Drop for PanicGuard {
|
||||
///
|
||||
/// [`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;
|
||||
|
@ -20,7 +20,7 @@ pub enum Profile {
|
||||
Codegen,
|
||||
Library,
|
||||
Tools,
|
||||
Dist,
|
||||
User,
|
||||
None,
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ impl Profile {
|
||||
pub fn all() -> impl Iterator<Item = Self> {
|
||||
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"
|
||||
);
|
||||
|
@ -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) => {
|
||||
|
@ -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<Stability> {
|
||||
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<ConstStability> {
|
||||
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<Deprecation> {
|
||||
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<DefId> {
|
||||
self.item_id.as_def_id()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -121,6 +121,11 @@ pub(crate) struct Cache {
|
||||
pub(crate) intra_doc_links: FxHashMap<ItemId, FxIndexSet<clean::ItemLink>>,
|
||||
/// Cfg that have been hidden via #![doc(cfg_hide(...))]
|
||||
pub(crate) hidden_cfg: FxHashSet<clean::cfg::Cfg>,
|
||||
|
||||
/// 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`.
|
||||
|
@ -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<clean::Type>,
|
||||
/// 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.
|
||||
|
@ -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.
|
||||
|
16
tests/rustdoc/alias-reexport.rs
Normal file
16
tests/rustdoc/alias-reexport.rs
Normal file
@ -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<Reexported, ()>'
|
||||
// @has 'foo/reexport/type.Reexported.html'
|
||||
// @has - '//*[@class="rust item-decl"]' 'pub type Reexported = u8;'
|
||||
#[doc(inline)]
|
||||
pub use alias_reexport2 as reexport;
|
16
tests/rustdoc/alias-reexport2.rs
Normal file
16
tests/rustdoc/alias-reexport2.rs
Normal file
@ -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<Reexported, ()>'
|
||||
pub fn foo2() -> Result<Reexported, ()> { Ok(0) }
|
3
tests/rustdoc/auxiliary/alias-reexport.rs
Normal file
3
tests/rustdoc/auxiliary/alias-reexport.rs
Normal file
@ -0,0 +1,3 @@
|
||||
#![feature(lazy_type_alias)]
|
||||
|
||||
pub type Reexported = u8;
|
12
tests/rustdoc/auxiliary/alias-reexport2.rs
Normal file
12
tests/rustdoc/auxiliary/alias-reexport2.rs
Normal file
@ -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<Reexported, ()>'
|
||||
pub fn foo2() -> Result<Reexported, ()> { Ok(0) }
|
23
tests/rustdoc/files-creation-hidden.rs
Normal file
23
tests/rustdoc/files-creation-hidden.rs
Normal file
@ -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;
|
18
tests/rustdoc/files-creation-private.rs
Normal file
18
tests/rustdoc/files-creation-private.rs
Normal file
@ -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;
|
@ -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 <https://github.com/rust-lang/rust/issues/111249>.
|
||||
// !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 - '<meta http-equiv="refresh" content="0;URL=../../../foo/visible/trait.Foo.html">'
|
||||
#[doc(hidden)]
|
||||
pub mod hidden {
|
||||
pub mod inner {
|
||||
|
34
tests/rustdoc/issue-111249-file-creation.rs
Normal file
34
tests/rustdoc/issue-111249-file-creation.rs
Normal file
@ -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 - '<meta http-equiv="refresh" content="0;URL=../../../foo/visible/trait.Foo.html">'
|
||||
// @!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 {}
|
@ -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 - '<meta http-equiv="refresh" content="0;URL=../../reexp_stripped/struct.Bar.html">'
|
||||
// @has 'reexp_stripped/struct.Bar.html'
|
||||
// @has - '//a[@href="struct.Bar.html"]' 'Bar'
|
||||
#[doc(no_inline)]
|
||||
|
Loading…
Reference in New Issue
Block a user