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:
commit
401ae55427
84 changed files with 671 additions and 638 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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::*;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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}` : "?";
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
;;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
292be5c7c05138d753bbd4b30db7a3f1a5c914f7
|
||||
5f9dd05862d2e4bceb3be1031b6c936e35671501
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ mod math;
|
|||
#[cfg(all(unix, feature = "native-lib"))]
|
||||
mod native_lib;
|
||||
mod unix;
|
||||
mod wasi;
|
||||
mod windows;
|
||||
mod x86;
|
||||
|
||||
|
|
|
|||
|
|
@ -253,7 +253,6 @@ impl<'tcx> TlsDtorsState<'tcx> {
|
|||
}
|
||||
_ => {
|
||||
// No TLS dtor support.
|
||||
// FIXME: should we do something on wasi?
|
||||
break 'new_state Done;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
pub mod foreign_items;
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
45
tests/ui/deprecation/unit_and_tuple_struct.rs
Normal file
45
tests/ui/deprecation/unit_and_tuple_struct.rs
Normal 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`
|
||||
}
|
||||
80
tests/ui/deprecation/unit_and_tuple_struct.stderr
Normal file
80
tests/ui/deprecation/unit_and_tuple_struct.stderr
Normal 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
|
||||
|
||||
|
|
@ -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() {}
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue