提交 7cc28c12 编写于 作者: B bors

Auto merge of #93468 - matthiaskrgr:rollup-vxullvd, r=matthiaskrgr

Rollup of 8 pull requests

Successful merges:

 - #93256 (Make `join!` description more accurate)
 - #93358 (Add note suggesting that predicate may be satisfied, but is not `const`)
 - #93362 (Do not register infer var for GAT projection in RPIT)
 - #93391 (rustdoc: remove tooltip from source link)
 - #93414 (Move unstable is_{arch}_feature_detected! macros to std::arch)
 - #93441 (rustdoc: load the set of in-scope traits for modules with no docstring)
 - #93459 (fs: Don't copy d_name from struct dirent)
 - #93463 (Rename _args -> args in format_args expansion)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
...@@ -791,7 +791,7 @@ fn into_expr(self) -> P<ast::Expr> { ...@@ -791,7 +791,7 @@ fn into_expr(self) -> P<ast::Expr> {
// Thus in the not nicely ordered case we emit the following instead: // Thus in the not nicely ordered case we emit the following instead:
// //
// match (&$arg0, &$arg1, …) { // match (&$arg0, &$arg1, …) {
// _args => [ArgumentV1::new(_args.$i, …), ArgumentV1::new(_args.$j, …), …] // args => [ArgumentV1::new(args.$i, …), ArgumentV1::new(args.$j, …), …]
// } // }
// //
// for the sequence of indices $i, $j, … governed by fmt_arg_index_and_ty. // for the sequence of indices $i, $j, … governed by fmt_arg_index_and_ty.
...@@ -804,7 +804,7 @@ fn into_expr(self) -> P<ast::Expr> { ...@@ -804,7 +804,7 @@ fn into_expr(self) -> P<ast::Expr> {
self.ecx.expr_addr_of(expansion_span, P(e.take())) self.ecx.expr_addr_of(expansion_span, P(e.take()))
} else { } else {
let def_site = self.ecx.with_def_site_ctxt(span); let def_site = self.ecx.with_def_site_ctxt(span);
let args_tuple = self.ecx.expr_ident(def_site, Ident::new(sym::_args, def_site)); let args_tuple = self.ecx.expr_ident(def_site, Ident::new(sym::args, def_site));
let member = Ident::new(sym::integer(arg_index), def_site); let member = Ident::new(sym::integer(arg_index), def_site);
self.ecx.expr(def_site, ast::ExprKind::Field(args_tuple, member)) self.ecx.expr(def_site, ast::ExprKind::Field(args_tuple, member))
}; };
...@@ -828,7 +828,7 @@ fn into_expr(self) -> P<ast::Expr> { ...@@ -828,7 +828,7 @@ fn into_expr(self) -> P<ast::Expr> {
.map(|e| self.ecx.expr_addr_of(e.span.with_ctxt(self.macsp.ctxt()), e)) .map(|e| self.ecx.expr_addr_of(e.span.with_ctxt(self.macsp.ctxt()), e))
.collect(); .collect();
let pat = self.ecx.pat_ident(self.macsp, Ident::new(sym::_args, self.macsp)); let pat = self.ecx.pat_ident(self.macsp, Ident::new(sym::args, self.macsp));
let arm = self.ecx.arm(self.macsp, pat, args_array); let arm = self.ecx.arm(self.macsp, pat, args_array);
let head = self.ecx.expr(self.macsp, ast::ExprKind::Tup(heads)); let head = self.ecx.expr(self.macsp, ast::ExprKind::Tup(heads));
self.ecx.expr_match(self.macsp, head, vec![arm]) self.ecx.expr_match(self.macsp, head, vec![arm])
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
}; };
use rustc_errors::ErrorReported; use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::interpret::ErrorHandled;
...@@ -216,7 +215,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>( ...@@ -216,7 +215,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> { ) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> {
assert!(key.param_env.constness() == hir::Constness::Const); assert!(key.param_env.is_const());
// see comment in eval_to_allocation_raw_provider for what we're doing here // see comment in eval_to_allocation_raw_provider for what we're doing here
if key.param_env.reveal() == Reveal::All { if key.param_env.reveal() == Reveal::All {
let mut key = key; let mut key = key;
...@@ -251,7 +250,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( ...@@ -251,7 +250,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> { ) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
assert!(key.param_env.constness() == hir::Constness::Const); assert!(key.param_env.is_const());
// Because the constant is computed twice (once per value of `Reveal`), we are at risk of // Because the constant is computed twice (once per value of `Reveal`), we are at risk of
// reporting the same error twice here. To resolve this, we check whether we can evaluate the // reporting the same error twice here. To resolve this, we check whether we can evaluate the
// constant in the more restrictive `Reveal::UserFacing`, which most likely already was // constant in the more restrictive `Reveal::UserFacing`, which most likely already was
......
...@@ -569,13 +569,15 @@ fn fold_opaque_ty( ...@@ -569,13 +569,15 @@ fn fold_opaque_ty(
let predicate = predicate.fold_with(&mut BottomUpFolder { let predicate = predicate.fold_with(&mut BottomUpFolder {
tcx, tcx,
ty_op: |ty| match ty.kind() { ty_op: |ty| match ty.kind() {
ty::Projection(projection_ty) => infcx.infer_projection( ty::Projection(projection_ty) if !projection_ty.has_escaping_bound_vars() => {
self.param_env, infcx.infer_projection(
*projection_ty, self.param_env,
traits::ObligationCause::misc(self.value_span, self.body_id), *projection_ty,
0, traits::ObligationCause::misc(self.value_span, self.body_id),
&mut self.obligations, 0,
), &mut self.obligations,
)
}
_ => ty, _ => ty,
}, },
lt_op: |lt| lt, lt_op: |lt| lt,
......
...@@ -86,7 +86,6 @@ ...@@ -86,7 +86,6 @@
impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
use rustc_middle::ty;
use rustc_middle::ty::PredicateKind::*; use rustc_middle::ty::PredicateKind::*;
let predicates = cx.tcx.explicit_predicates_of(item.def_id); let predicates = cx.tcx.explicit_predicates_of(item.def_id);
...@@ -94,7 +93,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { ...@@ -94,7 +93,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
let Trait(trait_predicate) = predicate.kind().skip_binder() else { let Trait(trait_predicate) = predicate.kind().skip_binder() else {
continue continue
}; };
if trait_predicate.constness == ty::BoundConstness::ConstIfConst { if trait_predicate.is_const_if_const() {
// `~const Drop` definitely have meanings so avoid linting here. // `~const Drop` definitely have meanings so avoid linting here.
continue; continue;
} }
......
...@@ -784,6 +784,11 @@ pub fn def_id(self) -> DefId { ...@@ -784,6 +784,11 @@ pub fn def_id(self) -> DefId {
pub fn self_ty(self) -> Ty<'tcx> { pub fn self_ty(self) -> Ty<'tcx> {
self.trait_ref.self_ty() self.trait_ref.self_ty()
} }
#[inline]
pub fn is_const_if_const(self) -> bool {
self.constness == BoundConstness::ConstIfConst
}
} }
impl<'tcx> PolyTraitPredicate<'tcx> { impl<'tcx> PolyTraitPredicate<'tcx> {
...@@ -803,6 +808,11 @@ pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) { ...@@ -803,6 +808,11 @@ pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) {
p p
}); });
} }
#[inline]
pub fn is_const_if_const(self) -> bool {
self.skip_binder().is_const_if_const()
}
} }
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
...@@ -1388,6 +1398,11 @@ pub fn constness(self) -> hir::Constness { ...@@ -1388,6 +1398,11 @@ pub fn constness(self) -> hir::Constness {
self.packed.tag().constness self.packed.tag().constness
} }
#[inline]
pub fn is_const(self) -> bool {
self.packed.tag().constness == hir::Constness::Const
}
/// Construct a trait environment with no where-clauses in scope /// Construct a trait environment with no where-clauses in scope
/// where the values of all `impl Trait` and other hidden types /// where the values of all `impl Trait` and other hidden types
/// are revealed. This is suitable for monomorphized, post-typeck /// are revealed. This is suitable for monomorphized, post-typeck
...@@ -1503,6 +1518,7 @@ pub fn with_constness(self, constness: BoundConstness) -> PolyTraitPredicate<'tc ...@@ -1503,6 +1518,7 @@ pub fn with_constness(self, constness: BoundConstness) -> PolyTraitPredicate<'tc
polarity: ty::ImplPolarity::Positive, polarity: ty::ImplPolarity::Positive,
}) })
} }
#[inline] #[inline]
pub fn without_const(self) -> PolyTraitPredicate<'tcx> { pub fn without_const(self) -> PolyTraitPredicate<'tcx> {
self.with_constness(BoundConstness::NotConst) self.with_constness(BoundConstness::NotConst)
......
...@@ -272,7 +272,6 @@ ...@@ -272,7 +272,6 @@
__H, __H,
__S, __S,
__try_var, __try_var,
_args,
_d, _d,
_e, _e,
_task_context, _task_context,
...@@ -324,6 +323,7 @@ ...@@ -324,6 +323,7 @@
append_const_msg, append_const_msg,
arbitrary_enum_discriminant, arbitrary_enum_discriminant,
arbitrary_self_types, arbitrary_self_types,
args,
arith_offset, arith_offset,
arm, arm,
arm_target_feature, arm_target_feature,
......
...@@ -439,6 +439,28 @@ fn report_selection_error( ...@@ -439,6 +439,28 @@ fn report_selection_error(
} else { } else {
err.span_label(span, explanation); err.span_label(span, explanation);
} }
if trait_predicate.is_const_if_const() && obligation.param_env.is_const() {
let non_const_predicate = trait_ref.without_const();
let non_const_obligation = Obligation {
cause: obligation.cause.clone(),
param_env: obligation.param_env.without_const(),
predicate: non_const_predicate.to_predicate(tcx),
recursion_depth: obligation.recursion_depth,
};
if self.predicate_may_hold(&non_const_obligation) {
err.span_note(
span,
&format!(
"the trait `{}` is implemented for `{}`, \
but that implementation is not `const`",
non_const_predicate.print_modifiers_and_trait_path(),
trait_ref.skip_binder().self_ty(),
),
);
}
}
if let Some((msg, span)) = type_def { if let Some((msg, span)) = type_def {
err.span_label(span, &msg); err.span_label(span, &msg);
} }
......
...@@ -305,7 +305,7 @@ pub(super) fn assemble_candidates<'o>( ...@@ -305,7 +305,7 @@ pub(super) fn assemble_candidates<'o>(
} else if lang_items.unsize_trait() == Some(def_id) { } else if lang_items.unsize_trait() == Some(def_id) {
self.assemble_candidates_for_unsizing(obligation, &mut candidates); self.assemble_candidates_for_unsizing(obligation, &mut candidates);
} else if lang_items.drop_trait() == Some(def_id) } else if lang_items.drop_trait() == Some(def_id)
&& obligation.predicate.skip_binder().constness == ty::BoundConstness::ConstIfConst && obligation.predicate.is_const_if_const()
{ {
self.assemble_const_drop_candidates(obligation, &mut candidates); self.assemble_const_drop_candidates(obligation, &mut candidates);
} else { } else {
......
...@@ -72,9 +72,7 @@ pub(super) fn confirm_candidate( ...@@ -72,9 +72,7 @@ pub(super) fn confirm_candidate(
// CheckPredicate(&A: Super) // CheckPredicate(&A: Super)
// CheckPredicate(A: ~const Super) // <- still const env, failure // CheckPredicate(A: ~const Super) // <- still const env, failure
// ``` // ```
if obligation.param_env.constness() == Constness::Const if obligation.param_env.is_const() && !obligation.predicate.is_const_if_const() {
&& obligation.predicate.skip_binder().constness == ty::BoundConstness::NotConst
{
new_obligation = TraitObligation { new_obligation = TraitObligation {
cause: obligation.cause.clone(), cause: obligation.cause.clone(),
param_env: obligation.param_env.without_const(), param_env: obligation.param_env.without_const(),
......
...@@ -1173,9 +1173,7 @@ fn filter_impls( ...@@ -1173,9 +1173,7 @@ fn filter_impls(
ImplCandidate(def_id) ImplCandidate(def_id)
if tcx.impl_constness(def_id) == hir::Constness::Const => {} if tcx.impl_constness(def_id) == hir::Constness::Const => {}
// const param // const param
ParamCandidate(trait_pred) ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
if trait_pred.skip_binder().constness
== ty::BoundConstness::ConstIfConst => {}
// auto trait impl // auto trait impl
AutoImplCandidate(..) => {} AutoImplCandidate(..) => {}
// generator, this will raise error in other places // generator, this will raise error in other places
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
/// Polls multiple futures simultaneously, returning a tuple /// Polls multiple futures simultaneously, returning a tuple
/// of all results once complete. /// of all results once complete.
/// ///
/// While `join!(a, b)` is similar to `(a.await, b.await)`, /// While `join!(a, b).await` is similar to `(a.await, b.await)`,
/// `join!` polls both futures concurrently and is therefore more efficient. /// `join!` polls both futures concurrently and is therefore more efficient.
/// ///
/// # Examples /// # Examples
......
...@@ -1504,3 +1504,19 @@ fn create_dir_long_paths() { ...@@ -1504,3 +1504,19 @@ fn create_dir_long_paths() {
let path = Path::new(""); let path = Path::new("");
assert_eq!(path.canonicalize().unwrap_err().kind(), crate::io::ErrorKind::NotFound); assert_eq!(path.canonicalize().unwrap_err().kind(), crate::io::ErrorKind::NotFound);
} }
/// Ensure ReadDir works on large directories.
/// Regression test for https://github.com/rust-lang/rust/issues/93384.
#[test]
fn read_large_dir() {
let tmpdir = tmpdir();
let count = 32 * 1024;
for i in 0..count {
check!(fs::File::create(tmpdir.join(&i.to_string())));
}
for entry in fs::read_dir(tmpdir.path()).unwrap() {
entry.unwrap();
}
}
...@@ -403,13 +403,6 @@ ...@@ -403,13 +403,6 @@
pub use alloc_crate::vec; pub use alloc_crate::vec;
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub use core::any; pub use core::any;
#[stable(feature = "simd_arch", since = "1.27.0")]
// The `no_inline`-attribute is required to make the documentation of all
// targets available.
// See https://github.com/rust-lang/rust/pull/57808#issuecomment-457390549 for
// more information.
#[doc(no_inline)] // Note (#82861): required for correct documentation
pub use core::arch;
#[stable(feature = "core_array", since = "1.36.0")] #[stable(feature = "core_array", since = "1.36.0")]
pub use core::array; pub use core::array;
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
...@@ -527,6 +520,31 @@ pub mod task { ...@@ -527,6 +520,31 @@ pub mod task {
pub use alloc::task::*; pub use alloc::task::*;
} }
#[doc = include_str!("../../stdarch/crates/core_arch/src/core_arch_docs.md")]
#[stable(feature = "simd_arch", since = "1.27.0")]
pub mod arch {
#[stable(feature = "simd_arch", since = "1.27.0")]
// The `no_inline`-attribute is required to make the documentation of all
// targets available.
// See https://github.com/rust-lang/rust/pull/57808#issuecomment-457390549 for
// more information.
#[doc(no_inline)] // Note (#82861): required for correct documentation
pub use core::arch::*;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub use std_detect::is_x86_feature_detected;
#[unstable(feature = "stdsimd", issue = "48556")]
pub use std_detect::{
is_aarch64_feature_detected, is_arm_feature_detected, is_mips64_feature_detected,
is_mips_feature_detected, is_powerpc64_feature_detected, is_powerpc_feature_detected,
is_riscv_feature_detected,
};
}
// This was stabilized in the crate root so we have to keep it there.
#[stable(feature = "simd_x86", since = "1.27.0")]
pub use std_detect::is_x86_feature_detected;
// The runtime entry point and a few unstable public functions used by the // The runtime entry point and a few unstable public functions used by the
// compiler // compiler
#[macro_use] #[macro_use]
...@@ -545,18 +563,6 @@ pub mod task { ...@@ -545,18 +563,6 @@ pub mod task {
#[allow(dead_code, unused_attributes)] #[allow(dead_code, unused_attributes)]
mod backtrace_rs; mod backtrace_rs;
#[stable(feature = "simd_x86", since = "1.27.0")]
pub use std_detect::is_x86_feature_detected;
#[doc(hidden)]
#[unstable(feature = "stdsimd", issue = "48556")]
pub use std_detect::*;
#[unstable(feature = "stdsimd", issue = "48556")]
pub use std_detect::{
is_aarch64_feature_detected, is_arm_feature_detected, is_mips64_feature_detected,
is_mips_feature_detected, is_powerpc64_feature_detected, is_powerpc_feature_detected,
is_riscv_feature_detected,
};
// Re-export macros defined in libcore. // Re-export macros defined in libcore.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated, deprecated_in_future)] #[allow(deprecated, deprecated_in_future)]
......
...@@ -489,10 +489,18 @@ fn next(&mut self) -> Option<io::Result<DirEntry>> { ...@@ -489,10 +489,18 @@ fn next(&mut self) -> Option<io::Result<DirEntry>> {
}; };
} }
// Only d_reclen bytes of *entry_ptr are valid, so we can't just copy the
// whole thing (#93384). Instead, copy everything except the name.
let entry_bytes = entry_ptr as *const u8;
let entry_name = ptr::addr_of!((*entry_ptr).d_name) as *const u8;
let name_offset = entry_name.offset_from(entry_bytes) as usize;
let mut entry: dirent64 = mem::zeroed();
ptr::copy_nonoverlapping(entry_bytes, &mut entry as *mut _ as *mut u8, name_offset);
let ret = DirEntry { let ret = DirEntry {
entry: *entry_ptr, entry,
// d_name is guaranteed to be null-terminated. // d_name is guaranteed to be null-terminated.
name: CStr::from_ptr((*entry_ptr).d_name.as_ptr()).to_owned(), name: CStr::from_ptr(entry_name as *const _).to_owned(),
dir: Arc::clone(&self.inner), dir: Arc::clone(&self.inner),
}; };
if ret.name_bytes() != b"." && ret.name_bytes() != b".." { if ret.name_bytes() != b"." && ret.name_bytes() != b".." {
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#[test] #[test]
#[cfg(all(target_arch = "arm", any(target_os = "linux", target_os = "android")))] #[cfg(all(target_arch = "arm", any(target_os = "linux", target_os = "android")))]
fn arm_linux() { fn arm_linux() {
use std::arch::is_arm_feature_detected;
println!("neon: {}", is_arm_feature_detected!("neon")); println!("neon: {}", is_arm_feature_detected!("neon"));
println!("pmull: {}", is_arm_feature_detected!("pmull")); println!("pmull: {}", is_arm_feature_detected!("pmull"));
println!("crypto: {}", is_arm_feature_detected!("crypto")); println!("crypto: {}", is_arm_feature_detected!("crypto"));
...@@ -25,6 +26,7 @@ fn arm_linux() { ...@@ -25,6 +26,7 @@ fn arm_linux() {
#[test] #[test]
#[cfg(all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")))] #[cfg(all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")))]
fn aarch64_linux() { fn aarch64_linux() {
use std::arch::is_aarch64_feature_detected;
println!("neon: {}", is_aarch64_feature_detected!("neon")); println!("neon: {}", is_aarch64_feature_detected!("neon"));
println!("asimd: {}", is_aarch64_feature_detected!("asimd")); println!("asimd: {}", is_aarch64_feature_detected!("asimd"));
println!("pmull: {}", is_aarch64_feature_detected!("pmull")); println!("pmull: {}", is_aarch64_feature_detected!("pmull"));
...@@ -71,6 +73,7 @@ fn aarch64_linux() { ...@@ -71,6 +73,7 @@ fn aarch64_linux() {
#[test] #[test]
#[cfg(all(target_arch = "powerpc", target_os = "linux"))] #[cfg(all(target_arch = "powerpc", target_os = "linux"))]
fn powerpc_linux() { fn powerpc_linux() {
use std::arch::is_powerpc_feature_detected;
println!("altivec: {}", is_powerpc_feature_detected!("altivec")); println!("altivec: {}", is_powerpc_feature_detected!("altivec"));
println!("vsx: {}", is_powerpc_feature_detected!("vsx")); println!("vsx: {}", is_powerpc_feature_detected!("vsx"));
println!("power8: {}", is_powerpc_feature_detected!("power8")); println!("power8: {}", is_powerpc_feature_detected!("power8"));
...@@ -79,6 +82,7 @@ fn powerpc_linux() { ...@@ -79,6 +82,7 @@ fn powerpc_linux() {
#[test] #[test]
#[cfg(all(target_arch = "powerpc64", target_os = "linux"))] #[cfg(all(target_arch = "powerpc64", target_os = "linux"))]
fn powerpc64_linux() { fn powerpc64_linux() {
use std::arch::is_powerpc64_feature_detected;
println!("altivec: {}", is_powerpc64_feature_detected!("altivec")); println!("altivec: {}", is_powerpc64_feature_detected!("altivec"));
println!("vsx: {}", is_powerpc64_feature_detected!("vsx")); println!("vsx: {}", is_powerpc64_feature_detected!("vsx"));
println!("power8: {}", is_powerpc64_feature_detected!("power8")); println!("power8: {}", is_powerpc64_feature_detected!("power8"));
...@@ -87,6 +91,8 @@ fn powerpc64_linux() { ...@@ -87,6 +91,8 @@ fn powerpc64_linux() {
#[test] #[test]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn x86_all() { fn x86_all() {
use std::arch::is_x86_feature_detected;
// the below is the set of features we can test at runtime, but don't actually // the below is the set of features we can test at runtime, but don't actually
// use to gate anything and are thus not part of the X86_ALLOWED_FEATURES list // use to gate anything and are thus not part of the X86_ALLOWED_FEATURES list
......
Subproject commit 11c98f6eb9c4ba48b2362ad4960343b312d056b8 Subproject commit eaee02ffdf5d820729ccdf2f95fa08b08c7d24d2
...@@ -182,7 +182,7 @@ impl StylePath { ...@@ -182,7 +182,7 @@ impl StylePath {
fn write_srclink(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) { fn write_srclink(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) {
if let Some(l) = cx.src_href(item) { if let Some(l) = cx.src_href(item) {
write!(buf, "<a class=\"srclink\" href=\"{}\" title=\"goto source code\">source</a>", l) write!(buf, "<a class=\"srclink\" href=\"{}\">source</a>", l)
} }
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
{% endif %} {% endif %}
{%- match src_href -%} {%- match src_href -%}
{%- when Some with (href) -%} {%- when Some with (href) -%}
<a class="srclink" href="{{href|safe}}" title="goto source code">source</a> · {# -#} <a class="srclink" href="{{href|safe}}">source</a> · {# -#}
{%- else -%} {%- else -%}
{%- endmatch -%} {%- endmatch -%}
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs"> {#- -#} <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs"> {#- -#}
......
...@@ -920,6 +920,7 @@ fn trait_assoc_to_impl_assoc_item<'tcx>( ...@@ -920,6 +920,7 @@ fn trait_assoc_to_impl_assoc_item<'tcx>(
/// ///
/// NOTE: this cannot be a query because more traits could be available when more crates are compiled! /// NOTE: this cannot be a query because more traits could be available when more crates are compiled!
/// So it is not stable to serialize cross-crate. /// So it is not stable to serialize cross-crate.
#[instrument(level = "debug", skip(cx))]
fn trait_impls_for<'a>( fn trait_impls_for<'a>(
cx: &mut DocContext<'a>, cx: &mut DocContext<'a>,
ty: Ty<'a>, ty: Ty<'a>,
......
...@@ -32,6 +32,11 @@ ...@@ -32,6 +32,11 @@
all_trait_impls: Default::default(), all_trait_impls: Default::default(),
}; };
// Because of the `crate::` prefix, any doc comment can reference
// the crate root's set of in-scope traits. This line makes sure
// it's available.
loader.add_traits_in_scope(CRATE_DEF_ID.to_def_id());
// Overridden `visit_item` below doesn't apply to the crate root, // Overridden `visit_item` below doesn't apply to the crate root,
// so we have to visit its attributes and reexports separately. // so we have to visit its attributes and reexports separately.
loader.load_links_in_attrs(&krate.attrs, krate.span); loader.load_links_in_attrs(&krate.attrs, krate.span);
...@@ -180,6 +185,11 @@ fn visit_item(&mut self, item: &ast::Item) { ...@@ -180,6 +185,11 @@ fn visit_item(&mut self, item: &ast::Item) {
if let ItemKind::Mod(..) = item.kind { if let ItemKind::Mod(..) = item.kind {
let old_mod = mem::replace(&mut self.current_mod, self.resolver.local_def_id(item.id)); let old_mod = mem::replace(&mut self.current_mod, self.resolver.local_def_id(item.id));
// A module written with a outline doc comments will resolve traits relative
// to the parent module. Make sure the parent module's traits-in-scope are
// loaded, even if the module itself has no doc comments.
self.add_traits_in_parent_scope(self.current_mod.to_def_id());
self.load_links_in_attrs(&item.attrs, item.span); self.load_links_in_attrs(&item.attrs, item.span);
self.process_module_children_or_reexports(self.current_mod.to_def_id()); self.process_module_children_or_reexports(self.current_mod.to_def_id());
visit::walk_item(self, item); visit::walk_item(self, item);
......
pub struct Test<'a> {
data: &'a (),
}
impl<'a> Test<'a> {
pub fn do_test(&self) {}
}
// @has crate_relative/demo/index.html
// @has - '//a/@href' '../struct.Test.html#method.do_test'
pub mod demo {
//! [`crate::Test::do_test`]
}
pub mod wrapper {
pub struct Test<'a> {
data: &'a (),
}
impl<'a> Test<'a> {
pub fn do_test(&self) {}
}
// @has mod_relative/wrapper/demo/index.html
// @has - '//a/@href' '../struct.Test.html#method.do_test'
/// [`Test::do_test`]
pub mod demo {
}
}
// check-pass
#![feature(generic_associated_types)]
pub trait Scalar: 'static {
type RefType<'a>: ScalarRef<'a>;
}
pub trait ScalarRef<'a>: 'a {}
fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefType<'b>) -> O {
todo!()
}
fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
cmp_eq
}
fn main() {}
...@@ -7,6 +7,11 @@ LL | const_eval_select((), || {}, || {}); ...@@ -7,6 +7,11 @@ LL | const_eval_select((), || {}, || {});
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: the trait `~const FnOnce<()>` is not implemented for `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]` = help: the trait `~const FnOnce<()>` is not implemented for `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]`
note: the trait `FnOnce<()>` is implemented for `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]`, but that implementation is not `const`
--> $DIR/const-eval-select-bad.rs:6:27
|
LL | const_eval_select((), || {}, || {});
| ^^^^^
= note: wrap the `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]` in a closure with no arguments: `|| { /* code */ }` = note: wrap the `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `const_eval_select` note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
......
...@@ -5,6 +5,11 @@ LL | type Bar = NonConstAdd; ...@@ -5,6 +5,11 @@ LL | type Bar = NonConstAdd;
| ^^^^^^^^^^^ no implementation for `NonConstAdd + NonConstAdd` | ^^^^^^^^^^^ no implementation for `NonConstAdd + NonConstAdd`
| |
= help: the trait `~const Add` is not implemented for `NonConstAdd` = help: the trait `~const Add` is not implemented for `NonConstAdd`
note: the trait `Add` is implemented for `NonConstAdd`, but that implementation is not `const`
--> $DIR/assoc-type.rs:18:16
|
LL | type Bar = NonConstAdd;
| ^^^^^^^^^^^
note: required by a bound in `Foo::Bar` note: required by a bound in `Foo::Bar`
--> $DIR/assoc-type.rs:14:15 --> $DIR/assoc-type.rs:14:15
| |
......
...@@ -7,6 +7,11 @@ LL | pub const EQ: bool = equals_self(&S); ...@@ -7,6 +7,11 @@ LL | pub const EQ: bool = equals_self(&S);
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: the trait `~const PartialEq` is not implemented for `S` = help: the trait `~const PartialEq` is not implemented for `S`
note: the trait `PartialEq` is implemented for `S`, but that implementation is not `const`
--> $DIR/call-generic-method-nonconst.rs:19:34
|
LL | pub const EQ: bool = equals_self(&S);
| ^^
note: required by a bound in `equals_self` note: required by a bound in `equals_self`
--> $DIR/call-generic-method-nonconst.rs:12:25 --> $DIR/call-generic-method-nonconst.rs:12:25
| |
......
...@@ -28,6 +28,11 @@ LL | const _: () = check($exp); ...@@ -28,6 +28,11 @@ LL | const _: () = check($exp);
LL | ConstImplWithDropGlue(NonTrivialDrop), LL | ConstImplWithDropGlue(NonTrivialDrop),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Drop` is not implemented for `NonTrivialDrop` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Drop` is not implemented for `NonTrivialDrop`
| |
note: the trait `Drop` is implemented for `NonTrivialDrop`, but that implementation is not `const`
--> $DIR/const-drop-fail.rs:46:5
|
LL | ConstImplWithDropGlue(NonTrivialDrop),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because it appears within the type `ConstImplWithDropGlue` note: required because it appears within the type `ConstImplWithDropGlue`
--> $DIR/const-drop-fail.rs:17:8 --> $DIR/const-drop-fail.rs:17:8
| |
......
...@@ -28,6 +28,11 @@ LL | const _: () = check($exp); ...@@ -28,6 +28,11 @@ LL | const _: () = check($exp);
LL | ConstImplWithDropGlue(NonTrivialDrop), LL | ConstImplWithDropGlue(NonTrivialDrop),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Drop` is not implemented for `NonTrivialDrop` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Drop` is not implemented for `NonTrivialDrop`
| |
note: the trait `Drop` is implemented for `NonTrivialDrop`, but that implementation is not `const`
--> $DIR/const-drop-fail.rs:46:5
|
LL | ConstImplWithDropGlue(NonTrivialDrop),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because it appears within the type `ConstImplWithDropGlue` note: required because it appears within the type `ConstImplWithDropGlue`
--> $DIR/const-drop-fail.rs:17:8 --> $DIR/const-drop-fail.rs:17:8
| |
......
...@@ -4,6 +4,11 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied ...@@ -4,6 +4,11 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied
LL | foo::<()>(); LL | foo::<()>();
| ^^ the trait `~const Tr` is not implemented for `()` | ^^ the trait `~const Tr` is not implemented for `()`
| |
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
--> $DIR/default-method-body-is-const-body-checking.rs:12:15
|
LL | foo::<()>();
| ^^
note: required by a bound in `foo` note: required by a bound in `foo`
--> $DIR/default-method-body-is-const-body-checking.rs:7:28 --> $DIR/default-method-body-is-const-body-checking.rs:7:28
| |
......
...@@ -4,6 +4,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied ...@@ -4,6 +4,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied
LL | T::b(); LL | T::b();
| ^^^^ the trait `~const Bar` is not implemented for `T` | ^^^^ the trait `~const Bar` is not implemented for `T`
| |
note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
--> $DIR/trait-where-clause.rs:14:5
|
LL | T::b();
| ^^^^
note: required by a bound in `Foo::b` note: required by a bound in `Foo::b`
--> $DIR/trait-where-clause.rs:8:24 --> $DIR/trait-where-clause.rs:8:24
| |
...@@ -20,6 +25,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied ...@@ -20,6 +25,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied
LL | T::c::<T>(); LL | T::c::<T>();
| ^^^^^^^^^ the trait `~const Bar` is not implemented for `T` | ^^^^^^^^^ the trait `~const Bar` is not implemented for `T`
| |
note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
--> $DIR/trait-where-clause.rs:16:5
|
LL | T::c::<T>();
| ^^^^^^^^^
note: required by a bound in `Foo::c` note: required by a bound in `Foo::c`
--> $DIR/trait-where-clause.rs:9:13 --> $DIR/trait-where-clause.rs:9:13
| |
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册