mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
Auto merge of #123814 - matthiaskrgr:rollup-lxn0t4t, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #123459 (Correctly handle inlining of doc hidden foreign items) - #123740 (Reduce Size of `ModifierInfo`) - #123770 (Correct broken link in core::pin doc) - #123777 (Deduplicate some function implementations between the parser and AST/HIR) - #123808 (codegen tests: Tolerate `nuw` `nsw` on `trunc`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
616a8f85f1
@ -920,14 +920,8 @@ impl BinOpKind {
|
|||||||
matches!(self, BinOpKind::And | BinOpKind::Or)
|
matches!(self, BinOpKind::And | BinOpKind::Or)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_comparison(&self) -> bool {
|
pub fn is_comparison(self) -> bool {
|
||||||
use BinOpKind::*;
|
crate::util::parser::AssocOp::from_ast_binop(self).is_comparison()
|
||||||
// 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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the binary operator takes its arguments by value.
|
/// Returns `true` if the binary operator takes its arguments by value.
|
||||||
|
@ -1142,7 +1142,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn print_expr_binary(&mut self, op: hir::BinOp, lhs: &hir::Expr<'_>, rhs: &hir::Expr<'_>) {
|
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 prec = assoc_op.precedence() as i8;
|
||||||
let fixity = assoc_op.fixity();
|
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
|
/// 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
|
/// 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.
|
/// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.
|
||||||
|
@ -9,11 +9,11 @@ use std::str::FromStr;
|
|||||||
pub struct ModifierInfo {
|
pub struct ModifierInfo {
|
||||||
pub modifier: char,
|
pub modifier: char,
|
||||||
pub result: &'static str,
|
pub result: &'static str,
|
||||||
pub size: u64,
|
pub size: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<(char, &'static str, u64)> for ModifierInfo {
|
impl From<(char, &'static str, u16)> for ModifierInfo {
|
||||||
fn from((modifier, result, size): (char, &'static str, u64)) -> Self {
|
fn from((modifier, result, size): (char, &'static str, u16)) -> Self {
|
||||||
Self { modifier, result, size }
|
Self { modifier, result, size }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,11 +379,11 @@
|
|||||||
//!
|
//!
|
||||||
//! Exposing access to the inner field which you want to remain pinned must then be carefully
|
//! 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
|
//! considered as well! Remember, exposing a method that gives access to a
|
||||||
//! <code>[Pin]<[&mut] InnerT>></code> where `InnerT: [Unpin]` would allow safe code to trivially
|
//! <code>[Pin]<[&mut] InnerT>></code> where <code>InnerT: [Unpin]</code> would allow safe code to
|
||||||
//! move the inner value out of that pinning pointer, which is precisely what you're seeking to
|
//! trivially move the inner value out of that pinning pointer, which is precisely what you're
|
||||||
//! prevent! Exposing a field of a pinned value through a pinning pointer is called "projecting"
|
//! seeking to prevent! Exposing a field of a pinned value through a pinning pointer is called
|
||||||
//! a pin, and the more general case of deciding in which cases a pin should be able to be
|
//! "projecting" a pin, and the more general case of deciding in which cases a pin should be able
|
||||||
//! projected or not is called "structural pinning." We will go into more detail about this
|
//! to be projected or not is called "structural pinning." We will go into more detail about this
|
||||||
//! [below][structural-pinning].
|
//! [below][structural-pinning].
|
||||||
//!
|
//!
|
||||||
//! # Examples of address-sensitive types
|
//! # Examples of address-sensitive types
|
||||||
|
@ -63,8 +63,6 @@ pub(crate) fn try_inline(
|
|||||||
|
|
||||||
let import_def_id = attrs.and_then(|(_, def_id)| def_id);
|
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 {
|
let kind = match res {
|
||||||
Res::Def(DefKind::Trait, did) => {
|
Res::Def(DefKind::Trait, did) => {
|
||||||
record_extern_fqn(cx, did, ItemType::Trait);
|
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)))
|
cx.with_param_env(did, |cx| clean::ConstantItem(build_const(cx, did)))
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Macro(kind), 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 {
|
let type_kind = match kind {
|
||||||
MacroKind::Bang => ItemType::Macro,
|
MacroKind::Bang => ItemType::Macro,
|
||||||
@ -148,8 +150,14 @@ pub(crate) fn try_inline(
|
|||||||
};
|
};
|
||||||
|
|
||||||
cx.inlined.insert(did.into());
|
cx.inlined.insert(did.into());
|
||||||
let mut item =
|
let mut item = crate::clean::generate_item_with_correct_attrs(
|
||||||
clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, Box::new(attrs), cfg);
|
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.
|
// The visibility needs to reflect the one from the reexport and not from the "source" DefId.
|
||||||
item.inline_stmt_id = import_def_id;
|
item.inline_stmt_id = import_def_id;
|
||||||
ret.push(item);
|
ret.push(item);
|
||||||
@ -179,6 +187,7 @@ pub(crate) fn try_inline_glob(
|
|||||||
.iter()
|
.iter()
|
||||||
.filter(|child| !child.reexport_chain.is_empty())
|
.filter(|child| !child.reexport_chain.is_empty())
|
||||||
.filter_map(|child| child.res.opt_def_id())
|
.filter_map(|child| child.res.opt_def_id())
|
||||||
|
.filter(|def_id| !cx.tcx.is_doc_hidden(def_id))
|
||||||
.collect();
|
.collect();
|
||||||
let attrs = cx.tcx.hir().attrs(import.hir_id());
|
let attrs = cx.tcx.hir().attrs(import.hir_id());
|
||||||
let mut items = build_module_items(
|
let mut items = build_module_items(
|
||||||
|
@ -3007,14 +3007,15 @@ fn clean_use_statement_inner<'tcx>(
|
|||||||
// were specifically asked for it
|
// were specifically asked for it
|
||||||
denied = true;
|
denied = true;
|
||||||
}
|
}
|
||||||
if !denied {
|
if !denied
|
||||||
if let Some(mut items) = inline::try_inline(
|
&& let Some(mut items) = inline::try_inline(
|
||||||
cx,
|
cx,
|
||||||
path.res,
|
path.res,
|
||||||
name,
|
name,
|
||||||
Some((attrs, Some(import_def_id))),
|
Some((attrs, Some(import_def_id))),
|
||||||
&mut Default::default(),
|
&mut Default::default(),
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
items.push(Item::from_def_id_and_parts(
|
items.push(Item::from_def_id_and_parts(
|
||||||
import_def_id,
|
import_def_id,
|
||||||
None,
|
None,
|
||||||
@ -3023,7 +3024,6 @@ fn clean_use_statement_inner<'tcx>(
|
|||||||
));
|
));
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Import::new_simple(name, resolve_use_source(cx, path), true)
|
Import::new_simple(name, resolve_use_source(cx, path), true)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
/// This function exists because it runs on `hir::Attributes` whereas the other is a
|
||||||
/// `clean::Attributes` method.
|
/// `clean::Attributes` method.
|
||||||
pub(crate) fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool {
|
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<Item = &'a ast::Attribute>,
|
||||||
|
flag: Symbol,
|
||||||
|
) -> bool {
|
||||||
|
attrs
|
||||||
.any(|attr| attr.meta_item_list().is_some_and(|l| rustc_attr::list_contains_name(&l, flag)))
|
.any(|attr| attr.meta_item_list().is_some_and(|l| rustc_attr::list_contains_name(&l, flag)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,10 +203,10 @@ impl Cache {
|
|||||||
impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
||||||
fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
|
fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
|
||||||
if item.item_id.is_local() {
|
if item.item_id.is_local() {
|
||||||
let is_stripped = matches!(*item.kind, clean::ItemKind::StrippedItem(..));
|
|
||||||
debug!(
|
debug!(
|
||||||
"folding {} (stripped: {is_stripped:?}) \"{:?}\", id {:?}",
|
"folding {} (stripped: {:?}) \"{:?}\", id {:?}",
|
||||||
item.type_(),
|
item.type_(),
|
||||||
|
item.is_stripped(),
|
||||||
item.name,
|
item.name,
|
||||||
item.item_id
|
item.item_id
|
||||||
);
|
);
|
||||||
@ -246,13 +246,11 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||||||
// trait.
|
// trait.
|
||||||
if let clean::TraitItem(ref t) = *item.kind {
|
if let clean::TraitItem(ref t) = *item.kind {
|
||||||
self.cache.traits.entry(item.item_id.expect_def_id()).or_insert_with(|| (**t).clone());
|
self.cache.traits.entry(item.item_id.expect_def_id()).or_insert_with(|| (**t).clone());
|
||||||
}
|
} else if let clean::ImplItem(ref i) = *item.kind
|
||||||
|
|
||||||
// Collect all the implementors of traits.
|
|
||||||
if let clean::ImplItem(ref i) = *item.kind
|
|
||||||
&& let Some(trait_) = &i.trait_
|
&& let Some(trait_) = &i.trait_
|
||||||
&& !i.kind.is_blanket()
|
&& !i.kind.is_blanket()
|
||||||
{
|
{
|
||||||
|
// Collect all the implementors of traits.
|
||||||
self.cache
|
self.cache
|
||||||
.implementors
|
.implementors
|
||||||
.entry(trait_.def_id())
|
.entry(trait_.def_id())
|
||||||
|
@ -12,7 +12,7 @@ pub fn unwrap_digit_from_remainder(v: u32) -> AsciiChar {
|
|||||||
// CHECK-NOT: panic
|
// CHECK-NOT: panic
|
||||||
|
|
||||||
// CHECK: %[[R:.+]] = urem i32 %v, 10
|
// 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: %[[D:.+]] = or{{( disjoint)?}} i8 %[[T]], 48
|
||||||
// CHECK-NEXT: ret i8 %[[D]]
|
// CHECK-NEXT: ret i8 %[[D]]
|
||||||
|
|
||||||
|
@ -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: %[[INRANGE:.+]] = icmp ult i32 %b, 16
|
||||||
// CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
|
// 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]]
|
// CHECK-DAG: shl i16 %a, %[[TRUNC]]
|
||||||
a.unchecked_shl(b)
|
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: %[[INRANGE:.+]] = icmp ult i32 %b, 16
|
||||||
// CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
|
// 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]]
|
// CHECK-DAG: ashr i16 %a, %[[TRUNC]]
|
||||||
a.unchecked_shr(b)
|
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: %[[INRANGE:.+]] = icmp ult i128 %b, 8
|
||||||
// CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
|
// 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]]
|
// CHECK-DAG: shl i8 %a, %[[TRUNC]]
|
||||||
std::intrinsics::unchecked_shl(a, b)
|
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: %[[INRANGE:.+]] = icmp ult i128 %b, 8
|
||||||
// CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
|
// 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]]
|
// CHECK-DAG: ashr i8 %a, %[[TRUNC]]
|
||||||
std::intrinsics::unchecked_shr(a, b)
|
std::intrinsics::unchecked_shr(a, b)
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,23 @@
|
|||||||
|
|
||||||
extern crate rustdoc_hidden;
|
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)]
|
#[doc(no_inline)]
|
||||||
pub use rustdoc_hidden::Foo;
|
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 inline_hidden/fn.foo.html
|
||||||
// @!has - '//a/@title' 'Foo'
|
// @!has - '//a/@title' 'Foo'
|
||||||
pub fn foo(_: Foo) {}
|
pub fn foo(_: Foo) {}
|
||||||
|
Loading…
Reference in New Issue
Block a user