diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index ecf9745b77945..8f33e0806cbce 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -57,6 +57,8 @@ pub fn provide(providers: &mut Providers) {
providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
};
+ providers.hooks.validate_scalar_in_layout =
+ |tcx, scalar, layout| util::validate_scalar_in_layout(tcx, scalar, layout);
}
/// `rustc_driver::main` installs a handler that will set this to `true` if
diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
index a729d9325c84a..83d45b12cd746 100644
--- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
+++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
@@ -1,9 +1,10 @@
use rustc_abi::{BackendRepr, FieldsShape, Scalar, Variants};
-use rustc_middle::bug;
+use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{
HasTyCtxt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement,
};
-use rustc_middle::ty::{PseudoCanonicalInput, Ty, TyCtxt};
+use rustc_middle::ty::{PseudoCanonicalInput, ScalarInt, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug, ty};
use crate::const_eval::{CanAccessMutGlobal, CheckAlignment, CompileTimeMachine};
use crate::interpret::{InterpCx, MemoryKind};
@@ -34,7 +35,7 @@ pub fn check_validity_requirement<'tcx>(
let layout_cx = LayoutCx::new(tcx, input.typing_env);
if kind == ValidityRequirement::Uninit || tcx.sess.opts.unstable_opts.strict_init_checks {
- check_validity_requirement_strict(layout, &layout_cx, kind)
+ Ok(check_validity_requirement_strict(layout, &layout_cx, kind))
} else {
check_validity_requirement_lax(layout, &layout_cx, kind)
}
@@ -46,7 +47,7 @@ fn check_validity_requirement_strict<'tcx>(
ty: TyAndLayout<'tcx>,
cx: &LayoutCx<'tcx>,
kind: ValidityRequirement,
-) -> Result> {
+) -> bool {
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.typing_env, machine);
@@ -69,14 +70,13 @@ fn check_validity_requirement_strict<'tcx>(
// due to this.
// The value we are validating is temporary and discarded at the end of this function, so
// there is no point in reseting provenance and padding.
- Ok(cx
- .validate_operand(
- &allocated.into(),
- /*recursive*/ false,
- /*reset_provenance_and_padding*/ false,
- )
- .discard_err()
- .is_some())
+ cx.validate_operand(
+ &allocated.into(),
+ /*recursive*/ false,
+ /*reset_provenance_and_padding*/ false,
+ )
+ .discard_err()
+ .is_some()
}
/// Implements the 'lax' (default) version of the [`check_validity_requirement`] checks; see that
@@ -168,3 +168,31 @@ fn check_validity_requirement_lax<'tcx>(
Ok(true)
}
+
+pub(crate) fn validate_scalar_in_layout<'tcx>(
+ tcx: TyCtxtAt<'tcx>,
+ scalar: ScalarInt,
+ ty: Ty<'tcx>,
+) -> bool {
+ let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
+
+ let typing_env = ty::TypingEnv::fully_monomorphized();
+ let mut cx = InterpCx::new(tcx.tcx, tcx.span, typing_env, machine);
+
+ let Ok(layout) = cx.layout_of(ty) else {
+ span_bug!(tcx.span, "could not compute layout of {scalar:?}:{ty:?}")
+ };
+ let allocated = cx
+ .allocate(layout, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
+ .expect("OOM: failed to allocate for uninit check");
+
+ cx.write_scalar(scalar, &allocated).unwrap();
+
+ cx.validate_operand(
+ &allocated.into(),
+ /*recursive*/ false,
+ /*reset_provenance_and_padding*/ false,
+ )
+ .discard_err()
+ .is_some()
+}
diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs
index 25a9dbb2c1117..5be5ee8d1ae97 100644
--- a/compiler/rustc_const_eval/src/util/mod.rs
+++ b/compiler/rustc_const_eval/src/util/mod.rs
@@ -8,6 +8,7 @@ mod type_name;
pub use self::alignment::{is_disaligned, is_within_packed};
pub use self::check_validity_requirement::check_validity_requirement;
+pub(crate) use self::check_validity_requirement::validate_scalar_in_layout;
pub use self::compare_types::{relate_types, sub_types};
pub use self::type_name::type_name;
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 1a216ebf117c6..f5761da60f2c2 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -529,6 +529,8 @@ declare_features! (
(unstable, inline_const_pat, "1.58.0", Some(76001)),
/// Allows using `pointer` and `reference` in intra-doc links
(unstable, intra_doc_pointers, "1.51.0", Some(80896)),
+ // Allows using the `kl` and `widekl` target features and the associated intrinsics
+ (unstable, keylocker_x86, "CURRENT_RUSTC_VERSION", Some(134813)),
// Allows setting the threshold for the `large_assignments` lint.
(unstable, large_assignments, "1.52.0", Some(83518)),
/// Allow to have type alias types for inter-crate use.
diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs
index 276a02b4e0feb..c5ce6efcb817e 100644
--- a/compiler/rustc_middle/src/hooks/mod.rs
+++ b/compiler/rustc_middle/src/hooks/mod.rs
@@ -98,6 +98,10 @@ declare_hooks! {
hook save_dep_graph() -> ();
hook query_key_hash_verify_all() -> ();
+
+ /// Ensure the given scalar is valid for the given type.
+ /// This checks non-recursive runtime validity.
+ hook validate_scalar_in_layout(scalar: crate::ty::ScalarInt, ty: Ty<'tcx>) -> bool;
}
#[cold]
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 6c8591dae895b..f603add3c1153 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1741,7 +1741,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
" as ",
)?;
}
- ty::Pat(base_ty, pat) => {
+ ty::Pat(base_ty, pat) if self.tcx().validate_scalar_in_layout(int, ty) => {
self.pretty_print_const_scalar_int(int, *base_ty, print_ty)?;
p!(write(" is {pat:?}"));
}
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 20a728d6d5b2c..0aa61152330a7 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -155,42 +155,41 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
fn lower_pattern_range_endpoint(
&mut self,
expr: Option<&'tcx hir::PatExpr<'tcx>>,
- ) -> Result<
- (Option>, Option>, Option),
- ErrorGuaranteed,
- > {
- match expr {
- None => Ok((None, None, None)),
- Some(expr) => {
- let (kind, ascr, inline_const) = match self.lower_lit(expr) {
- PatKind::ExpandedConstant { subpattern, def_id, is_inline: true } => {
- (subpattern.kind, None, def_id.as_local())
- }
- PatKind::ExpandedConstant { subpattern, is_inline: false, .. } => {
- (subpattern.kind, None, None)
- }
- PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
- (kind, Some(ascription), None)
- }
- kind => (kind, None, None),
- };
- let value = match kind {
- PatKind::Constant { value } => value,
- PatKind::ExpandedConstant { subpattern, .. }
- if let PatKind::Constant { value } = subpattern.kind =>
- {
- value
- }
- _ => {
- let msg = format!(
- "found bad range pattern endpoint `{expr:?}` outside of error recovery"
- );
- return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg));
+ // Out-parameters collecting extra data to be reapplied by the caller
+ ascriptions: &mut Vec>,
+ inline_consts: &mut Vec,
+ ) -> Result
\
In older versions of Rust, dyn compatibility was called \"object safety\", \
so this trait is not object safe.
",
- base = crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL
+ base = crate::clean::utils::DOC_RUST_LANG_ORG_VERSION
),
);
}
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index ccf4002bb300d..bfd5cb7764fd4 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -1534,10 +1534,10 @@ function preLoadCss(cssUrl) {
function buildHelpMenu() {
const book_info = document.createElement("span");
- const channel = getVar("channel");
+ const drloChannel = `https://doc.rust-lang.org/${getVar("channel")}`;
book_info.className = "top";
book_info.innerHTML = `You can find more information in \
-the rustdoc book.`;
+the rustdoc book.`;
const shortcuts = [
["?", "Show this help dialog"],
@@ -1557,8 +1557,8 @@ function preLoadCss(cssUrl) {
div_shortcuts.innerHTML = "
Keyboard Shortcuts
" + shortcuts + "
";
const infos = [
- `For a full list of all search features, take a look here.`,
+ `For a full list of all search features, take a look \
+ here.`,
"Prefix searches with a type followed by a colon (e.g., fn:) to \
restrict the search to a given item kind.",
"Accepted kinds are: fn, mod, struct, \
@@ -1568,10 +1568,10 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
-> vec or String, enum:Cow -> bool)",
"You can look for items with an exact name by putting double quotes around \
your request: \"string\"",
- "Look for functions that accept or return \
- slices and \
- arrays by writing \
- square brackets (e.g., -> [u8] or [] -> Option)",
+ `Look for functions that accept or return \
+ slices and \
+ arrays by writing square \
+ brackets (e.g., -> [u8] or [] -> Option)`,
"Look for items inside another one by searching for a path: vec::Vec",
].map(x => "