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) {}