diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index d1393528d1c..bdc92a2c096 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -791,7 +791,7 @@ impl<'a, 'b> Context<'a, 'b> {
// Thus in the not nicely ordered case we emit the following instead:
//
// 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.
@@ -804,7 +804,7 @@ impl<'a, 'b> Context<'a, 'b> {
self.ecx.expr_addr_of(expansion_span, P(e.take()))
} else {
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);
self.ecx.expr(def_site, ast::ExprKind::Field(args_tuple, member))
};
@@ -828,7 +828,7 @@ impl<'a, 'b> Context<'a, 'b> {
.map(|e| self.ecx.expr_addr_of(e.span.with_ctxt(self.macsp.ctxt()), e))
.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 head = self.ecx.expr(self.macsp, ast::ExprKind::Tup(heads));
self.ecx.expr_match(self.macsp, head, vec![arm])
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 3ec9f3ca3b8..9dc34260de7 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -7,7 +7,6 @@ use crate::interpret::{
};
use rustc_errors::ErrorReported;
-use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_middle::mir;
use rustc_middle::mir::interpret::ErrorHandled;
@@ -216,7 +215,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
tcx: TyCtxt<'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'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
if key.param_env.reveal() == Reveal::All {
let mut key = key;
@@ -251,7 +250,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
tcx: TyCtxt<'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'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
// 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
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 4851e637d3a..e7dca94806c 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -569,13 +569,15 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
let predicate = predicate.fold_with(&mut BottomUpFolder {
tcx,
ty_op: |ty| match ty.kind() {
- ty::Projection(projection_ty) => infcx.infer_projection(
- self.param_env,
- *projection_ty,
- traits::ObligationCause::misc(self.value_span, self.body_id),
- 0,
- &mut self.obligations,
- ),
+ ty::Projection(projection_ty) if !projection_ty.has_escaping_bound_vars() => {
+ infcx.infer_projection(
+ self.param_env,
+ *projection_ty,
+ traits::ObligationCause::misc(self.value_span, self.body_id),
+ 0,
+ &mut self.obligations,
+ )
+ }
_ => ty,
},
lt_op: |lt| lt,
diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs
index dafff640b36..4c7f3482776 100644
--- a/compiler/rustc_lint/src/traits.rs
+++ b/compiler/rustc_lint/src/traits.rs
@@ -86,7 +86,6 @@ declare_lint_pass!(
impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
- use rustc_middle::ty;
use rustc_middle::ty::PredicateKind::*;
let predicates = cx.tcx.explicit_predicates_of(item.def_id);
@@ -94,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
let Trait(trait_predicate) = predicate.kind().skip_binder() else {
continue
};
- if trait_predicate.constness == ty::BoundConstness::ConstIfConst {
+ if trait_predicate.is_const_if_const() {
// `~const Drop` definitely have meanings so avoid linting here.
continue;
}
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 6174c922e2d..e7a8e71ce71 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -784,6 +784,11 @@ impl<'tcx> TraitPredicate<'tcx> {
pub fn self_ty(self) -> Ty<'tcx> {
self.trait_ref.self_ty()
}
+
+ #[inline]
+ pub fn is_const_if_const(self) -> bool {
+ self.constness == BoundConstness::ConstIfConst
+ }
}
impl<'tcx> PolyTraitPredicate<'tcx> {
@@ -803,6 +808,11 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
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)]
@@ -1388,6 +1398,11 @@ impl<'tcx> ParamEnv<'tcx> {
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
/// where the values of all `impl Trait` and other hidden types
/// are revealed. This is suitable for monomorphized, post-typeck
@@ -1503,6 +1518,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
polarity: ty::ImplPolarity::Positive,
})
}
+
#[inline]
pub fn without_const(self) -> PolyTraitPredicate<'tcx> {
self.with_constness(BoundConstness::NotConst)
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9fba9c77d07..757c430e799 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -272,7 +272,6 @@ symbols! {
__H,
__S,
__try_var,
- _args,
_d,
_e,
_task_context,
@@ -324,6 +323,7 @@ symbols! {
append_const_msg,
arbitrary_enum_discriminant,
arbitrary_self_types,
+ args,
arith_offset,
arm,
arm_target_feature,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 37cf41a0ec2..687bd16ba30 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -439,6 +439,28 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
} else {
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 {
err.span_label(span, &msg);
}
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 0099fba9200..db86041f618 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -305,7 +305,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} else if lang_items.unsize_trait() == Some(def_id) {
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
} 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);
} else {
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 2e20ea34e10..639884844b2 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -72,9 +72,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// CheckPredicate(&A: Super)
// CheckPredicate(A: ~const Super) // <- still const env, failure
// ```
- if obligation.param_env.constness() == Constness::Const
- && obligation.predicate.skip_binder().constness == ty::BoundConstness::NotConst
- {
+ if obligation.param_env.is_const() && !obligation.predicate.is_const_if_const() {
new_obligation = TraitObligation {
cause: obligation.cause.clone(),
param_env: obligation.param_env.without_const(),
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index ae536905483..47427395b93 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1173,9 +1173,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ImplCandidate(def_id)
if tcx.impl_constness(def_id) == hir::Constness::Const => {}
// const param
- ParamCandidate(trait_pred)
- if trait_pred.skip_binder().constness
- == ty::BoundConstness::ConstIfConst => {}
+ ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
// auto trait impl
AutoImplCandidate(..) => {}
// generator, this will raise error in other places
diff --git a/library/core/src/future/join.rs b/library/core/src/future/join.rs
index a6ffbe07d91..fa4eb0d2f33 100644
--- a/library/core/src/future/join.rs
+++ b/library/core/src/future/join.rs
@@ -9,7 +9,7 @@ use crate::task::{Context, Poll};
/// Polls multiple futures simultaneously, returning a tuple
/// 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.
///
/// # Examples
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index a62c01ef29b..16b8bf68242 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1504,3 +1504,19 @@ fn create_dir_long_paths() {
let path = Path::new("");
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();
+ }
+}
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 489d362be42..7c8cb5378a2 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -403,13 +403,6 @@ pub use alloc_crate::string;
pub use alloc_crate::vec;
#[stable(feature = "rust1", since = "1.0.0")]
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")]
pub use core::array;
#[stable(feature = "rust1", since = "1.0.0")]
@@ -527,6 +520,31 @@ pub mod 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
// compiler
#[macro_use]
@@ -545,18 +563,6 @@ mod panicking;
#[allow(dead_code, unused_attributes)]
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.
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated, deprecated_in_future)]
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index 5b2199c2b7f..65e000d9215 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -489,10 +489,18 @@ impl Iterator for ReadDir {
};
}
+ // 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 {
- entry: *entry_ptr,
+ entry,
// 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),
};
if ret.name_bytes() != b"." && ret.name_bytes() != b".." {
diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs
index 079f00a5753..14a9e3acca4 100644
--- a/library/std/tests/run-time-detect.rs
+++ b/library/std/tests/run-time-detect.rs
@@ -14,6 +14,7 @@
#[test]
#[cfg(all(target_arch = "arm", any(target_os = "linux", target_os = "android")))]
fn arm_linux() {
+ use std::arch::is_arm_feature_detected;
println!("neon: {}", is_arm_feature_detected!("neon"));
println!("pmull: {}", is_arm_feature_detected!("pmull"));
println!("crypto: {}", is_arm_feature_detected!("crypto"));
@@ -25,6 +26,7 @@ fn arm_linux() {
#[test]
#[cfg(all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")))]
fn aarch64_linux() {
+ use std::arch::is_aarch64_feature_detected;
println!("neon: {}", is_aarch64_feature_detected!("neon"));
println!("asimd: {}", is_aarch64_feature_detected!("asimd"));
println!("pmull: {}", is_aarch64_feature_detected!("pmull"));
@@ -71,6 +73,7 @@ fn aarch64_linux() {
#[test]
#[cfg(all(target_arch = "powerpc", target_os = "linux"))]
fn powerpc_linux() {
+ use std::arch::is_powerpc_feature_detected;
println!("altivec: {}", is_powerpc_feature_detected!("altivec"));
println!("vsx: {}", is_powerpc_feature_detected!("vsx"));
println!("power8: {}", is_powerpc_feature_detected!("power8"));
@@ -79,6 +82,7 @@ fn powerpc_linux() {
#[test]
#[cfg(all(target_arch = "powerpc64", target_os = "linux"))]
fn powerpc64_linux() {
+ use std::arch::is_powerpc64_feature_detected;
println!("altivec: {}", is_powerpc64_feature_detected!("altivec"));
println!("vsx: {}", is_powerpc64_feature_detected!("vsx"));
println!("power8: {}", is_powerpc64_feature_detected!("power8"));
@@ -87,6 +91,8 @@ fn powerpc64_linux() {
#[test]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
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
// use to gate anything and are thus not part of the X86_ALLOWED_FEATURES list
diff --git a/library/stdarch b/library/stdarch
index 11c98f6eb9c..eaee02ffdf5 160000
--- a/library/stdarch
+++ b/library/stdarch
@@ -1 +1 @@
-Subproject commit 11c98f6eb9c4ba48b2362ad4960343b312d056b8
+Subproject commit eaee02ffdf5d820729ccdf2f95fa08b08c7d24d2
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 0b6faa4b13e..cc12b7ba05b 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -182,7 +182,7 @@ impl StylePath {
fn write_srclink(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) {
if let Some(l) = cx.src_href(item) {
- write!(buf, "source", l)
+ write!(buf, "source", l)
}
}
diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html
index 1fa84e1c31f..62b1b7ca729 100644
--- a/src/librustdoc/html/templates/print_item.html
+++ b/src/librustdoc/html/templates/print_item.html
@@ -20,7 +20,7 @@
{% endif %}
{%- match src_href -%}
{%- when Some with (href) -%}
- source · {# -#}
+ source · {# -#}
{%- else -%}
{%- endmatch -%}
{#- -#}
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index e1747f3e392..86662ebaaca 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -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!
/// So it is not stable to serialize cross-crate.
+#[instrument(level = "debug", skip(cx))]
fn trait_impls_for<'a>(
cx: &mut DocContext<'a>,
ty: Ty<'a>,
diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs
index 34aae4b6e39..edd4e9da66d 100644
--- a/src/librustdoc/passes/collect_intra_doc_links/early.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs
@@ -32,6 +32,11 @@ crate fn early_resolve_intra_doc_links(
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,
// so we have to visit its attributes and reexports separately.
loader.load_links_in_attrs(&krate.attrs, krate.span);
@@ -180,6 +185,11 @@ impl Visitor<'_> for IntraLinkCrateLoader<'_, '_> {
if let ItemKind::Mod(..) = item.kind {
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.process_module_children_or_reexports(self.current_mod.to_def_id());
visit::walk_item(self, item);
diff --git a/src/test/rustdoc/intra-doc/crate-relative.rs b/src/test/rustdoc/intra-doc/crate-relative.rs
new file mode 100644
index 00000000000..bacbcabfc60
--- /dev/null
+++ b/src/test/rustdoc/intra-doc/crate-relative.rs
@@ -0,0 +1,13 @@
+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`]
+}
diff --git a/src/test/rustdoc/intra-doc/mod-relative.rs b/src/test/rustdoc/intra-doc/mod-relative.rs
new file mode 100644
index 00000000000..49d3399b972
--- /dev/null
+++ b/src/test/rustdoc/intra-doc/mod-relative.rs
@@ -0,0 +1,17 @@
+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 {
+ }
+
+}
diff --git a/src/test/ui/generic-associated-types/issue-93340.rs b/src/test/ui/generic-associated-types/issue-93340.rs
new file mode 100644
index 00000000000..d065bde88c4
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-93340.rs
@@ -0,0 +1,20 @@
+// 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(
+) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
+ cmp_eq
+}
+
+fn main() {}
diff --git a/src/test/ui/intrinsics/const-eval-select-bad.stderr b/src/test/ui/intrinsics/const-eval-select-bad.stderr
index 083b0064538..06a7a2f63cf 100644
--- a/src/test/ui/intrinsics/const-eval-select-bad.stderr
+++ b/src/test/ui/intrinsics/const-eval-select-bad.stderr
@@ -7,6 +7,11 @@ LL | const_eval_select((), || {}, || {});
| 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]`
+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: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
diff --git a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
index 429b9f3364b..0788b17a1c0 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
@@ -5,6 +5,11 @@ LL | type Bar = NonConstAdd;
| ^^^^^^^^^^^ no implementation for `NonConstAdd + 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`
--> $DIR/assoc-type.rs:14:15
|
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
index 13cffaba91a..35b7fe8e401 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
@@ -7,6 +7,11 @@ LL | pub const EQ: bool = equals_self(&S);
| required by a bound introduced by this call
|
= 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`
--> $DIR/call-generic-method-nonconst.rs:12:25
|
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
index df776908a03..d280cd2556f 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
@@ -28,6 +28,11 @@ LL | const _: () = check($exp);
LL | ConstImplWithDropGlue(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`
--> $DIR/const-drop-fail.rs:17:8
|
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
index df776908a03..d280cd2556f 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
@@ -28,6 +28,11 @@ LL | const _: () = check($exp);
LL | ConstImplWithDropGlue(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`
--> $DIR/const-drop-fail.rs:17:8
|
diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr
index 05a74757b94..bc807507fd6 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr
@@ -4,6 +4,11 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied
LL | foo::<()>();
| ^^ 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`
--> $DIR/default-method-body-is-const-body-checking.rs:7:28
|
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
index 903cd924ca5..f9b5d81c63b 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
@@ -4,6 +4,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied
LL | T::b();
| ^^^^ 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`
--> $DIR/trait-where-clause.rs:8:24
|
@@ -20,6 +25,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied
LL | T::c::();
| ^^^^^^^^^ 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::();
+ | ^^^^^^^^^
note: required by a bound in `Foo::c`
--> $DIR/trait-where-clause.rs:9:13
|