diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 63ce6685e435b..5b708cf4e1a55 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -920,14 +920,8 @@ impl BinOpKind {
matches!(self, BinOpKind::And | BinOpKind::Or)
}
- pub fn is_comparison(&self) -> bool {
- use BinOpKind::*;
- // Note for developers: please keep this match exhaustive;
- // we want compilation to fail if another variant is added.
- match *self {
- Eq | Lt | Le | Ne | Gt | Ge => true,
- And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false,
- }
+ pub fn is_comparison(self) -> bool {
+ crate::util::parser::AssocOp::from_ast_binop(self).is_comparison()
}
/// Returns `true` if the binary operator takes its arguments by value.
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index a590c648d2063..39312614c1b19 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1142,7 +1142,7 @@ impl<'a> State<'a> {
}
fn print_expr_binary(&mut self, op: hir::BinOp, lhs: &hir::Expr<'_>, rhs: &hir::Expr<'_>) {
- let assoc_op = bin_op_to_assoc_op(op.node);
+ let assoc_op = AssocOp::from_ast_binop(op.node);
let prec = assoc_op.precedence() as i8;
let fixity = assoc_op.fixity();
@@ -2328,33 +2328,6 @@ fn stmt_ends_with_semi(stmt: &hir::StmtKind<'_>) -> bool {
}
}
-fn bin_op_to_assoc_op(op: hir::BinOpKind) -> AssocOp {
- use crate::hir::BinOpKind::*;
- match op {
- Add => AssocOp::Add,
- Sub => AssocOp::Subtract,
- Mul => AssocOp::Multiply,
- Div => AssocOp::Divide,
- Rem => AssocOp::Modulus,
-
- And => AssocOp::LAnd,
- Or => AssocOp::LOr,
-
- BitXor => AssocOp::BitXor,
- BitAnd => AssocOp::BitAnd,
- BitOr => AssocOp::BitOr,
- Shl => AssocOp::ShiftLeft,
- Shr => AssocOp::ShiftRight,
-
- Eq => AssocOp::Equal,
- Lt => AssocOp::Less,
- Le => AssocOp::LessEqual,
- Ne => AssocOp::NotEqual,
- Ge => AssocOp::GreaterEqual,
- Gt => AssocOp::Greater,
- }
-}
-
/// Expressions that syntactically contain an "exterior" struct literal, i.e., not surrounded by any
/// parens or other delimiters, e.g., `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and
/// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index d6bbf4f36cf26..49de92b86cb48 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -9,11 +9,11 @@ use std::str::FromStr;
pub struct ModifierInfo {
pub modifier: char,
pub result: &'static str,
- pub size: u64,
+ pub size: u16,
}
-impl From<(char, &'static str, u64)> for ModifierInfo {
- fn from((modifier, result, size): (char, &'static str, u64)) -> Self {
+impl From<(char, &'static str, u16)> for ModifierInfo {
+ fn from((modifier, result, size): (char, &'static str, u16)) -> Self {
Self { modifier, result, size }
}
}
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index e843a5d5790d2..c18dbafff160a 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -379,11 +379,11 @@
//!
//! Exposing access to the inner field which you want to remain pinned must then be carefully
//! considered as well! Remember, exposing a method that gives access to a
-//! [Pin]<[&mut] InnerT>>
where `InnerT: [Unpin]` would allow safe code to trivially
-//! move the inner value out of that pinning pointer, which is precisely what you're seeking to
-//! prevent! Exposing a field of a pinned value through a pinning pointer is called "projecting"
-//! a pin, and the more general case of deciding in which cases a pin should be able to be
-//! projected or not is called "structural pinning." We will go into more detail about this
+//! [Pin]<[&mut] InnerT>>
where InnerT: [Unpin]
would allow safe code to
+//! trivially move the inner value out of that pinning pointer, which is precisely what you're
+//! seeking to prevent! Exposing a field of a pinned value through a pinning pointer is called
+//! "projecting" a pin, and the more general case of deciding in which cases a pin should be able
+//! to be projected or not is called "structural pinning." We will go into more detail about this
//! [below][structural-pinning].
//!
//! # Examples of address-sensitive types
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 6f86c6450d969..4d506edc47bd4 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -63,8 +63,6 @@ pub(crate) fn try_inline(
let import_def_id = attrs.and_then(|(_, def_id)| def_id);
- let (attrs, cfg) = merge_attrs(cx, load_attrs(cx, did), attrs);
-
let kind = match res {
Res::Def(DefKind::Trait, did) => {
record_extern_fqn(cx, did, ItemType::Trait);
@@ -134,7 +132,11 @@ pub(crate) fn try_inline(
cx.with_param_env(did, |cx| clean::ConstantItem(build_const(cx, did)))
}
Res::Def(DefKind::Macro(kind), did) => {
- let mac = build_macro(cx, did, name, import_def_id, kind, attrs.is_doc_hidden());
+ let is_doc_hidden = cx.tcx.is_doc_hidden(did)
+ || attrs_without_docs
+ .map(|(attrs, _)| attrs)
+ .is_some_and(|attrs| utils::attrs_have_doc_flag(attrs.iter(), sym::hidden));
+ let mac = build_macro(cx, did, name, import_def_id, kind, is_doc_hidden);
let type_kind = match kind {
MacroKind::Bang => ItemType::Macro,
@@ -148,8 +150,14 @@ pub(crate) fn try_inline(
};
cx.inlined.insert(did.into());
- let mut item =
- clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, Box::new(attrs), cfg);
+ let mut item = crate::clean::generate_item_with_correct_attrs(
+ cx,
+ kind,
+ did,
+ name,
+ import_def_id.and_then(|def_id| def_id.as_local()),
+ None,
+ );
// The visibility needs to reflect the one from the reexport and not from the "source" DefId.
item.inline_stmt_id = import_def_id;
ret.push(item);
@@ -179,6 +187,7 @@ pub(crate) fn try_inline_glob(
.iter()
.filter(|child| !child.reexport_chain.is_empty())
.filter_map(|child| child.res.opt_def_id())
+ .filter(|def_id| !cx.tcx.is_doc_hidden(def_id))
.collect();
let attrs = cx.tcx.hir().attrs(import.hir_id());
let mut items = build_module_items(
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 12f45fe497972..925d41e67f8fa 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -3007,22 +3007,22 @@ fn clean_use_statement_inner<'tcx>(
// were specifically asked for it
denied = true;
}
- if !denied {
- if let Some(mut items) = inline::try_inline(
+ if !denied
+ && let Some(mut items) = inline::try_inline(
cx,
path.res,
name,
Some((attrs, Some(import_def_id))),
&mut Default::default(),
- ) {
- items.push(Item::from_def_id_and_parts(
- import_def_id,
- None,
- ImportItem(Import::new_simple(name, resolve_use_source(cx, path), false)),
- cx,
- ));
- return items;
- }
+ )
+ {
+ items.push(Item::from_def_id_and_parts(
+ import_def_id,
+ None,
+ ImportItem(Import::new_simple(name, resolve_use_source(cx, path), false)),
+ cx,
+ ));
+ return items;
}
Import::new_simple(name, resolve_use_source(cx, path), true)
};
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index dc62fbb5edb55..aa923cc611734 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -580,7 +580,14 @@ pub(crate) fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Opti
/// This function exists because it runs on `hir::Attributes` whereas the other is a
/// `clean::Attributes` method.
pub(crate) fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool {
- tcx.get_attrs(did, sym::doc)
+ attrs_have_doc_flag(tcx.get_attrs(did, sym::doc), flag)
+}
+
+pub(crate) fn attrs_have_doc_flag<'a>(
+ mut attrs: impl Iterator- ,
+ flag: Symbol,
+) -> bool {
+ attrs
.any(|attr| attr.meta_item_list().is_some_and(|l| rustc_attr::list_contains_name(&l, flag)))
}
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 9802097ea290c..11fc99eb51111 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -203,10 +203,10 @@ impl Cache {
impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
fn fold_item(&mut self, item: clean::Item) -> Option {
if item.item_id.is_local() {
- let is_stripped = matches!(*item.kind, clean::ItemKind::StrippedItem(..));
debug!(
- "folding {} (stripped: {is_stripped:?}) \"{:?}\", id {:?}",
+ "folding {} (stripped: {:?}) \"{:?}\", id {:?}",
item.type_(),
+ item.is_stripped(),
item.name,
item.item_id
);
@@ -246,13 +246,11 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
// trait.
if let clean::TraitItem(ref t) = *item.kind {
self.cache.traits.entry(item.item_id.expect_def_id()).or_insert_with(|| (**t).clone());
- }
-
- // Collect all the implementors of traits.
- if let clean::ImplItem(ref i) = *item.kind
+ } else if let clean::ImplItem(ref i) = *item.kind
&& let Some(trait_) = &i.trait_
&& !i.kind.is_blanket()
{
+ // Collect all the implementors of traits.
self.cache
.implementors
.entry(trait_.def_id())
diff --git a/tests/codegen/ascii-char.rs b/tests/codegen/ascii-char.rs
index fab9f8632fcad..86ec9d73afea2 100644
--- a/tests/codegen/ascii-char.rs
+++ b/tests/codegen/ascii-char.rs
@@ -12,7 +12,7 @@ pub fn unwrap_digit_from_remainder(v: u32) -> AsciiChar {
// CHECK-NOT: panic
// CHECK: %[[R:.+]] = urem i32 %v, 10
- // CHECK-NEXT: %[[T:.+]] = trunc i32 %[[R]] to i8
+ // CHECK-NEXT: %[[T:.+]] = trunc{{( nuw)?( nsw)?}} i32 %[[R]] to i8
// CHECK-NEXT: %[[D:.+]] = or{{( disjoint)?}} i8 %[[T]], 48
// CHECK-NEXT: ret i8 %[[D]]
diff --git a/tests/codegen/unchecked_shifts.rs b/tests/codegen/unchecked_shifts.rs
index 7d020fbb4d253..86517c896276d 100644
--- a/tests/codegen/unchecked_shifts.rs
+++ b/tests/codegen/unchecked_shifts.rs
@@ -22,7 +22,7 @@ pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 {
// CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 16
// CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
- // CHECK-DAG: %[[TRUNC:.+]] = trunc i32 %b to i16
+ // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i32 %b to i16
// CHECK-DAG: shl i16 %a, %[[TRUNC]]
a.unchecked_shl(b)
}
@@ -54,7 +54,7 @@ pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 {
// CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 16
// CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
- // CHECK-DAG: %[[TRUNC:.+]] = trunc i32 %b to i16
+ // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i32 %b to i16
// CHECK-DAG: ashr i16 %a, %[[TRUNC]]
a.unchecked_shr(b)
}
@@ -94,7 +94,7 @@ pub unsafe fn unchecked_shl_u8_i128(a: u8, b: i128) -> u8 {
// CHECK-DAG: %[[INRANGE:.+]] = icmp ult i128 %b, 8
// CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
- // CHECK-DAG: %[[TRUNC:.+]] = trunc i128 %b to i8
+ // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i128 %b to i8
// CHECK-DAG: shl i8 %a, %[[TRUNC]]
std::intrinsics::unchecked_shl(a, b)
}
@@ -107,7 +107,7 @@ pub unsafe fn unchecked_shr_i8_u128(a: i8, b: u128) -> i8 {
// CHECK-DAG: %[[INRANGE:.+]] = icmp ult i128 %b, 8
// CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
- // CHECK-DAG: %[[TRUNC:.+]] = trunc i128 %b to i8
+ // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i128 %b to i8
// CHECK-DAG: ashr i8 %a, %[[TRUNC]]
std::intrinsics::unchecked_shr(a, b)
}
diff --git a/tests/rustdoc/inline_cross/inline_hidden.rs b/tests/rustdoc/inline_cross/inline_hidden.rs
index ec06f2f0c5d6d..2a3dd72749ccc 100644
--- a/tests/rustdoc/inline_cross/inline_hidden.rs
+++ b/tests/rustdoc/inline_cross/inline_hidden.rs
@@ -4,9 +4,23 @@
extern crate rustdoc_hidden;
+// @has inline_hidden/index.html
+// Ensures this item is not inlined.
+// @has - '//*[@id="reexport.Foo"]/code' 'pub use rustdoc_hidden::Foo;'
#[doc(no_inline)]
pub use rustdoc_hidden::Foo;
+// Even if the foreign item has `doc(hidden)`, we should be able to inline it.
+// @has - '//*[@class="item-name"]/a[@class="struct"]' 'Inlined'
+#[doc(inline)]
+pub use rustdoc_hidden::Foo as Inlined;
+
+// Even with this import, we should not see `Foo`.
+// @count - '//*[@class="item-name"]' 4
+// @has - '//*[@class="item-name"]/a[@class="struct"]' 'Bar'
+// @has - '//*[@class="item-name"]/a[@class="fn"]' 'foo'
+pub use rustdoc_hidden::*;
+
// @has inline_hidden/fn.foo.html
// @!has - '//a/@title' 'Foo'
pub fn foo(_: Foo) {}