Auto merge of #125423 - fmease:rollup-ne4l9y4, r=fmease

Rollup of 7 pull requests

Successful merges:

 - #125043 (reference type safety invariant docs: clarification)
 - #125306 (Force the inner coroutine of an async closure to `move` if the outer closure is `move` and `FnOnce`)
 - #125355 (Use Backtrace::force_capture instead of Backtrace::capture in rustc_log)
 - #125382 (rustdoc: rename `issue-\d+.rs` tests to have meaningful names (part 7))
 - #125391 (Minor serialize/span tweaks)
 - #125395 (Remove unnecessary `.md` from the documentation sidebar)
 - #125399 (Stop using `to_hir_binop` in codegen)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-05-22 21:51:26 +00:00
commit 9cdfe285ca
41 changed files with 253 additions and 137 deletions

View File

@ -14,6 +14,7 @@ use rustc_codegen_ssa::mir::operand::OperandRef;
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods};
use rustc_hir as hir;
use rustc_middle::mir::BinOp;
use rustc_middle::span_bug;
use rustc_middle::ty::layout::HasTyCtxt;
use rustc_middle::ty::{self, Ty};
@ -122,12 +123,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
let in_ty = arg_tys[0];
let comparison = match name {
sym::simd_eq => Some(hir::BinOpKind::Eq),
sym::simd_ne => Some(hir::BinOpKind::Ne),
sym::simd_lt => Some(hir::BinOpKind::Lt),
sym::simd_le => Some(hir::BinOpKind::Le),
sym::simd_gt => Some(hir::BinOpKind::Gt),
sym::simd_ge => Some(hir::BinOpKind::Ge),
sym::simd_eq => Some(BinOp::Eq),
sym::simd_ne => Some(BinOp::Ne),
sym::simd_lt => Some(BinOp::Lt),
sym::simd_le => Some(BinOp::Le),
sym::simd_gt => Some(BinOp::Gt),
sym::simd_ge => Some(BinOp::Ge),
_ => None,
};

View File

@ -14,6 +14,7 @@ use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
use rustc_hir as hir;
use rustc_middle::mir::BinOp;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf};
use rustc_middle::ty::{self, GenericArgsRef, Ty};
use rustc_middle::{bug, span_bug};
@ -1104,12 +1105,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
let in_ty = arg_tys[0];
let comparison = match name {
sym::simd_eq => Some(hir::BinOpKind::Eq),
sym::simd_ne => Some(hir::BinOpKind::Ne),
sym::simd_lt => Some(hir::BinOpKind::Lt),
sym::simd_le => Some(hir::BinOpKind::Le),
sym::simd_gt => Some(hir::BinOpKind::Gt),
sym::simd_ge => Some(hir::BinOpKind::Ge),
sym::simd_eq => Some(BinOp::Eq),
sym::simd_ne => Some(BinOp::Ne),
sym::simd_lt => Some(BinOp::Lt),
sym::simd_le => Some(BinOp::Le),
sym::simd_gt => Some(BinOp::Gt),
sym::simd_ge => Some(BinOp::Ge),
_ => None,
};

View File

@ -20,7 +20,6 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
use rustc_data_structures::sync::par_map;
use rustc_data_structures::unord::UnordMap;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::lang_items::LangItem;
use rustc_metadata::EncodedMetadata;
@ -30,6 +29,7 @@ use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, Debugger
use rustc_middle::middle::exported_symbols;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
use rustc_middle::middle::lang_items;
use rustc_middle::mir::BinOp;
use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem};
use rustc_middle::query::Providers;
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
@ -46,32 +46,32 @@ use std::time::{Duration, Instant};
use itertools::Itertools;
pub fn bin_op_to_icmp_predicate(op: hir::BinOpKind, signed: bool) -> IntPredicate {
pub fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate {
match op {
hir::BinOpKind::Eq => IntPredicate::IntEQ,
hir::BinOpKind::Ne => IntPredicate::IntNE,
hir::BinOpKind::Lt => {
BinOp::Eq => IntPredicate::IntEQ,
BinOp::Ne => IntPredicate::IntNE,
BinOp::Lt => {
if signed {
IntPredicate::IntSLT
} else {
IntPredicate::IntULT
}
}
hir::BinOpKind::Le => {
BinOp::Le => {
if signed {
IntPredicate::IntSLE
} else {
IntPredicate::IntULE
}
}
hir::BinOpKind::Gt => {
BinOp::Gt => {
if signed {
IntPredicate::IntSGT
} else {
IntPredicate::IntUGT
}
}
hir::BinOpKind::Ge => {
BinOp::Ge => {
if signed {
IntPredicate::IntSGE
} else {
@ -86,14 +86,14 @@ pub fn bin_op_to_icmp_predicate(op: hir::BinOpKind, signed: bool) -> IntPredicat
}
}
pub fn bin_op_to_fcmp_predicate(op: hir::BinOpKind) -> RealPredicate {
pub fn bin_op_to_fcmp_predicate(op: BinOp) -> RealPredicate {
match op {
hir::BinOpKind::Eq => RealPredicate::RealOEQ,
hir::BinOpKind::Ne => RealPredicate::RealUNE,
hir::BinOpKind::Lt => RealPredicate::RealOLT,
hir::BinOpKind::Le => RealPredicate::RealOLE,
hir::BinOpKind::Gt => RealPredicate::RealOGT,
hir::BinOpKind::Ge => RealPredicate::RealOGE,
BinOp::Eq => RealPredicate::RealOEQ,
BinOp::Ne => RealPredicate::RealUNE,
BinOp::Lt => RealPredicate::RealOLT,
BinOp::Le => RealPredicate::RealOLE,
BinOp::Gt => RealPredicate::RealOGT,
BinOp::Ge => RealPredicate::RealOGE,
op => {
bug!(
"comparison_op_to_fcmp_predicate: expected comparison operator, \
@ -110,7 +110,7 @@ pub fn compare_simd_types<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
rhs: Bx::Value,
t: Ty<'tcx>,
ret_ty: Bx::Type,
op: hir::BinOpKind,
op: BinOp,
) -> Bx::Value {
let signed = match t.kind() {
ty::Float(_) => {

View File

@ -7,7 +7,6 @@ use crate::common::IntPredicate;
use crate::traits::*;
use crate::MemFlags;
use rustc_hir as hir;
use rustc_middle::mir;
use rustc_middle::ty::cast::{CastTy, IntTy};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
@ -896,9 +895,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
| mir::BinOp::Le
| mir::BinOp::Ge => {
if is_float {
bx.fcmp(base::bin_op_to_fcmp_predicate(op.to_hir_binop()), lhs, rhs)
bx.fcmp(base::bin_op_to_fcmp_predicate(op), lhs, rhs)
} else {
bx.icmp(base::bin_op_to_icmp_predicate(op.to_hir_binop(), is_signed), lhs, rhs)
bx.icmp(base::bin_op_to_icmp_predicate(op, is_signed), lhs, rhs)
}
}
mir::BinOp::Cmp => {
@ -912,16 +911,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// `PartialOrd`, so only use it in debug for now. Once LLVM can handle it
// better (see <https://github.com/llvm/llvm-project/issues/73417>), it'll
// be worth trying it in optimized builds as well.
let is_gt = bx.icmp(pred(hir::BinOpKind::Gt), lhs, rhs);
let is_gt = bx.icmp(pred(mir::BinOp::Gt), lhs, rhs);
let gtext = bx.zext(is_gt, bx.type_i8());
let is_lt = bx.icmp(pred(hir::BinOpKind::Lt), lhs, rhs);
let is_lt = bx.icmp(pred(mir::BinOp::Lt), lhs, rhs);
let ltext = bx.zext(is_lt, bx.type_i8());
bx.unchecked_ssub(gtext, ltext)
} else {
// These operations are those expected by `tests/codegen/integer-cmp.rs`,
// from <https://github.com/rust-lang/rust/pull/63767>.
let is_lt = bx.icmp(pred(hir::BinOpKind::Lt), lhs, rhs);
let is_ne = bx.icmp(pred(hir::BinOpKind::Ne), lhs, rhs);
let is_lt = bx.icmp(pred(mir::BinOp::Lt), lhs, rhs);
let is_ne = bx.icmp(pred(mir::BinOp::Ne), lhs, rhs);
let ge = bx.select(
is_ne,
bx.cx().const_i8(Ordering::Greater as i8),

View File

@ -204,6 +204,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fake_reads: Default::default(),
};
let _ = euv::ExprUseVisitor::new(
&FnCtxt::new(self, self.tcx.param_env(closure_def_id), closure_def_id),
&mut delegate,
)
.consume_body(body);
// There are several curious situations with coroutine-closures where
// analysis is too aggressive with borrows when the coroutine-closure is
// marked `move`. Specifically:
//
// 1. If the coroutine-closure was inferred to be `FnOnce` during signature
// inference, then it's still possible that we try to borrow upvars from
// the coroutine-closure because they are not used by the coroutine body
// in a way that forces a move. See the test:
// `async-await/async-closures/force-move-due-to-inferred-kind.rs`.
//
// 2. If the coroutine-closure is forced to be `FnOnce` due to the way it
// uses its upvars, but not *all* upvars would force the closure to `FnOnce`.
// See the test: `async-await/async-closures/force-move-due-to-actually-fnonce.rs`.
//
// This would lead to an impossible to satisfy situation, since `AsyncFnOnce`
// coroutine bodies can't borrow from their parent closure. To fix this,
// we force the inner coroutine to also be `move`. This only matters for
// coroutine-closures that are `move` since otherwise they themselves will
// be borrowing from the outer environment, so there's no self-borrows occuring.
//
// One *important* note is that we do a call to `process_collected_capture_information`
// to eagerly test whether the coroutine would end up `FnOnce`, but we do this
// *before* capturing all the closure args by-value below, since that would always
// cause the analysis to return `FnOnce`.
if let UpvarArgs::Coroutine(..) = args
&& let hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure) =
self.tcx.coroutine_kind(closure_def_id).expect("coroutine should have kind")
&& let parent_hir_id =
self.tcx.local_def_id_to_hir_id(self.tcx.local_parent(closure_def_id))
&& let parent_ty = self.node_ty(parent_hir_id)
&& let hir::CaptureBy::Value { move_kw } =
self.tcx.hir_node(parent_hir_id).expect_closure().capture_clause
{
// (1.) Closure signature inference forced this closure to `FnOnce`.
if let Some(ty::ClosureKind::FnOnce) = self.closure_kind(parent_ty) {
capture_clause = hir::CaptureBy::Value { move_kw };
}
// (2.) The way that the closure uses its upvars means it's `FnOnce`.
else if let (_, ty::ClosureKind::FnOnce, _) = self
.process_collected_capture_information(
capture_clause,
&delegate.capture_information,
)
{
capture_clause = hir::CaptureBy::Value { move_kw };
}
}
// As noted in `lower_coroutine_body_with_moved_arguments`, we default the capture mode
// to `ByRef` for the `async {}` block internal to async fns/closure. This means
// that we would *not* be moving all of the parameters into the async block by default.
@ -253,34 +307,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
let _ = euv::ExprUseVisitor::new(
&FnCtxt::new(self, self.tcx.param_env(closure_def_id), closure_def_id),
&mut delegate,
)
.consume_body(body);
// If a coroutine is comes from a coroutine-closure that is `move`, but
// the coroutine-closure was inferred to be `FnOnce` during signature
// inference, then it's still possible that we try to borrow upvars from
// the coroutine-closure because they are not used by the coroutine body
// in a way that forces a move.
//
// This would lead to an impossible to satisfy situation, since `AsyncFnOnce`
// coroutine bodies can't borrow from their parent closure. To fix this,
// we force the inner coroutine to also be `move`. This only matters for
// coroutine-closures that are `move` since otherwise they themselves will
// be borrowing from the outer environment, so there's no self-borrows occuring.
if let UpvarArgs::Coroutine(..) = args
&& let hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure) =
self.tcx.coroutine_kind(closure_def_id).expect("coroutine should have kind")
&& let parent_hir_id =
self.tcx.local_def_id_to_hir_id(self.tcx.local_parent(closure_def_id))
&& let parent_ty = self.node_ty(parent_hir_id)
&& let Some(ty::ClosureKind::FnOnce) = self.closure_kind(parent_ty)
{
capture_clause = self.tcx.hir_node(parent_hir_id).expect_closure().capture_clause;
}
debug!(
"For closure={:?}, capture_information={:#?}",
closure_def_id, delegate.capture_information
@ -289,7 +315,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.log_capture_analysis_first_pass(closure_def_id, &delegate.capture_information, span);
let (capture_information, closure_kind, origin) = self
.process_collected_capture_information(capture_clause, delegate.capture_information);
.process_collected_capture_information(capture_clause, &delegate.capture_information);
self.compute_min_captures(closure_def_id, capture_information, span);
@ -545,13 +571,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn process_collected_capture_information(
&self,
capture_clause: hir::CaptureBy,
capture_information: InferredCaptureInformation<'tcx>,
capture_information: &InferredCaptureInformation<'tcx>,
) -> (InferredCaptureInformation<'tcx>, ty::ClosureKind, Option<(Span, Place<'tcx>)>) {
let mut closure_kind = ty::ClosureKind::LATTICE_BOTTOM;
let mut origin: Option<(Span, Place<'tcx>)> = None;
let processed = capture_information
.into_iter()
.iter()
.cloned()
.map(|(place, mut capture_info)| {
// Apply rules for safety before inferring closure kind
let (place, capture_kind) =

View File

@ -159,7 +159,9 @@ where
if !target.contains(&self.backtrace_target) {
return Ok(());
}
let backtrace = std::backtrace::Backtrace::capture();
// Use Backtrace::force_capture because we don't want to depend on the
// RUST_BACKTRACE environment variable being set.
let backtrace = std::backtrace::Backtrace::force_capture();
writeln!(writer, "stack backtrace: \n{backtrace:?}")
}
}

View File

@ -13,7 +13,7 @@ pub fn type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
quote! {}
};
s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_type_ir::codec::TyDecoder #bound });
s.add_impl_generic(parse_quote! { #decoder_ty: ::rustc_type_ir::codec::TyDecoder #bound });
s.add_bounds(synstructure::AddBounds::Fields);
s.underscore_const(true);
@ -34,7 +34,7 @@ pub fn meta_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
pub fn decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
let decoder_ty = quote! { __D };
s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_span::SpanDecoder});
s.add_impl_generic(parse_quote! { #decoder_ty: ::rustc_span::SpanDecoder });
s.add_bounds(synstructure::AddBounds::Generics);
s.underscore_const(true);
@ -43,7 +43,7 @@ pub fn decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Toke
pub fn decodable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
let decoder_ty = quote! { __D };
s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_serialize::Decoder});
s.add_impl_generic(parse_quote! { #decoder_ty: ::rustc_serialize::Decoder });
s.add_bounds(synstructure::AddBounds::Generics);
s.underscore_const(true);
@ -120,7 +120,7 @@ fn decode_field(field: &syn::Field) -> proc_macro2::TokenStream {
let __decoder = quote! { __decoder };
// Use the span of the field for the method call, so
// that backtraces will point to the field.
quote_spanned! {field_span=> #decode_inner_method(#__decoder) }
quote_spanned! { field_span=> #decode_inner_method(#__decoder) }
}
pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
@ -133,7 +133,7 @@ pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
};
let encoder_ty = quote! { __E };
s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_type_ir::codec::TyEncoder #bound });
s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_type_ir::codec::TyEncoder #bound });
s.add_bounds(synstructure::AddBounds::Fields);
s.underscore_const(true);
@ -142,7 +142,7 @@ pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
pub fn meta_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
s.add_impl_generic(parse_quote! {'tcx});
s.add_impl_generic(parse_quote! { 'tcx });
}
s.add_impl_generic(parse_quote! { '__a });
let encoder_ty = quote! { EncodeContext<'__a, 'tcx> };
@ -154,7 +154,7 @@ pub fn meta_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
pub fn encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
let encoder_ty = quote! { __E };
s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_span::SpanEncoder});
s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_span::SpanEncoder });
s.add_bounds(synstructure::AddBounds::Generics);
s.underscore_const(true);
@ -163,7 +163,7 @@ pub fn encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Toke
pub fn encodable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
let encoder_ty = quote! { __E };
s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_serialize::Encoder});
s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_serialize::Encoder });
s.add_bounds(synstructure::AddBounds::Generics);
s.underscore_const(true);

View File

@ -295,7 +295,7 @@ impl BorrowKind {
}
impl BinOp {
pub fn to_hir_binop(self) -> hir::BinOpKind {
pub(crate) fn to_hir_binop(self) -> hir::BinOpKind {
match self {
BinOp::Add => hir::BinOpKind::Add,
BinOp::Sub => hir::BinOpKind::Sub,

View File

@ -40,6 +40,7 @@ use std::cell::RefCell;
use std::collections::hash_map::Entry;
use std::fmt;
use std::hash::Hash;
use tracing::{debug, trace};
/// A `SyntaxContext` represents a chain of pairs `(ExpnId, Transparency)` named "marks".
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]

View File

@ -33,15 +33,16 @@
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
// The code produced by the `Encodable`/`Decodable` derive macros refer to
// `rustc_span::Span{Encoder,Decoder}`. That's fine outside this crate, but doesn't work inside
// this crate without this line making `rustc_span` available.
extern crate self as rustc_span;
#[macro_use]
extern crate tracing;
use rustc_data_structures::{outline, AtomicRef};
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_serialize::opaque::{FileEncoder, MemDecoder};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use tracing::debug;
mod caching_source_map_view;
pub mod source_map;

View File

@ -16,6 +16,7 @@ use rustc_macros::{Decodable, Encodable};
use std::fs;
use std::io::{self, BorrowedBuf, Read};
use std::path;
use tracing::{debug, instrument, trace};
#[cfg(test)]
mod tests;

View File

@ -1476,14 +1476,17 @@ mod prim_usize {}
///
/// For instance, this means that unsafe code in a safe function may assume these invariants are
/// ensured of arguments passed by the caller, and it may assume that these invariants are ensured
/// of return values from any safe functions it calls. In most cases, the inverse is also true:
/// unsafe code must not violate these invariants when passing arguments to safe functions or
/// returning values from safe functions; such violations may result in undefined behavior. Where
/// exceptions to this latter requirement exist, they will be called out explicitly in documentation.
/// of return values from any safe functions it calls.
///
/// For the other direction, things are more complicated: when unsafe code passes arguments
/// to safe functions or returns values from safe functions, they generally must *at least*
/// not violate these invariants. The full requirements are stronger, as the reference generally
/// must point to data that is safe to use at type `T`.
///
/// It is not decided yet whether unsafe code may violate these invariants temporarily on internal
/// data. As a consequence, unsafe code which violates these invariants temporarily on internal data
/// may become unsound in future versions of Rust depending on how this question is decided.
/// may be unsound or become unsound in future versions of Rust depending on how this question is
/// decided.
///
/// [allocated object]: ptr#allocated-object
#[stable(feature = "rust1", since = "1.0.0")]

View File

@ -20,10 +20,10 @@
- [\*-apple-darwin](platform-support/apple-darwin.md)
- [i686-apple-darwin](platform-support/i686-apple-darwin.md)
- [x86_64h-apple-darwin](platform-support/x86_64h-apple-darwin.md)
- [arm64e-apple-darwin.md](platform-support/arm64e-apple-darwin.md)
- [arm64e-apple-darwin](platform-support/arm64e-apple-darwin.md)
- [\*-apple-ios](platform-support/apple-ios.md)
- [\*-apple-ios-macabi](platform-support/apple-ios-macabi.md)
- [arm64e-apple-ios.md](platform-support/arm64e-apple-ios.md)
- [arm64e-apple-ios](platform-support/arm64e-apple-ios.md)
- [\*-apple-tvos](platform-support/apple-tvos.md)
- [\*-apple-watchos](platform-support/apple-watchos.md)
- [\*-apple-visionos](platform-support/apple-visionos.md)

View File

@ -1,6 +1,8 @@
//@ check-pass
//@ compile-flags: --document-private-items
// This ensures that no ICE is triggered when rustdoc is run on this code.
// https://github.com/rust-lang/rust/issues/95633
mod stdlib {
pub (crate) use std::i8;

View File

@ -1,7 +1,10 @@
// https://github.com/rust-lang/rust/issues/82465
#![crate_name = "foo"]
use std::convert::AsRef;
pub struct Local;
// @has issue_82465_asref_for_and_of_local/struct.Local.html '//h3[@class="code-header"]' 'impl AsRef<str> for Local'
// @has foo/struct.Local.html '//h3[@class="code-header"]' 'impl AsRef<str> for Local'
impl AsRef<str> for Local {
fn as_ref(&self) -> &str {
todo!()

View File

@ -1,4 +1,6 @@
// This test ensure that #[doc(hidden)] is applied correctly in enum variant fields.
// https://github.com/rust-lang/rust/issues/88600
#![crate_name = "foo"]
// Denotes a field which should be hidden.
pub struct H;
@ -6,7 +8,7 @@ pub struct H;
// Denotes a field which should not be hidden (shown).
pub struct S;
// @has issue_88600/enum.FooEnum.html
// @has foo/enum.FooEnum.html
pub enum FooEnum {
// @has - '//*[@id="variant.HiddenTupleItem"]//h3' 'HiddenTupleItem(/* private fields */)'
// @count - '//*[@id="variant.HiddenTupleItem.field.0"]' 0

View File

@ -1,3 +1,4 @@
// https://github.com/rust-lang/rust/issues/89309
#![crate_name = "foo"]
// @has foo/trait.Read.html

View File

@ -1,6 +1,7 @@
//@ aux-build:issue-85454.rs
//@ build-aux-docs
#![crate_name = "foo"]
// https://github.com/rust-lang/rust/issues/85454
extern crate issue_85454;

View File

@ -0,0 +1,18 @@
//@ aux-build:reexport-with-anonymous-lifetime-98697.rs
//@ ignore-cross-compile
#![crate_name = "foo"]
// When reexporting a function with a HRTB with anonymous lifetimes,
// make sure the anonymous lifetimes are not rendered.
//
// https://github.com/rust-lang/rust/issues/98697
extern crate reexport_with_anonymous_lifetime_98697;
// @has foo/fn.repro.html '//pre[@class="rust item-decl"]/code' 'fn repro<F>()where F: Fn(&str)'
// @!has foo/fn.repro.html '//pre[@class="rust item-decl"]/code' 'for<'
pub use reexport_with_anonymous_lifetime_98697::repro;
// @has foo/struct.Extra.html '//div[@id="trait-implementations-list"]//h3[@class="code-header"]' 'impl MyTrait<&Extra> for Extra'
// @!has foo/struct.Extra.html '//div[@id="trait-implementations-list"]//h3[@class="code-header"]' 'impl<'
pub use reexport_with_anonymous_lifetime_98697::Extra;

View File

@ -2,6 +2,7 @@
// This test ensures that a publicly re-exported private trait will
// appear in the blanket impl list.
// https://github.com/rust-lang/rust/issues/94183
#![crate_name = "foo"]
// @has 'foo/struct.S.html'

View File

@ -1,5 +1,6 @@
//@ edition:2015
// https://github.com/rust-lang/rust/issues/81141
#![crate_name = "foo"]
use external::Public as Private;

View File

@ -1,6 +1,7 @@
// This test ensures that if a private re-export is present in a public API, it'll be
// replaced by the first public item in the re-export chain or by the private item.
// https://github.com/rust-lang/rust/issues/81141
#![crate_name = "foo"]
use crate::bar::Bar as Alias;

View File

@ -1,3 +1,4 @@
// https://github.com/rust-lang/rust/issues/81141
#![crate_name = "foo"]
use crate::bar::Foo as Alias;

View File

@ -1,5 +1,6 @@
//@ compile-flags: -Z unstable-options --document-hidden-items
// https://github.com/rust-lang/rust/issues/81141
#![crate_name = "foo"]
#[doc(hidden)]

View File

@ -1,5 +1,6 @@
//@ compile-flags: --document-private-items
// https://github.com/rust-lang/rust/issues/81141
#![crate_name = "foo"]
use crate::bar::Bar as Alias;

View File

@ -0,0 +1,16 @@
//@ edition:2018
// https://github.com/rust-lang/rust/issues/89852
#![crate_name = "foo"]
#![no_core]
#![feature(no_core)]
// @matchesraw 'foo/sidebar-items.js' '"repro"'
// @!matchesraw 'foo/sidebar-items.js' '"repro".*"repro"'
#[macro_export]
macro_rules! repro {
() => {};
}
pub use crate::repro as repro2;

View File

@ -1,9 +0,0 @@
//@ aux-build:issue-86620-1.rs
extern crate issue_86620_1;
use issue_86620_1::*;
// @!has issue_86620/struct.S.html '//*[@id="method.vzip"]//a[@class="fnname"]/@href' #tymethod.vzip
// @has issue_86620/struct.S.html '//*[@id="method.vzip"]//a[@class="anchor"]/@href' #method.vzip
pub struct S;

View File

@ -1,14 +0,0 @@
//@ edition:2018
#![no_core]
#![feature(no_core)]
// @matchesraw 'issue_89852/sidebar-items.js' '"repro"'
// @!matchesraw 'issue_89852/sidebar-items.js' '"repro".*"repro"'
#[macro_export]
macro_rules! repro {
() => {};
}
pub use crate::repro as repro2;

View File

@ -1,2 +0,0 @@
// @has issue_95873/index.html "//*[@class='item-name']" "pub use ::std as x;"
pub use ::std as x;

View File

@ -1,17 +0,0 @@
//@ aux-build:issue-98697-reexport-with-anonymous-lifetime.rs
//@ ignore-cross-compile
// When reexporting a function with a HRTB with anonymous lifetimes,
// make sure the anonymous lifetimes are not rendered.
//
// https://github.com/rust-lang/rust/issues/98697
extern crate issue_98697_reexport_with_anonymous_lifetime;
// @has issue_98697/fn.repro.html '//pre[@class="rust item-decl"]/code' 'fn repro<F>()where F: Fn(&str)'
// @!has issue_98697/fn.repro.html '//pre[@class="rust item-decl"]/code' 'for<'
pub use issue_98697_reexport_with_anonymous_lifetime::repro;
// @has issue_98697/struct.Extra.html '//div[@id="trait-implementations-list"]//h3[@class="code-header"]' 'impl MyTrait<&Extra> for Extra'
// @!has issue_98697/struct.Extra.html '//div[@id="trait-implementations-list"]//h3[@class="code-header"]' 'impl<'
pub use issue_98697_reexport_with_anonymous_lifetime::Extra;

View File

@ -0,0 +1,11 @@
//@ aux-build:issue-86620-1.rs
#![crate_name = "foo"]
// https://github.com/rust-lang/rust/issues/86620
extern crate issue_86620_1;
use issue_86620_1::*;
// @!has foo/struct.S.html '//*[@id="method.vzip"]//a[@class="fnname"]/@href' #tymethod.vzip
// @has foo/struct.S.html '//*[@id="method.vzip"]//a[@class="anchor"]/@href' #method.vzip
pub struct S;

View File

@ -2,6 +2,7 @@
//@ build-aux-docs
//@ ignore-cross-compile
// https://github.com/rust-lang/rust/issues/99221
#![crate_name = "foo"]
#[macro_use]

View File

@ -1,3 +1,4 @@
// https://github.com/rust-lang/rust/issues/83375
#![crate_name = "foo"]
pub mod sub {
@ -8,9 +9,9 @@ pub mod sub {
}
}
#[doc(inline)]
pub use sub::*;
// @count foo/index.html '//a[@class="mod"][@title="mod foo::prelude"]' 1
// @count foo/prelude/index.html '//div[@class="item-row"]' 0
pub mod prelude {}
#[doc(inline)]
pub use sub::*;

View File

@ -1,3 +1,4 @@
// https://github.com/rust-lang/rust/issues/83375
#![crate_name = "foo"]
pub mod sub {
@ -8,9 +9,9 @@ pub mod sub {
}
}
#[doc(inline)]
pub use sub::*;
// @count foo/index.html '//a[@class="mod"][@title="mod foo::prelude"]' 1
// @count foo/prelude/index.html '//div[@class="item-row"]' 0
pub mod prelude {}
#[doc(inline)]
pub use sub::*;

View File

@ -0,0 +1,5 @@
// https://github.com/rust-lang/rust/issues/95873
#![crate_name = "foo"]
// @has foo/index.html "//*[@class='item-name']" "pub use ::std as x;"
pub use ::std as x;

View File

@ -1,7 +1,9 @@
// Regression test for issue #80233
// Tests that we don't ICE when processing auto traits
// https://github.com/rust-lang/rust/issues/80233
#![crate_type = "lib"]
#![crate_name = "foo"]
pub trait Trait1 {}
pub trait Trait2 {
@ -30,7 +32,7 @@ impl<T: Trait3> Trait3 for Vec<T> {
pub struct Struct1 {}
// @has issue_80233_normalize_auto_trait/struct.Question.html
// @has foo/struct.Question.html
// @has - '//h3[@class="code-header"]' 'impl<T> Send for Question<T>'
pub struct Question<T: Trait1> {
pub ins: <<Vec<T> as Trait3>::Type3 as Trait2>::Type2,

View File

@ -1,4 +1,5 @@
//@ should-fail
// https://github.com/rust-lang/rust/issues/96381
#![allow(unused)]

View File

@ -0,0 +1,27 @@
//@ aux-build:block-on.rs
//@ edition:2021
//@ check-pass
#![feature(async_closure)]
extern crate block_on;
fn consume(_: String) {}
fn main() {
block_on::block_on(async {
let x = 1i32;
let s = String::new();
// `consume(s)` pulls the closure's kind down to `FnOnce`,
// which means that we don't treat the borrow of `x` as a
// self-borrow (with `'env` lifetime). This leads to a lifetime
// error which is solved by forcing the inner coroutine to
// be `move` as well, so that it moves `x`.
let c = async move || {
println!("{x}");
// This makes the closure FnOnce...
consume(s);
};
c().await;
});
}

View File

@ -0,0 +1,24 @@
//@ aux-build:block-on.rs
//@ edition:2021
//@ check-pass
#![feature(async_closure)]
extern crate block_on;
fn force_fnonce<T: async FnOnce()>(t: T) -> T { t }
fn main() {
block_on::block_on(async {
let x = 1i32;
// `force_fnonce` pulls the closure's kind down to `FnOnce`,
// which means that we don't treat the borrow of `x` as a
// self-borrow (with `'env` lifetime). This leads to a lifetime
// error which is solved by forcing the inner coroutine to
// be `move` as well, so that it moves `x`.
let c = force_fnonce(async move || {
println!("{x}");
});
c().await;
});
}