Auto merge of #148544 - matthiaskrgr:rollup-n9dqgwc, r=matthiaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang/rust#147994 (Deduplicate deprecation warning when using unit or tuple structs)
 - rust-lang/rust#148440 ([rustdoc search] Simplify itemTypes and filter "dependencies")
 - rust-lang/rust#148501 (triagebot: Create Zulip topics for libs backports)
 - rust-lang/rust#148517 (Remove no longer necessary lint allow)
 - rust-lang/rust#148518 (Unify the configuration of the compiler docs)
 - rust-lang/rust#148523 (miri subtree update)
 - rust-lang/rust#148525 (Fix ICE from lit_to_mir_constant caused by type error)
 - rust-lang/rust#148534 (Merge `Vec::push{,_mut}_within_capacity`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-11-05 21:07:24 +00:00
commit 401ae55427
84 changed files with 671 additions and 638 deletions

View file

@ -1,9 +1,7 @@
// tidy-alphabetical-start
#![cfg_attr(feature = "nightly", allow(internal_features))]
#![cfg_attr(feature = "nightly", doc(rust_logo))]
#![cfg_attr(feature = "nightly", feature(assert_matches))]
#![cfg_attr(feature = "nightly", feature(rustc_attrs))]
#![cfg_attr(feature = "nightly", feature(rustdoc_internals))]
#![cfg_attr(feature = "nightly", feature(step_trait))]
// tidy-alphabetical-end

View file

@ -12,18 +12,13 @@
#![allow(internal_features)]
#![cfg_attr(test, feature(test))]
#![deny(unsafe_op_in_unsafe_fn)]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(no_crate_inject, attr(deny(warnings)))
)]
#![doc(rust_logo)]
#![doc(test(no_crate_inject, attr(deny(warnings), allow(internal_features))))]
#![feature(core_intrinsics)]
#![feature(decl_macro)]
#![feature(dropck_eyepatch)]
#![feature(maybe_uninit_slice)]
#![feature(never_type)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(unwrap_infallible)]
// tidy-alphabetical-end

View file

@ -5,19 +5,13 @@
//! This API is completely unstable and subject to change.
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(deny(warnings)))
)]
#![doc(rust_logo)]
#![doc(test(attr(deny(warnings), allow(internal_features))))]
#![feature(array_windows)]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_order_by)]
#![feature(macro_metavar_expr)]
#![feature(rustdoc_internals)]
#![recursion_limit = "256"]
// tidy-alphabetical-end

View file

@ -31,11 +31,8 @@
//! in the HIR, especially for multiple identifiers.
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
use std::sync::Arc;

View file

@ -3,12 +3,9 @@
//! by `rustc_ast_lowering`.
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_is_partitioned)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
pub mod ast_validation;

View file

@ -1,9 +1,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(box_patterns)]
#![feature(negative_impls)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
mod helpers;

View file

@ -77,10 +77,7 @@
//! containing both `C` and `packed` annotations.
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(decl_macro)]
#![feature(rustdoc_internals)]
#![recursion_limit = "256"]
// tidy-alphabetical-end

View file

@ -21,10 +21,7 @@
// tidy-alphabetical-start
#![allow(elided_lifetimes_in_paths)]
#![allow(internal_features)]
#![allow(unreachable_pub)] // because this crate is mostly generated code
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
// #![warn(unreachable_pub)] // don't use because this crate is mostly generated code
// tidy-alphabetical-end

View file

@ -2,7 +2,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(file_buffered)]
@ -10,7 +9,6 @@
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(stmt_expr_attributes)]
#![feature(try_blocks)]
// tidy-alphabetical-end

View file

@ -5,8 +5,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(decl_macro)]
@ -14,7 +12,6 @@
#![feature(iter_order_by)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]
#![recursion_limit = "256"]
// tidy-alphabetical-end

View file

@ -1,9 +1,6 @@
// tidy-alphabetical-start
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(doc, allow(internal_features))]
#![cfg_attr(doc, doc(rust_logo))]
#![cfg_attr(doc, feature(rustdoc_internals))]
// Note: please avoid adding other feature gates where possible
#![feature(rustc_private)]
// Only used to define intrinsics in `compiler_builtins.rs`.

View file

@ -13,9 +13,6 @@
* TODO(antoyo): remove the patches.
*/
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
#![feature(rustc_private)]
#![recursion_limit = "256"]
#![warn(rust_2018_idioms)]

View file

@ -5,9 +5,6 @@
//! This API is completely unstable and subject to change.
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(extern_types)]
#![feature(file_buffered)]
@ -15,7 +12,6 @@
#![feature(impl_trait_in_assoc_type)]
#![feature(iter_intersperse)]
#![feature(macro_derive)]
#![feature(rustdoc_internals)]
#![feature(slice_as_array)]
#![feature(trim_prefix_suffix)]
#![feature(try_blocks)]

View file

@ -1,15 +1,11 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(negative_impls)]
#![feature(rustdoc_internals)]
#![feature(string_from_utf8_lossy_owned)]
#![feature(trait_alias)]
#![feature(try_blocks)]

View file

@ -1,14 +1,11 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![doc(rust_logo)]
#![feature(array_try_map)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(decl_macro)]
#![feature(if_let_guard)]
#![feature(never_type)]
#![feature(rustdoc_internals)]
#![feature(slice_ptr_get)]
#![feature(trait_alias)]
#![feature(try_blocks)]

View file

@ -11,8 +11,6 @@
#![allow(rustc::default_hash_types)]
#![allow(rustc::potential_query_instability)]
#![deny(unsafe_op_in_unsafe_fn)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(allocator_api)]
#![feature(array_windows)]
#![feature(ascii_char)]
@ -30,7 +28,6 @@
#![feature(never_type)]
#![feature(ptr_alignment_type)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(sized_hierarchy)]
#![feature(test)]
#![feature(thread_id_value)]

View file

@ -1,10 +1,4 @@
// This crate is intentionally empty and a re-export of `rustc_driver_impl` to allow the code in
// `rustc_driver_impl` to be compiled in parallel with other crates.
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
pub use rustc_driver_impl::*;

View file

@ -5,14 +5,10 @@
//! This API is completely unstable and subject to change.
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(decl_macro)]
#![feature(panic_backtrace_config)]
#![feature(panic_update_hook)]
#![feature(rustdoc_internals)]
#![feature(trim_prefix_suffix)]
#![feature(try_blocks)]
// tidy-alphabetical-end

View file

@ -2,10 +2,7 @@
//! their maintenance easier.
// tidy-alphabetical-start
#![allow(internal_features)]
#![deny(rustdoc::invalid_codeblock_attributes)]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
// This higher-order macro defines the error codes that are in use. It is used

View file

@ -1,8 +1,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
use std::borrow::Cow;

View file

@ -7,8 +7,6 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::direct_use_of_rustc_type_ir)]
#![allow(rustc::untranslatable_diagnostic)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(array_windows)]
#![feature(assert_matches)]
#![feature(associated_type_defaults)]
@ -18,7 +16,6 @@
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]
#![feature(yeet_expr)]
// tidy-alphabetical-end

View file

@ -1,14 +1,12 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![doc(rust_logo)]
#![feature(array_windows)]
#![feature(associated_type_defaults)]
#![feature(if_let_guard)]
#![feature(macro_metavar_expr)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_internals)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]
#![feature(yeet_expr)]
// tidy-alphabetical-end

View file

@ -11,12 +11,6 @@
//! even if it is stabilized or removed, *do not remove it*. Instead, move the
//! symbol to the `accepted` or `removed` modules respectively.
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
mod accepted;
mod builtin_attrs;
mod removed;

View file

@ -1,10 +1,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::default_hash_types)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(proc_macro_diagnostic)]
#![feature(rustdoc_internals)]
#![feature(track_path)]
// tidy-alphabetical-end

View file

@ -270,13 +270,7 @@
//! * [DOT language](https://www.graphviz.org/doc/info/lang.html)
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(allow(unused_variables), deny(warnings)))
)]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))]
// tidy-alphabetical-end
use std::borrow::Cow;

View file

@ -56,18 +56,14 @@ This API is completely unstable and subject to change.
*/
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(debug_closure_helpers))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(gen_blocks)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(never_type)]
#![feature(rustdoc_internals)]
#![feature(slice_partition_dedup)]
#![feature(try_blocks)]
#![feature(unwrap_infallible)]

View file

@ -1,12 +1,8 @@
//! Support for serializing the dep-graph and reloading it.
// tidy-alphabetical-start
#![allow(internal_features)]
#![deny(missing_docs)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(file_buffered)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
mod assert_dep_graph;

View file

@ -1,6 +1,5 @@
// tidy-alphabetical-start
#![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))]
#![cfg_attr(feature = "nightly", allow(internal_features))]
#![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))]
#![cfg_attr(feature = "nightly", feature(new_range_api))]
// tidy-alphabetical-end

View file

@ -13,13 +13,9 @@
//! This API is completely unstable and subject to change.
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::direct_use_of_rustc_type_ir)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(extend_one)]
#![feature(rustdoc_internals)]
#![recursion_limit = "512"] // For rustdoc
// tidy-alphabetical-end

View file

@ -21,15 +21,12 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(array_windows)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_order_by)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]
// tidy-alphabetical-end

View file

@ -1,9 +1,5 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(extern_types)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
use std::cell::RefCell;

View file

@ -1,7 +1,5 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(decl_macro)]
#![feature(error_iter)]
#![feature(file_buffered)]
@ -11,7 +9,6 @@
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(proc_macro_internals)]
#![feature(rustdoc_internals)]
#![feature(trusted_len)]
// tidy-alphabetical-end

View file

@ -29,8 +29,6 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::direct_use_of_rustc_type_ir)]
#![allow(rustc::untranslatable_diagnostic)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(allocator_api)]
#![feature(array_windows)]
#![feature(assert_matches)]
@ -52,7 +50,6 @@
#![feature(never_type)]
#![feature(ptr_alignment_type)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(sized_hierarchy)]
#![feature(try_blocks)]
#![feature(try_trait_v2)]

View file

@ -8,11 +8,7 @@
// We want to be able to build this crate with a stable compiler,
// so no `#![feature]` attributes should be added.
#![deny(unstable_features)]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
html_playground_url = "https://play.rust-lang.org/",
test(attr(deny(warnings)))
)]
#![doc(test(attr(deny(warnings), allow(internal_features))))]
// tidy-alphabetical-end
use std::ops::Range;

View file

@ -5,12 +5,8 @@
//! This API is completely unstable and subject to change.
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(if_let_guard)]
#![feature(map_try_insert)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
use rustc_middle::util::Providers;

View file

@ -12,8 +12,8 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModDefId};
use rustc_hir::intravisit::{self, Visitor, VisitorExt};
use rustc_hir::{
self as hir, AmbigArg, ConstStability, DefaultBodyStability, FieldDef, Item, ItemKind,
Stability, StabilityLevel, StableSince, TraitRef, Ty, TyKind, UnstableReason,
self as hir, AmbigArg, ConstStability, DefaultBodyStability, FieldDef, HirId, Item, ItemKind,
Path, Stability, StabilityLevel, StableSince, TraitRef, Ty, TyKind, UnstableReason, UsePath,
VERSION_PLACEHOLDER, Variant, find_attr,
};
use rustc_middle::hir::nested_filter;
@ -739,6 +739,35 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
intravisit::walk_poly_trait_ref(self, t);
}
fn visit_use(&mut self, path: &'tcx UsePath<'tcx>, hir_id: HirId) {
let res = path.res;
// A use item can import something from two namespaces at the same time.
// For deprecation/stability we don't want to warn twice.
// This specifically happens with constructors for unit/tuple structs.
if let Some(ty_ns_res) = res.type_ns
&& let Some(value_ns_res) = res.value_ns
&& let Some(type_ns_did) = ty_ns_res.opt_def_id()
&& let Some(value_ns_did) = value_ns_res.opt_def_id()
&& let DefKind::Ctor(.., _) = self.tcx.def_kind(value_ns_did)
&& self.tcx.parent(value_ns_did) == type_ns_did
{
// Only visit the value namespace path when we've detected a duplicate,
// not the type namespace path.
let UsePath { segments, res: _, span } = *path;
self.visit_path(&Path { segments, res: value_ns_res, span }, hir_id);
// Though, visit the macro namespace if it exists,
// regardless of the checks above relating to constructors.
if let Some(res) = res.macro_ns {
self.visit_path(&Path { segments, res, span }, hir_id);
}
} else {
// if there's no duplicate, just walk as normal
intravisit::walk_use(self, path, hir_id)
}
}
fn visit_path(&mut self, path: &hir::Path<'tcx>, id: hir::HirId) {
if let Some(def_id) = path.res.opt_def_id() {
let method_span = path.segments.last().map(|s| s.ident.span);

View file

@ -1,9 +1,5 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(associated_type_defaults)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]
// tidy-alphabetical-end

View file

@ -7,10 +7,7 @@
//! This API is still completely unstable and subject to change.
#![allow(rustc::usage_of_ty_tykind)]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(allow(unused_variables), deny(warnings)))
)]
#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))]
#![feature(sized_hierarchy)]
//!
//! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to

View file

@ -12,14 +12,8 @@
//! This API is still completely unstable and subject to change.
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::usage_of_ty_tykind)]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(allow(unused_variables), deny(warnings)))
)]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))]
#![feature(sized_hierarchy)]
#![feature(trait_alias)]
// tidy-alphabetical-end

View file

@ -2,11 +2,8 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(min_specialization)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
use rustc_data_structures::stable_hasher::HashStable;

View file

@ -10,8 +10,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(arbitrary_self_types)]
#![feature(assert_matches)]
#![feature(box_patterns)]
@ -21,7 +19,6 @@
#![feature(iter_intersperse)]
#![feature(ptr_as_ref_unchecked)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(trim_prefix_suffix)]
#![recursion_limit = "256"]
// tidy-alphabetical-end

View file

@ -4,16 +4,10 @@
#![allow(internal_features)]
#![allow(rustc::internal)]
#![cfg_attr(test, feature(test))]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
html_playground_url = "https://play.rust-lang.org/",
test(attr(allow(unused_variables), deny(warnings)))
)]
#![doc(rust_logo)]
#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))]
#![feature(core_intrinsics)]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(rustdoc_internals)]
#![feature(sized_hierarchy)]
// tidy-alphabetical-end

View file

@ -18,8 +18,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(target_arch = "loongarch64", feature(stdarch_loongarch))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(array_windows)]
#![feature(cfg_select)]
#![feature(core_io_borrowed_buf)]
@ -28,7 +26,6 @@
#![feature(negative_impls)]
#![feature(read_buf)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
// The code produced by the `Encodable`/`Decodable` derive macros refer to

View file

@ -88,11 +88,7 @@
//! DefPaths which are much more robust in the face of changes to the code base.
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
use rustc_hir::def::DefKind;

View file

@ -8,12 +8,8 @@
//! LLVM.
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(debug_closure_helpers))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(iter_intersperse)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
use std::path::{Path, PathBuf};

View file

@ -250,29 +250,30 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
let mut reported = None;
for from_expansion in [false, true] {
for (error, suppressed) in iter::zip(&errors, &is_suppressed) {
if !suppressed
&& error.obligation.cause.span.from_expansion() == from_expansion
&& !error.references_error()
{
let guar = self.report_fulfillment_error(error);
self.infcx.set_tainted_by_errors(guar);
reported = Some(guar);
// We want to ignore desugarings here: spans are equivalent even
// if one is the result of a desugaring and the other is not.
let mut span = error.obligation.cause.span;
let expn_data = span.ctxt().outer_expn_data();
if let ExpnKind::Desugaring(_) = expn_data.kind {
span = expn_data.call_site;
if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion {
if !error.references_error() {
let guar = self.report_fulfillment_error(error);
self.infcx.set_tainted_by_errors(guar);
reported = Some(guar);
// We want to ignore desugarings here: spans are equivalent even
// if one is the result of a desugaring and the other is not.
let mut span = error.obligation.cause.span;
let expn_data = span.ctxt().outer_expn_data();
if let ExpnKind::Desugaring(_) = expn_data.kind {
span = expn_data.call_site;
}
self.reported_trait_errors
.borrow_mut()
.entry(span)
.or_insert_with(|| (vec![], guar))
.0
.push(error.obligation.as_goal());
}
if let Some(guar) = self.dcx().has_errors() {
self.infcx.set_tainted_by_errors(guar);
}
self.reported_trait_errors
.borrow_mut()
.entry(span)
.or_insert_with(|| (vec![], guar))
.0
.push(error.obligation.as_goal());
}
}
}

View file

@ -11,11 +11,8 @@
//! This API is completely unstable and subject to change.
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
@ -24,7 +21,6 @@
#![feature(iter_intersperse)]
#![feature(iterator_try_reduce)]
#![feature(never_type)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]
#![feature(unwrap_infallible)]
#![feature(yeet_expr)]

View file

@ -5,16 +5,12 @@
//! This API is completely unstable and subject to change.
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iterator_try_collect)]
#![feature(never_type)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
use rustc_middle::query::Providers;

View file

@ -2564,8 +2564,8 @@ impl<T, A: Allocator> Vec<T, A> {
let _ = self.push_mut(value);
}
/// Appends an element if there is sufficient spare capacity, otherwise an error is returned
/// with the element.
/// Appends an element and returns a reference to it if there is sufficient spare capacity,
/// otherwise an error is returned with the element.
///
/// Unlike [`push`] this method will not reallocate when there's insufficient capacity.
/// The caller should use [`reserve`] or [`try_reserve`] to ensure that there is enough capacity.
@ -2601,8 +2601,20 @@ impl<T, A: Allocator> Vec<T, A> {
/// Takes *O*(1) time.
#[inline]
#[unstable(feature = "vec_push_within_capacity", issue = "100486")]
pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> {
self.push_mut_within_capacity(value).map(|_| ())
// #[unstable(feature = "push_mut", issue = "135974")]
pub fn push_within_capacity(&mut self, value: T) -> Result<&mut T, T> {
if self.len == self.buf.capacity() {
return Err(value);
}
unsafe {
let end = self.as_mut_ptr().add(self.len);
ptr::write(end, value);
self.len += 1;
// SAFETY: We just wrote a value to the pointer that will live the lifetime of the reference.
Ok(&mut *end)
}
}
/// Appends an element to the back of a collection, returning a reference to it.
@ -2654,36 +2666,6 @@ impl<T, A: Allocator> Vec<T, A> {
}
}
/// Appends an element and returns a reference to it if there is sufficient spare capacity,
/// otherwise an error is returned with the element.
///
/// Unlike [`push_mut`] this method will not reallocate when there's insufficient capacity.
/// The caller should use [`reserve`] or [`try_reserve`] to ensure that there is enough capacity.
///
/// [`push_mut`]: Vec::push_mut
/// [`reserve`]: Vec::reserve
/// [`try_reserve`]: Vec::try_reserve
///
/// # Time complexity
///
/// Takes *O*(1) time.
#[unstable(feature = "push_mut", issue = "135974")]
// #[unstable(feature = "vec_push_within_capacity", issue = "100486")]
#[inline]
#[must_use = "if you don't need a reference to the value, use `Vec::push_within_capacity` instead"]
pub fn push_mut_within_capacity(&mut self, value: T) -> Result<&mut T, T> {
if self.len == self.buf.capacity() {
return Err(value);
}
unsafe {
let end = self.as_mut_ptr().add(self.len);
ptr::write(end, value);
self.len += 1;
// SAFETY: We just wrote a value to the pointer that will live the lifetime of the reference.
Ok(&mut *end)
}
}
/// Removes the last element from a vector and returns it, or [`None`] if it
/// is empty.
///

View file

@ -24,8 +24,6 @@
#![feature(rustc_attrs)]
#![panic_runtime]
#![feature(panic_runtime)]
// `real_imp` is unused with Miri, so silence warnings.
#![cfg_attr(miri, allow(dead_code))]
#![allow(internal_features)]
#![warn(unreachable_pub)]
#![deny(unsafe_op_in_unsafe_fn)]

View file

@ -60,6 +60,21 @@ fn main() {
cmd.arg("--cfg=bootstrap");
}
if let Some(crate_name) = parse_value_from_args(&args, "--crate-name") {
// Add rust logo and set html root for all rustc crates.
if crate_name.starts_with("rustc_") {
cmd.arg("-Ainternal_features")
.arg("-Zcrate-attr=doc(rust_logo)")
.arg("-Zcrate-attr=doc(html_root_url = \"https://doc.rust-lang.org/nightly/nightly-rustc/\")");
// rustc_proc_macro is another build of library/proc_macro which already enables this
// feature
if crate_name != "rustc_proc_macro" {
cmd.arg("-Zcrate-attr=feature(rustdoc_internals)");
}
}
}
maybe_dump(format!("stage{}-rustdoc", stage + 1), &cmd);
if verbose > 1 {

View file

@ -91,54 +91,55 @@ if (!Promise.withResolvers) {
// ==================== Core search logic begin ====================
// This mapping table should match the discriminants of
// `rustdoc::formats::item_type::ItemType` type in Rust.
const itemTypes = [
"keyword",
"primitive",
"mod",
"externcrate",
"import",
"struct", // 5
"enum",
"fn",
"type",
"static",
"trait", // 10
"impl",
"tymethod",
"method",
"structfield",
"variant", // 15
"macro",
"associatedtype",
"constant",
"associatedconstant",
"union", // 20
"foreigntype",
"existential",
"attr",
"derive",
"traitalias", // 25
"generic",
"attribute",
];
const itemTypes = Object.freeze({
keyword: 0,
primitive: 1,
mod: 2,
externcrate: 3,
import: 4,
struct: 5,
enum: 6,
fn: 7,
type: 8,
static: 9,
trait: 10,
impl: 11,
tymethod: 12,
method: 13,
structfield: 14,
variant: 15,
macro: 16,
associatedtype: 17,
constant: 18,
associatedconstant: 19,
union: 20,
foreigntype: 21,
existential: 22,
attr: 23,
derive: 24,
traitalias: 25,
generic: 26,
attribute: 27,
});
const itemTypesName = Array.from(Object.keys(itemTypes));
// When filtering, some types might be included as well. For example, when you filter on `constant`,
// we also include associated constant items.
//
// This map is built as follows: the first item of the array is the type to be included when the
// second type of the array is used as filter.
const itemParents = new Map([
[itemTypes.associatedconstant, itemTypes.constant],
[itemTypes.method, itemTypes.fn],
[itemTypes.tymethod, itemTypes.fn],
[itemTypes.primitive, itemTypes.type],
[itemTypes.associatedtype, itemTypes.type],
[itemTypes.traitalias, itemTypes.trait],
[itemTypes.attr, itemTypes.macro],
[itemTypes.derive, itemTypes.macro],
[itemTypes.externcrate, itemTypes.import],
]);
// used for special search precedence
/** @type {rustdoc.ItemType} */
const TY_PRIMITIVE = 1;
/** @type {rustdoc.ItemType} */
const TY_GENERIC = 26;
/** @type {rustdoc.ItemType} */
const TY_IMPORT = 4;
/** @type {rustdoc.ItemType} */
const TY_TRAIT = 10;
/** @type {rustdoc.ItemType} */
const TY_FN = 7;
/** @type {rustdoc.ItemType} */
const TY_METHOD = 13;
/** @type {rustdoc.ItemType} */
const TY_TYMETHOD = 12;
/** @type {rustdoc.ItemType} */
const TY_ASSOCTYPE = 17;
const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../";
// Hard limit on how deep to recurse into generics when doing type-driven search.
@ -302,7 +303,7 @@ function isEndCharacter(c) {
* @returns
*/
function isFnLikeTy(ty) {
return ty === TY_FN || ty === TY_METHOD || ty === TY_TYMETHOD;
return ty === itemTypes.fn || ty === itemTypes.method || ty === itemTypes.tymethod;
}
/**
@ -1205,8 +1206,9 @@ function itemTypeFromName(typename) {
if (typename === null) {
return NO_TYPE_FILTER;
}
const index = itemTypes.findIndex(i => i === typename);
if (index < 0) {
// @ts-expect-error
const index = itemTypes[typename];
if (index === undefined) {
throw ["Unknown type filter ", typename];
}
return index;
@ -1329,21 +1331,21 @@ class DocSearch {
}
return -1;
};
const typeNameIdOfOutput = await first(output, TY_ASSOCTYPE, "");
const typeNameIdOfFnPtr = await first(fn, TY_PRIMITIVE, "");
const typeNameIdOfFn = await first(fn, TY_TRAIT, "core::ops");
const typeNameIdOfFnMut = await first(fnMut, TY_TRAIT, "core::ops");
const typeNameIdOfFnOnce = await first(fnOnce, TY_TRAIT, "core::ops");
const typeNameIdOfArray = await first(array, TY_PRIMITIVE, "");
const typeNameIdOfSlice = await first(slice, TY_PRIMITIVE, "");
const typeNameIdOfArrayOrSlice = await first(arrayOrSlice, TY_PRIMITIVE, "");
const typeNameIdOfTuple = await first(tuple, TY_PRIMITIVE, "");
const typeNameIdOfUnit = await first(unit, TY_PRIMITIVE, "");
const typeNameIdOfTupleOrUnit = await first(tupleOrUnit, TY_PRIMITIVE, "");
const typeNameIdOfReference = await first(reference, TY_PRIMITIVE, "");
const typeNameIdOfPointer = await first(pointer, TY_PRIMITIVE, "");
const typeNameIdOfHof = await first(hof, TY_PRIMITIVE, "");
const typeNameIdOfNever = await first(never, TY_PRIMITIVE, "");
const typeNameIdOfOutput = await first(output, itemTypes.associatedtype, "");
const typeNameIdOfFnPtr = await first(fn, itemTypes.primitive, "");
const typeNameIdOfFn = await first(fn, itemTypes.trait, "core::ops");
const typeNameIdOfFnMut = await first(fnMut, itemTypes.trait, "core::ops");
const typeNameIdOfFnOnce = await first(fnOnce, itemTypes.trait, "core::ops");
const typeNameIdOfArray = await first(array, itemTypes.primitive, "");
const typeNameIdOfSlice = await first(slice, itemTypes.primitive, "");
const typeNameIdOfArrayOrSlice = await first(arrayOrSlice, itemTypes.primitive, "");
const typeNameIdOfTuple = await first(tuple, itemTypes.primitive, "");
const typeNameIdOfUnit = await first(unit, itemTypes.primitive, "");
const typeNameIdOfTupleOrUnit = await first(tupleOrUnit, itemTypes.primitive, "");
const typeNameIdOfReference = await first(reference, itemTypes.primitive, "");
const typeNameIdOfPointer = await first(pointer, itemTypes.primitive, "");
const typeNameIdOfHof = await first(hof, itemTypes.primitive, "");
const typeNameIdOfNever = await first(never, itemTypes.primitive, "");
this.typeNameIds = {
typeNameIdOfOutput,
typeNameIdOfFnPtr,
@ -1520,7 +1522,7 @@ class DocSearch {
/** @param {rustdoc.ParserQueryElement} elem */
const checkTypeFilter = elem => {
const ty = itemTypeFromName(elem.typeFilter);
if (ty === TY_GENERIC && elem.generics.length !== 0) {
if (ty === itemTypes.generic && elem.generics.length !== 0) {
throw [
"Generic type parameter ",
elem.name,
@ -2033,7 +2035,7 @@ class DocSearch {
result = {
id,
name: "",
ty: TY_GENERIC,
ty: itemTypes.generic,
path: null,
exactPath: null,
generics,
@ -2045,7 +2047,7 @@ class DocSearch {
result = {
id: null,
name: "",
ty: TY_GENERIC,
ty: itemTypes.generic,
path: null,
exactPath: null,
generics,
@ -2062,7 +2064,7 @@ class DocSearch {
return {
id: null,
name: "",
ty: TY_GENERIC,
ty: itemTypes.generic,
path: null,
exactPath: null,
generics,
@ -2149,7 +2151,7 @@ class DocSearch {
let displayPath;
let href;
let traitPath = null;
const type = itemTypes[item.ty];
const type = itemTypesName[item.ty];
const name = item.name;
let path = item.modulePath;
let exactPath = item.exactModulePath;
@ -2173,7 +2175,7 @@ class DocSearch {
} else if (item.parent) {
const myparent = item.parent;
let anchor = type + "." + name;
const parentType = itemTypes[myparent.path.ty];
const parentType = itemTypesName[myparent.path.ty];
let pageType = parentType;
let pageName = myparent.name;
exactPath = `${myparent.path.exactModulePath}::${myparent.name}`;
@ -2520,11 +2522,11 @@ class DocSearch {
whereClause.set(fnParamNames[-1 - fnType.id], where);
}
} else {
if (fnType.ty === TY_PRIMITIVE) {
if (fnType.ty === itemTypes.primitive) {
if (await writeSpecialPrimitive(fnType, result)) {
return;
}
} else if (fnType.ty === TY_TRAIT && (
} else if (fnType.ty === itemTypes.trait && (
fnType.id === typeNameIds.typeNameIdOfFn ||
fnType.id === typeNameIds.typeNameIdOfFnMut ||
fnType.id === typeNameIds.typeNameIdOfFnOnce ||
@ -2691,8 +2693,8 @@ class DocSearch {
// unlike other items, methods have a different ty when they are
// in an impl block vs a trait. want to normalize this away.
let ty = obj.item.ty;
if (ty === TY_TYMETHOD) {
ty = TY_METHOD;
if (ty === itemTypes.tymethod) {
ty = itemTypes.method;
}
// To be sure than it some items aren't considered as duplicate.
obj.fullPath = res[2] + "|" + ty;
@ -2714,10 +2716,10 @@ class DocSearch {
// Exports are specifically not shown if the items they point at
// are already in the results.
if (obj.item.ty === TY_IMPORT && duplicates.has(res[2])) {
if (obj.item.ty === itemTypes.import && duplicates.has(res[2])) {
continue;
}
if (duplicates.has(res[2] + "|" + TY_IMPORT)) {
if (duplicates.has(res[2] + "|" + itemTypes.import)) {
continue;
}
duplicates.add(obj.fullPath);
@ -3894,24 +3896,8 @@ class DocSearch {
if (filter <= NO_TYPE_FILTER || filter === type) return true;
// Match related items
const name = itemTypes[type];
switch (itemTypes[filter]) {
case "constant":
return name === "associatedconstant";
case "fn":
return name === "method" || name === "tymethod";
case "type":
return name === "primitive" || name === "associatedtype";
case "trait":
return name === "traitalias";
case "macro":
return name === "attr" || name === "derive";
case "import":
return name === "externcrate";
}
// No match
return false;
// @ts-expect-error
return filter === itemParents.get(type);
}
const innerRunNameQuery =
@ -4246,7 +4232,7 @@ class DocSearch {
* ]>[]}
* */
const typePromises = [];
if (typeFilter !== TY_GENERIC && searchResults) {
if (typeFilter !== itemTypes.generic && searchResults) {
for (const id of searchResults.matches().entries()) {
typePromises.push(Promise.all([
this.getName(id),
@ -4262,7 +4248,7 @@ class DocSearch {
ty && !ty[polarity].every(bitmap => {
return bitmap.isEmpty();
}) &&
path && path.ty !== TY_ASSOCTYPE &&
path && path.ty !== itemTypes.associatedtype &&
(elem.pathWithoutLast.length === 0 ||
checkPath(
elem.pathWithoutLast,
@ -4270,14 +4256,14 @@ class DocSearch {
) === 0),
);
if (types.length === 0) {
const areGenericsAllowed = typeFilter === TY_GENERIC || (
const areGenericsAllowed = typeFilter === itemTypes.generic || (
typeFilter === -1 &&
(parsedQuery.totalElems > 1 || parsedQuery.hasReturnArrow) &&
elem.pathWithoutLast.length === 0 &&
elem.generics.length === 0 &&
elem.bindings.size === 0
);
if (typeFilter !== TY_GENERIC &&
if (typeFilter !== itemTypes.generic &&
(elem.name.length >= 3 || !areGenericsAllowed)
) {
/** @type {string|null} */
@ -4301,7 +4287,7 @@ class DocSearch {
!ty[polarity].every(bitmap => {
return bitmap.isEmpty();
}) &&
path.ty !== TY_ASSOCTYPE
path.ty !== itemTypes.associatedtype
) {
let dist = editDistance(
name,
@ -4363,7 +4349,7 @@ class DocSearch {
queryElem: {
name: elem.name,
id: (-genericId) - 1,
typeFilter: TY_GENERIC,
typeFilter: itemTypes.generic,
generics: [],
bindings: EMPTY_BINDINGS_MAP,
fullPath: elem.fullPath,
@ -4930,7 +4916,7 @@ async function addTab(results, query, display, finishedCallback, isTypeSearch) {
count += 1;
const name = obj.item.name;
const type = itemTypes[obj.item.ty];
const type = itemTypesName[obj.item.ty];
const longType = longItemTypes[obj.item.ty];
const typeName = longType.length !== 0 ? `${longType}` : "?";

View file

@ -220,7 +220,6 @@ degree documented below):
- `solaris` / `illumos`: maintained by @devnexen. Supports the entire test suite.
- `freebsd`: maintained by @YohDeadfall and @LorrensP-2158466. Supports the entire test suite.
- `android`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works.
- `wasi`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works.
- For targets on other operating systems, Miri might fail before even reaching the `main` function.
However, even for targets that we do support, the degree of support for accessing platform APIs

View file

@ -153,7 +153,6 @@ case $HOST_TARGET in
BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator
UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency epoll eventfd
TEST_TARGET=wasm32-wasip2 run_tests_minimal $BASIC hello wasm
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std
;;

View file

@ -26,9 +26,9 @@ mod downloading {
use super::GENMC_DOWNLOAD_PATH;
/// The GenMC repository the we get our commit from.
pub(crate) const GENMC_GITHUB_URL: &str = "https://gitlab.inf.ethz.ch/public-plf/genmc.git";
pub(crate) const GENMC_GITHUB_URL: &str = "https://github.com/MPI-SWS/genmc.git";
/// The GenMC commit we depend on. It must be available on the specified GenMC repository.
pub(crate) const GENMC_COMMIT: &str = "ce775ccd7866db820fa12ffca66463087a11dd96";
pub(crate) const GENMC_COMMIT: &str = "d9527280bb99f1cef64326b1803ffd952e3880df";
/// Ensure that a local GenMC repo is present and set to the correct commit.
/// Return the path of the GenMC repo and whether the checked out commit was changed.

View file

@ -261,7 +261,7 @@ namespace GenmcScalarExt {
inline GenmcScalar uninit() {
return GenmcScalar {
.value = 0,
.extra = 0,
.provenance = 0,
.is_init = false,
};
}
@ -269,19 +269,19 @@ inline GenmcScalar uninit() {
inline GenmcScalar from_sval(SVal sval) {
return GenmcScalar {
.value = sval.get(),
.extra = sval.getExtra(),
.provenance = sval.getProvenance(),
.is_init = true,
};
}
inline SVal to_sval(GenmcScalar scalar) {
ERROR_ON(!scalar.is_init, "Cannot convert an uninitialized `GenmcScalar` into an `SVal`\n");
return SVal(scalar.value, scalar.extra);
return SVal(scalar.value, scalar.provenance);
}
inline std::optional<SVal> try_to_sval(GenmcScalar scalar) {
if (scalar.is_init)
return { SVal(scalar.value, scalar.extra) };
return { SVal(scalar.value, scalar.provenance) };
return std::nullopt;
}
} // namespace GenmcScalarExt

View file

@ -45,14 +45,14 @@ pub fn create_genmc_driver_handle(
}
impl GenmcScalar {
pub const UNINIT: Self = Self { value: 0, extra: 0, is_init: false };
pub const UNINIT: Self = Self { value: 0, provenance: 0, is_init: false };
pub const fn from_u64(value: u64) -> Self {
Self { value, extra: 0, is_init: true }
Self { value, provenance: 0, is_init: true }
}
pub const fn has_provenance(&self) -> bool {
self.extra != 0
self.provenance != 0
}
}
@ -172,8 +172,9 @@ mod ffi {
value: u64,
/// This is zero for integer values. For pointers, this encodes the provenance by
/// storing the base address of the allocation that this pointer belongs to.
/// Operations on `SVal` in GenMC (e.g., `fetch_add`) preserve the `extra` of the left argument (`left.fetch_add(right, ...)`).
extra: u64,
/// Operations on `SVal` in GenMC (e.g., `fetch_add`) preserve the `provenance` of the left
/// argument (`left.fetch_add(right, ...)`).
provenance: u64,
/// Indicates whether this value is initialized. If this is `false`, the other fields do not matter.
/// (Ideally we'd use `std::optional` but CXX does not support that.)
is_init: bool,

View file

@ -1 +1 @@
292be5c7c05138d753bbd4b30db7a3f1a5c914f7
5f9dd05862d2e4bceb3be1031b6c936e35671501

View file

@ -640,7 +640,7 @@ mod propagation_optimization_checks {
impl Exhaustive for AccessRelatedness {
fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
use AccessRelatedness::*;
Box::new(vec![This, StrictChildAccess, AncestorAccess, CousinAccess].into_iter())
Box::new(vec![ForeignAccess, LocalAccess].into_iter())
}
}
@ -716,13 +716,11 @@ mod propagation_optimization_checks {
// We now assert it is idempotent, and never causes UB.
// First, if the SIFA includes foreign reads, assert it is idempotent under foreign reads.
if access >= IdempotentForeignAccess::Read {
// We use `CousinAccess` here. We could also use `AncestorAccess`, since `transition::perform_access` treats these the same.
// The only place they are treated differently is in protector end accesses, but these are not handled here.
assert_eq!(perm, transition::perform_access(AccessKind::Read, AccessRelatedness::CousinAccess, perm, prot).unwrap());
assert_eq!(perm, transition::perform_access(AccessKind::Read, AccessRelatedness::ForeignAccess, perm, prot).unwrap());
}
// Then, if the SIFA includes foreign writes, assert it is idempotent under foreign writes.
if access >= IdempotentForeignAccess::Write {
assert_eq!(perm, transition::perform_access(AccessKind::Write, AccessRelatedness::CousinAccess, perm, prot).unwrap());
assert_eq!(perm, transition::perform_access(AccessKind::Write, AccessRelatedness::ForeignAccess, perm, prot).unwrap());
}
}
}

View file

@ -24,7 +24,7 @@ use crate::borrow_tracker::tree_borrows::diagnostics::{
};
use crate::borrow_tracker::tree_borrows::foreign_access_skipping::IdempotentForeignAccess;
use crate::borrow_tracker::tree_borrows::perms::PermTransition;
use crate::borrow_tracker::tree_borrows::unimap::{UniEntry, UniIndex, UniKeyMap, UniValMap};
use crate::borrow_tracker::tree_borrows::unimap::{UniIndex, UniKeyMap, UniValMap};
use crate::borrow_tracker::{GlobalState, ProtectorKind};
use crate::*;
@ -265,13 +265,15 @@ pub(super) struct Node {
}
/// Data given to the transition function
struct NodeAppArgs<'node> {
/// Node on which the transition is currently being applied
node: &'node mut Node,
/// Mutable access to its permissions
perm: UniEntry<'node, LocationState>,
/// Relative position of the access
struct NodeAppArgs<'visit> {
/// The index of the current node.
idx: UniIndex,
/// Relative position of the access.
rel_pos: AccessRelatedness,
/// The node map of this tree.
nodes: &'visit mut UniValMap<Node>,
/// The permissions map of this tree.
perms: &'visit mut UniValMap<LocationState>,
}
/// Data given to the error handler
struct ErrHandlerArgs<'node, InErr> {
@ -348,8 +350,7 @@ where
idx: UniIndex,
rel_pos: AccessRelatedness,
) -> ContinueTraversal {
let node = this.nodes.get_mut(idx).unwrap();
let args = NodeAppArgs { node, perm: this.perms.entry(idx), rel_pos };
let args = NodeAppArgs { idx, rel_pos, nodes: this.nodes, perms: this.perms };
(self.f_continue)(&args)
}
@ -359,16 +360,14 @@ where
idx: UniIndex,
rel_pos: AccessRelatedness,
) -> Result<(), OutErr> {
let node = this.nodes.get_mut(idx).unwrap();
(self.f_propagate)(NodeAppArgs { node, perm: this.perms.entry(idx), rel_pos }).map_err(
|error_kind| {
(self.f_propagate)(NodeAppArgs { idx, rel_pos, nodes: this.nodes, perms: this.perms })
.map_err(|error_kind| {
(self.err_builder)(ErrHandlerArgs {
error_kind,
conflicting_info: &this.nodes.get(idx).unwrap().debug_info,
accessed_info: &this.nodes.get(self.initial).unwrap().debug_info,
})
},
)
})
}
fn go_upwards_from_accessed(
@ -386,14 +385,14 @@ where
// be handled differently here compared to the further parents
// of `accesssed_node`.
{
self.propagate_at(this, accessed_node, AccessRelatedness::This)?;
self.propagate_at(this, accessed_node, AccessRelatedness::LocalAccess)?;
if matches!(visit_children, ChildrenVisitMode::VisitChildrenOfAccessed) {
let accessed_node = this.nodes.get(accessed_node).unwrap();
// We `rev()` here because we reverse the entire stack later.
for &child in accessed_node.children.iter().rev() {
self.stack.push((
child,
AccessRelatedness::AncestorAccess,
AccessRelatedness::ForeignAccess,
RecursionState::BeforeChildren,
));
}
@ -404,7 +403,7 @@ where
// not the subtree that contains the accessed node.
let mut last_node = accessed_node;
while let Some(current) = this.nodes.get(last_node).unwrap().parent {
self.propagate_at(this, current, AccessRelatedness::StrictChildAccess)?;
self.propagate_at(this, current, AccessRelatedness::LocalAccess)?;
let node = this.nodes.get(current).unwrap();
// We `rev()` here because we reverse the entire stack later.
for &child in node.children.iter().rev() {
@ -413,7 +412,7 @@ where
}
self.stack.push((
child,
AccessRelatedness::CousinAccess,
AccessRelatedness::ForeignAccess,
RecursionState::BeforeChildren,
));
}
@ -741,7 +740,9 @@ impl<'tcx> Tree {
// visit all children, skipping none
|_| ContinueTraversal::Recurse,
|args: NodeAppArgs<'_>| -> Result<(), TransitionError> {
let NodeAppArgs { node, perm, .. } = args;
let node = args.nodes.get(args.idx).unwrap();
let perm = args.perms.entry(args.idx);
let perm =
perm.get().copied().unwrap_or_else(|| node.default_location_state());
if global.borrow().protected_tags.get(&node.tag)
@ -812,32 +813,34 @@ impl<'tcx> Tree {
// `perms_range` is only for diagnostics (it is the range of
// the `RangeMap` on which we are currently working).
let node_skipper = |access_kind: AccessKind, args: &NodeAppArgs<'_>| -> ContinueTraversal {
let NodeAppArgs { node, perm, rel_pos } = args;
let node = args.nodes.get(args.idx).unwrap();
let perm = args.perms.get(args.idx);
let old_state = perm.get().copied().unwrap_or_else(|| node.default_location_state());
old_state.skip_if_known_noop(access_kind, *rel_pos)
let old_state = perm.copied().unwrap_or_else(|| node.default_location_state());
old_state.skip_if_known_noop(access_kind, args.rel_pos)
};
let node_app = |perms_range: Range<u64>,
access_kind: AccessKind,
access_cause: diagnostics::AccessCause,
args: NodeAppArgs<'_>|
-> Result<(), TransitionError> {
let NodeAppArgs { node, mut perm, rel_pos } = args;
let node = args.nodes.get_mut(args.idx).unwrap();
let mut perm = args.perms.entry(args.idx);
let old_state = perm.or_insert(node.default_location_state());
// Call this function now, which ensures it is only called when
// `skip_if_known_noop` returns `Recurse`, due to the contract of
// `traverse_this_parents_children_other`.
old_state.record_new_access(access_kind, rel_pos);
old_state.record_new_access(access_kind, args.rel_pos);
let protected = global.borrow().protected_tags.contains_key(&node.tag);
let transition = old_state.perform_access(access_kind, rel_pos, protected)?;
let transition = old_state.perform_access(access_kind, args.rel_pos, protected)?;
// Record the event as part of the history
if !transition.is_noop() {
node.debug_info.history.push(diagnostics::Event {
transition,
is_foreign: rel_pos.is_foreign(),
is_foreign: args.rel_pos.is_foreign(),
access_cause,
access_range: access_range_and_kind.map(|x| x.0),
transition_range: perms_range,
@ -1075,24 +1078,18 @@ impl VisitProvenance for Tree {
/// Relative position of the access
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AccessRelatedness {
/// The accessed pointer is the current one
This,
/// The accessed pointer is a (transitive) child of the current one.
// Current pointer is excluded (unlike in some other places of this module
// where "child" is inclusive).
StrictChildAccess,
/// The accessed pointer is a (transitive) parent of the current one.
// Current pointer is excluded.
AncestorAccess,
/// The accessed pointer is neither of the above.
// It's a cousin/uncle/etc., something in a side branch.
CousinAccess,
/// The access happened either through the node itself or one of
/// its transitive children.
LocalAccess,
/// The access happened through this nodes ancestor or through
/// a sibling/cousin/uncle/etc.
ForeignAccess,
}
impl AccessRelatedness {
/// Check that access is either Ancestor or Distant, i.e. not
/// a transitive child (initial pointer included).
pub fn is_foreign(self) -> bool {
matches!(self, AccessRelatedness::AncestorAccess | AccessRelatedness::CousinAccess)
matches!(self, AccessRelatedness::ForeignAccess)
}
}

View file

@ -263,15 +263,15 @@ mod spurious_read {
match xy_rel {
RelPosXY::MutuallyForeign =>
match self {
PtrSelector::X => (This, CousinAccess),
PtrSelector::Y => (CousinAccess, This),
PtrSelector::Other => (CousinAccess, CousinAccess),
PtrSelector::X => (LocalAccess, ForeignAccess),
PtrSelector::Y => (ForeignAccess, LocalAccess),
PtrSelector::Other => (ForeignAccess, ForeignAccess),
},
RelPosXY::XChildY =>
match self {
PtrSelector::X => (This, StrictChildAccess),
PtrSelector::Y => (AncestorAccess, This),
PtrSelector::Other => (CousinAccess, CousinAccess),
PtrSelector::X => (LocalAccess, LocalAccess),
PtrSelector::Y => (ForeignAccess, LocalAccess),
PtrSelector::Other => (ForeignAccess, ForeignAccess),
},
}
}

View file

@ -55,7 +55,7 @@ pub fn scalar_to_genmc_scalar<'tcx>(
rustc_const_eval::interpret::Scalar::Int(scalar_int) => {
// FIXME(genmc): Add u128 support once GenMC supports it.
let value: u64 = scalar_int.to_uint(scalar_int.size()).try_into().unwrap();
GenmcScalar { value, extra: 0, is_init: true }
GenmcScalar { value, provenance: 0, is_init: true }
}
rustc_const_eval::interpret::Scalar::Ptr(pointer, size) => {
// FIXME(genmc,borrow tracking): Borrow tracking information is lost.
@ -69,7 +69,7 @@ pub fn scalar_to_genmc_scalar<'tcx>(
let base_addr = ecx.addr_from_alloc_id(alloc_id, None)?;
// Add the base_addr alloc_id pair to the map.
genmc_ctx.exec_state.genmc_shared_allocs_map.borrow_mut().insert(base_addr, alloc_id);
GenmcScalar { value: addr.bytes(), extra: base_addr, is_init: true }
GenmcScalar { value: addr.bytes(), provenance: base_addr, is_init: true }
}
})
}
@ -84,16 +84,17 @@ pub fn genmc_scalar_to_scalar<'tcx>(
scalar: GenmcScalar,
size: Size,
) -> InterpResult<'tcx, Scalar> {
// If `extra` is zero, we have a regular integer.
if scalar.extra == 0 {
// If `provenance` is zero, we have a regular integer.
if scalar.provenance == 0 {
// NOTE: GenMC always returns 64 bit values, and the upper bits are not yet truncated.
// FIXME(genmc): GenMC should be doing the truncation, not Miri.
let (value_scalar_int, _got_truncated) = ScalarInt::truncate_from_uint(scalar.value, size);
return interp_ok(Scalar::from(value_scalar_int));
}
// `extra` is non-zero, we have a pointer.
// When we get a pointer from GenMC, then we must have sent it to GenMC before in the same execution (since the reads-from relation is always respected).
let alloc_id = genmc_ctx.exec_state.genmc_shared_allocs_map.borrow()[&scalar.extra];
// `provenance` is non-zero, we have a pointer.
// When we get a pointer from GenMC, then we must have sent it to GenMC before in the same
// execution (since the reads-from relation is always respected).
let alloc_id = genmc_ctx.exec_state.genmc_shared_allocs_map.borrow()[&scalar.provenance];
// FIXME(genmc,borrow tracking): Borrow tracking not yet supported.
let provenance = machine::Provenance::Concrete { alloc_id, tag: BorTag::default() };
let ptr = interpret::Pointer::new(provenance, Size::from_bytes(scalar.value));

View file

@ -181,7 +181,6 @@ pub struct Thread<'tcx> {
/// The index of the topmost user-relevant frame in `stack`. This field must contain
/// the value produced by `get_top_user_relevant_frame`.
/// The `None` state here represents
/// This field is a cache to reduce how often we call that method. The cache is manually
/// maintained inside `MiriMachine::after_stack_push` and `MiriMachine::after_stack_pop`.
top_user_relevant_frame: Option<usize>,
@ -232,12 +231,21 @@ impl<'tcx> Thread<'tcx> {
/// justifying the optimization that only pushes of user-relevant frames require updating the
/// `top_user_relevant_frame` field.
fn compute_top_user_relevant_frame(&self, skip: usize) -> Option<usize> {
self.stack
.iter()
.enumerate()
.rev()
.skip(skip)
.find_map(|(idx, frame)| if frame.extra.is_user_relevant { Some(idx) } else { None })
// We are search for the frame with maximum relevance.
let mut best = None;
for (idx, frame) in self.stack.iter().enumerate().rev().skip(skip) {
let relevance = frame.extra.user_relevance;
if relevance == u8::MAX {
// We can short-circuit this search.
return Some(idx);
}
if best.is_none_or(|(_best_idx, best_relevance)| best_relevance < relevance) {
// The previous best frame has strictly worse relevance, so despite us being lower
// in the stack, we win.
best = Some((idx, relevance));
}
}
best.map(|(idx, _relevance)| idx)
}
/// Re-compute the top user-relevant frame from scratch. `skip` indicates how many top frames
@ -256,14 +264,20 @@ impl<'tcx> Thread<'tcx> {
/// Returns the topmost frame that is considered user-relevant, or the
/// top of the stack if there is no such frame, or `None` if the stack is empty.
pub fn top_user_relevant_frame(&self) -> Option<usize> {
debug_assert_eq!(self.top_user_relevant_frame, self.compute_top_user_relevant_frame(0));
// This can be called upon creation of an allocation. We create allocations while setting up
// parts of the Rust runtime when we do not have any stack frames yet, so we need to handle
// empty stacks.
self.top_user_relevant_frame.or_else(|| self.stack.len().checked_sub(1))
}
pub fn current_user_relevance(&self) -> u8 {
self.top_user_relevant_frame()
.map(|frame_idx| self.stack[frame_idx].extra.user_relevance)
.unwrap_or(0)
}
pub fn current_user_relevant_span(&self) -> Span {
debug_assert_eq!(self.top_user_relevant_frame, self.compute_top_user_relevant_frame(0));
self.top_user_relevant_frame()
.map(|frame_idx| self.stack[frame_idx].current_span())
.unwrap_or(rustc_span::DUMMY_SP)

View file

@ -187,16 +187,14 @@ pub fn prune_stacktrace<'tcx>(
}
BacktraceStyle::Short => {
let original_len = stacktrace.len();
// Only prune frames if there is at least one local frame. This check ensures that if
// we get a backtrace that never makes it to the user code because it has detected a
// bug in the Rust runtime, we don't prune away every frame.
let has_local_frame = stacktrace.iter().any(|frame| machine.is_local(frame));
// Remove all frames marked with `caller_location` -- that attribute indicates we
// usually want to point at the caller, not them.
stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(machine.tcx));
// Only prune further frames if there is at least one local frame. This check ensures
// that if we get a backtrace that never makes it to the user code because it has
// detected a bug in the Rust runtime, we don't prune away every frame.
let has_local_frame = stacktrace.iter().any(|frame| machine.is_local(frame.instance));
if has_local_frame {
// Remove all frames marked with `caller_location` -- that attribute indicates we
// usually want to point at the caller, not them.
stacktrace
.retain(|frame| !frame.instance.def.requires_caller_location(machine.tcx));
// This is part of the logic that `std` uses to select the relevant part of a
// backtrace. But here, we only look for __rust_begin_short_backtrace, not
// __rust_end_short_backtrace because the end symbol comes from a call to the default
@ -216,7 +214,7 @@ pub fn prune_stacktrace<'tcx>(
// This len check ensures that we don't somehow remove every frame, as doing so breaks
// the primary error message.
while stacktrace.len() > 1
&& stacktrace.last().is_some_and(|frame| !machine.is_local(frame))
&& stacktrace.last().is_some_and(|frame| !machine.is_local(frame.instance))
{
stacktrace.pop();
}
@ -619,7 +617,7 @@ pub fn report_msg<'tcx>(
write!(backtrace_title, ":").unwrap();
err.note(backtrace_title);
for (idx, frame_info) in stacktrace.iter().enumerate() {
let is_local = machine.is_local(frame_info);
let is_local = machine.is_local(frame_info.instance);
// No span for non-local frames and the first frame (which is the error site).
if is_local && idx > 0 {
err.subdiagnostic(frame_info.as_note(machine.tcx));

View file

@ -1088,11 +1088,18 @@ impl<'tcx> MiriMachine<'tcx> {
self.threads.active_thread_ref().top_user_relevant_frame()
}
/// This is the source of truth for the `is_user_relevant` flag in our `FrameExtra`.
pub fn is_user_relevant(&self, frame: &Frame<'tcx, Provenance>) -> bool {
let def_id = frame.instance().def_id();
(def_id.is_local() || self.user_relevant_crates.contains(&def_id.krate))
&& !frame.instance().def.requires_caller_location(self.tcx)
/// This is the source of truth for the `user_relevance` flag in our `FrameExtra`.
pub fn user_relevance(&self, frame: &Frame<'tcx, Provenance>) -> u8 {
if frame.instance().def.requires_caller_location(self.tcx) {
return 0;
}
if self.is_local(frame.instance()) {
u8::MAX
} else {
// A non-relevant frame, but at least it doesn't require a caller location, so
// better than nothing.
1
}
}
}

View file

@ -140,11 +140,10 @@ pub struct FrameExtra<'tcx> {
/// we use this to register a completed event with `measureme`.
pub timing: Option<measureme::DetachedTiming>,
/// Indicates whether a `Frame` is part of a workspace-local crate and is also not
/// `#[track_caller]`. We compute this once on creation and store the result, as an
/// optimization.
/// This is used by `MiriMachine::current_span` and `MiriMachine::caller_span`
pub is_user_relevant: bool,
/// Indicates how user-relevant this frame is. `#[track_caller]` frames are never relevant.
/// Frames from user-relevant crates are maximally relevant; frames from other crates are less
/// relevant.
pub user_relevance: u8,
/// Data race detector per-frame data.
pub data_race: Option<data_race::FrameState>,
@ -153,12 +152,12 @@ pub struct FrameExtra<'tcx> {
impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// Omitting `timing`, it does not support `Debug`.
let FrameExtra { borrow_tracker, catch_unwind, timing: _, is_user_relevant, data_race } =
let FrameExtra { borrow_tracker, catch_unwind, timing: _, user_relevance, data_race } =
self;
f.debug_struct("FrameData")
.field("borrow_tracker", borrow_tracker)
.field("catch_unwind", catch_unwind)
.field("is_user_relevant", is_user_relevant)
.field("user_relevance", user_relevance)
.field("data_race", data_race)
.finish()
}
@ -166,13 +165,8 @@ impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> {
impl VisitProvenance for FrameExtra<'_> {
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
let FrameExtra {
catch_unwind,
borrow_tracker,
timing: _,
is_user_relevant: _,
data_race: _,
} = self;
let FrameExtra { catch_unwind, borrow_tracker, timing: _, user_relevance: _, data_race: _ } =
self;
catch_unwind.visit_provenance(visit);
borrow_tracker.visit_provenance(visit);
@ -911,8 +905,8 @@ impl<'tcx> MiriMachine<'tcx> {
}
/// Check whether the stack frame that this `FrameInfo` refers to is part of a local crate.
pub(crate) fn is_local(&self, frame: &FrameInfo<'_>) -> bool {
let def_id = frame.instance.def_id();
pub(crate) fn is_local(&self, instance: ty::Instance<'tcx>) -> bool {
let def_id = instance.def_id();
def_id.is_local() || self.user_relevant_crates.contains(&def_id.krate)
}
@ -1703,7 +1697,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
borrow_tracker: borrow_tracker.map(|bt| bt.borrow_mut().new_frame()),
catch_unwind: None,
timing,
is_user_relevant: ecx.machine.is_user_relevant(&frame),
user_relevance: ecx.machine.user_relevance(&frame),
data_race: ecx
.machine
.data_race
@ -1759,9 +1753,9 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
#[inline(always)]
fn after_stack_push(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {
if ecx.frame().extra.is_user_relevant {
// We just pushed a local frame, so we know that the topmost local frame is the topmost
// frame. If we push a non-local frame, there's no need to do anything.
if ecx.frame().extra.user_relevance >= ecx.active_thread_ref().current_user_relevance() {
// We just pushed a frame that's at least as relevant as the so-far most relevant frame.
// That means we are now the most relevant frame.
let stack_len = ecx.active_thread_stack().len();
ecx.active_thread_mut().set_top_user_relevant_frame(stack_len - 1);
}
@ -1775,9 +1769,14 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
if ecx.machine.borrow_tracker.is_some() {
ecx.on_stack_pop(frame)?;
}
if frame.extra.is_user_relevant {
// All that we store is whether or not the frame we just removed is local, so now we
// have no idea where the next topmost local frame is. So we recompute it.
if ecx
.active_thread_ref()
.top_user_relevant_frame()
.expect("there should always be a most relevant frame for a non-empty stack")
== ecx.frame_idx()
{
// We are popping the most relevant frame. We have no clue what the next relevant frame
// below that is, so we recompute that.
// (If this ever becomes a bottleneck, we could have `push` store the previous
// user-relevant frame and restore that here.)
// We have to skip the frame that is just being popped.

View file

@ -51,7 +51,7 @@ impl<'tcx> EnvVars<'tcx> {
} else if ecx.tcx.sess.target.os == "windows" {
EnvVars::Windows(WindowsEnvVars::new(ecx, env_vars)?)
} else {
// Used e.g. for wasi
// For "none" targets (i.e., without an OS).
EnvVars::Uninit
};
ecx.machine.env_vars = env_vars;

View file

@ -103,7 +103,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let this = self.eval_context_ref();
match this.tcx.sess.target.os.as_ref() {
os if this.target_os_is_unix() => shims::unix::foreign_items::is_dyn_sym(name, os),
"wasi" => shims::wasi::foreign_items::is_dyn_sym(name),
"windows" => shims::windows::foreign_items::is_dyn_sym(name),
_ => false,
}
@ -851,10 +850,6 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_inner(
this, link_name, abi, args, dest,
),
"wasi" =>
shims::wasi::foreign_items::EvalContextExt::emulate_foreign_item_inner(
this, link_name, abi, args, dest,
),
"windows" =>
shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_inner(
this, link_name, abi, args, dest,

View file

@ -8,7 +8,6 @@ mod math;
#[cfg(all(unix, feature = "native-lib"))]
mod native_lib;
mod unix;
mod wasi;
mod windows;
mod x86;

View file

@ -253,7 +253,6 @@ impl<'tcx> TlsDtorsState<'tcx> {
}
_ => {
// No TLS dtor support.
// FIXME: should we do something on wasi?
break 'new_state Done;
}
}

View file

@ -1,110 +0,0 @@
use rustc_abi::CanonAbi;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::FnAbi;
use crate::shims::alloc::EvalContextExt as _;
use crate::*;
pub fn is_dyn_sym(_name: &str) -> bool {
false
}
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner(
&mut self,
link_name: Symbol,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
let this = self.eval_context_mut();
match link_name.as_str() {
// Allocation
"posix_memalign" => {
let [memptr, align, size] =
this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
let result = this.posix_memalign(memptr, align, size)?;
this.write_scalar(result, dest)?;
}
"aligned_alloc" => {
let [align, size] =
this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
let res = this.aligned_alloc(align, size)?;
this.write_pointer(res, dest)?;
}
// Standard input/output
// FIXME: These shims are hacks that just get basic stdout/stderr working. We can't
// constrain them to "std" since std itself uses the wasi crate for this.
"get-stdout" => {
let [] =
this.check_shim_sig(shim_sig!(extern "C" fn() -> i32), link_name, abi, args)?;
this.write_scalar(Scalar::from_i32(1), dest)?; // POSIX FD number for stdout
}
"get-stderr" => {
let [] =
this.check_shim_sig(shim_sig!(extern "C" fn() -> i32), link_name, abi, args)?;
this.write_scalar(Scalar::from_i32(2), dest)?; // POSIX FD number for stderr
}
"[resource-drop]output-stream" => {
let [handle] =
this.check_shim_sig(shim_sig!(extern "C" fn(i32) -> ()), link_name, abi, args)?;
let handle = this.read_scalar(handle)?.to_i32()?;
if !(handle == 1 || handle == 2) {
throw_unsup_format!("wasm output-stream: unsupported handle");
}
// We don't actually close these FDs, so this is a NOP.
}
"[method]output-stream.blocking-write-and-flush" => {
let [handle, buf, len, ret_area] = this.check_shim_sig(
shim_sig!(extern "C" fn(i32, *mut _, usize, *mut _) -> ()),
link_name,
abi,
args,
)?;
let handle = this.read_scalar(handle)?.to_i32()?;
let buf = this.read_pointer(buf)?;
let len = this.read_target_usize(len)?;
let ret_area = this.read_pointer(ret_area)?;
if len > 4096 {
throw_unsup_format!(
"wasm output-stream.blocking-write-and-flush: buffer too big"
);
}
let len = usize::try_from(len).unwrap();
let Some(fd) = this.machine.fds.get(handle) else {
throw_unsup_format!(
"wasm output-stream.blocking-write-and-flush: unsupported handle"
);
};
fd.write(
this.machine.communicate(),
buf,
len,
this,
callback!(
@capture<'tcx> {
len: usize,
ret_area: Pointer,
}
|this, result: Result<usize, IoError>| {
if !matches!(result, Ok(l) if l == len) {
throw_unsup_format!("wasm output-stream.blocking-write-and-flush: returning errors is not supported");
}
// 0 in the first byte of the ret_area indicates success.
let ret = this.ptr_to_mplace(ret_area, this.machine.layouts.u8);
this.write_null(&ret)?;
interp_ok(())
}),
)?;
}
_ => return interp_ok(EmulateItemResult::NotSupported),
}
interp_ok(EmulateItemResult::NeedsReturn)
}
}

View file

@ -1 +0,0 @@
pub mod foreign_items;

View file

@ -4,5 +4,6 @@ ow
fatal runtime error: thread local panicked on drop, aborting
error: abnormal termination: the program aborted execution
error: aborting due to 1 previous error

View file

@ -1,9 +1,9 @@
Running GenMC Verification...
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
--> RUSTLIB/std/src/thread/mod.rs:LL:CC
|
LL | intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC
@ -91,19 +91,34 @@ LL | handle.join().unwrap();
| ^^^^^^^^^^^^^
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
--> RUSTLIB/std/src/rt.rs:LL:CC
|
LL | intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | / CLEANUP.call_once(|| unsafe {
LL | | // Flush stdout and disable buffering.
LL | | crate::io::cleanup();
... |
LL | | });
| |______^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/std/src/sync/once.rs:LL:CC
|
LL | intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | self.inner.call(true, &mut |p| f.take().unwrap()(p));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access.
--> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC
|
LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC

View file

@ -1,9 +1,9 @@
Running GenMC Verification...
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
--> RUSTLIB/std/src/thread/mod.rs:LL:CC
|
LL | intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC
@ -91,19 +91,34 @@ LL | handle.join().unwrap();
| ^^^^^^^^^^^^^
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
--> RUSTLIB/std/src/rt.rs:LL:CC
|
LL | intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | / CLEANUP.call_once(|| unsafe {
LL | | // Flush stdout and disable buffering.
LL | | crate::io::cleanup();
... |
LL | | });
| |______^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/std/src/sync/once.rs:LL:CC
|
LL | intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | self.inner.call(true, &mut |p| f.take().unwrap()(p));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access.
--> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC
|
LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC

View file

@ -1,28 +1,43 @@
Running GenMC Verification...
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
--> RUSTLIB/std/src/thread/mod.rs:LL:CC
|
LL | intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
--> RUSTLIB/std/src/rt.rs:LL:CC
|
LL | intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | / CLEANUP.call_once(|| unsafe {
LL | | // Flush stdout and disable buffering.
LL | | crate::io::cleanup();
... |
LL | | });
| |______^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/std/src/sync/once.rs:LL:CC
|
LL | intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | self.inner.call(true, &mut |p| f.take().unwrap()(p));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access.
--> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC
|
LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC

View file

@ -1,9 +1,9 @@
Running GenMC Verification...
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
--> RUSTLIB/std/src/thread/mod.rs:LL:CC
|
LL | intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC
@ -95,19 +95,34 @@ LL | handles.into_iter().for_each(|handle| handle.join().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
--> RUSTLIB/std/src/rt.rs:LL:CC
|
LL | intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | / CLEANUP.call_once(|| unsafe {
LL | | // Flush stdout and disable buffering.
LL | | crate::io::cleanup();
... |
LL | | });
| |______^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/std/src/sync/once.rs:LL:CC
|
LL | intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | self.inner.call(true, &mut |p| f.take().unwrap()(p));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access.
--> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC
|
LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC

View file

@ -1,9 +1,9 @@
Running GenMC Verification...
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
--> RUSTLIB/std/src/thread/mod.rs:LL:CC
|
LL | intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC
@ -78,19 +78,34 @@ LL | handles.into_iter().for_each(|handle| handle.join().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
--> RUSTLIB/std/src/rt.rs:LL:CC
|
LL | intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | / CLEANUP.call_once(|| unsafe {
LL | | // Flush stdout and disable buffering.
LL | | crate::io::cleanup();
... |
LL | | });
| |______^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access.
--> RUSTLIB/core/src/sync/atomic.rs:LL:CC
warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures.
--> RUSTLIB/std/src/sync/once.rs:LL:CC
|
LL | intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
LL | self.inner.call(true, &mut |p| f.take().unwrap()(p));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access.
--> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC
|
LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code
|
= note: BACKTRACE:
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC

View file

@ -11,25 +11,27 @@ use std::arch::x86_64::*;
use std::collections::HashSet;
fn main() {
let a = unsafe { _mm_setr_ps(4.0, 4.0, 4.0, 4.0) };
let exact = 0.5;
// max error: 2^-12.
let rel_error_bound = 1.0 / (1 << 12) as f32;
let mut vals = HashSet::new();
for _ in 0..50 {
unsafe {
// Compute the inverse square root of 4.0, four times.
let a = _mm_setr_ps(4.0, 4.0, 4.0, 4.0);
let exact = 0.5;
let r = _mm_rsqrt_ps(a);
let r: [f32; 4] = std::mem::transmute(r);
// Check the results.
for r in r {
vals.insert(r.to_bits());
// Ensure the relative error is less than 2^-12.
let rel_error = (r - exact) / exact;
let log_error = rel_error.abs().log2();
assert!(
rel_error == 0.0 || log_error < -12.0,
"got an error of {rel_error} = 2^{log_error}"
);
}
// Compute the inverse square root of 4.0, four times.
let r = unsafe { _mm_rsqrt_ps(a) };
let r: [f32; 4] = unsafe { std::mem::transmute(r) };
// Check the results.
for r in r {
vals.insert(r.to_bits());
// Ensure the relative error is no more than 2^-12.
let rel_error = (r - exact) / exact;
assert!(
rel_error.abs() <= rel_error_bound,
"correct result: {exact}, got: {r}\n\
that's a relative error of {rel_error} (= 2^{log_error})",
log_error = rel_error.abs().log2()
);
}
}
// Ensure we saw a bunch of different results.

View file

@ -0,0 +1,45 @@
#![deny(deprecated)]
#[deprecated]
pub mod a {
pub struct Foo;
pub struct Bar();
pub struct Baz {}
pub enum Enum {
VFoo,
VBar(),
VBaz {},
}
}
use a::Foo;
//~^ ERROR use of deprecated unit struct `a::Foo`
use a::Bar;
//~^ ERROR use of deprecated tuple struct `a::Bar`
use a::Baz;
//~^ ERROR use of deprecated struct `a::Baz`
use a::Enum::VFoo;
//~^ ERROR use of deprecated unit variant `a::Enum::VFoo`
use a::Enum::VBar;
//~^ ERROR use of deprecated tuple variant `a::Enum::VBar`
use a::Enum::VBaz;
//~^ ERROR use of deprecated variant `a::Enum::VBaz`
fn main() {
a::Foo;
//~^ ERROR use of deprecated unit struct `a::Foo`
a::Bar();
//~^ ERROR use of deprecated tuple struct `a::Bar`
a::Baz {};
//~^ ERROR use of deprecated struct `a::Baz`
a::Enum::VFoo;
//~^ ERROR use of deprecated unit variant `a::Enum::VFoo`
a::Enum::VBar();
//~^ ERROR use of deprecated tuple variant `a::Enum::VBar`
a::Enum::VBaz{};
//~^ ERROR use of deprecated variant `a::Enum::VBaz`
}

View file

@ -0,0 +1,80 @@
error: use of deprecated unit struct `a::Foo`
--> $DIR/unit_and_tuple_struct.rs:17:8
|
LL | use a::Foo;
| ^^^
|
note: the lint level is defined here
--> $DIR/unit_and_tuple_struct.rs:1:9
|
LL | #![deny(deprecated)]
| ^^^^^^^^^^
error: use of deprecated tuple struct `a::Bar`
--> $DIR/unit_and_tuple_struct.rs:19:8
|
LL | use a::Bar;
| ^^^
error: use of deprecated struct `a::Baz`
--> $DIR/unit_and_tuple_struct.rs:21:8
|
LL | use a::Baz;
| ^^^
error: use of deprecated unit variant `a::Enum::VFoo`
--> $DIR/unit_and_tuple_struct.rs:24:14
|
LL | use a::Enum::VFoo;
| ^^^^
error: use of deprecated tuple variant `a::Enum::VBar`
--> $DIR/unit_and_tuple_struct.rs:26:14
|
LL | use a::Enum::VBar;
| ^^^^
error: use of deprecated variant `a::Enum::VBaz`
--> $DIR/unit_and_tuple_struct.rs:28:14
|
LL | use a::Enum::VBaz;
| ^^^^
error: use of deprecated unit struct `a::Foo`
--> $DIR/unit_and_tuple_struct.rs:32:6
|
LL | a::Foo;
| ^^^
error: use of deprecated tuple struct `a::Bar`
--> $DIR/unit_and_tuple_struct.rs:34:6
|
LL | a::Bar();
| ^^^
error: use of deprecated struct `a::Baz`
--> $DIR/unit_and_tuple_struct.rs:36:6
|
LL | a::Baz {};
| ^^^
error: use of deprecated unit variant `a::Enum::VFoo`
--> $DIR/unit_and_tuple_struct.rs:39:12
|
LL | a::Enum::VFoo;
| ^^^^
error: use of deprecated tuple variant `a::Enum::VBar`
--> $DIR/unit_and_tuple_struct.rs:41:12
|
LL | a::Enum::VBar();
| ^^^^
error: use of deprecated variant `a::Enum::VBaz`
--> $DIR/unit_and_tuple_struct.rs:43:12
|
LL | a::Enum::VBaz{};
| ^^^^
error: aborting due to 12 previous errors

View file

@ -0,0 +1,18 @@
//@ edition: 2024
enum Test {
Value = -5 >> 1_usize,
}
fn test1(x: impl Iterator<Item = Foo>) {
//~^ ERROR cannot find type `Foo` in this scope
assert_eq!(Test::Value as u8, -3);
}
fn test2(_: impl Iterator<Item = Foo>) {
//~^ ERROR cannot find type `Foo` in this scope
0u8 == -3;
//~^ ERROR cannot apply unary operator `-` to type `u8`
}
fn main() {}

View file

@ -0,0 +1,24 @@
error[E0412]: cannot find type `Foo` in this scope
--> $DIR/ice-from-type-error-issue-148515.rs:7:34
|
LL | fn test1(x: impl Iterator<Item = Foo>) {
| ^^^ not found in this scope
error[E0412]: cannot find type `Foo` in this scope
--> $DIR/ice-from-type-error-issue-148515.rs:12:34
|
LL | fn test2(_: impl Iterator<Item = Foo>) {
| ^^^ not found in this scope
error[E0600]: cannot apply unary operator `-` to type `u8`
--> $DIR/ice-from-type-error-issue-148515.rs:14:12
|
LL | 0u8 == -3;
| ^^ cannot apply unary operator `-`
|
= note: unsigned values cannot be negated
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0412, E0600.
For more information about an error, try `rustc --explain E0412`.

View file

@ -794,6 +794,55 @@ zulip_stream = 474880 # #t-compiler/backports
topic = "#{number}: stable-nominated"
message_on_add = "PR #{number} has been **accepted** for **stable** backport."
[notify-zulip."beta-nominated".libs]
required_labels = ["T-libs"]
zulip_stream = 542373 # #t-libs/backports
topic = "#{number}: beta-nominated"
message_on_add = [
"""\
@*T-libs* PR #{number} "{title}" has been nominated for beta backport.
""",
"""\
/poll Should #{number} be beta backported?
approve
decline
don't know
""",
]
message_on_remove = "PR #{number}'s beta-nomination has been removed."
[notify-zulip."beta-accepted".libs]
required_labels = ["T-libs"]
zulip_stream = 542373 # #t-libs/backports
# Put it in the same Zulip topic as beta-nominated.
topic = "#{number}: beta-nominated"
message_on_add = "PR #{number} has been **accepted** for **beta** backport."
[notify-zulip."stable-nominated".libs]
required_labels = ["T-libs"]
zulip_stream = 542373 # #t-libs/backports
topic = "#{number}: stable-nominated"
message_on_add = [
"""\
@**channel** PR #{number} "{title}" has been nominated for stable backport.
""",
"""\
/poll Approve stable backport of #{number}?
approve
approve (but does not justify new dot release on its own)
decline
don't know
""",
]
message_on_remove = "PR #{number}'s stable-nomination has been removed."
[notify-zulip."stable-accepted".libs]
required_labels = ["T-libs"]
zulip_stream = 542373 # #t-libs/backports
# Put it in the same thread as stable-nominated.
topic = "#{number}: stable-nominated"
message_on_add = "PR #{number} has been **accepted** for **stable** backport."
[notify-zulip."beta-nominated".bootstrap]
required_labels = ["T-bootstrap"]