diff --git a/compiler/rustc_data_structures/src/binary_search_util/mod.rs b/compiler/rustc_data_structures/src/binary_search_util/mod.rs
index d40172a2e2f..bc8a6b9eac0 100644
--- a/compiler/rustc_data_structures/src/binary_search_util/mod.rs
+++ b/compiler/rustc_data_structures/src/binary_search_util/mod.rs
@@ -10,41 +10,17 @@ pub fn binary_search_slice<'d, E, K>(data: &'d [E], key_fn: impl Fn(&E) -> K, ke
where
K: Ord,
{
- let Ok(mid) = data.binary_search_by_key(key, &key_fn) else {
+ let size = data.len();
+ let start = data.partition_point(|x| key_fn(x) < *key);
+ // At this point `start` either points at the first entry with equal or
+ // greater key or is equal to `size` in case all elements have smaller keys
+ if start == size || key_fn(&data[start]) != *key {
return &[];
};
- let size = data.len();
-
- // We get back *some* element with the given key -- so do
- // a galloping search backwards to find the *first* one.
- let mut start = mid;
- let mut previous = mid;
- let mut step = 1;
- loop {
- start = start.saturating_sub(step);
- if start == 0 || key_fn(&data[start]) != *key {
- break;
- }
- previous = start;
- step *= 2;
- }
- step = previous - start;
- while step > 1 {
- let half = step / 2;
- let mid = start + half;
- if key_fn(&data[mid]) != *key {
- start = mid;
- }
- step -= half;
- }
- // adjust by one if we have overshot
- if start < size && key_fn(&data[start]) != *key {
- start += 1;
- }
// Now search forward to find the *last* one.
- let mut end = mid;
- let mut previous = mid;
+ let mut end = start;
+ let mut previous = start;
let mut step = 1;
loop {
end = end.saturating_add(step).min(size);
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 22380a52104..bbc3d291e20 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -449,7 +449,7 @@ pub fn set(&self, features: &mut Features, span: Span) {
// 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, "1.72.0", Some(112792), None),
+ (incomplete, lazy_type_alias, "1.72.0", 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/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 9839b82d7d7..6ec8f516366 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2809,7 +2809,7 @@ fn clean_use_statement_inner<'tcx>(
cx: &mut DocContext<'tcx>,
inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
) -> Vec- {
- if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = path.res {
+ if should_ignore_res(path.res) {
return Vec::new();
}
// We need this comparison because some imports (for std types for example)
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 5c8db3b8774..baf90b6d73e 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -13,7 +13,7 @@
use rustc_ast::tokenstream::TokenTree;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{DefId, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
use rustc_middle::mir;
use rustc_middle::mir::interpret::ConstValue;
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, TyCtxt};
@@ -629,3 +629,35 @@ pub(super) fn display_macro_source(
}
}
}
+
+pub(crate) fn inherits_doc_hidden(
+ tcx: TyCtxt<'_>,
+ mut def_id: LocalDefId,
+ stop_at: Option,
+) -> bool {
+ let hir = tcx.hir();
+ while let Some(id) = tcx.opt_local_parent(def_id) {
+ if let Some(stop_at) = stop_at && id == stop_at {
+ return false;
+ }
+ def_id = id;
+ if tcx.is_doc_hidden(def_id.to_def_id()) {
+ return true;
+ } else if let Some(node) = hir.find_by_def_id(def_id) &&
+ matches!(
+ node,
+ hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }),
+ )
+ {
+ // `impl` blocks stand a bit on their own: unless they have `#[doc(hidden)]` directly
+ // on them, they don't inherit it from the parent context.
+ return false;
+ }
+ }
+ false
+}
+
+#[inline]
+pub(crate) fn should_ignore_res(res: Res) -> bool {
+ matches!(res, Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..))
+}
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index a6200654ffa..0773d3b81f8 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -268,7 +268,7 @@ fn new() -> AllTypes {
fn append(&mut self, item_name: String, item_type: &ItemType) {
let mut url: Vec<_> = item_name.split("::").skip(1).collect();
if let Some(name) = url.pop() {
- let new_url = format!("{}/{}.{}.html", url.join("/"), item_type, name);
+ let new_url = format!("{}/{item_type}.{name}.html", url.join("/"));
url.push(name);
let name = url.join("::");
match *item_type {
@@ -385,16 +385,17 @@ fn print_entries(f: &mut Buffer, e: &FxHashSet, kind: ItemSection) {
fn scrape_examples_help(shared: &SharedContext<'_>) -> String {
let mut content = SCRAPE_EXAMPLES_HELP_MD.to_owned();
content.push_str(&format!(
- "## More information\n\n\
- If you want more information about this feature, please read the [corresponding chapter in the Rustdoc book]({}/rustdoc/scraped-examples.html).",
- DOC_RUST_LANG_ORG_CHANNEL));
+ "## More information\n\n\
+ If you want more information about this feature, please read the [corresponding chapter in \
+ the Rustdoc book]({DOC_RUST_LANG_ORG_CHANNEL}/rustdoc/scraped-examples.html)."
+ ));
let mut ids = IdMap::default();
format!(
"
\
-
About scraped examples
\
-
\
- {}
",
+ About scraped examples
\
+ \
+ {}
",
Markdown {
content: &content,
links: &[],
@@ -473,7 +474,7 @@ fn document_short<'a, 'cx: 'a>(
MarkdownSummaryLine(&s, &item.links(cx)).into_string_with_has_more_content();
if has_more_content {
- let link = format!(r#" Read more"#, assoc_href_attr(item, link, cx));
+ let link = format!(" Read more", assoc_href_attr(item, link, cx));
if let Some(idx) = summary_html.rfind("") {
summary_html.insert_str(idx, &link);
@@ -482,7 +483,7 @@ fn document_short<'a, 'cx: 'a>(
}
}
- write!(f, "{}
", summary_html)?;
+ write!(f, "{summary_html}
")?;
}
Ok(())
})
@@ -517,9 +518,9 @@ fn document_full_inner<'a, 'cx: 'a>(
write!(
f,
"\
- \
+ \
Expand description\
-
{}
",
+ {}",
render_markdown(cx, &s, item.links(cx), heading_offset)
)?;
} else {
@@ -701,8 +702,8 @@ fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>)
let item_type = it.type_();
let href = match link {
- AssocItemLink::Anchor(Some(ref id)) => Some(format!("#{}", id)),
- AssocItemLink::Anchor(None) => Some(format!("#{}.{}", item_type, name)),
+ AssocItemLink::Anchor(Some(ref id)) => Some(format!("#{id}")),
+ AssocItemLink::Anchor(None) => Some(format!("#{item_type}.{name}")),
AssocItemLink::GotoSource(did, provided_methods) => {
// We're creating a link from the implementation of an associated item to its
// declaration in the trait declaration.
@@ -722,7 +723,7 @@ fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>)
};
match href(did.expect_def_id(), cx) {
- Ok((url, ..)) => Some(format!("{}#{}.{}", url, item_type, name)),
+ Ok((url, ..)) => Some(format!("{url}#{item_type}.{name}")),
// The link is broken since it points to an external crate that wasn't documented.
// Do not create any link in such case. This is better than falling back to a
// dummy anchor like `#{item_type}.{name}` representing the `id` of *this* impl item
@@ -735,14 +736,14 @@ fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>)
// In this scenario, the actual `id` of this impl item would be
// `#{item_type}.{name}-{n}` for some number `n` (a disambiguator).
Err(HrefError::DocumentationNotBuilt) => None,
- Err(_) => Some(format!("#{}.{}", item_type, name)),
+ Err(_) => Some(format!("#{item_type}.{name}")),
}
}
};
// If there is no `href` for the reason explained above, simply do not render it which is valid:
// https://html.spec.whatwg.org/multipage/links.html#links-created-by-a-and-area-elements
- href.map(|href| format!(" href=\"{}\"", href)).unwrap_or_default()
+ href.map(|href| format!(" href=\"{href}\"")).unwrap_or_default()
}
fn assoc_const(
@@ -767,7 +768,7 @@ fn assoc_const(
ty = ty.print(cx),
);
if let Some(default) = default {
- write!(w, " = ");
+ w.write_str(" = ");
// FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the
// hood which adds noisy underscores and a type suffix to number literals.
@@ -910,39 +911,41 @@ fn render_stability_since_raw_with_extra(
if let Some(ver) = stable_version {
stability.push_str(ver.as_str());
- title.push_str(&format!("Stable since Rust version {}", ver));
+ title.push_str(&format!("Stable since Rust version {ver}"));
}
let const_title_and_stability = match const_stability {
Some(ConstStability { level: StabilityLevel::Stable { since, .. }, .. })
if Some(since) != containing_const_ver =>
{
- Some((format!("const since {}", since), format!("const: {}", since)))
+ Some((format!("const since {since}"), format!("const: {since}")))
}
Some(ConstStability { level: StabilityLevel::Unstable { issue, .. }, feature, .. }) => {
let unstable = if let Some(n) = issue {
format!(
- r#"unstable"#,
- n, feature
+ "unstable"
)
} else {
String::from("unstable")
};
- Some((String::from("const unstable"), format!("const: {}", unstable)))
+ Some((String::from("const unstable"), format!("const: {unstable}")))
}
_ => None,
};
if let Some((const_title, const_stability)) = const_title_and_stability {
if !title.is_empty() {
- title.push_str(&format!(", {}", const_title));
+ title.push_str(&format!(", {const_title}"));
} else {
title.push_str(&const_title);
}
if !stability.is_empty() {
- stability.push_str(&format!(" ({})", const_stability));
+ stability.push_str(&format!(" ({const_stability})"));
} else {
stability.push_str(&const_stability);
}
@@ -1091,7 +1094,7 @@ pub(crate) fn render_all_impls(
let impls = impls.into_inner();
if !impls.is_empty() {
write_impl_section_heading(&mut w, "Trait Implementations", "trait-implementations");
- write!(w, "{}
", impls).unwrap();
+ write!(w, "{impls}
").unwrap();
}
if !synthetic.is_empty() {
@@ -1189,10 +1192,13 @@ fn render_assoc_items_inner(
);
}
if !impls_buf.is_empty() {
- write!(w, "{}", tmp_buf.into_inner()).unwrap();
- write!(w, "").unwrap();
- write!(w, "{}", impls_buf.into_inner()).unwrap();
- w.write_str("
").unwrap();
+ write!(
+ w,
+ "{}{}
",
+ tmp_buf.into_inner(),
+ impls_buf.into_inner()
+ )
+ .unwrap();
}
}
@@ -1392,7 +1398,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
}
}
if out.is_empty() {
- write!(&mut out, "",);
+ out.write_str("");
}
(format!("{:#}", ty.print(cx)), out.into_inner())
@@ -1538,25 +1544,25 @@ fn doc_impl_item(
let toggled = !doc_buffer.is_empty();
if toggled {
let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
- write!(w, "", method_toggle_class);
+ write!(w, "");
}
match &*item.kind {
clean::MethodItem(..) | clean::TyMethodItem(_) => {
// Only render when the method is not static or we allow static methods
if render_method_item {
- let id = cx.derive_id(format!("{}.{}", item_type, name));
+ let id = cx.derive_id(format!("{item_type}.{name}"));
let source_id = trait_
.and_then(|trait_| {
trait_.items.iter().find(|item| {
item.name.map(|n| n.as_str().eq(name.as_str())).unwrap_or(false)
})
})
- .map(|item| format!("{}.{}", item.type_(), name));
- write!(w, "", id, item_type, in_trait_class,);
+ .map(|item| format!("{}.{name}", item.type_()));
+ write!(w, "");
render_rightside(w, cx, item, containing_item, render_mode);
if trait_.is_some() {
// Anchors are only used on trait impls.
- write!(w, "§", id);
+ write!(w, "§");
}
w.write_str("");
- w.write_str("");
+ w.write_str("");
}
}
kind @ (clean::TyAssocConstItem(generics, ty)
| clean::AssocConstItem(generics, ty, _)) => {
- let source_id = format!("{}.{}", item_type, name);
+ let source_id = format!("{item_type}.{name}");
let id = cx.derive_id(source_id.clone());
- write!(w, "", id, item_type, in_trait_class);
+ write!(w, "");
render_rightside(w, cx, item, containing_item, render_mode);
if trait_.is_some() {
// Anchors are only used on trait impls.
- write!(w, "§", id);
+ write!(w, "§");
}
w.write_str("");
- w.write_str("");
+ w.write_str("");
}
clean::TyAssocTypeItem(generics, bounds) => {
- let source_id = format!("{}.{}", item_type, name);
+ let source_id = format!("{item_type}.{name}");
let id = cx.derive_id(source_id.clone());
- write!(w, "", id, item_type, in_trait_class);
+ write!(w, "");
if trait_.is_some() {
// Anchors are only used on trait impls.
- write!(w, "§", id);
+ write!(w, "§");
}
w.write_str("");
- w.write_str("");
+ w.write_str("");
}
clean::AssocTypeItem(tydef, _bounds) => {
- let source_id = format!("{}.{}", item_type, name);
+ let source_id = format!("{item_type}.{name}");
let id = cx.derive_id(source_id.clone());
- write!(w, "", id, item_type, in_trait_class);
+ write!(w, "");
if trait_.is_some() {
// Anchors are only used on trait impls.
- write!(w, "§", id);
+ write!(w, "§");
}
w.write_str("");
- w.write_str("");
+ w.write_str("");
}
clean::StrippedItem(..) => return,
_ => panic!("can't make docs for trait item with name {:?}", item.name),
@@ -1744,10 +1746,10 @@ fn render_default_items(
close_tags.insert_str(0, "
");
write!(
w,
- "",
+ "\
+ ",
if rendering_params.toggle_open_by_default { " open" } else { "" }
);
- write!(w, "")
}
render_impl_summary(
w,
@@ -1760,15 +1762,15 @@ fn render_default_items(
aliases,
);
if toggled {
- write!(w, "
")
+ w.write_str("
");
}
if let Some(ref dox) = i.impl_item.opt_doc_value() {
if trait_.is_none() && i.inner_impl().items.is_empty() {
w.write_str(
"\
-
This impl block contains no items.
\
-
",
+ This impl block contains no items.
\
+ ",
);
}
write!(
@@ -1827,11 +1829,11 @@ fn render_rightside(
const_stable_since,
if has_src_ref { "" } else { " rightside" },
);
- if let Some(l) = src_href {
+ if let Some(link) = src_href {
if has_stability {
- write!(rightside, " · source", l)
+ write!(rightside, " · source")
} else {
- write!(rightside, "source", l)
+ write!(rightside, "source")
}
}
if has_stability && has_src_ref {
@@ -1860,10 +1862,13 @@ pub(crate) fn render_impl_summary(
} else {
format!(" data-aliases=\"{}\"", aliases.join(","))
};
- write!(w, "", id, aliases);
+ write!(w, "");
render_rightside(w, cx, &i.impl_item, containing_item, RenderMode::Normal);
- write!(w, "§", id);
- write!(w, "");
let is_trait = inner_impl.trait_.is_some();
if is_trait {
if let Some(portability) = portability(&i.impl_item, Some(parent)) {
write!(
w,
- "{}
",
- portability
+ "\
+ {portability}
\
+ ",
);
}
}
@@ -1949,7 +1955,7 @@ fn dont_escape(c: u8) -> bool {
// consistent with itself when encoding them.
st += "+";
} else {
- write!(st, "%{:02X}", b).unwrap();
+ write!(st, "%{b:02X}").unwrap();
}
// Invariant: if the current byte is not at the start of a multi-byte character,
// we need to get down here so that when the next turn of the loop comes around,
@@ -2264,7 +2270,7 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c
format!("lines {}-{}", line_lo + 1, line_hi + 1),
)
};
- let url = format!("{}{}#{}", cx.root_path(), call_data.url, anchor);
+ let url = format!("{}{}#{anchor}", cx.root_path(), call_data.url);
(url, title)
};
@@ -2274,7 +2280,7 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c
Ok(contents) => contents,
Err(err) => {
let span = item.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner());
- tcx.sess.span_err(span, format!("failed to read file {}: {}", path.display(), err));
+ tcx.sess.span_err(span, format!("failed to read file {}: {err}", path.display()));
return false;
}
};
@@ -2333,7 +2339,7 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c
.unwrap();
if line_ranges.len() > 1 {
- write!(w, r#" "#)
+ w.write_str(r#" "#)
.unwrap();
}
@@ -2369,7 +2375,7 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c
highlight::DecorationInfo(decoration_info),
sources::SourceContext::Embedded { offset: line_min, needs_expansion },
);
- write!(w, "").unwrap();
+ w.write_str("").unwrap();
true
};
@@ -2436,8 +2442,10 @@ fn sort_criterion<'a>(
// For the remaining examples, generate a ").unwrap();
+ w.write_str(" ").unwrap();
}
- write!(w, "").unwrap();
+ w.write_str("").unwrap();
}
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index 011ca9a4961..e333a35e8ad 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -7,11 +7,11 @@
use super::Pass;
use crate::clean;
+use crate::clean::utils::inherits_doc_hidden;
use crate::clean::*;
use crate::core::DocContext;
use crate::html::markdown::{find_testable_code, ErrorCodes, Ignore, LangString};
use crate::visit::DocVisitor;
-use crate::visit_ast::inherits_doc_hidden;
use rustc_hir as hir;
use rustc_middle::lint::LintLevelSource;
use rustc_session::lint;
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index 7b990cd4348..81a90ed498a 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -6,11 +6,11 @@
use std::mem;
use crate::clean;
+use crate::clean::utils::inherits_doc_hidden;
use crate::clean::{Item, ItemIdSet};
use crate::core::DocContext;
use crate::fold::{strip_item, DocFolder};
use crate::passes::{ImplStripper, Pass};
-use crate::visit_ast::inherits_doc_hidden;
pub(crate) const STRIP_HIDDEN: Pass = Pass {
name: "strip-hidden",
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index a6d31534f1d..64a4ace5b9f 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -3,10 +3,10 @@
use rustc_middle::ty::{TyCtxt, Visibility};
use std::mem;
+use crate::clean::utils::inherits_doc_hidden;
use crate::clean::{self, Item, ItemId, ItemIdSet};
use crate::fold::{strip_item, DocFolder};
use crate::formats::cache::Cache;
-use crate::visit_ast::inherits_doc_hidden;
use crate::visit_lib::RustdocEffectiveVisibilities;
pub(crate) struct Stripper<'a, 'tcx> {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 2f67e12df91..3bad9ba4e4a 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -16,6 +16,7 @@
use std::mem;
+use crate::clean::utils::{inherits_doc_hidden, should_ignore_res};
use crate::clean::{cfg::Cfg, reexport_chain, AttributesExt, NestedAttributesExt};
use crate::core;
@@ -73,33 +74,6 @@ fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec {
std::iter::once(crate_name).chain(relative).collect()
}
-pub(crate) fn inherits_doc_hidden(
- tcx: TyCtxt<'_>,
- mut def_id: LocalDefId,
- stop_at: Option,
-) -> bool {
- let hir = tcx.hir();
- while let Some(id) = tcx.opt_local_parent(def_id) {
- if let Some(stop_at) = stop_at && id == stop_at {
- return false;
- }
- def_id = id;
- if tcx.is_doc_hidden(def_id.to_def_id()) {
- return true;
- } else if let Some(node) = hir.find_by_def_id(def_id) &&
- matches!(
- node,
- hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }),
- )
- {
- // `impl` blocks stand a bit on their own: unless they have `#[doc(hidden)]` directly
- // on them, they don't inherit it from the parent context.
- return false;
- }
- }
- false
-}
-
pub(crate) struct RustdocVisitor<'a, 'tcx> {
cx: &'a mut core::DocContext<'tcx>,
view_item_stack: LocalDefIdSet,
@@ -466,7 +440,7 @@ fn visit_item_inner(
for &res in &path.res {
// Struct and variant constructors and proc macro stubs always show up alongside
// their definitions, we've already processed them so just discard these.
- if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res {
+ if should_ignore_res(res) {
continue;
}
diff --git a/tests/rustdoc/alias-reexport.rs b/tests/rustdoc/alias-reexport.rs
index a2a8e651caf..4003ecec21c 100644
--- a/tests/rustdoc/alias-reexport.rs
+++ b/tests/rustdoc/alias-reexport.rs
@@ -3,6 +3,7 @@
#![crate_name = "foo"]
#![feature(lazy_type_alias)]
+#![allow(incomplete_features)]
extern crate alias_reexport2;
diff --git a/tests/rustdoc/alias-reexport2.rs b/tests/rustdoc/alias-reexport2.rs
index 85d3cdad962..5f6357ad128 100644
--- a/tests/rustdoc/alias-reexport2.rs
+++ b/tests/rustdoc/alias-reexport2.rs
@@ -3,6 +3,7 @@
#![crate_name = "foo"]
#![feature(lazy_type_alias)]
+#![allow(incomplete_features)]
extern crate alias_reexport;
diff --git a/tests/ui/type-alias/lazy-type-alias-enum-variant.rs b/tests/ui/type-alias/lazy-type-alias-enum-variant.rs
index 78c3159d1c2..6d18e9eca62 100644
--- a/tests/ui/type-alias/lazy-type-alias-enum-variant.rs
+++ b/tests/ui/type-alias/lazy-type-alias-enum-variant.rs
@@ -2,6 +2,7 @@
// check-pass
#![feature(lazy_type_alias)]
+//~^ WARN the feature `lazy_type_alias` is incomplete and may not be safe to use
enum Enum {
Unit,
diff --git a/tests/ui/type-alias/lazy-type-alias-enum-variant.stderr b/tests/ui/type-alias/lazy-type-alias-enum-variant.stderr
new file mode 100644
index 00000000000..381261b95c7
--- /dev/null
+++ b/tests/ui/type-alias/lazy-type-alias-enum-variant.stderr
@@ -0,0 +1,11 @@
+warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/lazy-type-alias-enum-variant.rs:4:12
+ |
+LL | #![feature(lazy_type_alias)]
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: see issue #112792 for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+