diff --git a/Cargo.lock b/Cargo.lock index d2b96e6d10270..5c095e0eefa8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -600,6 +600,7 @@ dependencies = [ "serde_json", "tempfile", "termize", + "tikv-jemalloc-sys", "toml 0.9.7", "ui_test", "walkdir", @@ -4806,6 +4807,7 @@ dependencies = [ "stringdex", "tempfile", "threadpool", + "tikv-jemalloc-sys", "tracing", "tracing-subscriber", "tracing-tree", @@ -5537,9 +5539,9 @@ version = "0.1.0" [[package]] name = "tikv-jemalloc-sys" -version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" +version = "0.6.1+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d" +checksum = "cd8aa5b2ab86a2cefa406d889139c162cbb230092f7d1d7cbc1716405d852a3b" dependencies = [ "cc", "libc", diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 9ef8fa75062a2..d2ab70895eb38 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -21,9 +21,9 @@ rustc_public_bridge = { path = "../rustc_public_bridge" } # tidy-alphabetical-end [dependencies.tikv-jemalloc-sys] -version = "0.6.0" +version = "0.6.1" optional = true -features = ['unprefixed_malloc_on_supported_platforms'] +features = ['override_allocator_on_supported_platforms'] [features] # tidy-alphabetical-start diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index ca1bb59e59d60..89c61cdf00a59 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -7,26 +7,25 @@ // distribution. The obvious way to do this is with the `#[global_allocator]` // mechanism. However, for complicated reasons (see // https://github.com/rust-lang/rust/pull/81782#issuecomment-784438001 for some -// details) that mechanism doesn't work here. Also, we must use a consistent -// allocator across the rustc <-> llvm boundary, and `#[global_allocator]` -// wouldn't provide that. +// details) that mechanism doesn't work here. Also, we'd like to use a +// consistent allocator across the rustc <-> llvm boundary, and +// `#[global_allocator]` wouldn't provide that. // -// Instead, we use a lower-level mechanism. rustc is linked with jemalloc in a -// way such that jemalloc's implementation of `malloc`, `free`, etc., override -// the libc allocator's implementation. This means that Rust's `System` -// allocator, which calls `libc::malloc()` et al., is actually calling into -// jemalloc. +// Instead, we use a lower-level mechanism, namely the +// `"override_allocator_on_supported_platforms"` Cargo feature of jemalloc-sys. +// +// This makes jemalloc-sys override the libc/system allocator's implementation +// of `malloc`, `free`, etc.. This means that Rust's `System` allocator, which +// calls `libc::malloc()` et al., is actually calling into jemalloc. // // A consequence of not using `GlobalAlloc` (and the `tikv-jemallocator` crate // provides an impl of that trait, which is called `Jemalloc`) is that we // cannot use the sized deallocation APIs (`sdallocx`) that jemalloc provides. // It's unclear how much performance is lost because of this. // -// As for the symbol overrides in `main` below: we're pulling in a static copy -// of jemalloc. We need to actually reference its symbols for it to get linked. -// The two crates we link to here, `std` and `rustc_driver`, are both dynamic -// libraries. So we must reference jemalloc symbols one way or another, because -// this file is the only object code in the rustc executable. +// NOTE: Even though Cargo passes `--extern` with `tikv_jemalloc_sys`, we still need to `use` the +// crate for the compiler to see the `#[used]`, see https://github.com/rust-lang/rust/issues/64402. +// This is similarly required if we used a crate with `#[global_allocator]`. // // NOTE: if you are reading this comment because you want to set a custom `global_allocator` for // benchmarking, consider using the benchmarks in the `rustc-perf` collector suite instead: @@ -36,43 +35,9 @@ // to compare their performance, see // https://github.com/rust-lang/rust/commit/b90cfc887c31c3e7a9e6d462e2464db1fe506175#diff-43914724af6e464c1da2171e4a9b6c7e607d5bc1203fa95c0ab85be4122605ef // for an example of how to do so. +#[cfg(feature = "jemalloc")] +use tikv_jemalloc_sys as _; fn main() { - // See the comment at the top of this file for an explanation of this. - #[cfg(feature = "jemalloc")] - { - use std::os::raw::{c_int, c_void}; - - use tikv_jemalloc_sys as jemalloc_sys; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = - jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - // On OSX, jemalloc doesn't directly override malloc/free, but instead - // registers itself with the allocator's zone APIs in a ctor. However, - // the linker doesn't seem to consider ctors as "used" when statically - // linking, so we need to explicitly depend on the function. - #[cfg(target_os = "macos")] - { - unsafe extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } - } - rustc_driver::main() } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 4ae193a42ff28..094875f38d741 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -645,8 +645,9 @@ macro_rules! common_visitor_and_walkers { fn visit_fn( &mut self, fk: FnKind<$($lt)? $(${ignore($mut)} '_)?>, + _: &AttrVec, _: Span, - _: NodeId + _: NodeId, ) -> Self::Result { walk_fn(self, fk) } @@ -740,6 +741,7 @@ macro_rules! common_visitor_and_walkers { type Ctxt; fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( &$($lt)? $($mut)? self, + attrs: &AttrVec, span: Span, id: NodeId, visibility: &$($lt)? $($mut)? Visibility, @@ -773,7 +775,7 @@ macro_rules! common_visitor_and_walkers { ) -> V::Result { let Item { attrs, id, kind, vis, span, tokens: _ } = item; visit_visitable!($($mut)? visitor, id, attrs, vis); - try_visit!(kind.walk(*span, *id, vis, ctxt, visitor)); + try_visit!(kind.walk(attrs, *span, *id, vis, ctxt, visitor)); visit_visitable!($($mut)? visitor, span); V::Result::output() } @@ -799,6 +801,7 @@ macro_rules! common_visitor_and_walkers { type Ctxt = (); fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( &$($lt)? $($mut)? self, + attrs: &AttrVec, span: Span, id: NodeId, visibility: &$($lt)? $($mut)? Visibility, @@ -808,7 +811,7 @@ macro_rules! common_visitor_and_walkers { match self { ItemKind::Fn(func) => { let kind = FnKind::Fn(FnCtxt::Free, visibility, &$($mut)? *func); - try_visit!(vis.visit_fn(kind, span, id)); + try_visit!(vis.visit_fn(kind, attrs, span, id)); } ItemKind::ExternCrate(orig_name, ident) => visit_visitable!($($mut)? vis, orig_name, ident), @@ -856,6 +859,7 @@ macro_rules! common_visitor_and_walkers { type Ctxt = AssocCtxt; fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( &$($lt)? $($mut)? self, + attrs: &AttrVec, span: Span, id: NodeId, visibility: &$($lt)? $($mut)? Visibility, @@ -867,7 +871,7 @@ macro_rules! common_visitor_and_walkers { visit_visitable!($($mut)? vis, item), AssocItemKind::Fn(func) => { let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &$($mut)? *func); - try_visit!(vis.visit_fn(kind, span, id)) + try_visit!(vis.visit_fn(kind, attrs, span, id)) } AssocItemKind::Type(alias) => visit_visitable!($($mut)? vis, alias), @@ -886,6 +890,7 @@ macro_rules! common_visitor_and_walkers { type Ctxt = (); fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( &$($lt)? $($mut)? self, + attrs: &AttrVec, span: Span, id: NodeId, visibility: &$($lt)? $($mut)? Visibility, @@ -897,7 +902,7 @@ macro_rules! common_visitor_and_walkers { visit_visitable!($($mut)? vis, item), ForeignItemKind::Fn(func) => { let kind = FnKind::Fn(FnCtxt::Foreign, visibility, &$($mut)?*func); - try_visit!(vis.visit_fn(kind, span, id)) + try_visit!(vis.visit_fn(kind, attrs, span, id)) } ForeignItemKind::TyAlias(alias) => visit_visitable!($($mut)? vis, alias), @@ -999,7 +1004,7 @@ macro_rules! common_visitor_and_walkers { }) => { visit_visitable!($($mut)? vis, constness, movability, capture_clause); let kind = FnKind::Closure(binder, coroutine_kind, fn_decl, body); - try_visit!(vis.visit_fn(kind, *span, *id)); + try_visit!(vis.visit_fn(kind, attrs, *span, *id)); visit_visitable!($($mut)? vis, fn_decl_span, fn_arg_span); } ExprKind::Block(block, opt_label) => diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 2be2fca87c3c5..c6f24c1a19b48 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1771,8 +1771,14 @@ impl<'hir> LoweringContext<'_, 'hir> { let pat = self.lower_pat(pat); let for_span = self.mark_span_with_reason(DesugaringKind::ForLoop, self.lower_span(e.span), None); - let head_span = self.mark_span_with_reason(DesugaringKind::ForLoop, head.span, None); - let pat_span = self.mark_span_with_reason(DesugaringKind::ForLoop, pat.span, None); + let for_ctxt = for_span.ctxt(); + + // Try to point both the head and pat spans to their position in the for loop + // rather than inside a macro. + let head_span = + head.span.find_ancestor_in_same_ctxt(e.span).unwrap_or(head.span).with_ctxt(for_ctxt); + let pat_span = + pat.span.find_ancestor_in_same_ctxt(e.span).unwrap_or(pat.span).with_ctxt(for_ctxt); let loop_hir_id = self.lower_node_id(e.id); let label = self.lower_label(opt_label, e.id, loop_hir_id); diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 7d618f16b26e5..1bfe4b07551f2 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -68,6 +68,10 @@ ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` .label = `extern "{$abi}"` because of this .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list +ast_passes_c_variadic_bad_naked_extern = `...` is not supported for `extern "{$abi}"` naked functions + .label = `extern "{$abi}"` because of this + .help = C-variadic function must have a compatible calling convention + ast_passes_c_variadic_must_be_unsafe = functions with a C variable argument list must be unsafe .suggestion = add the `unsafe` keyword to this definition diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index c203e5426b1e4..37e40bd6e94db 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -21,7 +21,7 @@ use std::ops::{Deref, DerefMut}; use std::str::FromStr; use itertools::{Either, Itertools}; -use rustc_abi::{CanonAbi, ExternAbi, InterruptKind}; +use rustc_abi::{CVariadicStatus, CanonAbi, ExternAbi, InterruptKind}; use rustc_ast::visit::{AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, walk_list}; use rustc_ast::*; use rustc_ast_pretty::pprust::{self, State}; @@ -35,6 +35,7 @@ use rustc_session::lint::builtin::{ DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN, PATTERNS_IN_FNS_WITHOUT_BODY, }; +use rustc_session::parse::feature_err; use rustc_span::{Ident, Span, kw, sym}; use rustc_target::spec::{AbiMap, AbiMapping}; use thin_vec::thin_vec; @@ -661,7 +662,7 @@ impl<'a> AstValidator<'a> { /// C-variadics must be: /// - Non-const /// - Either foreign, or free and `unsafe extern "C"` semantically - fn check_c_variadic_type(&self, fk: FnKind<'a>) { + fn check_c_variadic_type(&self, fk: FnKind<'a>, attrs: &'a AttrVec) { // `...` is already rejected when it is not the final parameter. let variadic_param = match fk.decl().inputs.last() { Some(param) if matches!(param.ty.kind, TyKind::CVarArgs) => param, @@ -693,36 +694,92 @@ impl<'a> AstValidator<'a> { match fn_ctxt { FnCtxt::Foreign => return, - FnCtxt::Free | FnCtxt::Assoc(_) => match sig.header.ext { - Extern::Implicit(_) => { - if !matches!(sig.header.safety, Safety::Unsafe(_)) { - self.dcx().emit_err(errors::CVariadicMustBeUnsafe { - span: variadic_param.span, - unsafe_span: sig.safety_span(), - }); + FnCtxt::Free | FnCtxt::Assoc(_) => { + match sig.header.ext { + Extern::Implicit(_) => { + if !matches!(sig.header.safety, Safety::Unsafe(_)) { + self.dcx().emit_err(errors::CVariadicMustBeUnsafe { + span: variadic_param.span, + unsafe_span: sig.safety_span(), + }); + } + } + Extern::Explicit(StrLit { symbol_unescaped, .. }, _) => { + // Just bail if the ABI is not even recognized. + let Ok(abi) = ExternAbi::from_str(symbol_unescaped.as_str()) else { + return; + }; + + self.check_c_variadic_abi(abi, attrs, variadic_param.span, sig); + + if !matches!(sig.header.safety, Safety::Unsafe(_)) { + self.dcx().emit_err(errors::CVariadicMustBeUnsafe { + span: variadic_param.span, + unsafe_span: sig.safety_span(), + }); + } + } + Extern::None => { + let err = errors::CVariadicNoExtern { span: variadic_param.span }; + self.dcx().emit_err(err); } } - Extern::Explicit(StrLit { symbol_unescaped, .. }, _) => { - if !matches!(symbol_unescaped, sym::C | sym::C_dash_unwind) { - self.dcx().emit_err(errors::CVariadicBadExtern { - span: variadic_param.span, - abi: symbol_unescaped, - extern_span: sig.extern_span(), - }); + } + } + } + + fn check_c_variadic_abi( + &self, + abi: ExternAbi, + attrs: &'a AttrVec, + dotdotdot_span: Span, + sig: &FnSig, + ) { + // For naked functions we accept any ABI that is accepted on c-variadic + // foreign functions, if the c_variadic_naked_functions feature is enabled. + if attr::contains_name(attrs, sym::naked) { + match abi.supports_c_variadic() { + CVariadicStatus::Stable if let ExternAbi::C { .. } = abi => { + // With `c_variadic` naked c-variadic `extern "C"` functions are allowed. + } + CVariadicStatus::Stable => { + // For e.g. aapcs or sysv64 `c_variadic_naked_functions` must also be enabled. + if !self.features.enabled(sym::c_variadic_naked_functions) { + let msg = format!("Naked c-variadic `extern {abi}` functions are unstable"); + feature_err(&self.sess, sym::c_variadic_naked_functions, sig.span, msg) + .emit(); + } + } + CVariadicStatus::Unstable { feature } => { + // Some ABIs need additional features. + if !self.features.enabled(sym::c_variadic_naked_functions) { + let msg = format!("Naked c-variadic `extern {abi}` functions are unstable"); + feature_err(&self.sess, sym::c_variadic_naked_functions, sig.span, msg) + .emit(); } - if !matches!(sig.header.safety, Safety::Unsafe(_)) { - self.dcx().emit_err(errors::CVariadicMustBeUnsafe { - span: variadic_param.span, - unsafe_span: sig.safety_span(), - }); + if !self.features.enabled(feature) { + let msg = format!( + "C-variadic functions with the {abi} calling convention are unstable" + ); + feature_err(&self.sess, feature, sig.span, msg).emit(); } } - Extern::None => { - let err = errors::CVariadicNoExtern { span: variadic_param.span }; - self.dcx().emit_err(err); + CVariadicStatus::NotSupported => { + // Some ABIs, e.g. `extern "Rust"`, never support c-variadic functions. + self.dcx().emit_err(errors::CVariadicBadNakedExtern { + span: dotdotdot_span, + abi: abi.as_str(), + extern_span: sig.extern_span(), + }); } - }, + } + } else if !matches!(abi, ExternAbi::C { .. }) { + self.dcx().emit_err(errors::CVariadicBadExtern { + span: dotdotdot_span, + abi: abi.as_str(), + extern_span: sig.extern_span(), + }); } } @@ -1106,7 +1163,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } let kind = FnKind::Fn(FnCtxt::Free, &item.vis, &*func); - self.visit_fn(kind, item.span, item.id); + self.visit_fn(kind, &item.attrs, item.span, item.id); } ItemKind::ForeignMod(ForeignMod { extern_span, abi, safety, .. }) => { let old_item = mem::replace(&mut self.extern_mod_span, Some(item.span)); @@ -1473,7 +1530,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_param_bound(self, bound) } - fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) { + fn visit_fn(&mut self, fk: FnKind<'a>, attrs: &AttrVec, span: Span, id: NodeId) { // Only associated `fn`s can have `self` parameters. let self_semantic = match fk.ctxt() { Some(FnCtxt::Assoc(_)) => SelfSemantic::Yes, @@ -1492,7 +1549,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_extern_fn_signature(abi, ctxt, &fun.ident, &fun.sig); } - self.check_c_variadic_type(fk); + self.check_c_variadic_type(fk, attrs); // Functions cannot both be `const async` or `const gen` if let Some(&FnHeader { @@ -1643,7 +1700,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { { self.visit_attrs_vis_ident(&item.attrs, &item.vis, &func.ident); let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), &item.vis, &*func); - self.visit_fn(kind, item.span, item.id); + self.visit_fn(kind, &item.attrs, item.span, item.id); } AssocItemKind::Type(_) => { let disallowed = (!parent_is_const).then(|| match self.outer_trait_or_trait_impl { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 7c63b8e35999e..20813d936c001 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -347,7 +347,18 @@ pub(crate) struct CVariadicMustBeUnsafe { pub(crate) struct CVariadicBadExtern { #[primary_span] pub span: Span, - pub abi: Symbol, + pub abi: &'static str, + #[label] + pub extern_span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_c_variadic_bad_naked_extern)] +#[help] +pub(crate) struct CVariadicBadNakedExtern { + #[primary_span] + pub span: Span, + pub abi: &'static str, #[label] pub extern_span: Span, } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index b8a29a9a08f43..2d87d8c84d7c9 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -1,6 +1,5 @@ -use rustc_ast as ast; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; -use rustc_ast::{NodeId, PatKind, attr, token}; +use rustc_ast::{self as ast, AttrVec, NodeId, PatKind, attr, token}; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features}; use rustc_session::Session; use rustc_session::parse::{feature_err, feature_warn}; @@ -392,7 +391,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_poly_trait_ref(self, t); } - fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { + fn visit_fn(&mut self, fn_kind: FnKind<'a>, _: &AttrVec, span: Span, _: NodeId) { if let Some(_header) = fn_kind.header() { // Stability of const fn methods are covered in `visit_assoc_item` below. } diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index f84ed64e036e2..9a8927c102973 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -3087,6 +3087,39 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { }); explanation.add_explanation_to_diagnostic(&self, &mut err, "", Some(borrow_span), None); + + // Detect buffer reuse pattern + if let BorrowExplanation::UsedLater(_dropped_local, _, _, _) = explanation { + // Check all locals at the borrow location to find Vec<&T> types + for (local, local_decl) in self.body.local_decls.iter_enumerated() { + if let ty::Adt(adt_def, args) = local_decl.ty.kind() + && self.infcx.tcx.is_diagnostic_item(sym::Vec, adt_def.did()) + && args.len() > 0 + { + let vec_inner_ty = args.type_at(0); + // Check if Vec contains references + if vec_inner_ty.is_ref() { + let local_place = local.into(); + if let Some(local_name) = self.describe_place(local_place) { + err.span_label( + local_decl.source_info.span, + format!("variable `{local_name}` declared here"), + ); + err.note( + format!( + "`{local_name}` is a collection that stores borrowed references, \ + but {name} does not live long enough to be stored in it" + ) + ); + err.help( + "buffer reuse with borrowed references requires unsafe code or restructuring" + ); + break; + } + } + } + } + } } err diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 8397cd294e0a9..f51bc7031c31d 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -410,6 +410,9 @@ declare_features! ( (unstable, avx10_target_feature, "1.88.0", Some(138843)), /// Allows using C-variadics. (unstable, c_variadic, "1.34.0", Some(44930)), + /// Allows defining c-variadic naked functions with any extern ABI that is allowed + /// on c-variadic foreign functions. + (unstable, c_variadic_naked_functions, "CURRENT_RUSTC_VERSION", Some(148767)), /// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled. (unstable, cfg_contract_checks, "1.86.0", Some(128044)), /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour. diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 1b8ecdbee579d..86ed7a0a5a28a 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1079,6 +1079,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_ident, expected); + self.suggest_bounds_for_range_to_method(&mut err, source, item_ident); err.emit() } @@ -3260,6 +3261,71 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn suggest_bounds_for_range_to_method( + &self, + err: &mut Diag<'_>, + source: SelfSource<'tcx>, + item_ident: Ident, + ) { + let SelfSource::MethodCall(rcvr_expr) = source else { return }; + let hir::ExprKind::Struct(qpath, fields, _) = rcvr_expr.kind else { return }; + let Some(lang_item) = self.tcx.qpath_lang_item(*qpath) else { + return; + }; + let is_inclusive = match lang_item { + hir::LangItem::RangeTo => false, + hir::LangItem::RangeToInclusive | hir::LangItem::RangeInclusiveCopy => true, + _ => return, + }; + + let Some(iterator_trait) = self.tcx.get_diagnostic_item(sym::Iterator) else { return }; + let Some(_) = self + .tcx + .associated_items(iterator_trait) + .filter_by_name_unhygienic(item_ident.name) + .next() + else { + return; + }; + + let source_map = self.tcx.sess.source_map(); + let range_type = if is_inclusive { "RangeInclusive" } else { "Range" }; + let Some(end_field) = fields.iter().find(|f| f.ident.name == rustc_span::sym::end) else { + return; + }; + + let element_ty = self.typeck_results.borrow().expr_ty_opt(end_field.expr); + let is_integral = element_ty.is_some_and(|ty| ty.is_integral()); + let end_is_negative = is_integral + && matches!(end_field.expr.kind, hir::ExprKind::Unary(rustc_ast::UnOp::Neg, _)); + + let Ok(snippet) = source_map.span_to_snippet(rcvr_expr.span) else { return }; + + let offset = snippet + .chars() + .take_while(|&c| c == '(' || c.is_whitespace()) + .map(|c| c.len_utf8()) + .sum::(); + + let insert_span = rcvr_expr + .span + .with_lo(rcvr_expr.span.lo() + rustc_span::BytePos(offset as u32)) + .shrink_to_lo(); + + let (value, appl) = if is_integral && !end_is_negative { + ("0", Applicability::MachineApplicable) + } else { + ("/* start */", Applicability::HasPlaceholders) + }; + + err.span_suggestion_verbose( + insert_span, + format!("consider using a bounded `{range_type}` by adding a concrete starting value"), + value, + appl, + ); + } + /// Print out the type for use in value namespace. fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String { match ty.kind() { diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index dff1fc4367021..6cb5aea798407 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -5,7 +5,7 @@ //! syntactical lints. use rustc_ast::visit::{self as ast_visit, Visitor, walk_list}; -use rustc_ast::{self as ast, HasAttrs}; +use rustc_ast::{self as ast, AttrVec, HasAttrs}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer}; use rustc_feature::Features; @@ -135,7 +135,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast> }); } - fn visit_fn(&mut self, fk: ast_visit::FnKind<'ast>, span: Span, id: ast::NodeId) { + fn visit_fn(&mut self, fk: ast_visit::FnKind<'ast>, _: &AttrVec, span: Span, id: ast::NodeId) { lint_callback!(self, check_fn, fk, span, id); ast_visit::walk_fn(self, fk); } diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index c83610da1aad2..fe50b730256b7 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -3,7 +3,7 @@ // completely accurate (some things might be counted twice, others missed). use rustc_ast::visit::BoundKind; -use rustc_ast::{self as ast, NodeId, visit as ast_visit}; +use rustc_ast::{self as ast, AttrVec, NodeId, visit as ast_visit}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::thousands::usize_with_underscores; use rustc_hir::{self as hir, AmbigArg, HirId, intravisit as hir_visit}; @@ -709,7 +709,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { ast_visit::walk_where_predicate(self, p) } - fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, _: Span, _: NodeId) { + fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, _: &AttrVec, _: Span, _: NodeId) { self.record("FnDecl", None, fk.decl()); ast_visit::walk_fn(self, fk) } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 886ffcffbb4d9..cd12d5ad10cf7 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1358,7 +1358,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { // Visit attributes after items for backward compatibility. // This way they can use `macro_rules` defined later. self.visit_vis(&item.vis); - item.kind.walk(item.span, item.id, &item.vis, (), self); + item.kind.walk(&item.attrs, item.span, item.id, &item.vis, (), self); visit::walk_list!(self, visit_attribute, &item.attrs); } _ => visit::walk_item(self, item), diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 14538df8187d8..ea64a1e6c64dd 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -193,7 +193,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { }); } - fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { + fn visit_fn(&mut self, fn_kind: FnKind<'a>, _: &AttrVec, span: Span, _: NodeId) { match fn_kind { FnKind::Fn( _ctxt, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 16cbfe3b3c743..107803c5c2651 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1034,7 +1034,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc } } } - fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, fn_id: NodeId) { + fn visit_fn(&mut self, fn_kind: FnKind<'ast>, _: &AttrVec, sp: Span, fn_id: NodeId) { let previous_value = self.diag_metadata.current_function; match fn_kind { // Bail if the function is foreign, and thus cannot validly have diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1d7de626f251b..60a5aa2378e2f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -612,6 +612,7 @@ symbols! { c_str_literals, c_unwind, c_variadic, + c_variadic_naked_functions, c_void, call, call_mut, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 08fae288c441c..c4e0e1eddc08f 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -3198,15 +3198,7 @@ impl Target { return load_file(&p); } - // Leave in a specialized error message for the removed target. - // FIXME: If you see this and it's been a few months after this has been released, - // you can probably remove it. - if target_tuple == "i586-pc-windows-msvc" { - Err("the `i586-pc-windows-msvc` target has been removed. Use the `i686-pc-windows-msvc` target instead.\n\ - Windows 10 (the minimum required OS version) requires a CPU baseline of at least i686 so you can safely switch".into()) - } else { - Err(format!("could not find specification for target {target_tuple:?}")) - } + Err(format!("could not find specification for target {target_tuple:?}")) } TargetTuple::TargetJson { ref contents, .. } => Target::from_json(contents), } diff --git a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs index 8221d8f17e90e..32d37b5533926 100644 --- a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs +++ b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs @@ -170,7 +170,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(mut self, rhs: Self) -> Self { for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) { *l &= r; @@ -187,7 +186,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(mut self, rhs: Self) -> Self { for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) { *l |= r; @@ -203,7 +201,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(mut self, rhs: Self) -> Self::Output { for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) { *l ^= r; @@ -219,7 +216,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn not(mut self) -> Self::Output { for x in self.0.as_mut() { *x = !*x; diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index be05b92a09734..9c9bb7cc1ed3f 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3413,6 +3413,13 @@ impl Step for Bootstrap { .env("INSTA_WORKSPACE_ROOT", &builder.src) .env("RUSTC_BOOTSTRAP", "1"); + if builder.config.cmd.bless() { + // Tell `insta` to automatically bless any failing `.snap` files. + // Unlike compiletest blessing, the tests might still report failure. + // Does not bless inline snapshots. + cargo.env("INSTA_UPDATE", "always"); + } + run_cargo_test(cargo, &[], &[], None, host, builder); } diff --git a/src/bootstrap/src/core/builder/cli_paths.rs b/src/bootstrap/src/core/builder/cli_paths.rs index aa81c4684eab3..fef1979465e8b 100644 --- a/src/bootstrap/src/core/builder/cli_paths.rs +++ b/src/bootstrap/src/core/builder/cli_paths.rs @@ -7,6 +7,9 @@ use std::path::PathBuf; use crate::core::builder::{Builder, Kind, PathSet, ShouldRun, StepDescription}; +#[cfg(test)] +mod tests; + pub(crate) const PATH_REMAP: &[(&str, &[&str])] = &[ // bootstrap.toml uses `rust-analyzer-proc-macro-srv`, but the // actual path is `proc-macro-srv-cli` diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build.snap new file mode 100644 index 0000000000000..f8c6deccb3bcb --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build.snap @@ -0,0 +1,23 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build +--- +[Build] compile::Std + targets: [aarch64-unknown-linux-gnu] + - Set({build::library}) + - Set({build::library/alloc}) + - Set({build::library/compiler-builtins/compiler-builtins}) + - Set({build::library/core}) + - Set({build::library/panic_abort}) + - Set({build::library/panic_unwind}) + - Set({build::library/proc_macro}) + - Set({build::library/rustc-std-workspace-core}) + - Set({build::library/std}) + - Set({build::library/std_detect}) + - Set({build::library/sysroot}) + - Set({build::library/test}) + - Set({build::library/unwind}) +[Build] tool::Rustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({build::src/librustdoc}) + - Set({build::src/tools/rustdoc}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiler.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiler.snap new file mode 100644 index 0000000000000..721ecaf4c487e --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiler.snap @@ -0,0 +1,84 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build compiler +--- +[Build] compile::Rustc + targets: [x86_64-unknown-linux-gnu] + - Set({build::compiler/rustc_abi}) + - Set({build::compiler/rustc_arena}) + - Set({build::compiler/rustc_ast}) + - Set({build::compiler/rustc_ast_ir}) + - Set({build::compiler/rustc_ast_lowering}) + - Set({build::compiler/rustc_ast_passes}) + - Set({build::compiler/rustc_ast_pretty}) + - Set({build::compiler/rustc_attr_parsing}) + - Set({build::compiler/rustc_baked_icu_data}) + - Set({build::compiler/rustc_borrowck}) + - Set({build::compiler/rustc_builtin_macros}) + - Set({build::compiler/rustc_codegen_llvm}) + - Set({build::compiler/rustc_codegen_ssa}) + - Set({build::compiler/rustc_const_eval}) + - Set({build::compiler/rustc_data_structures}) + - Set({build::compiler/rustc_driver}) + - Set({build::compiler/rustc_driver_impl}) + - Set({build::compiler/rustc_error_codes}) + - Set({build::compiler/rustc_error_messages}) + - Set({build::compiler/rustc_errors}) + - Set({build::compiler/rustc_expand}) + - Set({build::compiler/rustc_feature}) + - Set({build::compiler/rustc_fluent_macro}) + - Set({build::compiler/rustc_fs_util}) + - Set({build::compiler/rustc_graphviz}) + - Set({build::compiler/rustc_hashes}) + - Set({build::compiler/rustc_hir}) + - Set({build::compiler/rustc_hir_analysis}) + - Set({build::compiler/rustc_hir_id}) + - Set({build::compiler/rustc_hir_pretty}) + - Set({build::compiler/rustc_hir_typeck}) + - Set({build::compiler/rustc_incremental}) + - Set({build::compiler/rustc_index}) + - Set({build::compiler/rustc_index_macros}) + - Set({build::compiler/rustc_infer}) + - Set({build::compiler/rustc_interface}) + - Set({build::compiler/rustc_lexer}) + - Set({build::compiler/rustc_lint}) + - Set({build::compiler/rustc_lint_defs}) + - Set({build::compiler/rustc_llvm}) + - Set({build::compiler/rustc_log}) + - Set({build::compiler/rustc_macros}) + - Set({build::compiler/rustc_metadata}) + - Set({build::compiler/rustc_middle}) + - Set({build::compiler/rustc_mir_build}) + - Set({build::compiler/rustc_mir_dataflow}) + - Set({build::compiler/rustc_mir_transform}) + - Set({build::compiler/rustc_monomorphize}) + - Set({build::compiler/rustc_next_trait_solver}) + - Set({build::compiler/rustc_parse}) + - Set({build::compiler/rustc_parse_format}) + - Set({build::compiler/rustc_passes}) + - Set({build::compiler/rustc_pattern_analysis}) + - Set({build::compiler/rustc_privacy}) + - Set({build::compiler/rustc_proc_macro}) + - Set({build::compiler/rustc_public}) + - Set({build::compiler/rustc_public_bridge}) + - Set({build::compiler/rustc_query_impl}) + - Set({build::compiler/rustc_query_system}) + - Set({build::compiler/rustc_resolve}) + - Set({build::compiler/rustc_sanitizers}) + - Set({build::compiler/rustc_serialize}) + - Set({build::compiler/rustc_session}) + - Set({build::compiler/rustc_span}) + - Set({build::compiler/rustc_symbol_mangling}) + - Set({build::compiler/rustc_target}) + - Set({build::compiler/rustc_thread_pool}) + - Set({build::compiler/rustc_trait_selection}) + - Set({build::compiler/rustc_traits}) + - Set({build::compiler/rustc_transmute}) + - Set({build::compiler/rustc_ty_utils}) + - Set({build::compiler/rustc_type_ir}) + - Set({build::compiler/rustc_type_ir_macros}) + - Set({build::compiler/rustc_windows_rc}) +[Build] compile::Assemble + targets: [x86_64-unknown-linux-gnu] + - Set({build::compiler}) + - Set({build::compiler/rustc}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiletest.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiletest.snap new file mode 100644 index 0000000000000..97f60bfa0370b --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiletest.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build compiletest +--- +[Build] tool::Compiletest + targets: [aarch64-unknown-linux-gnu] + - Set({build::src/tools/compiletest}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_llvm.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_llvm.snap new file mode 100644 index 0000000000000..f4764a5279a71 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_llvm.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build llvm +--- +[Build] llvm::Llvm + targets: [x86_64-unknown-linux-gnu] + - Set({build::src/llvm-project/llvm}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rustc.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rustc.snap new file mode 100644 index 0000000000000..a6d3d13154ed4 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rustc.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build rustc +--- +[Build] compile::Assemble + targets: [x86_64-unknown-linux-gnu] + - Set({build::compiler/rustc}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rustc_llvm.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rustc_llvm.snap new file mode 100644 index 0000000000000..30f598ddb7816 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rustc_llvm.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build rustc_llvm +--- +[Build] compile::Rustc + targets: [x86_64-unknown-linux-gnu] + - Set({build::compiler/rustc_llvm}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rustdoc.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rustdoc.snap new file mode 100644 index 0000000000000..9a98092d714f4 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rustdoc.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build rustdoc +--- +[Build] tool::Rustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({build::src/tools/rustdoc}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check.snap new file mode 100644 index 0000000000000..0fe26fac57fc5 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check.snap @@ -0,0 +1,134 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: check +--- +[Check] check::Rustc + targets: [x86_64-unknown-linux-gnu] + - Set({check::compiler}) + - Set({check::compiler/rustc}) + - Set({check::compiler/rustc_abi}) + - Set({check::compiler/rustc_arena}) + - Set({check::compiler/rustc_ast}) + - Set({check::compiler/rustc_ast_ir}) + - Set({check::compiler/rustc_ast_lowering}) + - Set({check::compiler/rustc_ast_passes}) + - Set({check::compiler/rustc_ast_pretty}) + - Set({check::compiler/rustc_attr_parsing}) + - Set({check::compiler/rustc_baked_icu_data}) + - Set({check::compiler/rustc_borrowck}) + - Set({check::compiler/rustc_builtin_macros}) + - Set({check::compiler/rustc_codegen_llvm}) + - Set({check::compiler/rustc_codegen_ssa}) + - Set({check::compiler/rustc_const_eval}) + - Set({check::compiler/rustc_data_structures}) + - Set({check::compiler/rustc_driver}) + - Set({check::compiler/rustc_driver_impl}) + - Set({check::compiler/rustc_error_codes}) + - Set({check::compiler/rustc_error_messages}) + - Set({check::compiler/rustc_errors}) + - Set({check::compiler/rustc_expand}) + - Set({check::compiler/rustc_feature}) + - Set({check::compiler/rustc_fluent_macro}) + - Set({check::compiler/rustc_fs_util}) + - Set({check::compiler/rustc_graphviz}) + - Set({check::compiler/rustc_hashes}) + - Set({check::compiler/rustc_hir}) + - Set({check::compiler/rustc_hir_analysis}) + - Set({check::compiler/rustc_hir_id}) + - Set({check::compiler/rustc_hir_pretty}) + - Set({check::compiler/rustc_hir_typeck}) + - Set({check::compiler/rustc_incremental}) + - Set({check::compiler/rustc_index}) + - Set({check::compiler/rustc_index_macros}) + - Set({check::compiler/rustc_infer}) + - Set({check::compiler/rustc_interface}) + - Set({check::compiler/rustc_lexer}) + - Set({check::compiler/rustc_lint}) + - Set({check::compiler/rustc_lint_defs}) + - Set({check::compiler/rustc_llvm}) + - Set({check::compiler/rustc_log}) + - Set({check::compiler/rustc_macros}) + - Set({check::compiler/rustc_metadata}) + - Set({check::compiler/rustc_middle}) + - Set({check::compiler/rustc_mir_build}) + - Set({check::compiler/rustc_mir_dataflow}) + - Set({check::compiler/rustc_mir_transform}) + - Set({check::compiler/rustc_monomorphize}) + - Set({check::compiler/rustc_next_trait_solver}) + - Set({check::compiler/rustc_parse}) + - Set({check::compiler/rustc_parse_format}) + - Set({check::compiler/rustc_passes}) + - Set({check::compiler/rustc_pattern_analysis}) + - Set({check::compiler/rustc_privacy}) + - Set({check::compiler/rustc_proc_macro}) + - Set({check::compiler/rustc_public}) + - Set({check::compiler/rustc_public_bridge}) + - Set({check::compiler/rustc_query_impl}) + - Set({check::compiler/rustc_query_system}) + - Set({check::compiler/rustc_resolve}) + - Set({check::compiler/rustc_sanitizers}) + - Set({check::compiler/rustc_serialize}) + - Set({check::compiler/rustc_session}) + - Set({check::compiler/rustc_span}) + - Set({check::compiler/rustc_symbol_mangling}) + - Set({check::compiler/rustc_target}) + - Set({check::compiler/rustc_thread_pool}) + - Set({check::compiler/rustc_trait_selection}) + - Set({check::compiler/rustc_traits}) + - Set({check::compiler/rustc_transmute}) + - Set({check::compiler/rustc_ty_utils}) + - Set({check::compiler/rustc_type_ir}) + - Set({check::compiler/rustc_type_ir_macros}) + - Set({check::compiler/rustc_windows_rc}) +[Check] check::Rustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/librustdoc, check::src/tools/rustdoc}) +[Check] check::CraneliftCodegenBackend + targets: [x86_64-unknown-linux-gnu] + - Set({check::cg_clif}) + - Set({check::rustc_codegen_cranelift}) +[Check] check::GccCodegenBackend + targets: [x86_64-unknown-linux-gnu] + - Set({check::cg_gcc}) + - Set({check::rustc_codegen_gcc}) +[Check] check::Clippy + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/clippy}) +[Check] check::Miri + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/miri}) +[Check] check::CargoMiri + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/miri/cargo-miri}) +[Check] check::MiroptTestTools + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/miropt-test-tools}) +[Check] check::Rustfmt + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/rustfmt}) +[Check] check::RustAnalyzer + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/rust-analyzer}) +[Check] check::TestFloatParse + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/test-float-parse}) +[Check] check::FeaturesStatusDump + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/features-status-dump}) +[Check] check::Std + targets: [aarch64-unknown-linux-gnu] + - Set({check::library}) + - Set({check::library/alloc}) + - Set({check::library/alloctests}) + - Set({check::library/compiler-builtins/compiler-builtins}) + - Set({check::library/core}) + - Set({check::library/coretests}) + - Set({check::library/panic_abort}) + - Set({check::library/panic_unwind}) + - Set({check::library/proc_macro}) + - Set({check::library/rustc-std-workspace-core}) + - Set({check::library/std}) + - Set({check::library/std_detect}) + - Set({check::library/sysroot}) + - Set({check::library/test}) + - Set({check::library/unwind}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_bootstrap.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_bootstrap.snap new file mode 100644 index 0000000000000..a746783b3909c --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_bootstrap.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: check bootstrap +--- +[Check] check::Bootstrap + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/bootstrap}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiler.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiler.snap new file mode 100644 index 0000000000000..71d9c0fafb809 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiler.snap @@ -0,0 +1,82 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: check compiler +--- +[Check] check::Rustc + targets: [x86_64-unknown-linux-gnu] + - Set({check::compiler}) + - Set({check::compiler/rustc}) + - Set({check::compiler/rustc_abi}) + - Set({check::compiler/rustc_arena}) + - Set({check::compiler/rustc_ast}) + - Set({check::compiler/rustc_ast_ir}) + - Set({check::compiler/rustc_ast_lowering}) + - Set({check::compiler/rustc_ast_passes}) + - Set({check::compiler/rustc_ast_pretty}) + - Set({check::compiler/rustc_attr_parsing}) + - Set({check::compiler/rustc_baked_icu_data}) + - Set({check::compiler/rustc_borrowck}) + - Set({check::compiler/rustc_builtin_macros}) + - Set({check::compiler/rustc_codegen_llvm}) + - Set({check::compiler/rustc_codegen_ssa}) + - Set({check::compiler/rustc_const_eval}) + - Set({check::compiler/rustc_data_structures}) + - Set({check::compiler/rustc_driver}) + - Set({check::compiler/rustc_driver_impl}) + - Set({check::compiler/rustc_error_codes}) + - Set({check::compiler/rustc_error_messages}) + - Set({check::compiler/rustc_errors}) + - Set({check::compiler/rustc_expand}) + - Set({check::compiler/rustc_feature}) + - Set({check::compiler/rustc_fluent_macro}) + - Set({check::compiler/rustc_fs_util}) + - Set({check::compiler/rustc_graphviz}) + - Set({check::compiler/rustc_hashes}) + - Set({check::compiler/rustc_hir}) + - Set({check::compiler/rustc_hir_analysis}) + - Set({check::compiler/rustc_hir_id}) + - Set({check::compiler/rustc_hir_pretty}) + - Set({check::compiler/rustc_hir_typeck}) + - Set({check::compiler/rustc_incremental}) + - Set({check::compiler/rustc_index}) + - Set({check::compiler/rustc_index_macros}) + - Set({check::compiler/rustc_infer}) + - Set({check::compiler/rustc_interface}) + - Set({check::compiler/rustc_lexer}) + - Set({check::compiler/rustc_lint}) + - Set({check::compiler/rustc_lint_defs}) + - Set({check::compiler/rustc_llvm}) + - Set({check::compiler/rustc_log}) + - Set({check::compiler/rustc_macros}) + - Set({check::compiler/rustc_metadata}) + - Set({check::compiler/rustc_middle}) + - Set({check::compiler/rustc_mir_build}) + - Set({check::compiler/rustc_mir_dataflow}) + - Set({check::compiler/rustc_mir_transform}) + - Set({check::compiler/rustc_monomorphize}) + - Set({check::compiler/rustc_next_trait_solver}) + - Set({check::compiler/rustc_parse}) + - Set({check::compiler/rustc_parse_format}) + - Set({check::compiler/rustc_passes}) + - Set({check::compiler/rustc_pattern_analysis}) + - Set({check::compiler/rustc_privacy}) + - Set({check::compiler/rustc_proc_macro}) + - Set({check::compiler/rustc_public}) + - Set({check::compiler/rustc_public_bridge}) + - Set({check::compiler/rustc_query_impl}) + - Set({check::compiler/rustc_query_system}) + - Set({check::compiler/rustc_resolve}) + - Set({check::compiler/rustc_sanitizers}) + - Set({check::compiler/rustc_serialize}) + - Set({check::compiler/rustc_session}) + - Set({check::compiler/rustc_span}) + - Set({check::compiler/rustc_symbol_mangling}) + - Set({check::compiler/rustc_target}) + - Set({check::compiler/rustc_thread_pool}) + - Set({check::compiler/rustc_trait_selection}) + - Set({check::compiler/rustc_traits}) + - Set({check::compiler/rustc_transmute}) + - Set({check::compiler/rustc_ty_utils}) + - Set({check::compiler/rustc_type_ir}) + - Set({check::compiler/rustc_type_ir_macros}) + - Set({check::compiler/rustc_windows_rc}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest.snap new file mode 100644 index 0000000000000..8f772bc55b82b --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: check compiletest +--- +[Check] check::Compiletest + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/compiletest}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest_include_default_paths.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest_include_default_paths.snap new file mode 100644 index 0000000000000..dae515c67ec6d --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest_include_default_paths.snap @@ -0,0 +1,137 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: check compiletest --include-default-paths +--- +[Check] check::Rustc + targets: [x86_64-unknown-linux-gnu] + - Set({check::compiler}) + - Set({check::compiler/rustc}) + - Set({check::compiler/rustc_abi}) + - Set({check::compiler/rustc_arena}) + - Set({check::compiler/rustc_ast}) + - Set({check::compiler/rustc_ast_ir}) + - Set({check::compiler/rustc_ast_lowering}) + - Set({check::compiler/rustc_ast_passes}) + - Set({check::compiler/rustc_ast_pretty}) + - Set({check::compiler/rustc_attr_parsing}) + - Set({check::compiler/rustc_baked_icu_data}) + - Set({check::compiler/rustc_borrowck}) + - Set({check::compiler/rustc_builtin_macros}) + - Set({check::compiler/rustc_codegen_llvm}) + - Set({check::compiler/rustc_codegen_ssa}) + - Set({check::compiler/rustc_const_eval}) + - Set({check::compiler/rustc_data_structures}) + - Set({check::compiler/rustc_driver}) + - Set({check::compiler/rustc_driver_impl}) + - Set({check::compiler/rustc_error_codes}) + - Set({check::compiler/rustc_error_messages}) + - Set({check::compiler/rustc_errors}) + - Set({check::compiler/rustc_expand}) + - Set({check::compiler/rustc_feature}) + - Set({check::compiler/rustc_fluent_macro}) + - Set({check::compiler/rustc_fs_util}) + - Set({check::compiler/rustc_graphviz}) + - Set({check::compiler/rustc_hashes}) + - Set({check::compiler/rustc_hir}) + - Set({check::compiler/rustc_hir_analysis}) + - Set({check::compiler/rustc_hir_id}) + - Set({check::compiler/rustc_hir_pretty}) + - Set({check::compiler/rustc_hir_typeck}) + - Set({check::compiler/rustc_incremental}) + - Set({check::compiler/rustc_index}) + - Set({check::compiler/rustc_index_macros}) + - Set({check::compiler/rustc_infer}) + - Set({check::compiler/rustc_interface}) + - Set({check::compiler/rustc_lexer}) + - Set({check::compiler/rustc_lint}) + - Set({check::compiler/rustc_lint_defs}) + - Set({check::compiler/rustc_llvm}) + - Set({check::compiler/rustc_log}) + - Set({check::compiler/rustc_macros}) + - Set({check::compiler/rustc_metadata}) + - Set({check::compiler/rustc_middle}) + - Set({check::compiler/rustc_mir_build}) + - Set({check::compiler/rustc_mir_dataflow}) + - Set({check::compiler/rustc_mir_transform}) + - Set({check::compiler/rustc_monomorphize}) + - Set({check::compiler/rustc_next_trait_solver}) + - Set({check::compiler/rustc_parse}) + - Set({check::compiler/rustc_parse_format}) + - Set({check::compiler/rustc_passes}) + - Set({check::compiler/rustc_pattern_analysis}) + - Set({check::compiler/rustc_privacy}) + - Set({check::compiler/rustc_proc_macro}) + - Set({check::compiler/rustc_public}) + - Set({check::compiler/rustc_public_bridge}) + - Set({check::compiler/rustc_query_impl}) + - Set({check::compiler/rustc_query_system}) + - Set({check::compiler/rustc_resolve}) + - Set({check::compiler/rustc_sanitizers}) + - Set({check::compiler/rustc_serialize}) + - Set({check::compiler/rustc_session}) + - Set({check::compiler/rustc_span}) + - Set({check::compiler/rustc_symbol_mangling}) + - Set({check::compiler/rustc_target}) + - Set({check::compiler/rustc_thread_pool}) + - Set({check::compiler/rustc_trait_selection}) + - Set({check::compiler/rustc_traits}) + - Set({check::compiler/rustc_transmute}) + - Set({check::compiler/rustc_ty_utils}) + - Set({check::compiler/rustc_type_ir}) + - Set({check::compiler/rustc_type_ir_macros}) + - Set({check::compiler/rustc_windows_rc}) +[Check] check::Rustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/librustdoc, check::src/tools/rustdoc}) +[Check] check::CraneliftCodegenBackend + targets: [x86_64-unknown-linux-gnu] + - Set({check::cg_clif}) + - Set({check::rustc_codegen_cranelift}) +[Check] check::GccCodegenBackend + targets: [x86_64-unknown-linux-gnu] + - Set({check::cg_gcc}) + - Set({check::rustc_codegen_gcc}) +[Check] check::Clippy + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/clippy}) +[Check] check::Miri + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/miri}) +[Check] check::CargoMiri + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/miri/cargo-miri}) +[Check] check::MiroptTestTools + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/miropt-test-tools}) +[Check] check::Rustfmt + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/rustfmt}) +[Check] check::RustAnalyzer + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/rust-analyzer}) +[Check] check::TestFloatParse + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/test-float-parse}) +[Check] check::FeaturesStatusDump + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/features-status-dump}) +[Check] check::Std + targets: [aarch64-unknown-linux-gnu] + - Set({check::library}) + - Set({check::library/alloc}) + - Set({check::library/alloctests}) + - Set({check::library/compiler-builtins/compiler-builtins}) + - Set({check::library/core}) + - Set({check::library/coretests}) + - Set({check::library/panic_abort}) + - Set({check::library/panic_unwind}) + - Set({check::library/proc_macro}) + - Set({check::library/rustc-std-workspace-core}) + - Set({check::library/std}) + - Set({check::library/std_detect}) + - Set({check::library/sysroot}) + - Set({check::library/test}) + - Set({check::library/unwind}) +[Check] check::Compiletest + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/compiletest}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_library.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_library.snap new file mode 100644 index 0000000000000..1a41aa98555b6 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_library.snap @@ -0,0 +1,21 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: check library +--- +[Check] check::Std + targets: [aarch64-unknown-linux-gnu] + - Set({check::library}) + - Set({check::library/alloc}) + - Set({check::library/alloctests}) + - Set({check::library/compiler-builtins/compiler-builtins}) + - Set({check::library/core}) + - Set({check::library/coretests}) + - Set({check::library/panic_abort}) + - Set({check::library/panic_unwind}) + - Set({check::library/proc_macro}) + - Set({check::library/rustc-std-workspace-core}) + - Set({check::library/std}) + - Set({check::library/std_detect}) + - Set({check::library/sysroot}) + - Set({check::library/test}) + - Set({check::library/unwind}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_rustc.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_rustc.snap new file mode 100644 index 0000000000000..9aed81d2c22d6 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_rustc.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: check rustc +--- +[Check] check::Rustc + targets: [x86_64-unknown-linux-gnu] + - Set({check::compiler/rustc}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_rustdoc.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_rustdoc.snap new file mode 100644 index 0000000000000..0a6b84f803c13 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_rustdoc.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: check rustdoc +--- +[Check] check::Rustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({check::src/tools/rustdoc}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_dist.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_dist.snap new file mode 100644 index 0000000000000..2fc8ca143dd0d --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_dist.snap @@ -0,0 +1,34 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: dist +--- +[Dist] dist::Docs + targets: [aarch64-unknown-linux-gnu] + - Set({dist::rust-docs}) +[Dist] dist::JsonDocs + targets: [aarch64-unknown-linux-gnu] + - Set({dist::rust-docs-json}) +[Dist] dist::Mingw + targets: [aarch64-unknown-linux-gnu] + - Set({dist::rust-mingw}) +[Dist] dist::Rustc + targets: [x86_64-unknown-linux-gnu] + - Set({dist::rustc}) +[Dist] dist::Std + targets: [aarch64-unknown-linux-gnu] + - Set({dist::rust-std}) +[Dist] dist::RustcDev + targets: [x86_64-unknown-linux-gnu] + - Set({dist::rustc-dev}) +[Dist] dist::Src + targets: [x86_64-unknown-linux-gnu] + - Set({dist::rust-src}) +[Dist] dist::RustDev + targets: [x86_64-unknown-linux-gnu] + - Set({dist::rust-dev}) +[Dist] dist::PlainSourceTarball + targets: [x86_64-unknown-linux-gnu] + - Set({dist::rustc-src}) +[Dist] dist::ReproducibleArtifacts + targets: [x86_64-unknown-linux-gnu] + - Set({dist::reproducible-artifacts}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap new file mode 100644 index 0000000000000..b9cb897a75697 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap @@ -0,0 +1,212 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test +--- +[Test] test::Tidy + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/tidy}) +[Test] test::Ui + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/ui) +[Test] test::Crashes + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/crashes) +[Test] test::Coverage + targets: [aarch64-unknown-linux-gnu] + - Set({test::coverage-map}) + - Set({test::coverage-run}) + - Suite(test::tests/coverage) +[Test] test::MirOpt + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/mir-opt) +[Test] test::CodegenLlvm + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/codegen-llvm) +[Test] test::CodegenUnits + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/codegen-units) +[Test] test::AssemblyLlvm + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/assembly-llvm) +[Test] test::Incremental + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/incremental) +[Test] test::Debuginfo + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/debuginfo) +[Test] test::UiFullDeps + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/ui-fulldeps) +[Test] test::Rustdoc + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc) +[Test] test::CoverageRunRustdoc + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/coverage-run-rustdoc) +[Test] test::Pretty + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/pretty) +[Test] test::CodegenCranelift + targets: [x86_64-unknown-linux-gnu] + - Set({test::compiler/rustc_codegen_cranelift}) +[Test] test::CodegenGCC + targets: [x86_64-unknown-linux-gnu] + - Set({test::compiler/rustc_codegen_gcc}) +[Test] test::Crate + targets: [aarch64-unknown-linux-gnu] + - Set({test::library/alloc}) + - Set({test::library/alloctests}) + - Set({test::library/compiler-builtins/compiler-builtins}) + - Set({test::library/core}) + - Set({test::library/coretests}) + - Set({test::library/panic_abort}) + - Set({test::library/panic_unwind}) + - Set({test::library/proc_macro}) + - Set({test::library/rustc-std-workspace-core}) + - Set({test::library/std}) + - Set({test::library/std_detect}) + - Set({test::library/sysroot}) + - Set({test::library/test}) + - Set({test::library/unwind}) +[Test] test::CrateLibrustc + targets: [x86_64-unknown-linux-gnu] + - Set({test::compiler}) + - Set({test::compiler/rustc}) + - Set({test::compiler/rustc_abi}) + - Set({test::compiler/rustc_arena}) + - Set({test::compiler/rustc_ast}) + - Set({test::compiler/rustc_ast_ir}) + - Set({test::compiler/rustc_ast_lowering}) + - Set({test::compiler/rustc_ast_passes}) + - Set({test::compiler/rustc_ast_pretty}) + - Set({test::compiler/rustc_attr_parsing}) + - Set({test::compiler/rustc_baked_icu_data}) + - Set({test::compiler/rustc_borrowck}) + - Set({test::compiler/rustc_builtin_macros}) + - Set({test::compiler/rustc_codegen_llvm}) + - Set({test::compiler/rustc_codegen_ssa}) + - Set({test::compiler/rustc_const_eval}) + - Set({test::compiler/rustc_data_structures}) + - Set({test::compiler/rustc_driver}) + - Set({test::compiler/rustc_driver_impl}) + - Set({test::compiler/rustc_error_codes}) + - Set({test::compiler/rustc_error_messages}) + - Set({test::compiler/rustc_errors}) + - Set({test::compiler/rustc_expand}) + - Set({test::compiler/rustc_feature}) + - Set({test::compiler/rustc_fluent_macro}) + - Set({test::compiler/rustc_fs_util}) + - Set({test::compiler/rustc_graphviz}) + - Set({test::compiler/rustc_hashes}) + - Set({test::compiler/rustc_hir}) + - Set({test::compiler/rustc_hir_analysis}) + - Set({test::compiler/rustc_hir_id}) + - Set({test::compiler/rustc_hir_pretty}) + - Set({test::compiler/rustc_hir_typeck}) + - Set({test::compiler/rustc_incremental}) + - Set({test::compiler/rustc_index}) + - Set({test::compiler/rustc_index_macros}) + - Set({test::compiler/rustc_infer}) + - Set({test::compiler/rustc_interface}) + - Set({test::compiler/rustc_lexer}) + - Set({test::compiler/rustc_lint}) + - Set({test::compiler/rustc_lint_defs}) + - Set({test::compiler/rustc_llvm}) + - Set({test::compiler/rustc_log}) + - Set({test::compiler/rustc_macros}) + - Set({test::compiler/rustc_metadata}) + - Set({test::compiler/rustc_middle}) + - Set({test::compiler/rustc_mir_build}) + - Set({test::compiler/rustc_mir_dataflow}) + - Set({test::compiler/rustc_mir_transform}) + - Set({test::compiler/rustc_monomorphize}) + - Set({test::compiler/rustc_next_trait_solver}) + - Set({test::compiler/rustc_parse}) + - Set({test::compiler/rustc_parse_format}) + - Set({test::compiler/rustc_passes}) + - Set({test::compiler/rustc_pattern_analysis}) + - Set({test::compiler/rustc_privacy}) + - Set({test::compiler/rustc_proc_macro}) + - Set({test::compiler/rustc_public}) + - Set({test::compiler/rustc_public_bridge}) + - Set({test::compiler/rustc_query_impl}) + - Set({test::compiler/rustc_query_system}) + - Set({test::compiler/rustc_resolve}) + - Set({test::compiler/rustc_sanitizers}) + - Set({test::compiler/rustc_serialize}) + - Set({test::compiler/rustc_session}) + - Set({test::compiler/rustc_span}) + - Set({test::compiler/rustc_symbol_mangling}) + - Set({test::compiler/rustc_target}) + - Set({test::compiler/rustc_thread_pool}) + - Set({test::compiler/rustc_trait_selection}) + - Set({test::compiler/rustc_traits}) + - Set({test::compiler/rustc_transmute}) + - Set({test::compiler/rustc_ty_utils}) + - Set({test::compiler/rustc_type_ir}) + - Set({test::compiler/rustc_type_ir_macros}) + - Set({test::compiler/rustc_windows_rc}) +[Test] test::CrateRustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/librustdoc, test::src/tools/rustdoc}) +[Test] test::CrateRustdocJsonTypes + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/rustdoc-json-types}) +[Test] test::CrateBootstrap + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/coverage-dump}) + - Set({test::src/tools/jsondoclint}) + - Set({test::src/tools/replace-version-placeholder}) + - Set({test::tidyselftest}) +[Test] test::Linkcheck + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/linkchecker}) +[Test] test::TierCheck + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/tier-check}) +[Test] test::RustAnalyzer + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rust-analyzer}) +[Test] test::ErrorIndex + targets: [x86_64-unknown-linux-gnu] + - Set({test::error-index}) + - Set({test::src/tools/error_index_generator}) +[Test] test::RustdocBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/rustdoc}) +[Test] test::UnstableBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/unstable-book}) +[Test] test::RustcBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/rustc}) +[Test] test::RustdocJSStd + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-js-std) +[Test] test::RustdocJSNotStd + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-js) +[Test] test::RustdocTheme + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rustdoc-themes}) +[Test] test::RustdocUi + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-ui) +[Test] test::RustdocJson + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-json) +[Test] test::HtmlCheck + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/html-checker}) +[Test] test::RustInstaller + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rust-installer}) +[Test] test::TestFloatParse + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/test-float-parse}) +[Test] test::RunMake + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/run-make) +[Test] test::RunMakeCargo + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/run-make-cargo) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_coverage.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_coverage.snap new file mode 100644 index 0000000000000..3b78d842dd704 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_coverage.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test coverage +--- +[Test] test::Coverage + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/coverage) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_coverage_map.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_coverage_map.snap new file mode 100644 index 0000000000000..fd79a0c8ad6ac --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_coverage_map.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test coverage-map +--- +[Test] test::Coverage + targets: [aarch64-unknown-linux-gnu] + - Set({test::coverage-map}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_coverage_run.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_coverage_run.snap new file mode 100644 index 0000000000000..8ffadc424348e --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_coverage_run.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test coverage-run +--- +[Test] test::Coverage + targets: [aarch64-unknown-linux-gnu] + - Set({test::coverage-run}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_coverage_skip_coverage_run.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_coverage_skip_coverage_run.snap new file mode 100644 index 0000000000000..76da4c82151ad --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_coverage_skip_coverage_run.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test coverage --skip=coverage-run +--- +[Test] test::Coverage + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/coverage) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_debuginfo.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_debuginfo.snap new file mode 100644 index 0000000000000..d462e1f7917d4 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_debuginfo.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test debuginfo +--- +[Test] test::Debuginfo + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/debuginfo) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc.snap new file mode 100644 index 0000000000000..bd217dbe692a4 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test librustdoc +--- +[Test] test::CrateRustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/librustdoc}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc_rustdoc.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc_rustdoc.snap new file mode 100644 index 0000000000000..6522a7e8edaf7 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc_rustdoc.snap @@ -0,0 +1,13 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test librustdoc rustdoc +--- +[Test] test::CrateRustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/librustdoc, test::src/tools/rustdoc}) +[Test] test::Rustdoc + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc) +[Test] test::RustdocBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/rustdoc}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_rustdoc.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_rustdoc.snap new file mode 100644 index 0000000000000..337ad33fe35fa --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_rustdoc.snap @@ -0,0 +1,13 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test rustdoc +--- +[Test] test::Rustdoc + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc) +[Test] test::CrateRustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rustdoc}) +[Test] test::RustdocBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/rustdoc}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap new file mode 100644 index 0000000000000..04253bba5ef7c --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap @@ -0,0 +1,211 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test --skip=coverage +--- +[Test] test::Tidy + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/tidy}) +[Test] test::Ui + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/ui) +[Test] test::Crashes + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/crashes) +[Test] test::Coverage + targets: [aarch64-unknown-linux-gnu] + - Set({test::coverage-map}) + - Set({test::coverage-run}) +[Test] test::MirOpt + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/mir-opt) +[Test] test::CodegenLlvm + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/codegen-llvm) +[Test] test::CodegenUnits + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/codegen-units) +[Test] test::AssemblyLlvm + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/assembly-llvm) +[Test] test::Incremental + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/incremental) +[Test] test::Debuginfo + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/debuginfo) +[Test] test::UiFullDeps + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/ui-fulldeps) +[Test] test::Rustdoc + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc) +[Test] test::CoverageRunRustdoc + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/coverage-run-rustdoc) +[Test] test::Pretty + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/pretty) +[Test] test::CodegenCranelift + targets: [x86_64-unknown-linux-gnu] + - Set({test::compiler/rustc_codegen_cranelift}) +[Test] test::CodegenGCC + targets: [x86_64-unknown-linux-gnu] + - Set({test::compiler/rustc_codegen_gcc}) +[Test] test::Crate + targets: [aarch64-unknown-linux-gnu] + - Set({test::library/alloc}) + - Set({test::library/alloctests}) + - Set({test::library/compiler-builtins/compiler-builtins}) + - Set({test::library/core}) + - Set({test::library/coretests}) + - Set({test::library/panic_abort}) + - Set({test::library/panic_unwind}) + - Set({test::library/proc_macro}) + - Set({test::library/rustc-std-workspace-core}) + - Set({test::library/std}) + - Set({test::library/std_detect}) + - Set({test::library/sysroot}) + - Set({test::library/test}) + - Set({test::library/unwind}) +[Test] test::CrateLibrustc + targets: [x86_64-unknown-linux-gnu] + - Set({test::compiler}) + - Set({test::compiler/rustc}) + - Set({test::compiler/rustc_abi}) + - Set({test::compiler/rustc_arena}) + - Set({test::compiler/rustc_ast}) + - Set({test::compiler/rustc_ast_ir}) + - Set({test::compiler/rustc_ast_lowering}) + - Set({test::compiler/rustc_ast_passes}) + - Set({test::compiler/rustc_ast_pretty}) + - Set({test::compiler/rustc_attr_parsing}) + - Set({test::compiler/rustc_baked_icu_data}) + - Set({test::compiler/rustc_borrowck}) + - Set({test::compiler/rustc_builtin_macros}) + - Set({test::compiler/rustc_codegen_llvm}) + - Set({test::compiler/rustc_codegen_ssa}) + - Set({test::compiler/rustc_const_eval}) + - Set({test::compiler/rustc_data_structures}) + - Set({test::compiler/rustc_driver}) + - Set({test::compiler/rustc_driver_impl}) + - Set({test::compiler/rustc_error_codes}) + - Set({test::compiler/rustc_error_messages}) + - Set({test::compiler/rustc_errors}) + - Set({test::compiler/rustc_expand}) + - Set({test::compiler/rustc_feature}) + - Set({test::compiler/rustc_fluent_macro}) + - Set({test::compiler/rustc_fs_util}) + - Set({test::compiler/rustc_graphviz}) + - Set({test::compiler/rustc_hashes}) + - Set({test::compiler/rustc_hir}) + - Set({test::compiler/rustc_hir_analysis}) + - Set({test::compiler/rustc_hir_id}) + - Set({test::compiler/rustc_hir_pretty}) + - Set({test::compiler/rustc_hir_typeck}) + - Set({test::compiler/rustc_incremental}) + - Set({test::compiler/rustc_index}) + - Set({test::compiler/rustc_index_macros}) + - Set({test::compiler/rustc_infer}) + - Set({test::compiler/rustc_interface}) + - Set({test::compiler/rustc_lexer}) + - Set({test::compiler/rustc_lint}) + - Set({test::compiler/rustc_lint_defs}) + - Set({test::compiler/rustc_llvm}) + - Set({test::compiler/rustc_log}) + - Set({test::compiler/rustc_macros}) + - Set({test::compiler/rustc_metadata}) + - Set({test::compiler/rustc_middle}) + - Set({test::compiler/rustc_mir_build}) + - Set({test::compiler/rustc_mir_dataflow}) + - Set({test::compiler/rustc_mir_transform}) + - Set({test::compiler/rustc_monomorphize}) + - Set({test::compiler/rustc_next_trait_solver}) + - Set({test::compiler/rustc_parse}) + - Set({test::compiler/rustc_parse_format}) + - Set({test::compiler/rustc_passes}) + - Set({test::compiler/rustc_pattern_analysis}) + - Set({test::compiler/rustc_privacy}) + - Set({test::compiler/rustc_proc_macro}) + - Set({test::compiler/rustc_public}) + - Set({test::compiler/rustc_public_bridge}) + - Set({test::compiler/rustc_query_impl}) + - Set({test::compiler/rustc_query_system}) + - Set({test::compiler/rustc_resolve}) + - Set({test::compiler/rustc_sanitizers}) + - Set({test::compiler/rustc_serialize}) + - Set({test::compiler/rustc_session}) + - Set({test::compiler/rustc_span}) + - Set({test::compiler/rustc_symbol_mangling}) + - Set({test::compiler/rustc_target}) + - Set({test::compiler/rustc_thread_pool}) + - Set({test::compiler/rustc_trait_selection}) + - Set({test::compiler/rustc_traits}) + - Set({test::compiler/rustc_transmute}) + - Set({test::compiler/rustc_ty_utils}) + - Set({test::compiler/rustc_type_ir}) + - Set({test::compiler/rustc_type_ir_macros}) + - Set({test::compiler/rustc_windows_rc}) +[Test] test::CrateRustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/librustdoc, test::src/tools/rustdoc}) +[Test] test::CrateRustdocJsonTypes + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/rustdoc-json-types}) +[Test] test::CrateBootstrap + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/coverage-dump}) + - Set({test::src/tools/jsondoclint}) + - Set({test::src/tools/replace-version-placeholder}) + - Set({test::tidyselftest}) +[Test] test::Linkcheck + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/linkchecker}) +[Test] test::TierCheck + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/tier-check}) +[Test] test::RustAnalyzer + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rust-analyzer}) +[Test] test::ErrorIndex + targets: [x86_64-unknown-linux-gnu] + - Set({test::error-index}) + - Set({test::src/tools/error_index_generator}) +[Test] test::RustdocBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/rustdoc}) +[Test] test::UnstableBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/unstable-book}) +[Test] test::RustcBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/rustc}) +[Test] test::RustdocJSStd + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-js-std) +[Test] test::RustdocJSNotStd + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-js) +[Test] test::RustdocTheme + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rustdoc-themes}) +[Test] test::RustdocUi + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-ui) +[Test] test::RustdocJson + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-json) +[Test] test::HtmlCheck + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/html-checker}) +[Test] test::RustInstaller + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rust-installer}) +[Test] test::TestFloatParse + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/test-float-parse}) +[Test] test::RunMake + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/run-make) +[Test] test::RunMakeCargo + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/run-make-cargo) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap new file mode 100644 index 0000000000000..f10589548f665 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap @@ -0,0 +1,157 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test --skip=tests +--- +[Test] test::Tidy + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/tidy}) +[Test] test::Coverage + targets: [aarch64-unknown-linux-gnu] + - Set({test::coverage-map}) + - Set({test::coverage-run}) +[Test] test::CodegenCranelift + targets: [x86_64-unknown-linux-gnu] + - Set({test::compiler/rustc_codegen_cranelift}) +[Test] test::CodegenGCC + targets: [x86_64-unknown-linux-gnu] + - Set({test::compiler/rustc_codegen_gcc}) +[Test] test::Crate + targets: [aarch64-unknown-linux-gnu] + - Set({test::library/alloc}) + - Set({test::library/alloctests}) + - Set({test::library/compiler-builtins/compiler-builtins}) + - Set({test::library/core}) + - Set({test::library/coretests}) + - Set({test::library/panic_abort}) + - Set({test::library/panic_unwind}) + - Set({test::library/proc_macro}) + - Set({test::library/rustc-std-workspace-core}) + - Set({test::library/std}) + - Set({test::library/std_detect}) + - Set({test::library/sysroot}) + - Set({test::library/test}) + - Set({test::library/unwind}) +[Test] test::CrateLibrustc + targets: [x86_64-unknown-linux-gnu] + - Set({test::compiler}) + - Set({test::compiler/rustc}) + - Set({test::compiler/rustc_abi}) + - Set({test::compiler/rustc_arena}) + - Set({test::compiler/rustc_ast}) + - Set({test::compiler/rustc_ast_ir}) + - Set({test::compiler/rustc_ast_lowering}) + - Set({test::compiler/rustc_ast_passes}) + - Set({test::compiler/rustc_ast_pretty}) + - Set({test::compiler/rustc_attr_parsing}) + - Set({test::compiler/rustc_baked_icu_data}) + - Set({test::compiler/rustc_borrowck}) + - Set({test::compiler/rustc_builtin_macros}) + - Set({test::compiler/rustc_codegen_llvm}) + - Set({test::compiler/rustc_codegen_ssa}) + - Set({test::compiler/rustc_const_eval}) + - Set({test::compiler/rustc_data_structures}) + - Set({test::compiler/rustc_driver}) + - Set({test::compiler/rustc_driver_impl}) + - Set({test::compiler/rustc_error_codes}) + - Set({test::compiler/rustc_error_messages}) + - Set({test::compiler/rustc_errors}) + - Set({test::compiler/rustc_expand}) + - Set({test::compiler/rustc_feature}) + - Set({test::compiler/rustc_fluent_macro}) + - Set({test::compiler/rustc_fs_util}) + - Set({test::compiler/rustc_graphviz}) + - Set({test::compiler/rustc_hashes}) + - Set({test::compiler/rustc_hir}) + - Set({test::compiler/rustc_hir_analysis}) + - Set({test::compiler/rustc_hir_id}) + - Set({test::compiler/rustc_hir_pretty}) + - Set({test::compiler/rustc_hir_typeck}) + - Set({test::compiler/rustc_incremental}) + - Set({test::compiler/rustc_index}) + - Set({test::compiler/rustc_index_macros}) + - Set({test::compiler/rustc_infer}) + - Set({test::compiler/rustc_interface}) + - Set({test::compiler/rustc_lexer}) + - Set({test::compiler/rustc_lint}) + - Set({test::compiler/rustc_lint_defs}) + - Set({test::compiler/rustc_llvm}) + - Set({test::compiler/rustc_log}) + - Set({test::compiler/rustc_macros}) + - Set({test::compiler/rustc_metadata}) + - Set({test::compiler/rustc_middle}) + - Set({test::compiler/rustc_mir_build}) + - Set({test::compiler/rustc_mir_dataflow}) + - Set({test::compiler/rustc_mir_transform}) + - Set({test::compiler/rustc_monomorphize}) + - Set({test::compiler/rustc_next_trait_solver}) + - Set({test::compiler/rustc_parse}) + - Set({test::compiler/rustc_parse_format}) + - Set({test::compiler/rustc_passes}) + - Set({test::compiler/rustc_pattern_analysis}) + - Set({test::compiler/rustc_privacy}) + - Set({test::compiler/rustc_proc_macro}) + - Set({test::compiler/rustc_public}) + - Set({test::compiler/rustc_public_bridge}) + - Set({test::compiler/rustc_query_impl}) + - Set({test::compiler/rustc_query_system}) + - Set({test::compiler/rustc_resolve}) + - Set({test::compiler/rustc_sanitizers}) + - Set({test::compiler/rustc_serialize}) + - Set({test::compiler/rustc_session}) + - Set({test::compiler/rustc_span}) + - Set({test::compiler/rustc_symbol_mangling}) + - Set({test::compiler/rustc_target}) + - Set({test::compiler/rustc_thread_pool}) + - Set({test::compiler/rustc_trait_selection}) + - Set({test::compiler/rustc_traits}) + - Set({test::compiler/rustc_transmute}) + - Set({test::compiler/rustc_ty_utils}) + - Set({test::compiler/rustc_type_ir}) + - Set({test::compiler/rustc_type_ir_macros}) + - Set({test::compiler/rustc_windows_rc}) +[Test] test::CrateRustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/librustdoc, test::src/tools/rustdoc}) +[Test] test::CrateRustdocJsonTypes + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/rustdoc-json-types}) +[Test] test::CrateBootstrap + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/coverage-dump}) + - Set({test::src/tools/jsondoclint}) + - Set({test::src/tools/replace-version-placeholder}) + - Set({test::tidyselftest}) +[Test] test::Linkcheck + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/linkchecker}) +[Test] test::TierCheck + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/tier-check}) +[Test] test::RustAnalyzer + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rust-analyzer}) +[Test] test::ErrorIndex + targets: [x86_64-unknown-linux-gnu] + - Set({test::error-index}) + - Set({test::src/tools/error_index_generator}) +[Test] test::RustdocBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/rustdoc}) +[Test] test::UnstableBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/unstable-book}) +[Test] test::RustcBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/rustc}) +[Test] test::RustdocTheme + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rustdoc-themes}) +[Test] test::HtmlCheck + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/html-checker}) +[Test] test::RustInstaller + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rust-installer}) +[Test] test::TestFloatParse + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/test-float-parse}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_etc.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_etc.snap new file mode 100644 index 0000000000000..65e05dfaef2d9 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_etc.snap @@ -0,0 +1,136 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test --skip=tests --skip=coverage-map --skip=coverage-run --skip=library --skip=tidyselftest +--- +[Test] test::Tidy + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/tidy}) +[Test] test::CodegenCranelift + targets: [x86_64-unknown-linux-gnu] + - Set({test::compiler/rustc_codegen_cranelift}) +[Test] test::CodegenGCC + targets: [x86_64-unknown-linux-gnu] + - Set({test::compiler/rustc_codegen_gcc}) +[Test] test::CrateLibrustc + targets: [x86_64-unknown-linux-gnu] + - Set({test::compiler}) + - Set({test::compiler/rustc}) + - Set({test::compiler/rustc_abi}) + - Set({test::compiler/rustc_arena}) + - Set({test::compiler/rustc_ast}) + - Set({test::compiler/rustc_ast_ir}) + - Set({test::compiler/rustc_ast_lowering}) + - Set({test::compiler/rustc_ast_passes}) + - Set({test::compiler/rustc_ast_pretty}) + - Set({test::compiler/rustc_attr_parsing}) + - Set({test::compiler/rustc_baked_icu_data}) + - Set({test::compiler/rustc_borrowck}) + - Set({test::compiler/rustc_builtin_macros}) + - Set({test::compiler/rustc_codegen_llvm}) + - Set({test::compiler/rustc_codegen_ssa}) + - Set({test::compiler/rustc_const_eval}) + - Set({test::compiler/rustc_data_structures}) + - Set({test::compiler/rustc_driver}) + - Set({test::compiler/rustc_driver_impl}) + - Set({test::compiler/rustc_error_codes}) + - Set({test::compiler/rustc_error_messages}) + - Set({test::compiler/rustc_errors}) + - Set({test::compiler/rustc_expand}) + - Set({test::compiler/rustc_feature}) + - Set({test::compiler/rustc_fluent_macro}) + - Set({test::compiler/rustc_fs_util}) + - Set({test::compiler/rustc_graphviz}) + - Set({test::compiler/rustc_hashes}) + - Set({test::compiler/rustc_hir}) + - Set({test::compiler/rustc_hir_analysis}) + - Set({test::compiler/rustc_hir_id}) + - Set({test::compiler/rustc_hir_pretty}) + - Set({test::compiler/rustc_hir_typeck}) + - Set({test::compiler/rustc_incremental}) + - Set({test::compiler/rustc_index}) + - Set({test::compiler/rustc_index_macros}) + - Set({test::compiler/rustc_infer}) + - Set({test::compiler/rustc_interface}) + - Set({test::compiler/rustc_lexer}) + - Set({test::compiler/rustc_lint}) + - Set({test::compiler/rustc_lint_defs}) + - Set({test::compiler/rustc_llvm}) + - Set({test::compiler/rustc_log}) + - Set({test::compiler/rustc_macros}) + - Set({test::compiler/rustc_metadata}) + - Set({test::compiler/rustc_middle}) + - Set({test::compiler/rustc_mir_build}) + - Set({test::compiler/rustc_mir_dataflow}) + - Set({test::compiler/rustc_mir_transform}) + - Set({test::compiler/rustc_monomorphize}) + - Set({test::compiler/rustc_next_trait_solver}) + - Set({test::compiler/rustc_parse}) + - Set({test::compiler/rustc_parse_format}) + - Set({test::compiler/rustc_passes}) + - Set({test::compiler/rustc_pattern_analysis}) + - Set({test::compiler/rustc_privacy}) + - Set({test::compiler/rustc_proc_macro}) + - Set({test::compiler/rustc_public}) + - Set({test::compiler/rustc_public_bridge}) + - Set({test::compiler/rustc_query_impl}) + - Set({test::compiler/rustc_query_system}) + - Set({test::compiler/rustc_resolve}) + - Set({test::compiler/rustc_sanitizers}) + - Set({test::compiler/rustc_serialize}) + - Set({test::compiler/rustc_session}) + - Set({test::compiler/rustc_span}) + - Set({test::compiler/rustc_symbol_mangling}) + - Set({test::compiler/rustc_target}) + - Set({test::compiler/rustc_thread_pool}) + - Set({test::compiler/rustc_trait_selection}) + - Set({test::compiler/rustc_traits}) + - Set({test::compiler/rustc_transmute}) + - Set({test::compiler/rustc_ty_utils}) + - Set({test::compiler/rustc_type_ir}) + - Set({test::compiler/rustc_type_ir_macros}) + - Set({test::compiler/rustc_windows_rc}) +[Test] test::CrateRustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/librustdoc, test::src/tools/rustdoc}) +[Test] test::CrateRustdocJsonTypes + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/rustdoc-json-types}) +[Test] test::CrateBootstrap + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/coverage-dump}) + - Set({test::src/tools/jsondoclint}) + - Set({test::src/tools/replace-version-placeholder}) +[Test] test::Linkcheck + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/linkchecker}) +[Test] test::TierCheck + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/tier-check}) +[Test] test::RustAnalyzer + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rust-analyzer}) +[Test] test::ErrorIndex + targets: [x86_64-unknown-linux-gnu] + - Set({test::error-index}) + - Set({test::src/tools/error_index_generator}) +[Test] test::RustdocBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/rustdoc}) +[Test] test::UnstableBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/unstable-book}) +[Test] test::RustcBook + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/doc/rustc}) +[Test] test::RustdocTheme + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rustdoc-themes}) +[Test] test::HtmlCheck + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/html-checker}) +[Test] test::RustInstaller + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/rust-installer}) +[Test] test::TestFloatParse + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/test-float-parse}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap new file mode 100644 index 0000000000000..b38af13d49c32 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap @@ -0,0 +1,64 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test tests +--- +[Test] test::AssemblyLlvm + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/assembly-llvm) +[Test] test::CodegenLlvm + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/codegen-llvm) +[Test] test::CodegenUnits + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/codegen-units) +[Test] test::Coverage + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/coverage) +[Test] test::CoverageRunRustdoc + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/coverage-run-rustdoc) +[Test] test::Crashes + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/crashes) +[Test] test::Debuginfo + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/debuginfo) +[Test] test::Incremental + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/incremental) +[Test] test::MirOpt + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/mir-opt) +[Test] test::Pretty + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/pretty) +[Test] test::RunMake + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/run-make) +[Test] test::RunMakeCargo + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/run-make-cargo) +[Test] test::Rustdoc + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc) +[Test] test::RustdocGUI + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-gui) +[Test] test::RustdocJSNotStd + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-js) +[Test] test::RustdocJSStd + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-js-std) +[Test] test::RustdocJson + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-json) +[Test] test::RustdocUi + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-ui) +[Test] test::Ui + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/ui) +[Test] test::UiFullDeps + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/ui-fulldeps) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap new file mode 100644 index 0000000000000..6a158ea62bb37 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap @@ -0,0 +1,61 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test tests --skip=coverage +--- +[Test] test::AssemblyLlvm + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/assembly-llvm) +[Test] test::CodegenLlvm + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/codegen-llvm) +[Test] test::CodegenUnits + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/codegen-units) +[Test] test::CoverageRunRustdoc + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/coverage-run-rustdoc) +[Test] test::Crashes + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/crashes) +[Test] test::Debuginfo + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/debuginfo) +[Test] test::Incremental + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/incremental) +[Test] test::MirOpt + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/mir-opt) +[Test] test::Pretty + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/pretty) +[Test] test::RunMake + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/run-make) +[Test] test::RunMakeCargo + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/run-make-cargo) +[Test] test::Rustdoc + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc) +[Test] test::RustdocGUI + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-gui) +[Test] test::RustdocJSNotStd + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-js) +[Test] test::RustdocJSStd + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-js-std) +[Test] test::RustdocJson + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-json) +[Test] test::RustdocUi + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-ui) +[Test] test::Ui + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/ui) +[Test] test::UiFullDeps + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/ui-fulldeps) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_ui.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_ui.snap new file mode 100644 index 0000000000000..1288af72fd5d2 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_ui.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test tests/ui +--- +[Test] test::Ui + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/ui) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tidy.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tidy.snap new file mode 100644 index 0000000000000..b2bebf39e120c --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tidy.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test tidy +--- +[Test] test::Tidy + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/tools/tidy}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tidyselftest.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tidyselftest.snap new file mode 100644 index 0000000000000..945c82ef1cd02 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tidyselftest.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test tidyselftest +--- +[Test] test::CrateBootstrap + targets: [x86_64-unknown-linux-gnu] + - Set({test::tidyselftest}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_ui.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_ui.snap new file mode 100644 index 0000000000000..5c764959cdaef --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_ui.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test ui +--- +[Test] test::Ui + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/ui) diff --git a/src/bootstrap/src/core/builder/cli_paths/tests.rs b/src/bootstrap/src/core/builder/cli_paths/tests.rs new file mode 100644 index 0000000000000..071cfa0e86e3f --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/tests.rs @@ -0,0 +1,171 @@ +use std::collections::{BTreeSet, HashSet}; +use std::fs; +use std::path::{Path, PathBuf}; +use std::sync::{Arc, Mutex}; + +use crate::Build; +use crate::core::builder::cli_paths::match_paths_to_steps_and_run; +use crate::core::builder::{Builder, StepDescription}; +use crate::utils::tests::TestCtx; + +fn render_steps_for_cli_args(args_str: &str) -> String { + // Split a single string into a step kind and subsequent arguments. + // E.g. "test ui" => ("test", &["ui"]) + let args = args_str.split_ascii_whitespace().collect::>(); + let (kind, args) = args.split_first().unwrap(); + + // Arbitrary tuple to represent the host system. + let hosts = &["x86_64-unknown-linux-gnu"]; + // Arbitrary tuple to represent the target system, which might not be the host. + let targets = &["aarch64-unknown-linux-gnu"]; + + let config = TestCtx::new() + .config(kind) + // `test::Bootstrap` is only run by default in CI, causing inconsistency. + .arg("--ci=false") + .args(args) + .hosts(hosts) + .targets(targets) + .create_config(); + let mut build = Build::new(config); + // Some rustdoc test steps are only run by default if nodejs is + // configured/discovered, causing inconsistency. + build.config.nodejs = Some(PathBuf::from("node")); + let mut builder = Builder::new(&build); + + // Tell the builder to log steps that it would run, instead of running them. + let mut buf = Arc::new(Mutex::new(String::new())); + let buf2 = Arc::clone(&buf); + builder.log_cli_step_for_tests = Some(Box::new(move |step_desc, pathsets, targets| { + use std::fmt::Write; + let mut buf = buf2.lock().unwrap(); + + let StepDescription { name, kind, .. } = step_desc; + // Strip boilerplate to make step names easier to read. + let name = name.strip_prefix("bootstrap::core::build_steps::").unwrap_or(name); + + writeln!(buf, "[{kind:?}] {name}").unwrap(); + writeln!(buf, " targets: {targets:?}").unwrap(); + for pathset in pathsets { + writeln!(buf, " - {pathset:?}").unwrap(); + } + })); + + builder.execute_cli(); + + String::clone(&buf.lock().unwrap()) +} + +fn snapshot_test_inner(name: &str, args_str: &str) { + let mut settings = insta::Settings::clone_current(); + // Use the test name as the snapshot filename, not its whole fully-qualified name. + settings.set_prepend_module_to_snapshot(false); + settings.bind(|| { + insta::assert_snapshot!(name, render_steps_for_cli_args(args_str), args_str); + }); +} + +/// Keep the snapshots directory tidy by forbidding `.snap` files that don't +/// correspond to a test name. +fn no_unused_snapshots_inner(known_test_names: &[&str]) { + let known_test_names = known_test_names.iter().copied().collect::>(); + + let mut unexpected_file_names = BTreeSet::new(); + + // FIXME(Zalathar): Is there a better way to locate the snapshots dir? + for entry in walkdir::WalkDir::new("src/core/builder/cli_paths/snapshots") + .into_iter() + .map(Result::unwrap) + { + let meta = entry.metadata().unwrap(); + if !meta.is_file() { + continue; + } + + let name = entry.file_name().to_str().unwrap(); + if let Some(name_stub) = name.strip_suffix(".snap") + && !known_test_names.contains(name_stub) + { + unexpected_file_names.insert(name.to_owned()); + } + } + + assert!( + unexpected_file_names.is_empty(), + "Found snapshot files that don't correspond to a test name: {unexpected_file_names:#?}", + ); +} + +macro_rules! declare_tests { + ( + $( ($name:ident, $args:literal) ),* $(,)? + ) => { + $( + #[test] + fn $name() { + snapshot_test_inner(stringify!($name), $args); + } + )* + + #[test] + fn no_unused_snapshots() { + let known_test_names = &[ $( stringify!($name), )* ]; + no_unused_snapshots_inner(known_test_names); + } + }; +} + +// Snapshot tests for bootstrap's command-line path-to-step handling. +// +// To bless these tests as necessary, choose one: +// - Run `INSTA_UPDATE=always ./x test bootstrap` +// - Run `./x test bootstrap --bless` +// - Follow the instructions for `cargo-insta` in bootstrap's README.md +// +// These snapshot tests capture _current_ behavior, to prevent unintended +// changes or regressions. If the current behavior is wrong or undersirable, +// then any fix will necessarily have to re-bless the affected tests! +declare_tests!( + // tidy-alphabetical-start + (x_build, "build"), + (x_build_compiler, "build compiler"), + (x_build_compiletest, "build compiletest"), + (x_build_llvm, "build llvm"), + (x_build_rustc, "build rustc"), + (x_build_rustc_llvm, "build rustc_llvm"), + (x_build_rustdoc, "build rustdoc"), + (x_check, "check"), + (x_check_bootstrap, "check bootstrap"), + (x_check_compiler, "check compiler"), + (x_check_compiletest, "check compiletest"), + (x_check_compiletest_include_default_paths, "check compiletest --include-default-paths"), + (x_check_library, "check library"), + (x_check_rustc, "check rustc"), + (x_check_rustdoc, "check rustdoc"), + (x_dist, "dist"), + (x_test, "test"), + (x_test_coverage, "test coverage"), + (x_test_coverage_map, "test coverage-map"), + (x_test_coverage_run, "test coverage-run"), + // FIXME(Zalathar): Currently this doesn't actually skip the coverage-run tests! + (x_test_coverage_skip_coverage_run, "test coverage --skip=coverage-run"), + (x_test_debuginfo, "test debuginfo"), + (x_test_librustdoc, "test librustdoc"), + (x_test_librustdoc_rustdoc, "test librustdoc rustdoc"), + (x_test_rustdoc, "test rustdoc"), + (x_test_skip_coverage, "test --skip=coverage"), + // FIXME(Zalathar): This doesn't skip the coverage-map or coverage-run tests. + (x_test_skip_tests, "test --skip=tests"), + // From `src/ci/docker/scripts/stage_2_test_set2.sh`. + ( + x_test_skip_tests_etc, + "test --skip=tests --skip=coverage-map --skip=coverage-run --skip=library --skip=tidyselftest" + ), + (x_test_tests, "test tests"), + (x_test_tests_skip_coverage, "test tests --skip=coverage"), + (x_test_tests_ui, "test tests/ui"), + (x_test_tidy, "test tidy"), + (x_test_tidyselftest, "test tidyselftest"), + (x_test_ui, "test ui"), + // tidy-alphabetical-end +); diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 43faf92fe6d9b..9124442e7f376 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -66,6 +66,12 @@ pub struct Builder<'a> { /// Cached list of submodules from self.build.src. submodule_paths_cache: OnceLock>, + + /// When enabled by tests, this causes the top-level steps that _would_ be + /// executed to be logged instead. Used by snapshot tests of command-line + /// paths-to-steps handling. + #[expect(clippy::type_complexity)] + log_cli_step_for_tests: Option>, } impl Deref for Builder<'_> { @@ -447,6 +453,13 @@ impl StepDescription { // Determine the targets participating in this rule. let targets = if self.is_host { &builder.hosts } else { &builder.targets }; + // Log the step that's about to run, for snapshot tests. + if let Some(ref log_cli_step) = builder.log_cli_step_for_tests { + log_cli_step(self, &pathsets, targets); + // Return so that the step won't actually run in snapshot tests. + return; + } + for target in targets { let run = RunConfig { builder, paths: pathsets.clone(), target: *target }; (self.make_run)(run); @@ -1079,6 +1092,7 @@ impl<'a> Builder<'a> { time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), paths, submodule_paths_cache: Default::default(), + log_cli_step_for_tests: None, } } diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index cbefb836c0044..42d9b00f004ae 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -143,14 +143,13 @@ pub fn check_path_modifications( /// Returns true if any of the passed `paths` have changed since the `base` commit. pub fn has_changed_since(git_dir: &Path, base: &str, paths: &[&str]) -> bool { - let mut git = Command::new("git"); - git.current_dir(git_dir); + run_git_diff_index(Some(git_dir), |cmd| { + cmd.args(["--quiet", base, "--"]).args(paths); - git.args(["diff-index", "--quiet", base, "--"]).args(paths); - - // Exit code 0 => no changes - // Exit code 1 => some changes were detected - !git.status().expect("cannot run git diff-index").success() + // Exit code 0 => no changes + // Exit code 1 => some changes were detected + !cmd.status().expect("cannot run git diff-index").success() + }) } /// Returns the latest upstream commit that modified `target_paths`, or `None` if no such commit @@ -267,31 +266,49 @@ pub fn get_git_modified_files( return Err("No upstream commit was found".to_string()); }; - let mut git = Command::new("git"); - if let Some(git_dir) = git_dir { - git.current_dir(git_dir); - } - let files = output_result(git.args(["diff-index", "--name-status", merge_base.trim()]))? - .lines() - .filter_map(|f| { - let (status, name) = f.trim().split_once(char::is_whitespace).unwrap(); - if status == "D" { - None - } else if Path::new(name).extension().map_or(extensions.is_empty(), |ext| { - // If there is no extension, we allow the path if `extensions` is empty - // If there is an extension, we allow it if `extension` is empty or it contains the - // extension. - extensions.is_empty() || extensions.contains(&ext.to_str().unwrap()) - }) { - Some(name.to_owned()) - } else { - None - } - }) - .collect(); + let files = run_git_diff_index(git_dir, |cmd| { + output_result(cmd.args(["--name-status", merge_base.trim()])) + })? + .lines() + .filter_map(|f| { + let (status, name) = f.trim().split_once(char::is_whitespace).unwrap(); + if status == "D" { + None + } else if Path::new(name).extension().map_or(extensions.is_empty(), |ext| { + // If there is no extension, we allow the path if `extensions` is empty + // If there is an extension, we allow it if `extension` is empty or it contains the + // extension. + extensions.is_empty() || extensions.contains(&ext.to_str().unwrap()) + }) { + Some(name.to_owned()) + } else { + None + } + }) + .collect(); Ok(files) } +/// diff-index can return outdated information, because it does not update the git index. +/// This function uses `update-index` to update the index first, and then provides `func` with a +/// command prepared to run `git diff-index`. +fn run_git_diff_index(git_dir: Option<&Path>, func: F) -> T +where + F: FnOnce(&mut Command) -> T, +{ + let git = || { + let mut git = Command::new("git"); + if let Some(git_dir) = git_dir { + git.current_dir(git_dir); + } + git + }; + + // We ignore the exit code, as it errors out when some files are modified. + let _ = output_result(git().args(["update-index", "--refresh", "-q"])); + func(git().arg("diff-index")) +} + /// Returns the files that haven't been added to git yet. pub fn get_git_untracked_files(git_dir: Option<&Path>) -> Result>, String> { let mut git = Command::new("git"); diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 63412e2b9373d..e1408bb7e5bce 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -24,6 +24,7 @@ smallvec = "1.8.1" stringdex = "=0.0.2" tempfile = "3" threadpool = "1.8.1" +tikv-jemalloc-sys = { version = "0.6.1", optional = true, features = ['override_allocator_on_supported_platforms'] } tracing = "0.1" tracing-tree = "0.3.0" unicode-segmentation = "1.9" @@ -42,7 +43,7 @@ minifier = { version = "0.3.2", default-features = false } expect-test = "1.4.0" [features] -jemalloc = [] +jemalloc = ["dep:tikv-jemalloc-sys"] [package.metadata.rust-analyzer] rustc_private = true diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index b470af50f68fe..70ba02d3c8d88 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -227,6 +227,30 @@ pub(crate) fn item_relative_path(tcx: TyCtxt<'_>, def_id: DefId) -> Vec tcx.def_path(def_id).data.into_iter().filter_map(|elem| elem.data.get_opt_name()).collect() } +/// Get the public Rust path to an item. This is used to generate the URL to the item's page. +/// +/// In particular: we handle macro differently: if it's not a macro 2.0 oe a built-in macro, then +/// it is generated at the top-level of the crate and its path will be `[crate_name, macro_name]`. +pub(crate) fn get_item_path(tcx: TyCtxt<'_>, def_id: DefId, kind: ItemType) -> Vec { + let crate_name = tcx.crate_name(def_id.krate); + let relative = item_relative_path(tcx, def_id); + + if let ItemType::Macro = kind { + // Check to see if it is a macro 2.0 or built-in macro + // More information in . + if matches!( + CStore::from_tcx(tcx).load_macro_untracked(def_id, tcx), + LoadedMacro::MacroDef { def, .. } if !def.macro_rules + ) { + once(crate_name).chain(relative).collect() + } else { + vec![crate_name, *relative.last().expect("relative was empty")] + } + } else { + once(crate_name).chain(relative).collect() + } +} + /// Record an external fully qualified name in the external_paths cache. /// /// These names are used later on by HTML rendering to generate things like @@ -240,27 +264,12 @@ pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemT return; } - let crate_name = cx.tcx.crate_name(did.krate); - - let relative = item_relative_path(cx.tcx, did); - let fqn = if let ItemType::Macro = kind { - // Check to see if it is a macro 2.0 or built-in macro - if matches!( - CStore::from_tcx(cx.tcx).load_macro_untracked(did, cx.tcx), - LoadedMacro::MacroDef { def, .. } if !def.macro_rules - ) { - once(crate_name).chain(relative).collect() - } else { - vec![crate_name, *relative.last().expect("relative was empty")] - } - } else { - once(crate_name).chain(relative).collect() - }; + let item_path = get_item_path(cx.tcx, did, kind); if did.is_local() { - cx.cache.exact_paths.insert(did, fqn); + cx.cache.exact_paths.insert(did, item_path); } else { - cx.cache.external_paths.insert(did, (fqn, kind)); + cx.cache.external_paths.insert(did, (item_path, kind)); } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 73d0f40275404..6e4c65dc91273 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -40,6 +40,7 @@ use crate::clean::utils::{is_literal_expr, print_evaluated_const}; use crate::core::DocContext; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; +use crate::html::format::HrefInfo; use crate::html::render::Context; use crate::passes::collect_intra_doc_links::UrlFragment; @@ -519,16 +520,16 @@ impl Item { .iter() .filter_map(|ItemLink { link: s, link_text, page_id: id, fragment }| { debug!(?id); - if let Ok((mut href, ..)) = href(*id, cx) { - debug!(?href); + if let Ok(HrefInfo { mut url, .. }) = href(*id, cx) { + debug!(?url); if let Some(ref fragment) = *fragment { - fragment.render(&mut href, cx.tcx()) + fragment.render(&mut url, cx.tcx()) } Some(RenderedLink { original_text: s.clone(), new_text: link_text.clone(), tooltip: link_tooltip(*id, fragment, cx).to_string(), - href, + href: url, }) } else { None diff --git a/src/librustdoc/display.rs b/src/librustdoc/display.rs index d62ea4c368804..550be1ae89588 100644 --- a/src/librustdoc/display.rs +++ b/src/librustdoc/display.rs @@ -10,19 +10,18 @@ pub(crate) trait Joined: IntoIterator { /// /// The performance of `joined` is slightly better than `format`, since it doesn't need to use a `Cell` to keep track of whether [`fmt`](Display::fmt) /// was already called (`joined`'s API doesn't allow it be called more than once). - fn joined(self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result; + fn joined(&mut self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result; } impl Joined for I where - I: IntoIterator, + I: Iterator, T: Display, { - fn joined(self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result { - let mut iter = self.into_iter(); - let Some(first) = iter.next() else { return Ok(()) }; + fn joined(&mut self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result { + let Some(first) = self.next() else { return Ok(()) }; first.fmt(f)?; - for item in iter { + for item in self { sep.fmt(f)?; item.fmt(f)?; } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 337429a6248d9..4843c20c758e6 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -17,10 +17,10 @@ use rustc_abi::ExternAbi; use rustc_ast::join_path_syms; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; -use rustc_hir::def::DefKind; +use rustc_hir::def::{DefKind, MacroKinds}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::{ConstStability, StabilityLevel, StableSince}; -use rustc_metadata::creader::{CStore, LoadedMacro}; +use rustc_metadata::creader::CStore; use rustc_middle::ty::{self, TyCtxt, TypingMode}; use rustc_span::symbol::kw; use rustc_span::{Symbol, sym}; @@ -349,38 +349,44 @@ pub(crate) enum HrefError { UnnamableItem, } +/// Type representing information of an `href` attribute. +pub(crate) struct HrefInfo { + /// URL to the item page. + pub(crate) url: String, + /// Kind of the item (used to generate the `title` attribute). + pub(crate) kind: ItemType, + /// Rust path to the item (used to generate the `title` attribute). + pub(crate) rust_path: Vec, +} + /// This function is to get the external macro path because they are not in the cache used in /// `href_with_root_path`. fn generate_macro_def_id_path( def_id: DefId, cx: &Context<'_>, root_path: Option<&str>, -) -> Result<(String, ItemType, Vec), HrefError> { +) -> Result { let tcx = cx.tcx(); let crate_name = tcx.crate_name(def_id.krate); let cache = cx.cache(); - let fqp = clean::inline::item_relative_path(tcx, def_id); - let mut relative = fqp.iter().copied(); let cstore = CStore::from_tcx(tcx); // We need this to prevent a `panic` when this function is used from intra doc links... if !cstore.has_crate_data(def_id.krate) { debug!("No data for crate {crate_name}"); return Err(HrefError::NotInExternalCache); } - // Check to see if it is a macro 2.0 or built-in macro. - // More information in . - let is_macro_2 = match cstore.load_macro_untracked(def_id, tcx) { - // If `def.macro_rules` is `true`, then it's not a macro 2.0. - LoadedMacro::MacroDef { def, .. } => !def.macro_rules, - _ => false, + let DefKind::Macro(kinds) = tcx.def_kind(def_id) else { + unreachable!(); }; - - let mut path = if is_macro_2 { - once(crate_name).chain(relative).collect() + let item_type = if kinds == MacroKinds::DERIVE { + ItemType::ProcDerive + } else if kinds == MacroKinds::ATTR { + ItemType::ProcAttribute } else { - vec![crate_name, relative.next_back().unwrap()] + ItemType::Macro }; + let mut path = clean::inline::get_item_path(tcx, def_id, item_type); if path.len() < 2 { // The minimum we can have is the crate name followed by the macro name. If shorter, then // it means that `relative` was empty, which is an error. @@ -388,8 +394,11 @@ fn generate_macro_def_id_path( return Err(HrefError::NotInExternalCache); } - if let Some(last) = path.last_mut() { - *last = Symbol::intern(&format!("macro.{last}.html")); + // FIXME: Try to use `iter().chain().once()` instead. + let mut prev = None; + if let Some(last) = path.pop() { + path.push(Symbol::intern(&format!("{}.{last}.html", item_type.as_str()))); + prev = Some(last); } let url = match cache.extern_locations[&def_id.krate] { @@ -410,7 +419,11 @@ fn generate_macro_def_id_path( return Err(HrefError::NotInExternalCache); } }; - Ok((url, ItemType::Macro, fqp)) + if let Some(prev) = prev { + path.pop(); + path.push(prev); + } + Ok(HrefInfo { url, kind: item_type, rust_path: path }) } fn generate_item_def_id_path( @@ -419,7 +432,7 @@ fn generate_item_def_id_path( cx: &Context<'_>, root_path: Option<&str>, original_def_kind: DefKind, -) -> Result<(String, ItemType, Vec), HrefError> { +) -> Result { use rustc_middle::traits::ObligationCause; use rustc_trait_selection::infer::TyCtxtInferExt; use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; @@ -455,7 +468,7 @@ fn generate_item_def_id_path( let kind = ItemType::from_def_kind(original_def_kind, Some(def_kind)); url_parts = format!("{url_parts}#{kind}.{}", tcx.item_name(original_def_id)) }; - Ok((url_parts, shortty, fqp)) + Ok(HrefInfo { url: url_parts, kind: shortty, rust_path: fqp }) } /// Checks if the given defid refers to an item that is unnamable, such as one defined in a const block. @@ -530,7 +543,7 @@ pub(crate) fn href_with_root_path( original_did: DefId, cx: &Context<'_>, root_path: Option<&str>, -) -> Result<(String, ItemType, Vec), HrefError> { +) -> Result { let tcx = cx.tcx(); let def_kind = tcx.def_kind(original_did); let did = match def_kind { @@ -596,14 +609,14 @@ pub(crate) fn href_with_root_path( } } }; - let url_parts = make_href(root_path, shortty, url_parts, fqp, is_remote); - Ok((url_parts, shortty, fqp.clone())) + Ok(HrefInfo { + url: make_href(root_path, shortty, url_parts, fqp, is_remote), + kind: shortty, + rust_path: fqp.clone(), + }) } -pub(crate) fn href( - did: DefId, - cx: &Context<'_>, -) -> Result<(String, ItemType, Vec), HrefError> { +pub(crate) fn href(did: DefId, cx: &Context<'_>) -> Result { href_with_root_path(did, cx, None) } @@ -690,12 +703,12 @@ fn resolved_path( } else { let path = fmt::from_fn(|f| { if use_absolute { - if let Ok((_, _, fqp)) = href(did, cx) { + if let Ok(HrefInfo { rust_path, .. }) = href(did, cx) { write!( f, "{path}::{anchor}", - path = join_path_syms(&fqp[..fqp.len() - 1]), - anchor = print_anchor(did, *fqp.last().unwrap(), cx) + path = join_path_syms(&rust_path[..rust_path.len() - 1]), + anchor = print_anchor(did, *rust_path.last().unwrap(), cx) ) } else { write!(f, "{}", last.name) @@ -824,12 +837,11 @@ fn print_higher_ranked_params_with_space( pub(crate) fn print_anchor(did: DefId, text: Symbol, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { - let parts = href(did, cx); - if let Ok((url, short_ty, fqp)) = parts { + if let Ok(HrefInfo { url, kind, rust_path }) = href(did, cx) { write!( f, - r#"{text}"#, - path = join_path_syms(fqp), + r#"{text}"#, + path = join_path_syms(rust_path), text = EscapeBodyText(text.as_str()), ) } else { @@ -1056,14 +1068,14 @@ fn print_qpath_data(qpath_data: &clean::QPathData, cx: &Context<'_>) -> impl Dis None => self_type.def_id(cx.cache()).and_then(|did| href(did, cx).ok()), }; - if let Some((url, _, path)) = parent_href { + if let Some(HrefInfo { url, rust_path, .. }) = parent_href { write!( f, "{name}", shortty = ItemType::AssocType, name = assoc.name, - path = join_path_syms(path), + path = join_path_syms(rust_path), ) } else { write!(f, "{}", assoc.name) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 798fbd284ca87..6f6345cd86664 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -21,6 +21,7 @@ use super::format; use crate::clean::PrimitiveType; use crate::display::Joined as _; use crate::html::escape::EscapeBodyText; +use crate::html::format::HrefInfo; use crate::html::macro_expansion::ExpandedCode; use crate::html::render::span_map::{DUMMY_SP, Span}; use crate::html::render::{Context, LinkFromSrc}; @@ -1357,7 +1358,7 @@ fn generate_link_to_def( LinkFromSrc::External(def_id) => { format::href_with_root_path(*def_id, context, Some(href_context.root_path)) .ok() - .map(|(url, _, _)| url) + .map(|HrefInfo { url, .. }| url) } LinkFromSrc::Primitive(prim) => format::href_with_root_path( PrimitiveType::primitive_locations(context.tcx())[prim], @@ -1365,11 +1366,11 @@ fn generate_link_to_def( Some(href_context.root_path), ) .ok() - .map(|(url, _, _)| url), + .map(|HrefInfo { url, .. }| url), LinkFromSrc::Doc(def_id) => { format::href_with_root_path(*def_id, context, Some(href_context.root_path)) .ok() - .map(|(doc_link, _, _)| doc_link) + .map(|HrefInfo { url, .. }| url) } } }) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 36990332b2fc8..871ed53bd3380 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -74,7 +74,7 @@ use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; use crate::html::escape::Escape; use crate::html::format::{ - Ending, HrefError, PrintWithSpace, full_print_fn_decl, href, print_abi_with_space, + Ending, HrefError, HrefInfo, PrintWithSpace, full_print_fn_decl, href, print_abi_with_space, print_constness_with_space, print_default_space, print_generic_bounds, print_generics, print_impl, print_path, print_type, print_where_clause, visibility_print_with_space, }; @@ -982,7 +982,7 @@ fn assoc_href_attr( }; match href(did.expect_def_id(), cx) { - Ok((url, ..)) => Href::Url(url, item_type), + Ok(HrefInfo { url, .. }) => Href::Url(url, item_type), // The link is broken since it points to an external crate that wasn't documented. // Do not create any link in such case. This is better than falling back to a // dummy anchor like `#{item_type}.{name}` representing the `id` of *this* impl item diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e88180c3033b2..57db12d2cb5dc 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -61,11 +61,6 @@ extern crate rustc_target; extern crate rustc_trait_selection; extern crate test; -// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs -// about jemalloc. -#[cfg(feature = "jemalloc")] -extern crate tikv_jemalloc_sys as jemalloc_sys; - use std::env::{self, VarError}; use std::io::{self, IsTerminal}; use std::path::Path; @@ -77,6 +72,10 @@ use rustc_interface::interface; use rustc_middle::ty::TyCtxt; use rustc_session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_option}; use rustc_session::{EarlyDiagCtxt, getopts}; +/// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs +/// and https://github.com/rust-lang/rust/pull/146627 for why we need this `use` statement. +#[cfg(feature = "jemalloc")] +use tikv_jemalloc_sys as _; use tracing::info; use crate::clean::utils::DOC_RUST_LANG_ORG_VERSION; @@ -124,37 +123,6 @@ mod visit_ast; mod visit_lib; pub fn main() { - // See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs - // about jemalloc. - #[cfg(feature = "jemalloc")] - { - use std::os::raw::{c_int, c_void}; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = - jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - #[cfg(target_os = "macos")] - { - unsafe extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } - } - let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); rustc_driver::install_ice_hook( diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml index fee885d8fa7e9..f0f9c05e4330d 100644 --- a/src/tools/clippy/Cargo.toml +++ b/src/tools/clippy/Cargo.toml @@ -31,6 +31,7 @@ tempfile = { version = "3.20", optional = true } termize = "0.2" color-print = "0.3.4" anstream = "0.6.18" +tikv-jemalloc-sys = { version = "0.6.1", optional = true, features = ['override_allocator_on_supported_platforms'] } [dev-dependencies] cargo_metadata = "0.18.1" @@ -56,7 +57,7 @@ rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" } [features] integration = ["dep:tempfile"] internal = ["dep:clippy_lints_internal", "dep:tempfile"] -jemalloc = [] +jemalloc = ["dep:tikv-jemalloc-sys"] [package.metadata.rust-analyzer] # This package uses #[feature(rustc_private)] diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index abc706b7772f1..a8db5dddf22fc 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -13,10 +13,10 @@ extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; -// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs -// about jemalloc. +/// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs +/// and https://github.com/rust-lang/rust/pull/146627 for why we need this `use` statement. #[cfg(feature = "jemalloc")] -extern crate tikv_jemalloc_sys as jemalloc_sys; +use tikv_jemalloc_sys as _; use clippy_utils::sym; use declare_clippy_lint::LintListBuilder; @@ -189,36 +189,6 @@ const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/ne #[expect(clippy::too_many_lines)] pub fn main() { - // See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs - // about jemalloc. - #[cfg(feature = "jemalloc")] - { - use std::os::raw::{c_int, c_void}; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - #[cfg(target_os = "macos")] - { - unsafe extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } - } - let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); rustc_driver::init_rustc_env_logger(&early_dcx); diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index 8bb4f1c160934..5341b3a486922 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -33,8 +33,8 @@ serde_json = { version = "1.0", optional = true } # But only for some targets, it fails for others. Rustc configures this in its CI, but we can't # easily use that since we support of-tree builds. [target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies.tikv-jemalloc-sys] -version = "0.6.0" -features = ['unprefixed_malloc_on_supported_platforms'] +version = "0.6.1" +features = ['override_allocator_on_supported_platforms'] [target.'cfg(unix)'.dependencies] libc = "0.2" diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 1ce491a50eae4..04d41c96f5c08 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -ceb7df7e6f17c92c7d49f7e4f02df0e68bc9b38b +8401398e1f14a24670ee1a3203713dc2f0f8b3a8 diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 920fc29481916..8b4445e379a20 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -20,6 +20,11 @@ extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; +/// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs +/// and https://github.com/rust-lang/rust/pull/146627 for why we need this `use` statement. +#[cfg(any(target_os = "linux", target_os = "macos"))] +use tikv_jemalloc_sys as _; + mod log; use std::env; @@ -392,48 +397,7 @@ fn parse_range(val: &str) -> Result, &'static str> { Ok(from..to) } -#[cfg(any(target_os = "linux", target_os = "macos"))] -fn jemalloc_magic() { - // These magic runes are copied from - // . - // See there for further comments. - use std::os::raw::{c_int, c_void}; - - use tikv_jemalloc_sys as jemalloc_sys; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = - jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - // On OSX, jemalloc doesn't directly override malloc/free, but instead - // registers itself with the allocator's zone APIs in a ctor. However, - // the linker doesn't seem to consider ctors as "used" when statically - // linking, so we need to explicitly depend on the function. - #[cfg(target_os = "macos")] - { - unsafe extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } -} - fn main() { - #[cfg(any(target_os = "linux", target_os = "macos"))] - jemalloc_magic(); - let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); // Snapshot a copy of the environment before `rustc` starts messing with it. diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index a4f8e9ccaab99..171826ffbf8ca 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1353,8 +1353,11 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { } #[inline(always)] - fn runtime_checks(ecx: &InterpCx<'tcx, Self>, r: mir::RuntimeChecks) -> InterpResult<'tcx, bool> { - interp_ok(r.value(&ecx.tcx.sess)) + fn runtime_checks( + ecx: &InterpCx<'tcx, Self>, + r: mir::RuntimeChecks, + ) -> InterpResult<'tcx, bool> { + interp_ok(r.value(ecx.tcx.sess)) } #[inline(always)] diff --git a/src/tools/miri/src/shims/files.rs b/src/tools/miri/src/shims/files.rs index 8c29cb040b55a..f86933029341e 100644 --- a/src/tools/miri/src/shims/files.rs +++ b/src/tools/miri/src/shims/files.rs @@ -14,7 +14,7 @@ use crate::*; /// A unique id for file descriptions. While we could use the address, considering that /// is definitely unique, the address would expose interpreter internal state when used -/// for sorting things. So instead we generate a unique id per file description is the name +/// for sorting things. So instead we generate a unique id per file description which is the same /// for all `dup`licates and is never reused. #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd)] pub struct FdId(usize); @@ -107,10 +107,10 @@ impl FileDescriptionExt for T { ) -> InterpResult<'tcx, io::Result<()>> { match Rc::into_inner(self.0) { Some(fd) => { - // Remove entry from the global epoll_event_interest table. - ecx.machine.epoll_interests.remove(fd.id); + // There might have been epolls interested in this FD. Remove that. + ecx.machine.epoll_interests.remove_epolls(fd.id); - fd.inner.close(communicate_allowed, ecx) + fd.inner.destroy(fd.id, communicate_allowed, ecx) } None => { // Not the last reference. @@ -183,9 +183,12 @@ pub trait FileDescription: std::fmt::Debug + FileDescriptionExt { throw_unsup_format!("cannot seek on {}", self.name()); } - /// Close the file descriptor. - fn close<'tcx>( + /// Destroys the file description. Only called when the last duplicate file descriptor is closed. + /// + /// `self_addr` is the address that this file description used to be stored at. + fn destroy<'tcx>( self, + _self_id: FdId, _communicate_allowed: bool, _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result<()>> @@ -362,8 +365,9 @@ impl FileDescription for FileHandle { interp_ok((&mut &self.file).seek(offset)) } - fn close<'tcx>( + fn destroy<'tcx>( self, + _self_id: FdId, communicate_allowed: bool, _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result<()>> { diff --git a/src/tools/miri/src/shims/unix/linux_like/epoll.rs b/src/tools/miri/src/shims/unix/linux_like/epoll.rs index 3133c149293db..865cdb2533cfd 100644 --- a/src/tools/miri/src/shims/unix/linux_like/epoll.rs +++ b/src/tools/miri/src/shims/unix/linux_like/epoll.rs @@ -1,28 +1,33 @@ use std::cell::RefCell; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, btree_map}; use std::io; -use std::rc::{Rc, Weak}; use std::time::Duration; use rustc_abi::FieldIdx; use crate::concurrency::VClock; use crate::shims::files::{ - DynFileDescriptionRef, FdId, FileDescription, FileDescriptionRef, WeakFileDescriptionRef, + DynFileDescriptionRef, FdId, FdNum, FileDescription, FileDescriptionRef, WeakFileDescriptionRef, }; use crate::shims::unix::UnixFileDescription; use crate::*; +type EpollEventKey = (FdId, FdNum); + /// An `Epoll` file descriptor connects file handles and epoll events #[derive(Debug, Default)] struct Epoll { /// A map of EpollEventInterests registered under this epoll instance. /// Each entry is differentiated using FdId and file descriptor value. - interest_list: RefCell>>>, + interest_list: RefCell>, /// A map of EpollEventInstance that will be returned when `epoll_wait` is called. /// Similar to interest_list, the entry is also differentiated using FdId /// and file descriptor value. - ready_list: ReadyList, + /// We keep this separate from `interest_list` for two reasons: there might be many + /// interests but only a few of them ready (so with a separate list it is more efficient + /// to find a ready event), and having separate `RefCell` lets us mutate the `interest_list` + /// while unblocking threads which might mutate the `ready_list`. + ready_list: RefCell>, /// A list of thread ids blocked on this epoll instance. blocked_tid: RefCell>, } @@ -33,23 +38,22 @@ impl VisitProvenance for Epoll { } } +/// Returns the range of all EpollEventKey for the given FD ID. +fn range_for_id(id: FdId) -> std::ops::RangeInclusive { + (id, 0)..=(id, i32::MAX) +} + /// EpollEventInstance contains information that will be returned by epoll_wait. -#[derive(Debug)] +#[derive(Debug, Default)] pub struct EpollEventInstance { - /// Xor-ed event types that happened to the file description. + /// Bitmask of event types that happened to the file description. events: u32, - /// Original data retrieved from `epoll_event` during `epoll_ctl`. + /// User-defined data associated with the interest that triggered this instance. data: u64, /// The release clock associated with this event. clock: VClock, } -impl EpollEventInstance { - pub fn new(events: u32, data: u64) -> EpollEventInstance { - EpollEventInstance { events, data, clock: Default::default() } - } -} - /// EpollEventInterest registers the file description information to an epoll /// instance during a successful `epoll_ctl` call. It also stores additional /// information needed to check and update readiness state for `epoll_wait`. @@ -61,25 +65,19 @@ impl EpollEventInstance { /// #[derive(Debug)] pub struct EpollEventInterest { - /// The file descriptor value of the file description registered. - /// This is only used for ready_list, to inform userspace which FD triggered an event. - /// For that, it is crucial to preserve the original FD number. - /// This FD number must never be "dereferenced" to a file description inside Miri. - fd_num: i32, /// The events bitmask retrieved from `epoll_event`. events: u32, + /// The way the events looked last time we checked (for edge trigger / ET detection). + prev_events: u32, /// The data retrieved from `epoll_event`. /// libc's data field in epoll_event can store integer or pointer, /// but only u64 is supported for now. /// data: u64, - /// The epoll file description that this EpollEventInterest is registered under. - /// This is weak to avoid cycles, but an upgrade is always guaranteed to succeed - /// because only the `Epoll` holds a strong ref to a `EpollEventInterest`. - weak_epfd: WeakFileDescriptionRef, } /// EpollReadyEvents reflects the readiness of a file description. +#[derive(Debug)] pub struct EpollReadyEvents { /// The associated file is available for read(2) operations, in the sense that a read will not block. /// (I.e., returning EOF is considered "ready".) @@ -99,11 +97,6 @@ pub struct EpollReadyEvents { pub epollerr: bool, } -#[derive(Debug, Default)] -struct ReadyList { - mapping: RefCell>, -} - impl EpollReadyEvents { pub fn new() -> Self { EpollReadyEvents { @@ -147,11 +140,18 @@ impl FileDescription for Epoll { "epoll" } - fn close<'tcx>( - self, + fn destroy<'tcx>( + mut self, + self_id: FdId, _communicate_allowed: bool, - _ecx: &mut MiriInterpCx<'tcx>, + ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result<()>> { + // If we were interested in some FDs, we can remove that now. + let mut ids = self.interest_list.get_mut().keys().map(|(id, _num)| *id).collect::>(); + ids.dedup(); // they come out of the map sorted + for id in ids { + ecx.machine.epoll_interests.remove(id, self_id); + } interp_ok(Ok(())) } @@ -163,41 +163,56 @@ impl FileDescription for Epoll { impl UnixFileDescription for Epoll {} /// The table of all EpollEventInterest. -/// The BTreeMap key is the FdId of an active file description registered with -/// any epoll instance. The value is a list of EpollEventInterest associated -/// with that file description. -pub struct EpollInterestTable(BTreeMap>>>); +/// This tracks, for each file description, which epoll instances have an interest in events +/// for this file description. The `FdId` is the ID of the epoll instance, so that we can recognize +/// it later when it is slated for removal. The vector is sorted by that ID. +pub struct EpollInterestTable(BTreeMap)>>); impl EpollInterestTable { pub(crate) fn new() -> Self { EpollInterestTable(BTreeMap::new()) } - pub fn insert_epoll_interest(&mut self, id: FdId, fd: Weak>) { - match self.0.get_mut(&id) { - Some(fds) => { - fds.push(fd); - } - None => { - let vec = vec![fd]; - self.0.insert(id, vec); - } - } + fn insert(&mut self, id: FdId, epoll: &FileDescriptionRef) { + let epolls = self.0.entry(id).or_default(); + let idx = epolls + .binary_search_by_key(&epoll.id(), |&(id, _)| id) + .expect_err("trying to add an epoll that's already in the list"); + epolls.insert(idx, (epoll.id(), FileDescriptionRef::downgrade(epoll))); } - pub fn get_epoll_interest(&self, id: FdId) -> Option<&Vec>>> { - self.0.get(&id) + fn remove(&mut self, id: FdId, epoll_id: FdId) { + let epolls = self.0.entry(id).or_default(); + let idx = epolls + .binary_search_by_key(&epoll_id, |&(id, _)| id) + .expect("trying to remove an epoll that's not in the list"); + epolls.remove(idx); } - pub fn get_epoll_interest_mut( - &mut self, - id: FdId, - ) -> Option<&mut Vec>>> { - self.0.get_mut(&id) + fn get_epolls(&self, id: FdId) -> Option>> { + self.0.get(&id).map(|epolls| epolls.iter().map(|(_id, epoll)| epoll)) } - pub fn remove(&mut self, id: FdId) { - self.0.remove(&id); + pub fn remove_epolls(&mut self, id: FdId) { + if let Some(epolls) = self.0.remove(&id) { + for epoll in epolls.iter().filter_map(|(_id, epoll)| epoll.upgrade()) { + // This is a still-live epoll with interest in this FD. Remove all + // relevent interests. + epoll + .interest_list + .borrow_mut() + .extract_if(range_for_id(id), |_, _| true) + // Consume the iterator. + .for_each(|_| ()); + // Also remove all events from the ready list that refer to this FD. + epoll + .ready_list + .borrow_mut() + .extract_if(range_for_id(id), |_, _| true) + // Consume the iterator. + .for_each(|_| ()); + } + } } } @@ -264,9 +279,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let epollhup = this.eval_libc_u32("EPOLLHUP"); let epollerr = this.eval_libc_u32("EPOLLERR"); - // Throw EINVAL if epfd and fd have the same value. + // Throw EFAULT if epfd and fd have the same value. if epfd_value == fd { - return this.set_last_error_and_return_i32(LibcError("EINVAL")); + return this.set_last_error_and_return_i32(LibcError("EFAULT")); } // Check if epfd is a valid epoll file descriptor. @@ -326,69 +341,59 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } + // Add new interest to list. Experiments show that we need to reset all state + // on `EPOLL_CTL_MOD`, including the edge tracking. let epoll_key = (id, fd); - - // Check the existence of fd in the interest list. - if op == epoll_ctl_add { - if interest_list.contains_key(&epoll_key) { - return this.set_last_error_and_return_i32(LibcError("EEXIST")); + let new_interest = EpollEventInterest { events, data, prev_events: 0 }; + let new_interest = if op == epoll_ctl_add { + if interest_list.range(range_for_id(id)).next().is_none() { + // This is the first time this FD got added to this epoll. + // Remember that in the global list so we get notified about FD events. + this.machine.epoll_interests.insert(id, &epfd); } - } else { - if !interest_list.contains_key(&epoll_key) { - return this.set_last_error_and_return_i32(LibcError("ENOENT")); + match interest_list.entry(epoll_key) { + btree_map::Entry::Occupied(_) => { + // We already had interest in this. + return this.set_last_error_and_return_i32(LibcError("EEXIST")); + } + btree_map::Entry::Vacant(e) => e.insert(new_interest), } - } - - if op == epoll_ctl_add { - // Create an epoll_interest. - let interest = Rc::new(RefCell::new(EpollEventInterest { - fd_num: fd, - events, - data, - weak_epfd: FileDescriptionRef::downgrade(&epfd), - })); - // Notification will be returned for current epfd if there is event in the file - // descriptor we registered. - check_and_update_one_event_interest(&fd_ref, &interest, id, this)?; - - // Insert an epoll_interest to global epoll_interest list. - this.machine.epoll_interests.insert_epoll_interest(id, Rc::downgrade(&interest)); - interest_list.insert(epoll_key, interest); } else { // Modify the existing interest. - let epoll_interest = interest_list.get_mut(&epoll_key).unwrap(); - { - let mut epoll_interest = epoll_interest.borrow_mut(); - epoll_interest.events = events; - epoll_interest.data = data; - } - // Updating an FD interest triggers events. - check_and_update_one_event_interest(&fd_ref, epoll_interest, id, this)?; - } + let Some(interest) = interest_list.get_mut(&epoll_key) else { + return this.set_last_error_and_return_i32(LibcError("ENOENT")); + }; + *interest = new_interest; + interest + }; + + // Deliver events for the new interest. + let force_edge = true; // makes no difference since we reset `prev_events` + send_ready_events_to_interests( + this, + &epfd, + fd_ref.as_unix(this).get_epoll_ready_events()?.get_event_bitmask(this), + force_edge, + std::iter::once((&epoll_key, new_interest)), + )?; interp_ok(Scalar::from_i32(0)) } else if op == epoll_ctl_del { let epoll_key = (id, fd); // Remove epoll_event_interest from interest_list. - let Some(epoll_interest) = interest_list.remove(&epoll_key) else { + if interest_list.remove(&epoll_key).is_none() { + // We did not have interest in this. return this.set_last_error_and_return_i32(LibcError("ENOENT")); }; - // All related Weak will fail to upgrade after the drop. - drop(epoll_interest); - - // Remove related epoll_interest from ready list. - epfd.ready_list.mapping.borrow_mut().remove(&epoll_key); - - // Remove dangling EpollEventInterest from its global table. - // .unwrap() below should succeed because the file description id must have registered - // at least one epoll_interest, if not, it will fail when removing epoll_interest from - // interest list. - this.machine - .epoll_interests - .get_epoll_interest_mut(id) - .unwrap() - .retain(|event| event.upgrade().is_some()); + // If this was the last interest in this FD, remove us from the global list + // of who is interested in this FD. + if interest_list.range(range_for_id(id)).next().is_none() { + this.machine.epoll_interests.remove(id, epfd.id()); + } + + // Remove related event instance from ready list. + epfd.ready_list.borrow_mut().remove(&epoll_key); interp_ok(Scalar::from_i32(0)) } else { @@ -462,7 +467,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { }; // We just need to know if the ready list is empty and borrow the thread_ids out. - let ready_list_empty = epfd.ready_list.mapping.borrow().is_empty(); + let ready_list_empty = epfd.ready_list.borrow().is_empty(); if timeout == 0 || !ready_list_empty { // If the ready list is not empty, or the timeout is 0, we can return immediately. return_ready_list(&epfd, dest, &event, this)?; @@ -518,103 +523,99 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(()) } - /// For a specific file description, get its ready events and update the corresponding ready - /// list. This function should be called whenever an event causes more bytes or an EOF to become - /// newly readable from an FD, and whenever more bytes can be written to an FD or no more future - /// writes are possible. + /// For a specific file description, get its ready events and send it to everyone who registered + /// interest in this FD. This function should be called whenever the result of + /// `get_epoll_ready_events` would change. /// - /// This *will* report an event if anyone is subscribed to it, without any further filtering, so - /// do not call this function when an FD didn't have anything happen to it! - fn check_and_update_readiness( + /// If `force_edge` is set, edge-triggered interests will be triggered even if the set of + /// ready events did not change. This can lead to spurious wakeups. Use with caution! + fn epoll_send_fd_ready_events( &mut self, fd_ref: DynFileDescriptionRef, - ) -> InterpResult<'tcx, ()> { + force_edge: bool, + ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); let id = fd_ref.id(); - let mut waiter = Vec::new(); - // Get a list of EpollEventInterest that is associated to a specific file description. - if let Some(epoll_interests) = this.machine.epoll_interests.get_epoll_interest(id) { - for weak_epoll_interest in epoll_interests { - if let Some(epoll_interest) = weak_epoll_interest.upgrade() { - let is_updated = - check_and_update_one_event_interest(&fd_ref, &epoll_interest, id, this)?; - if is_updated { - // Edge-triggered notification only notify one thread even if there are - // multiple threads blocked on the same epfd. - - // This unwrap can never fail because if the current epoll instance were - // closed, the upgrade of weak_epoll_interest - // above would fail. This guarantee holds because only the epoll instance - // holds a strong ref to epoll_interest. - let epfd = epoll_interest.borrow().weak_epfd.upgrade().unwrap(); - // FIXME: We can randomly pick a thread to unblock. - if let Some(thread_id) = epfd.blocked_tid.borrow_mut().pop() { - waiter.push(thread_id); - }; - } - } - } - } - waiter.sort(); - waiter.dedup(); - for thread_id in waiter { - this.unblock_thread(thread_id, BlockReason::Epoll)?; + // Figure out who is interested in this. We need to clone this list since we can't prove + // that `send_ready_events_to_interest` won't mutate it. + let Some(epolls) = this.machine.epoll_interests.get_epolls(id) else { + return interp_ok(()); + }; + let epolls = epolls + .map(|weak| { + weak.upgrade() + .expect("someone forgot to remove the garbage from `machine.epoll_interests`") + }) + .collect::>(); + let event_bitmask = fd_ref.as_unix(this).get_epoll_ready_events()?.get_event_bitmask(this); + for epoll in epolls { + send_ready_events_to_interests( + this, + &epoll, + event_bitmask, + force_edge, + epoll.interest_list.borrow_mut().range_mut(range_for_id(id)), + )?; } + interp_ok(()) } } -/// This function takes in ready list and returns EpollEventInstance with file description -/// that is not closed. -fn ready_list_next( - ecx: &MiriInterpCx<'_>, - ready_list: &mut BTreeMap<(FdId, i32), EpollEventInstance>, -) -> Option { - while let Some((epoll_key, epoll_event_instance)) = ready_list.pop_first() { - // This ensures that we only return events that we are interested. The FD might have been closed since - // the event was generated, in which case we are not interested anymore. - // When a file description is fully closed, it gets removed from `machine.epoll_interests`, - // so we skip events whose FD is not in that map anymore. - if ecx.machine.epoll_interests.get_epoll_interest(epoll_key.0).is_some() { - return Some(epoll_event_instance); +/// Send the latest ready events for one particular FD (identified by `event_key`) to everyone in +/// the `interests` list, if they are interested in this kind of event. +fn send_ready_events_to_interests<'tcx, 'a>( + ecx: &mut MiriInterpCx<'tcx>, + epoll: &Epoll, + event_bitmask: u32, + force_edge: bool, + interests: impl Iterator, +) -> InterpResult<'tcx> { + let mut wakeup = false; + for (&event_key, interest) in interests { + let mut ready_list = epoll.ready_list.borrow_mut(); + // This checks if any of the events specified in epoll_event_interest.events + // match those in ready_events. + let flags = interest.events & event_bitmask; + let prev = std::mem::replace(&mut interest.prev_events, flags); + if flags == 0 { + // Make sure we *remove* any previous item from the ready list, since this + // is not ready any more. + ready_list.remove(&event_key); + continue; } - } - None -} - -/// This helper function checks whether an epoll notification should be triggered for a specific -/// epoll_interest and, if necessary, triggers the notification, and returns whether the -/// notification was added/updated. Unlike check_and_update_readiness, this function sends a -/// notification to only one epoll instance. -fn check_and_update_one_event_interest<'tcx>( - fd_ref: &DynFileDescriptionRef, - interest: &RefCell, - id: FdId, - ecx: &MiriInterpCx<'tcx>, -) -> InterpResult<'tcx, bool> { - // Get the bitmask of ready events for a file description. - let ready_events_bitmask = fd_ref.as_unix(ecx).get_epoll_ready_events()?.get_event_bitmask(ecx); - let epoll_event_interest = interest.borrow(); - let epfd = epoll_event_interest.weak_epfd.upgrade().unwrap(); - // This checks if any of the events specified in epoll_event_interest.events - // match those in ready_events. - let flags = epoll_event_interest.events & ready_events_bitmask; - // If there is any event that we are interested in being specified as ready, - // insert an epoll_return to the ready list. - if flags != 0 { - let epoll_key = (id, epoll_event_interest.fd_num); - let mut ready_list = epfd.ready_list.mapping.borrow_mut(); - let mut event_instance = EpollEventInstance::new(flags, epoll_event_interest.data); - // If we are tracking data races, remember the current clock so we can sync with it later. + // Generate new instance, or update existing one. It is crucial that whe we are done, + // if an interest exists in the ready list, then it matches the latest events and data! + let instance = match ready_list.entry(event_key) { + btree_map::Entry::Occupied(e) => e.into_mut(), + btree_map::Entry::Vacant(e) => { + if !force_edge && flags == prev & flags { + // Every bit in `flags` was already set in `prev`, and there's currently + // no entry in the ready list for this. So there is nothing new and no + // prior entry to update; just skip it. + continue; + } + e.insert(EpollEventInstance::default()) + } + }; + instance.events = flags; + instance.data = interest.data; ecx.release_clock(|clock| { - event_instance.clock.clone_from(clock); + instance.clock.join(clock); })?; - // Triggers the notification by inserting it to the ready list. - ready_list.insert(epoll_key, event_instance); - interp_ok(true) - } else { - interp_ok(false) + wakeup = true; + } + if wakeup { + // Wake up threads that may have been waiting for events on this epoll. + // Do this only once for all the interests. + // Edge-triggered notification only notify one thread even if there are + // multiple threads blocked on the same epoll. + if let Some(thread_id) = epoll.blocked_tid.borrow_mut().pop() { + ecx.unblock_thread(thread_id, BlockReason::Epoll)?; + } } + + interp_ok(()) } /// Stores the ready list of the `epfd` epoll instance into `events` (which must be an array), @@ -625,12 +626,12 @@ fn return_ready_list<'tcx>( events: &MPlaceTy<'tcx>, ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx> { - let mut ready_list = epfd.ready_list.mapping.borrow_mut(); + let mut ready_list = epfd.ready_list.borrow_mut(); let mut num_of_events: i32 = 0; let mut array_iter = ecx.project_array_fields(events)?; while let Some(des) = array_iter.next(ecx)? { - if let Some(epoll_event_instance) = ready_list_next(ecx, &mut ready_list) { + if let Some((_, epoll_event_instance)) = ready_list.pop_first() { ecx.write_int_fields_named( &[ ("events", epoll_event_instance.events.into()), diff --git a/src/tools/miri/src/shims/unix/linux_like/eventfd.rs b/src/tools/miri/src/shims/unix/linux_like/eventfd.rs index 5d4f207d365e1..1b5f1db43953b 100644 --- a/src/tools/miri/src/shims/unix/linux_like/eventfd.rs +++ b/src/tools/miri/src/shims/unix/linux_like/eventfd.rs @@ -4,7 +4,7 @@ use std::io; use std::io::ErrorKind; use crate::concurrency::VClock; -use crate::shims::files::{FileDescription, FileDescriptionRef, WeakFileDescriptionRef}; +use crate::shims::files::{FdId, FileDescription, FileDescriptionRef, WeakFileDescriptionRef}; use crate::shims::unix::UnixFileDescription; use crate::shims::unix::linux_like::epoll::{EpollReadyEvents, EvalContextExt as _}; use crate::*; @@ -37,8 +37,9 @@ impl FileDescription for EventFd { "event" } - fn close<'tcx>( + fn destroy<'tcx>( self, + _self_id: FdId, _communicate_allowed: bool, _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result<()>> { @@ -216,7 +217,10 @@ fn eventfd_write<'tcx>( // The state changed; we check and update the status of all supported event // types for current file description. - ecx.check_and_update_readiness(eventfd)?; + // Linux seems to cause spurious wakeups here, and Tokio seems to rely on that + // (see + // and also ). + ecx.epoll_send_fd_ready_events(eventfd, /* force_edge */ true)?; // Return how many bytes we consumed from the user-provided buffer. return finish.call(ecx, Ok(buf_place.layout.size.bytes_usize())); @@ -311,7 +315,8 @@ fn eventfd_read<'tcx>( // The state changed; we check and update the status of all supported event // types for current file description. - ecx.check_and_update_readiness(eventfd)?; + // Linux seems to always emit do notifications here, even if we were already writable. + ecx.epoll_send_fd_ready_events(eventfd, /* force_edge */ true)?; // Tell userspace how many bytes we put into the buffer. return finish.call(ecx, Ok(buf_place.layout.size.bytes_usize())); diff --git a/src/tools/miri/src/shims/unix/unnamed_socket.rs b/src/tools/miri/src/shims/unix/unnamed_socket.rs index 81703d6e176bf..3e2949759377e 100644 --- a/src/tools/miri/src/shims/unix/unnamed_socket.rs +++ b/src/tools/miri/src/shims/unix/unnamed_socket.rs @@ -9,7 +9,7 @@ use std::io::ErrorKind; use crate::concurrency::VClock; use crate::shims::files::{ - EvalContextExt as _, FileDescription, FileDescriptionRef, WeakFileDescriptionRef, + EvalContextExt as _, FdId, FileDescription, FileDescriptionRef, WeakFileDescriptionRef, }; use crate::shims::unix::UnixFileDescription; use crate::shims::unix::linux_like::epoll::{EpollReadyEvents, EvalContextExt as _}; @@ -18,7 +18,7 @@ use crate::*; /// The maximum capacity of the socketpair buffer in bytes. /// This number is arbitrary as the value can always /// be configured in the real system. -const MAX_SOCKETPAIR_BUFFER_CAPACITY: usize = 212992; +const MAX_SOCKETPAIR_BUFFER_CAPACITY: usize = 0x34000; #[derive(Debug, PartialEq)] enum AnonSocketType { @@ -82,8 +82,9 @@ impl FileDescription for AnonSocket { } } - fn close<'tcx>( + fn destroy<'tcx>( self, + _self_id: FdId, _communicate_allowed: bool, ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result<()>> { @@ -96,7 +97,7 @@ impl FileDescription for AnonSocket { } } // Notify peer fd that close has happened, since that can unblock reads and writes. - ecx.check_and_update_readiness(peer_fd)?; + ecx.epoll_send_fd_ready_events(peer_fd, /* force_edge */ false)?; } interp_ok(Ok(())) } @@ -274,9 +275,11 @@ fn anonsocket_write<'tcx>( for thread_id in waiting_threads { ecx.unblock_thread(thread_id, BlockReason::UnnamedSocket)?; } - // Notification should be provided for peer fd as it became readable. - // The kernel does this even if the fd was already readable before, so we follow suit. - ecx.check_and_update_readiness(peer_fd)?; + // Notify epoll waiters: we might be no longer writable, peer might now be readable. + // The notification to the peer seems to be always sent on Linux, even if the + // FD was readable before. + ecx.epoll_send_fd_ready_events(self_ref, /* force_edge */ false)?; + ecx.epoll_send_fd_ready_events(peer_fd, /* force_edge */ true)?; return finish.call(ecx, Ok(write_size)); } @@ -350,6 +353,7 @@ fn anonsocket_read<'tcx>( // Do full read / partial read based on the space available. // Conveniently, `read` exists on `VecDeque` and has exactly the desired behavior. let read_size = ecx.read_from_host(&mut readbuf.buf, len, ptr)?.unwrap(); + let readbuf_now_empty = readbuf.buf.is_empty(); // Need to drop before others can access the readbuf again. drop(readbuf); @@ -368,9 +372,14 @@ fn anonsocket_read<'tcx>( for thread_id in waiting_threads { ecx.unblock_thread(thread_id, BlockReason::UnnamedSocket)?; } - // Notify epoll waiters. - ecx.check_and_update_readiness(peer_fd)?; + // Notify epoll waiters: peer is now writable. + // Linux seems to always notify the peer if the read buffer is now empty. + // (Linux also does that if this was a "big" read, but to avoid some arbitrary + // threshold, we do not match that.) + ecx.epoll_send_fd_ready_events(peer_fd, /* force_edge */ readbuf_now_empty)?; }; + // Notify epoll waiters: we might be no longer readable. + ecx.epoll_send_fd_ready_events(self_ref, /* force_edge */ false)?; return finish.call(ecx, Ok(read_size)); } diff --git a/src/tools/miri/src/shims/windows/fs.rs b/src/tools/miri/src/shims/windows/fs.rs index e4ec1b0130c9d..7192d8aec8510 100644 --- a/src/tools/miri/src/shims/windows/fs.rs +++ b/src/tools/miri/src/shims/windows/fs.rs @@ -6,7 +6,7 @@ use std::time::SystemTime; use bitflags::bitflags; -use crate::shims::files::{FileDescription, FileHandle}; +use crate::shims::files::{FdId, FileDescription, FileHandle}; use crate::shims::windows::handle::{EvalContextExt as _, Handle}; use crate::*; @@ -24,8 +24,9 @@ impl FileDescription for DirHandle { interp_ok(self.path.metadata()) } - fn close<'tcx>( + fn destroy<'tcx>( self, + _self_id: FdId, _communicate_allowed: bool, _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result<()>> { @@ -50,8 +51,9 @@ impl FileDescription for MetadataHandle { interp_ok(Ok(self.meta.clone())) } - fn close<'tcx>( + fn destroy<'tcx>( self, + _self_id: FdId, _communicate_allowed: bool, _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result<()>> { diff --git a/src/tools/miri/src/shims/x86/avx512.rs b/src/tools/miri/src/shims/x86/avx512.rs new file mode 100644 index 0000000000000..e15b99beba8b4 --- /dev/null +++ b/src/tools/miri/src/shims/x86/avx512.rs @@ -0,0 +1,85 @@ +use rustc_abi::CanonAbi; +use rustc_middle::ty::Ty; +use rustc_span::Symbol; +use rustc_target::callconv::FnAbi; + +use crate::*; + +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { + fn emulate_x86_avx512_intrinsic( + &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(); + // Prefix should have already been checked. + let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.avx512.").unwrap(); + + match unprefixed_name { + // Used by the ternarylogic functions. + "pternlog.d.128" | "pternlog.d.256" | "pternlog.d.512" => { + this.expect_target_feature_for_intrinsic(link_name, "avx512f")?; + if matches!(unprefixed_name, "pternlog.d.128" | "pternlog.d.256") { + this.expect_target_feature_for_intrinsic(link_name, "avx512vl")?; + } + + let [a, b, c, imm8] = + this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + assert_eq!(dest.layout, a.layout); + assert_eq!(dest.layout, b.layout); + assert_eq!(dest.layout, c.layout); + + // The signatures of these operations are: + // + // ``` + // fn vpternlogd(a: i32x16, b: i32x16, c: i32x16, imm8: i32) -> i32x16; + // fn vpternlogd256(a: i32x8, b: i32x8, c: i32x8, imm8: i32) -> i32x8; + // fn vpternlogd128(a: i32x4, b: i32x4, c: i32x4, imm8: i32) -> i32x4; + // ``` + // + // The element type is always a 32-bit integer, the width varies. + + let (a, _a_len) = this.project_to_simd(a)?; + let (b, _b_len) = this.project_to_simd(b)?; + let (c, _c_len) = this.project_to_simd(c)?; + let (dest, dest_len) = this.project_to_simd(dest)?; + + // Compute one lane with ternary table. + let tern = |xa: u32, xb: u32, xc: u32, imm: u32| -> u32 { + let mut out = 0u32; + // At each bit position, select bit from imm8 at index = (a << 2) | (b << 1) | c + for bit in 0..32 { + let ia = (xa >> bit) & 1; + let ib = (xb >> bit) & 1; + let ic = (xc >> bit) & 1; + let idx = (ia << 2) | (ib << 1) | ic; + let v = (imm >> idx) & 1; + out |= v << bit; + } + out + }; + + let imm8 = this.read_scalar(imm8)?.to_u32()? & 0xFF; + for i in 0..dest_len { + let a_lane = this.project_index(&a, i)?; + let b_lane = this.project_index(&b, i)?; + let c_lane = this.project_index(&c, i)?; + let d_lane = this.project_index(&dest, i)?; + + let va = this.read_scalar(&a_lane)?.to_u32()?; + let vb = this.read_scalar(&b_lane)?.to_u32()?; + let vc = this.read_scalar(&c_lane)?.to_u32()?; + + let r = tern(va, vb, vc, imm8); + this.write_scalar(Scalar::from_u32(r), &d_lane)?; + } + } + _ => return interp_ok(EmulateItemResult::NotSupported), + } + interp_ok(EmulateItemResult::NeedsReturn) + } +} diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 63d2b2d044b42..c730609a4a57f 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -13,6 +13,7 @@ use crate::*; mod aesni; mod avx; mod avx2; +mod avx512; mod bmi; mod gfni; mod sha; @@ -152,6 +153,11 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this, link_name, abi, args, dest, ); } + name if name.starts_with("avx512.") => { + return avx512::EvalContextExt::emulate_x86_avx512_intrinsic( + this, link_name, abi, args, dest, + ); + } _ => return interp_ok(EmulateItemResult::NotSupported), } diff --git a/src/tools/miri/tests/deps/Cargo.lock b/src/tools/miri/tests/deps/Cargo.lock index 65ca4215c6001..2549396251672 100644 --- a/src/tools/miri/tests/deps/Cargo.lock +++ b/src/tools/miri/tests/deps/Cargo.lock @@ -72,6 +72,79 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -190,6 +263,7 @@ name = "miri-test-deps" version = "0.1.0" dependencies = [ "cfg-if", + "futures", "getrandom 0.1.16", "getrandom 0.2.16", "getrandom 0.3.3", @@ -242,6 +316,12 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "proc-macro2" version = "1.0.95" diff --git a/src/tools/miri/tests/deps/Cargo.toml b/src/tools/miri/tests/deps/Cargo.toml index d85723f0915fb..fd301fc5cf321 100644 --- a/src/tools/miri/tests/deps/Cargo.toml +++ b/src/tools/miri/tests/deps/Cargo.toml @@ -23,6 +23,7 @@ page_size = "0.6" # Avoid pulling in all of tokio's dependencies. # However, without `net` and `signal`, tokio uses fewer relevant system APIs. tokio = { version = "1", features = ["macros", "rt-multi-thread", "time", "net", "fs", "sync", "signal", "io-util"] } +futures = { version = "0.3.0", default-features = false, features = ["alloc", "async-await"] } [target.'cfg(windows)'.dependencies] windows-sys = { version = "0.60", features = [ diff --git a/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.rs b/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.rs index f6ec5be61bb60..3b1217cda126a 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.rs +++ b/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.rs @@ -28,13 +28,10 @@ fn check_epoll_wait(epfd: i32, expected_notifications: &[(u32, u expected_notifications.len().try_into().unwrap(), "got wrong number of notifications" ); - let slice = unsafe { std::slice::from_raw_parts(array_ptr, res.try_into().unwrap()) }; - for (return_event, expected_event) in slice.iter().zip(expected_notifications.iter()) { - let event = return_event.events; - let data = return_event.u64; - assert_eq!(event, expected_event.0, "got wrong events"); - assert_eq!(data, expected_event.1, "got wrong data"); - } + let got_notifications = + unsafe { std::slice::from_raw_parts(array_ptr, res.try_into().unwrap()) }; + let got_notifications = got_notifications.iter().map(|e| (e.events, e.u64)).collect::>(); + assert_eq!(got_notifications, expected_notifications, "got wrong notifications"); } fn main() { diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs index c97206487a101..81d4e501c43a6 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs @@ -16,6 +16,7 @@ fn main() { test_epoll_block_then_unblock(); test_notification_after_timeout(); test_epoll_race(); + wakeup_on_new_interest(); } // Using `as` cast since `EPOLLET` wraps around @@ -35,18 +36,10 @@ fn check_epoll_wait( if res < 0 { panic!("epoll_wait failed: {}", std::io::Error::last_os_error()); } - assert_eq!( - res, - expected_notifications.len().try_into().unwrap(), - "got wrong number of notifications" - ); - let slice = unsafe { std::slice::from_raw_parts(array_ptr, res.try_into().unwrap()) }; - for (return_event, expected_event) in slice.iter().zip(expected_notifications.iter()) { - let event = return_event.events; - let data = return_event.u64; - assert_eq!(event, expected_event.0, "got wrong events"); - assert_eq!(data, expected_event.1, "got wrong data"); - } + let got_notifications = + unsafe { std::slice::from_raw_parts(array_ptr, res.try_into().unwrap()) }; + let got_notifications = got_notifications.iter().map(|e| (e.events, e.u64)).collect::>(); + assert_eq!(got_notifications, expected_notifications, "got wrong notifications"); } // This test allows epoll_wait to block, then unblock without notification. @@ -179,3 +172,41 @@ fn test_epoll_race() { }; thread1.join().unwrap(); } + +/// Ensure that a blocked thread gets woken up when new interested are registered with the +/// epoll it is blocked on. +fn wakeup_on_new_interest() { + // Create an epoll instance. + let epfd = unsafe { libc::epoll_create1(0) }; + assert_ne!(epfd, -1); + + // Create a socketpair instance. + let mut fds = [-1, -1]; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + assert_eq!(res, 0); + + // Write to fd[0] + let data = "abcde".as_bytes().as_ptr(); + let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 5) }; + assert_eq!(res, 5); + + // Block a thread on the epoll instance. + let t = std::thread::spawn(move || { + let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); + let expected_value = u64::try_from(fds[1]).unwrap(); + check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)], -1); + }); + // Ensure the thread is blocked. + std::thread::yield_now(); + + // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP + let mut ev = libc::epoll_event { + events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET | libc::EPOLLRDHUP) as _, + u64: u64::try_from(fds[1]).unwrap(), + }; + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; + assert_eq!(res, 0); + + // This should wake up the thread. + t.join().unwrap(); +} diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs index 7130790b86d61..569675a5e3c4d 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs @@ -26,6 +26,8 @@ fn main() { test_epoll_ctl_epfd_equal_fd(); test_epoll_ctl_notification(); test_issue_3858(); + test_issue_4374(); + test_issue_4374_reads(); } // Using `as` cast since `EPOLLET` wraps around @@ -41,18 +43,10 @@ fn check_epoll_wait(epfd: i32, expected_notifications: &[(u32, u if res < 0 { panic!("epoll_wait failed: {}", std::io::Error::last_os_error()); } - assert_eq!( - res, - expected_notifications.len().try_into().unwrap(), - "got wrong number of notifications" - ); - let slice = unsafe { std::slice::from_raw_parts(array_ptr, res.try_into().unwrap()) }; - for (return_event, expected_event) in slice.iter().zip(expected_notifications.iter()) { - let event = return_event.events; - let data = return_event.u64; - assert_eq!(event, expected_event.0, "got wrong events"); - assert_eq!(data, expected_event.1, "got wrong data"); - } + let got_notifications = + unsafe { std::slice::from_raw_parts(array_ptr, res.try_into().unwrap()) }; + let got_notifications = got_notifications.iter().map(|e| (e.events, e.u64)).collect::>(); + assert_eq!(got_notifications, expected_notifications, "got wrong notifications"); } fn test_epoll_socketpair() { @@ -64,6 +58,7 @@ fn test_epoll_socketpair() { let mut fds = [-1, -1]; let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; assert_eq!(res, 0); + let fds = [fds[1], fds[0]]; // Write to fd[0] let data = "abcde".as_bytes().as_ptr(); @@ -91,8 +86,9 @@ fn test_epoll_socketpair() { let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 5) }; assert_eq!(res, 5); - // This did not change the readiness of fd[1]. And yet, we're seeing the event reported - // again by the kernel, so Miri does the same. + // This did not change the readiness of fd[1], so we should get no event. + // However, Linux seems to always deliver spurious events to the peer on each write, + // so we match that. check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); // Close the peer socketpair. @@ -102,13 +98,14 @@ fn test_epoll_socketpair() { // Check result from epoll_wait. // We expect to get a read, write, HUP notification from the close since closing an FD always unblocks reads and writes on its peer. let expected_event = - u32::try_from(libc::EPOLLRDHUP | libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLHUP).unwrap(); + u32::try_from(libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLHUP | libc::EPOLLRDHUP).unwrap(); let expected_value = u64::try_from(fds[1]).unwrap(); check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); } // This test first registers a file description with a flag that does not lead to notification, // then EPOLL_CTL_MOD to add another flag that will lead to notification. +// Also check that the new data value set via MOD is applied properly. fn test_epoll_ctl_mod() { // Create an epoll instance. let epfd = unsafe { libc::epoll_create1(0) }; @@ -119,28 +116,49 @@ fn test_epoll_ctl_mod() { let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; assert_eq!(res, 0); - // Register fd[1] with EPOLLIN|EPOLLET. - let mut ev = libc::epoll_event { - events: (libc::EPOLLIN | libc::EPOLLET) as _, - u64: u64::try_from(fds[1]).unwrap(), - }; + // Register fd[1] with EPOLLIN|EPOLLET, and data of "0". + let mut ev = libc::epoll_event { events: (libc::EPOLLIN | libc::EPOLLET) as _, u64: 0 }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; assert_eq!(res, 0); // Check result from epoll_wait. No notification would be returned. check_epoll_wait::<8>(epfd, &[]); - // Use EPOLL_CTL_MOD to change to EPOLLOUT flag. - let mut ev = libc::epoll_event { - events: (libc::EPOLLOUT | libc::EPOLLET) as _, - u64: u64::try_from(fds[1]).unwrap(), - }; + // Use EPOLL_CTL_MOD to change to EPOLLOUT flag and data. + let mut ev = libc::epoll_event { events: (libc::EPOLLOUT | libc::EPOLLET) as _, u64: 1 }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_MOD, fds[1], &mut ev) }; assert_eq!(res, 0); - // Check result from epoll_wait. EPOLLOUT notification is expected. + // Check result from epoll_wait. EPOLLOUT notification and new data is expected. let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); - let expected_value = u64::try_from(fds[1]).unwrap(); + let expected_value = 1; + check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); + + // Write to fds[1] and read from fds[0] to make the notification ready again + // (relying on there always being an event when the buffer gets emptied). + let data = "abc".as_bytes(); + let res = unsafe { libc_utils::write_all(fds[1], data.as_ptr().cast(), data.len()) }; + assert_eq!(res, 3); + let mut buf = [0u8; 3]; + let res = unsafe { libc_utils::read_all(fds[0], buf.as_mut_ptr().cast(), buf.len()) }; + assert_eq!(res, 3); + + // Now that the event is already ready, change the "data" value. + let mut ev = libc::epoll_event { events: (libc::EPOLLOUT | libc::EPOLLET) as _, u64: 2 }; + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_MOD, fds[1], &mut ev) }; + assert_eq!(res, 0); + + // Receive event, with latest data value. + let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); + let expected_value = 2; + check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); + + // Do another update that changes nothing. + let mut ev = libc::epoll_event { events: (libc::EPOLLOUT | libc::EPOLLET) as _, u64: 2 }; + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_MOD, fds[1], &mut ev) }; + assert_eq!(res, 0); + + // This re-triggers the event, even if it's the same flags as before. check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); } @@ -230,7 +248,7 @@ fn test_two_same_fd_in_same_epoll_instance() { let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 5) }; assert_eq!(res, 5); - //Two notification should be received. + // Two notification should be received. let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); let expected_value = 5 as u64; check_epoll_wait::<8>( @@ -262,6 +280,34 @@ fn test_epoll_eventfd() { let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); let expected_value = u64::try_from(fd).unwrap(); check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); + + // Write to the eventfd again. + let res = unsafe { libc_utils::write_all(fd, sized_8_data.as_ptr() as *const libc::c_void, 8) }; + assert_eq!(res, 8); + + // This does not change the status, so we should get no event. + // However, Linux performs a spurious wakeup. + check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); + + // Read from the eventfd. + let mut buf = [0u8; 8]; + let res = unsafe { libc_utils::read_all(fd, buf.as_mut_ptr().cast(), 8) }; + assert_eq!(res, 8); + + // This consumes the event, so the read status is gone. However, deactivation + // does not trigger an event. + // Still, we see a spurious wakeup. + let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); + check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); + + // Write the maximum possible value. + let sized_8_data: [u8; 8] = (u64::MAX - 1).to_ne_bytes(); + let res = unsafe { libc_utils::write_all(fd, sized_8_data.as_ptr() as *const libc::c_void, 8) }; + assert_eq!(res, 8); + + // This reactivates reads, therefore triggering an event. Writing is no longer possible. + let expected_event = u32::try_from(libc::EPOLLIN).unwrap(); + check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); } // When read/write happened on one side of the socketpair, only the other side will be notified. @@ -284,11 +330,13 @@ fn test_epoll_socketpair_both_sides() { assert_eq!(res, 0); // Write to fds[1]. + // (We do the write after the register here, unlike in `test_epoll_socketpair`, to ensure + // we cover both orders in which this could be done.) let data = "abcde".as_bytes().as_ptr(); let res = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5) }; assert_eq!(res, 5); - //Two notification should be received. + // Two notification should be received. let expected_event0 = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); let expected_value0 = fds[0] as u64; let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap(); @@ -305,10 +353,9 @@ fn test_epoll_socketpair_both_sides() { assert_eq!(res, 5); assert_eq!(buf, "abcde".as_bytes()); - // Notification should be provided for fds[1]. - let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); - let expected_value = fds[1] as u64; - check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); + // The state of fds[1] does not change (was writable, is writable). + // However, we force a spurious wakeup as the read buffer just got emptied. + check_epoll_wait::<8>(epfd, &[(expected_event1, expected_value1)]); } // When file description is fully closed, epoll_wait should not provide any notification for @@ -448,12 +495,13 @@ fn test_socketpair_read() { let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; assert_eq!(res, 0); - // Write 5 bytes to fds[1]. - let data = "abcde".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5) }; - assert_eq!(res, 5); + // Write a bunch of data bytes to fds[1]. + let data = [42u8; 1024]; + let res = + unsafe { libc_utils::write_all(fds[1], data.as_ptr() as *const libc::c_void, data.len()) }; + assert_eq!(res, data.len() as isize); - //Two notification should be received. + // Two notification should be received. let expected_event0 = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); let expected_value0 = fds[0] as u64; let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap(); @@ -463,36 +511,26 @@ fn test_socketpair_read() { &[(expected_event0, expected_value0), (expected_event1, expected_value1)], ); - // Read 3 bytes from fds[0]. - let mut buf: [u8; 3] = [0; 3]; + // Read some of the data from fds[0]. + let mut buf = [0; 512]; let res = unsafe { libc_utils::read_all(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; - assert_eq!(res, 3); - assert_eq!(buf, "abc".as_bytes()); + assert_eq!(res, buf.len() as isize); - // Notification will be provided in Miri. - // But in real systems, no notification will be provided here, since Linux prefers to avoid - // wakeups that are likely to lead to only small amounts of data being read/written. - // We make the test work in both cases, thus documenting the difference in behavior. + // fds[1] did not change, it is still writable, so we get no event. let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); let expected_value = fds[1] as u64; - if cfg!(miri) { - check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); - } else { - check_epoll_wait::<8>(epfd, &[]); - } + check_epoll_wait::<8>(epfd, &[]); // Read until the buffer is empty. - let mut buf: [u8; 2] = [0; 2]; + let rest = data.len() - buf.len(); let res = - unsafe { libc_utils::read_all(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; - assert_eq!(res, 2); - assert_eq!(buf, "de".as_bytes()); + unsafe { libc_utils::read_all(fds[0], buf.as_mut_ptr().cast(), rest as libc::size_t) }; + assert_eq!(res, rest as isize); - // Notification will be provided. - // In real system, notification will be provided too. - let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); - let expected_value = fds[1] as u64; + // Now we get a notification that fds[1] can be written. This is spurious since it + // could already be written before, but Linux seems to always emit a notification for + // the writer when a read empties the buffer. check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); } @@ -512,7 +550,7 @@ fn test_no_notification_for_unregister_flag() { events: (libc::EPOLLOUT | libc::EPOLLET) as _, u64: u64::try_from(fds[0]).unwrap(), }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; assert_eq!(res, 0); // Write to fd[1]. @@ -599,7 +637,7 @@ fn test_epoll_lost_events() { let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; assert_eq!(res, 0); - //Two notification should be received. But we only provide buffer for one event. + // Two notification should be received. But we only provide buffer for one event. let expected_event0 = u32::try_from(libc::EPOLLOUT).unwrap(); let expected_value0 = fds[0] as u64; check_epoll_wait::<1>(epfd, &[(expected_event0, expected_value0)]); @@ -641,7 +679,8 @@ fn test_ready_list_fetching_logic() { check_epoll_wait::<1>(epfd, &[(expected_event1, expected_value1)]); } -// In epoll_ctl, if the value of epfd equals to fd, EINVAL should be returned. +// In epoll_ctl, if the value of epfd equals to fd, EFAULT should be returned. +// (The docs say loops cause EINVAL, but experiments show it is EFAULT.) fn test_epoll_ctl_epfd_equal_fd() { // Create an epoll instance. let epfd = unsafe { libc::epoll_create1(0) }; @@ -650,7 +689,7 @@ fn test_epoll_ctl_epfd_equal_fd() { let array_ptr = std::ptr::without_provenance_mut::(0x100); let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, epfd, array_ptr) }; let e = std::io::Error::last_os_error(); - assert_eq!(e.raw_os_error(), Some(libc::EINVAL)); + assert_eq!(e.raw_os_error(), Some(libc::EFAULT)); assert_eq!(res, -1); } @@ -728,3 +767,72 @@ fn test_issue_3858() { let res = unsafe { libc_utils::write_all(fd, sized_8_data.as_ptr() as *const libc::c_void, 8) }; assert_eq!(res, 8); } + +/// Ensure that if a socket becomes un-writable, we don't see it any more. +fn test_issue_4374() { + // Create an epoll instance. + let epfd0 = unsafe { libc::epoll_create1(0) }; + assert_ne!(epfd0, -1); + + // Create a socketpair instance, make it non-blocking. + let mut fds = [-1, -1]; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + assert_eq!(res, 0); + assert_eq!(unsafe { libc::fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK) }, 0); + assert_eq!(unsafe { libc::fcntl(fds[1], libc::F_SETFL, libc::O_NONBLOCK) }, 0); + + // Register fds[0] with epoll while it is writable (but not readable). + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; + let res = unsafe { libc::epoll_ctl(epfd0, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; + assert_eq!(res, 0); + + // Fill up fds[0] so that it is not writable any more. + let zeros = [0u8; 512]; + loop { + let res = unsafe { + libc_utils::write_all(fds[0], zeros.as_ptr() as *const libc::c_void, zeros.len()) + }; + if res < 0 { + break; + } + } + + // This should have canceled the previous readiness, so now we get nothing. + check_epoll_wait::<1>(epfd0, &[]); +} + +/// Same as above, but for becoming un-readable. +fn test_issue_4374_reads() { + // Create an epoll instance. + let epfd0 = unsafe { libc::epoll_create1(0) }; + assert_ne!(epfd0, -1); + + // Create a socketpair instance, make it non-blocking. + let mut fds = [-1, -1]; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + assert_eq!(res, 0); + assert_eq!(unsafe { libc::fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK) }, 0); + assert_eq!(unsafe { libc::fcntl(fds[1], libc::F_SETFL, libc::O_NONBLOCK) }, 0); + + // Write to fds[1] so that fds[0] becomes readable. + let data = "abcde".as_bytes().as_ptr(); + let res: i32 = unsafe { + libc_utils::write_all(fds[1], data as *const libc::c_void, 5).try_into().unwrap() + }; + assert_eq!(res, 5); + + // Register fds[0] with epoll while it is readable. + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; + let res = unsafe { libc::epoll_ctl(epfd0, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; + assert_eq!(res, 0); + + // Read fds[0] so it is no longer readable. + let mut buf = [0u8; 512]; + let res = unsafe { libc_utils::read_all(fds[0], buf.as_mut_ptr() as *mut libc::c_void, 5) }; + assert_eq!(res, 5); + + // We should now still see a notification, but only about it being writable. + let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); + let expected_value = fds[0] as u64; + check_epoll_wait::<1>(epfd0, &[(expected_event, expected_value)]); +} diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs index 9c211ffbdbe4a..ce3927ce48ca7 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs @@ -187,11 +187,11 @@ fn test_blocking_write() { let mut fds = [-1, -1]; let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; assert_eq!(res, 0); - let arr1: [u8; 212992] = [1; 212992]; + let arr1: [u8; 0x34000] = [1; 0x34000]; // Exhaust the space in the buffer so the subsequent write will block. let res = - unsafe { libc_utils::write_all(fds[0], arr1.as_ptr() as *const libc::c_void, 212992) }; - assert_eq!(res, 212992); + unsafe { libc_utils::write_all(fds[0], arr1.as_ptr() as *const libc::c_void, arr1.len()) }; + assert_eq!(res, 0x34000); let thread1 = thread::spawn(move || { let data = "abc".as_bytes().as_ptr(); // The write below will be blocked because the buffer is already full. diff --git a/src/tools/miri/tests/pass-dep/tokio/poll_fns.rs b/src/tools/miri/tests/pass-dep/tokio/poll_fns.rs new file mode 100644 index 0000000000000..738c80b51ad4e --- /dev/null +++ b/src/tools/miri/tests/pass-dep/tokio/poll_fns.rs @@ -0,0 +1,161 @@ +//! This is a stand-alone version of the `poll_fns` test in Tokio. It hits various +//! interesting edge cases in the epoll logic, making it a good integration test. +//! It also seems to depend on Tokio internals, so if Tokio changes we have have to update +//! or remove the test. + +//@only-target: linux # We only support tokio on Linux + +use std::fs::File; +use std::io::{ErrorKind, Read, Write}; +use std::os::fd::FromRawFd; +use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::task::{Context, Waker}; +use std::time::Duration; + +use futures::poll; +use tokio::io::unix::AsyncFd; + +macro_rules! assert_pending { + ($e:expr) => {{ + use core::task::Poll; + match $e { + Poll::Pending => {} + Poll::Ready(v) => panic!("ready; value = {:?}", v), + } + }}; +} + +struct TestWaker { + inner: Arc, + waker: Waker, +} + +#[derive(Default)] +struct TestWakerInner { + awoken: AtomicBool, +} + +impl futures::task::ArcWake for TestWakerInner { + fn wake_by_ref(arc_self: &Arc) { + arc_self.awoken.store(true, Ordering::SeqCst); + } +} + +impl TestWaker { + fn new() -> Self { + let inner: Arc = Default::default(); + + Self { inner: inner.clone(), waker: futures::task::waker(inner) } + } + + fn awoken(&self) -> bool { + self.inner.awoken.swap(false, Ordering::SeqCst) + } + + fn context(&self) -> Context<'_> { + Context::from_waker(&self.waker) + } +} + +fn socketpair() -> (File, File) { + let mut fds = [-1, -1]; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + assert_eq!(res, 0); + + assert_eq!(unsafe { libc::fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK) }, 0); + assert_eq!(unsafe { libc::fcntl(fds[1], libc::F_SETFL, libc::O_NONBLOCK) }, 0); + + unsafe { (File::from_raw_fd(fds[0]), File::from_raw_fd(fds[1])) } +} + +fn drain(mut fd: &File, mut amt: usize) { + let mut buf = [0u8; 512]; + while amt > 0 { + match fd.read(&mut buf[..]) { + Err(e) if e.kind() == ErrorKind::WouldBlock => {} + Ok(0) => panic!("unexpected EOF"), + Err(e) => panic!("unexpected error: {e:?}"), + Ok(x) => amt -= x, + } + } +} + +fn main() { + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(the_test()); +} + +async fn the_test() { + let (a, b) = socketpair(); + let afd_a = Arc::new(AsyncFd::new(a).unwrap()); + let afd_b = Arc::new(AsyncFd::new(b).unwrap()); + + // Fill up the write side of A + let mut bytes = 0; + while let Ok(amt) = afd_a.get_ref().write(&[0; 512]) { + bytes += amt; + } + + let waker = TestWaker::new(); + + assert_pending!(afd_a.as_ref().poll_read_ready(&mut waker.context())); + + let afd_a_2 = afd_a.clone(); + let r_barrier = Arc::new(tokio::sync::Barrier::new(2)); + let barrier_clone = r_barrier.clone(); + + let read_fut = tokio::spawn(async move { + // Move waker onto this task first + assert_pending!(poll!(std::future::poll_fn(|cx| afd_a_2.as_ref().poll_read_ready(cx)))); + barrier_clone.wait().await; + + let _ = std::future::poll_fn(|cx| afd_a_2.as_ref().poll_read_ready(cx)).await; + }); + + let afd_a_2 = afd_a.clone(); + let w_barrier = Arc::new(tokio::sync::Barrier::new(2)); + let barrier_clone = w_barrier.clone(); + + let mut write_fut = tokio::spawn(async move { + // Move waker onto this task first + assert_pending!(poll!(std::future::poll_fn(|cx| afd_a_2.as_ref().poll_write_ready(cx)))); + barrier_clone.wait().await; + + let _ = std::future::poll_fn(|cx| afd_a_2.as_ref().poll_write_ready(cx)).await; + }); + + r_barrier.wait().await; + w_barrier.wait().await; + + let readable = afd_a.readable(); + tokio::pin!(readable); + + tokio::select! { + _ = &mut readable => unreachable!(), + _ = tokio::task::yield_now() => {} + } + + // Make A readable. We expect that 'readable' and 'read_fut' will both complete quickly + afd_b.get_ref().write_all(b"0").unwrap(); + + let _ = tokio::join!(readable, read_fut); + + // Our original waker should _not_ be awoken (poll_read_ready retains only the last context) + assert!(!waker.awoken()); + + // The writable side should not be awoken + tokio::select! { + _ = &mut write_fut => unreachable!(), + _ = tokio::time::sleep(Duration::from_millis(50)) => {} + } + + // Make it writable now + drain(afd_b.get_ref(), bytes); + + // now we should be writable (ie - the waker for poll_write should still be registered after we wake the read side) + let _ = write_fut.await; +} diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs index 65d7b57d1ce51..c22227a8c6599 100644 --- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs @@ -17,6 +17,7 @@ fn main() { unsafe { test_avx512bitalg(); test_avx512vpopcntdq(); + test_avx512ternarylogic(); } } @@ -191,6 +192,77 @@ unsafe fn test_avx512vpopcntdq() { test_mm_popcnt_epi64(); } +#[target_feature(enable = "avx512f,avx512vl")] +unsafe fn test_avx512ternarylogic() { + #[target_feature(enable = "avx512f")] + unsafe fn test_mm512_ternarylogic_epi32() { + let a = _mm512_set4_epi32(0b100, 0b110, 0b001, 0b101); + let b = _mm512_set4_epi32(0b010, 0b011, 0b001, 0b110); + let c = _mm512_set4_epi32(0b001, 0b000, 0b001, 0b111); + + // Identity of A. + let r = _mm512_ternarylogic_epi32::<0b1111_0000>(a, b, c); + assert_eq_m512i(r, a); + + // Bitwise xor. + let r = _mm512_ternarylogic_epi32::<0b10010110>(a, b, c); + let e = _mm512_set4_epi32(0b111, 0b101, 0b001, 0b100); + assert_eq_m512i(r, e); + + // Majority (2 or more bits set). + let r = _mm512_ternarylogic_epi32::<0b1110_1000>(a, b, c); + let e = _mm512_set4_epi32(0b000, 0b010, 0b001, 0b111); + assert_eq_m512i(r, e); + } + test_mm512_ternarylogic_epi32(); + + #[target_feature(enable = "avx512f,avx512vl")] + unsafe fn test_mm256_ternarylogic_epi32() { + let _mm256_set4_epi32 = |a, b, c, d| _mm256_setr_epi32(a, b, c, d, a, b, c, d); + + let a = _mm256_set4_epi32(0b100, 0b110, 0b001, 0b101); + let b = _mm256_set4_epi32(0b010, 0b011, 0b001, 0b110); + let c = _mm256_set4_epi32(0b001, 0b000, 0b001, 0b111); + + // Identity of A. + let r = _mm256_ternarylogic_epi32::<0b1111_0000>(a, b, c); + assert_eq_m256i(r, a); + + // Bitwise xor. + let r = _mm256_ternarylogic_epi32::<0b10010110>(a, b, c); + let e = _mm256_set4_epi32(0b111, 0b101, 0b001, 0b100); + assert_eq_m256i(r, e); + + // Majority (2 or more bits set). + let r = _mm256_ternarylogic_epi32::<0b1110_1000>(a, b, c); + let e = _mm256_set4_epi32(0b000, 0b010, 0b001, 0b111); + assert_eq_m256i(r, e); + } + test_mm256_ternarylogic_epi32(); + + #[target_feature(enable = "avx512f,avx512vl")] + unsafe fn test_mm_ternarylogic_epi32() { + let a = _mm_setr_epi32(0b100, 0b110, 0b001, 0b101); + let b = _mm_setr_epi32(0b010, 0b011, 0b001, 0b110); + let c = _mm_setr_epi32(0b001, 0b000, 0b001, 0b111); + + // Identity of A. + let r = _mm_ternarylogic_epi32::<0b1111_0000>(a, b, c); + assert_eq_m128i(r, a); + + // Bitwise xor. + let r = _mm_ternarylogic_epi32::<0b10010110>(a, b, c); + let e = _mm_setr_epi32(0b111, 0b101, 0b001, 0b100); + assert_eq_m128i(r, e); + + // Majority (2 or more bits set). + let r = _mm_ternarylogic_epi32::<0b1110_1000>(a, b, c); + let e = _mm_setr_epi32(0b000, 0b010, 0b001, 0b111); + assert_eq_m128i(r, e); + } + test_mm_ternarylogic_epi32(); +} + #[track_caller] unsafe fn assert_eq_m512i(a: __m512i, b: __m512i) { assert_eq!(transmute::<_, [i32; 16]>(a), transmute::<_, [i32; 16]>(b)) diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index 7990ca2325c04..d5aa7a671636c 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -10,18 +10,18 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] name = "ammonia" -version = "4.1.1" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b346764dd0814805de8abf899fe03065bcee69bb1a4771c785817e39f3978f" +checksum = "17e913097e1a2124b46746c980134e8c954bc17a6a59bb3fde96f088d126dde6" dependencies = [ "cssparser", "html5ever", @@ -30,12 +30,6 @@ dependencies = [ "url", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -47,9 +41,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -62,9 +56,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -97,9 +91,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "autocfg" @@ -118,15 +112,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.9.2" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a65b545ab31d687cff52899d4890855fec459eb6afe0da6417b8a18da87aa29" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "block-buffer" @@ -139,9 +127,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", "regex-automata", @@ -156,26 +144,26 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "cc" -version = "1.2.33" +version = "1.2.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee0f8803222ba5a7e2777dd72ca451868909b1ac410621b676adf07280e9b5f" +checksum = "35900b6c8d709fb1d854671ae27aeaa9eec2f8b01b364e1619a40da3e6fe2afe" dependencies = [ + "find-msvc-tools", "shlex", ] [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", @@ -185,9 +173,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.45" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318" +checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" dependencies = [ "clap_builder", "clap_derive", @@ -195,9 +183,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.44" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8" +checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" dependencies = [ "anstream", "anstyle", @@ -208,18 +196,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.57" +version = "4.5.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d9501bd3f5f09f7bbee01da9a511073ed30a80cd7a509f1214bb74eadea71ad" +checksum = "8e602857739c5a4291dfa33b5a298aeac9006185229a700e5810a3ef7272d971" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.45" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", @@ -229,9 +217,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "colorchoice" @@ -282,7 +270,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf", + "phf 0.11.3", "smallvec", ] @@ -397,9 +385,9 @@ dependencies = [ [[package]] name = "doc-comment" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +checksum = "780955b8b195a21ab8e4ac6b60dd1dbdcec1dc6c51c0617964b08c81785e12c9" [[package]] name = "dtoa" @@ -430,9 +418,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" dependencies = [ "log", "regex", @@ -459,12 +447,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -480,11 +468,17 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "miniz_oxide", @@ -498,9 +492,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -517,9 +511,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -527,23 +521,23 @@ dependencies = [ [[package]] name = "getopts" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cba6ae63eb948698e300f645f87c70f76630d505f23b8907cf1e193ee85048c1" +checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" dependencies = [ "unicode-width", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi", + "wasip2", ] [[package]] @@ -559,14 +553,14 @@ dependencies = [ "pest_derive", "serde", "serde_json", - "thiserror 2.0.15", + "thiserror 2.0.17", ] [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" [[package]] name = "heck" @@ -608,9 +602,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -632,9 +626,9 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", @@ -645,9 +639,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -658,11 +652,10 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", @@ -673,42 +666,38 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", - "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", - "stable_deref_trait", - "tinystr", "writeable", "yoke", "zerofrom", @@ -724,9 +713,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -745,9 +734,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.10.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", "hashbrown", @@ -755,9 +744,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itoa" @@ -767,22 +756,22 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" dependencies = [ "jiff-static", "log", "portable-atomic", "portable-atomic-util", - "serde", + "serde_core", ] [[package]] name = "jiff-static" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" dependencies = [ "proc-macro2", "quote", @@ -791,9 +780,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" dependencies = [ "once_cell", "wasm-bindgen", @@ -828,25 +817,24 @@ checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "mac" @@ -976,6 +964,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -986,11 +975,11 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "normpath" -version = "1.3.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" +checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1025,9 +1014,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "onig" @@ -1035,7 +1024,7 @@ version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" dependencies = [ - "bitflags 2.9.2", + "bitflags", "libc", "once_cell", "onig_sys", @@ -1053,20 +1042,20 @@ dependencies = [ [[package]] name = "opener" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771b9704f8cd8b424ec747a320b30b47517a6966ba2c7da90047c16f4a962223" +checksum = "cb9024962ab91e00c89d2a14352a8d0fc1a64346bf96f1839b45c09149564e47" dependencies = [ "bstr", "normpath", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -1074,15 +1063,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -1093,26 +1082,25 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" dependencies = [ "memchr", - "thiserror 2.0.15", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" +checksum = "187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de" dependencies = [ "pest", "pest_generator", @@ -1120,9 +1108,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" +checksum = "49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843" dependencies = [ "pest", "pest_meta", @@ -1133,9 +1121,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" +checksum = "72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a" dependencies = [ "pest", "sha2", @@ -1148,17 +1136,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_macros", - "phf_shared", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_shared 0.13.1", + "serde", ] [[package]] name = "phf_codegen" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.13.1", + "phf_shared 0.13.1", ] [[package]] @@ -1167,18 +1165,28 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ - "phf_shared", + "phf_shared 0.11.3", "rand", ] +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared 0.13.1", +] + [[package]] name = "phf_macros" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.11.3", + "phf_shared 0.11.3", "proc-macro2", "quote", "syn", @@ -1193,6 +1201,15 @@ dependencies = [ "siphasher", ] +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] + [[package]] name = "pkg-config" version = "0.3.32" @@ -1225,9 +1242,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] @@ -1240,9 +1257,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] @@ -1253,7 +1270,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" dependencies = [ - "bitflags 2.9.2", + "bitflags", "memchr", "pulldown-cmark-escape 0.10.1", "unicase", @@ -1265,7 +1282,7 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f86ba2052aebccc42cbbb3ed234b8b13ce76f75c3551a303cb2bcffcff12bb14" dependencies = [ - "bitflags 2.9.2", + "bitflags", "getopts", "memchr", "pulldown-cmark-escape 0.11.0", @@ -1304,9 +1321,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -1343,18 +1360,18 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.2", + "bitflags", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -1364,9 +1381,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -1375,9 +1392,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "rustbook" @@ -1398,11 +1415,11 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.2", + "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1434,24 +1451,34 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -1460,14 +1487,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.142" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] @@ -1496,6 +1524,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "siphasher" version = "1.0.1" @@ -1510,31 +1544,31 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "string_cache" -version = "0.8.9" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" dependencies = [ "new_debug_unreachable", "parking_lot", - "phf_shared", + "phf_shared 0.13.1", "precomputed-hash", "serde", ] [[package]] name = "string_cache_codegen" -version = "0.5.4" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.13.1", + "phf_shared 0.13.1", "proc-macro2", "quote", ] @@ -1547,9 +1581,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.106" +version = "2.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" dependencies = [ "proc-macro2", "quote", @@ -1569,12 +1603,11 @@ dependencies = [ [[package]] name = "syntect" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1" +checksum = "656b45c05d95a5704399aeef6bd0ddec7b2b3531b7c9e900abbf7c4d2190c925" dependencies = [ "bincode", - "bitflags 1.3.2", "flate2", "fnv", "once_cell", @@ -1582,22 +1615,21 @@ dependencies = [ "regex-syntax", "serde", "serde_derive", - "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.17", "walkdir", ] [[package]] name = "tempfile" -version = "3.20.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", "getrandom", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1638,11 +1670,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.15" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d76d3f064b981389ecb4b6b7f45a0bf9fdac1d5b9204c7bd6714fecc302850" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.15", + "thiserror-impl 2.0.17", ] [[package]] @@ -1658,9 +1690,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.15" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d29feb33e986b6ea906bd9c3559a856983f92371b3eaa5e83782a351623de0" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -1669,9 +1701,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -1735,9 +1767,9 @@ checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ucd-trie" @@ -1753,25 +1785,26 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-width" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -1809,45 +1842,32 @@ dependencies = [ ] [[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1855,33 +1875,33 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" dependencies = [ "unicode-ident", ] [[package]] name = "web_atoms" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ffde1dc01240bdf9992e3205668b235e59421fd085e8a317ed98da0178d414" +checksum = "44b72896d90cfd22c495d0ee4960d3dd20ca64180895cb92cd5342ff7482a579" dependencies = [ - "phf", + "phf 0.13.1", "phf_codegen", "string_cache", "string_cache_codegen", @@ -1889,18 +1909,18 @@ dependencies = [ [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "windows-core" -version = "0.61.2" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", @@ -1911,9 +1931,9 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -1922,9 +1942,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -1933,206 +1953,138 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-result" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.52.6" +name = "windows-sys" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows-link", ] [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.2", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -2140,9 +2092,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", @@ -2173,9 +2125,9 @@ dependencies = [ [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -2184,9 +2136,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -2195,9 +2147,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", diff --git a/tests/coverage/async_block.cov-map b/tests/coverage/async_block.cov-map index 07d4c0eb3cd60..08f5a7b5d79ee 100644 --- a/tests/coverage/async_block.cov-map +++ b/tests/coverage/async_block.cov-map @@ -1,5 +1,5 @@ Function name: async_block::main -Raw bytes (41): 0x[01, 01, 01, 05, 01, 07, 01, 07, 01, 00, 0a, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 13, 02, 01, 0d, 00, 13, 02, 07, 09, 00, 1b, 02, 00, 1c, 00, 22, 01, 02, 01, 00, 02] +Raw bytes (41): 0x[01, 01, 01, 05, 01, 07, 01, 07, 01, 00, 0a, 02, 01, 09, 00, 0a, 01, 00, 0e, 00, 13, 02, 01, 0d, 00, 13, 02, 07, 09, 00, 1b, 02, 00, 1c, 00, 22, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async_block.rs Number of expressions: 1 @@ -8,7 +8,7 @@ Number of file 0 mappings: 7 - Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10) = (c1 - c0) -- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19) - Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 19) = (c1 - c0) - Code(Expression(0, Sub)) at (prev + 7, 9) to (start + 0, 27) @@ -16,7 +16,7 @@ Number of file 0 mappings: 7 - Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 0, 34) = (c1 - c0) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) -Highest counter ID seen: c1 +Highest counter ID seen: c0 Function name: async_block::main::{closure#0} Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 09, 1c, 00, 1d, 01, 01, 10, 00, 17, 05, 00, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] diff --git a/tests/coverage/continue.cov-map b/tests/coverage/continue.cov-map index 1a839f19a0f5b..05efd2707817a 100644 --- a/tests/coverage/continue.cov-map +++ b/tests/coverage/continue.cov-map @@ -1,5 +1,5 @@ Function name: continue::main -Raw bytes (241): 0x[01, 01, 1a, 05, 01, 05, 13, 01, 09, 05, 13, 01, 09, 0d, 01, 0d, 27, 01, 11, 0d, 27, 01, 11, 15, 01, 15, 33, 01, 19, 1d, 01, 1d, 47, 01, 21, 1d, 47, 01, 21, 25, 01, 25, 53, 01, 29, 25, 01, 2d, 01, 63, 2d, 01, 31, 2d, 01, 25, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0e, 00, 13, 02, 01, 0f, 00, 16, 09, 02, 11, 00, 19, 0e, 02, 12, 02, 0e, 0e, 04, 09, 00, 0e, 0d, 02, 0e, 00, 13, 16, 01, 0f, 00, 16, 22, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 22, 03, 09, 00, 0e, 15, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 19, 01, 15, 02, 0e, 2e, 04, 11, 00, 19, 19, 03, 09, 00, 0e, 1d, 02, 0e, 00, 13, 36, 01, 0c, 00, 13, 21, 01, 0d, 00, 15, 42, 01, 09, 00, 0a, 42, 01, 09, 00, 0e, 25, 02, 0e, 00, 13, 56, 01, 0f, 00, 16, 4e, 01, 16, 02, 0e, 29, 03, 12, 02, 0e, 56, 04, 09, 00, 0e, 2d, 02, 0e, 00, 13, 31, 01, 0f, 00, 16, 66, 01, 16, 02, 0e, 5e, 04, 11, 00, 16, 66, 03, 09, 00, 0e, 01, 02, 0d, 00, 0e, 01, 01, 01, 00, 02] +Raw bytes (241): 0x[01, 01, 1a, 05, 01, 05, 13, 01, 09, 05, 13, 01, 09, 0d, 01, 0d, 27, 01, 11, 0d, 27, 01, 11, 15, 01, 15, 33, 01, 19, 1d, 01, 1d, 47, 01, 21, 1d, 47, 01, 21, 25, 01, 25, 53, 01, 29, 25, 01, 31, 01, 63, 31, 01, 2d, 31, 01, 25, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 01, 01, 0e, 00, 13, 02, 01, 0f, 00, 16, 09, 02, 11, 00, 19, 0e, 02, 12, 02, 0e, 0e, 04, 09, 00, 0e, 01, 02, 0e, 00, 13, 16, 01, 0f, 00, 16, 22, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 22, 03, 09, 00, 0e, 01, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 19, 01, 15, 02, 0e, 2e, 04, 11, 00, 19, 19, 03, 09, 00, 0e, 01, 02, 0e, 00, 13, 36, 01, 0c, 00, 13, 21, 01, 0d, 00, 15, 42, 01, 09, 00, 0a, 42, 01, 09, 00, 0e, 01, 02, 0e, 00, 13, 56, 01, 0f, 00, 16, 4e, 01, 16, 02, 0e, 29, 03, 12, 02, 0e, 56, 04, 09, 00, 0e, 01, 02, 0e, 00, 13, 2d, 01, 0f, 00, 16, 66, 01, 16, 02, 0e, 5e, 04, 11, 00, 16, 66, 03, 09, 00, 0e, 01, 02, 0d, 00, 0e, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/continue.rs Number of expressions: 26 @@ -25,17 +25,17 @@ Number of expressions: 26 - expression 19 operands: lhs = Counter(9), rhs = Expression(20, Add) - expression 20 operands: lhs = Counter(0), rhs = Counter(10) - expression 21 operands: lhs = Counter(9), rhs = Counter(0) -- expression 22 operands: lhs = Counter(11), rhs = Counter(0) -- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(11) -- expression 24 operands: lhs = Counter(0), rhs = Counter(12) -- expression 25 operands: lhs = Counter(11), rhs = Counter(0) +- expression 22 operands: lhs = Counter(12), rhs = Counter(0) +- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(12) +- expression 24 operands: lhs = Counter(0), rhs = Counter(11) +- expression 25 operands: lhs = Counter(12), rhs = Counter(0) Number of file 0 mappings: 37 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) - Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14) - Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18) -- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 19) +- Code(Counter(0)) at (prev + 1, 14) to (start + 0, 19) - Code(Expression(0, Sub)) at (prev + 1, 15) to (start + 0, 22) = (c1 - c0) - Code(Counter(2)) at (prev + 2, 17) to (start + 0, 25) @@ -43,7 +43,7 @@ Number of file 0 mappings: 37 = (c1 - (c0 + c2)) - Code(Expression(3, Sub)) at (prev + 4, 9) to (start + 0, 14) = (c1 - (c0 + c2)) -- Code(Counter(3)) at (prev + 2, 14) to (start + 0, 19) +- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 19) - Code(Expression(5, Sub)) at (prev + 1, 15) to (start + 0, 22) = (c3 - c0) - Code(Expression(8, Sub)) at (prev + 1, 22) to (start + 2, 14) @@ -51,14 +51,14 @@ Number of file 0 mappings: 37 - Code(Counter(4)) at (prev + 4, 17) to (start + 0, 25) - Code(Expression(8, Sub)) at (prev + 3, 9) to (start + 0, 14) = (c3 - (c0 + c4)) -- Code(Counter(5)) at (prev + 2, 14) to (start + 0, 19) +- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 19) - Code(Expression(10, Sub)) at (prev + 1, 15) to (start + 0, 22) = (c5 - c0) - Code(Counter(6)) at (prev + 1, 21) to (start + 2, 14) - Code(Expression(11, Sub)) at (prev + 4, 17) to (start + 0, 25) = (c5 - (c0 + c6)) - Code(Counter(6)) at (prev + 3, 9) to (start + 0, 14) -- Code(Counter(7)) at (prev + 2, 14) to (start + 0, 19) +- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 19) - Code(Expression(13, Sub)) at (prev + 1, 12) to (start + 0, 19) = (c7 - c0) - Code(Counter(8)) at (prev + 1, 13) to (start + 0, 21) @@ -66,7 +66,7 @@ Number of file 0 mappings: 37 = (c7 - (c0 + c8)) - Code(Expression(16, Sub)) at (prev + 1, 9) to (start + 0, 14) = (c7 - (c0 + c8)) -- Code(Counter(9)) at (prev + 2, 14) to (start + 0, 19) +- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 19) - Code(Expression(21, Sub)) at (prev + 1, 15) to (start + 0, 22) = (c9 - c0) - Code(Expression(19, Sub)) at (prev + 1, 22) to (start + 2, 14) @@ -74,15 +74,15 @@ Number of file 0 mappings: 37 - Code(Counter(10)) at (prev + 3, 18) to (start + 2, 14) - Code(Expression(21, Sub)) at (prev + 4, 9) to (start + 0, 14) = (c9 - c0) -- Code(Counter(11)) at (prev + 2, 14) to (start + 0, 19) -- Code(Counter(12)) at (prev + 1, 15) to (start + 0, 22) +- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 19) +- Code(Counter(11)) at (prev + 1, 15) to (start + 0, 22) - Code(Expression(25, Sub)) at (prev + 1, 22) to (start + 2, 14) - = (c11 - c0) + = (c12 - c0) - Code(Expression(23, Sub)) at (prev + 4, 17) to (start + 0, 22) - = ((c0 + c12) - c11) + = ((c0 + c11) - c12) - Code(Expression(25, Sub)) at (prev + 3, 9) to (start + 0, 14) - = (c11 - c0) + = (c12 - c0) - Code(Counter(0)) at (prev + 2, 13) to (start + 0, 14) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c12 +Highest counter ID seen: c11 diff --git a/tests/coverage/inline.cov-map b/tests/coverage/inline.cov-map index 4c67dd96ac2f5..55f4b8484c024 100644 --- a/tests/coverage/inline.cov-map +++ b/tests/coverage/inline.cov-map @@ -1,5 +1,5 @@ Function name: inline::display:: -Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 29, 01, 00, 21, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 10, 02, 00, 11, 02, 06, 01, 03, 05, 00, 0d, 01, 01, 01, 00, 02] +Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 29, 01, 00, 21, 02, 01, 09, 00, 0a, 01, 00, 0e, 00, 10, 02, 00, 11, 02, 06, 01, 03, 05, 00, 0d, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline.rs Number of expressions: 1 @@ -8,12 +8,12 @@ Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 41, 1) to (start + 0, 33) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10) = (c1 - c0) -- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 16) - Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 2, 6) = (c1 - c0) - Code(Counter(0)) at (prev + 3, 5) to (start + 0, 13) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c1 +Highest counter ID seen: c0 Function name: inline::error Raw bytes (14): 0x[01, 01, 00, 02, 01, 31, 01, 00, 0b, 01, 01, 05, 00, 0b] @@ -50,7 +50,7 @@ Number of file 0 mappings: 4 Highest counter ID seen: c0 Function name: inline::permutate:: -Raw bytes (142): 0x[01, 01, 0e, 01, 05, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 01, 37, 05, 09, 16, 01, 0f, 01, 00, 38, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 13, 01, 00, 14, 00, 16, 01, 01, 08, 00, 0e, 05, 00, 0f, 02, 06, 02, 02, 0f, 00, 14, 2e, 01, 0d, 00, 0e, 09, 00, 12, 00, 13, 09, 00, 15, 00, 16, 2e, 00, 17, 04, 0a, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 2e, 00, 16, 00, 17, 2e, 00, 19, 00, 1a, 2e, 01, 0d, 00, 16, 2e, 00, 17, 00, 19, 2e, 00, 1b, 00, 20, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 32, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (137): 0x[01, 01, 0e, 01, 05, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 01, 37, 05, 09, 15, 01, 0f, 01, 00, 38, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 13, 01, 00, 14, 00, 16, 01, 01, 08, 00, 0e, 05, 00, 0f, 02, 06, 02, 02, 0f, 00, 14, 2e, 01, 0d, 00, 0e, 09, 00, 12, 00, 16, 2e, 00, 17, 04, 0a, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 2e, 00, 16, 00, 17, 2e, 00, 19, 00, 1a, 2e, 01, 0d, 00, 16, 2e, 00, 17, 00, 19, 2e, 00, 1b, 00, 20, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 32, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline.rs Number of expressions: 14 @@ -68,7 +68,7 @@ Number of expressions: 14 - expression 11 operands: lhs = Counter(3), rhs = Counter(2) - expression 12 operands: lhs = Counter(0), rhs = Expression(13, Add) - expression 13 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 22 +Number of file 0 mappings: 21 - Code(Counter(0)) at (prev + 15, 1) to (start + 0, 56) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 19) @@ -79,8 +79,7 @@ Number of file 0 mappings: 22 = (c0 - c1) - Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 14) = (c3 - c2) -- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 19) -- Code(Counter(2)) at (prev + 0, 21) to (start + 0, 22) +- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 22) - Code(Expression(11, Sub)) at (prev + 0, 23) to (start + 4, 10) = (c3 - c2) - Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 17) diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map index 78fdaa53f46f1..96dd705044131 100644 --- a/tests/coverage/loops_branches.cov-map +++ b/tests/coverage/loops_branches.cov-map @@ -1,12 +1,13 @@ Function name: ::fmt -Raw bytes (137): 0x[01, 01, 04, 07, 0b, 01, 0d, 05, 09, 09, 0d, 19, 01, 09, 05, 00, 43, 01, 01, 0c, 00, 10, 01, 01, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 0d, 03, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 14, 0d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0d, 01, 11, 00, 12, 0d, 01, 11, 00, 17, 0d, 00, 18, 00, 19, 0d, 00, 1b, 00, 21, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06] +Raw bytes (139): 0x[01, 01, 05, 01, 05, 0b, 0f, 01, 09, 05, 0d, 0d, 09, 19, 01, 09, 05, 00, 43, 01, 01, 0c, 00, 10, 01, 01, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 09, 03, 0d, 00, 0e, 02, 00, 12, 00, 17, 09, 01, 10, 00, 14, 09, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 17, 09, 00, 18, 00, 19, 09, 00, 1b, 00, 21, 06, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 12, 03, 09, 00, 0f, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/loops_branches.rs -Number of expressions: 4 -- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(2, Add) -- expression 1 operands: lhs = Counter(0), rhs = Counter(3) -- expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Counter(2), rhs = Counter(3) +Number of expressions: 5 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(3, Add) +- expression 2 operands: lhs = Counter(0), rhs = Counter(2) +- expression 3 operands: lhs = Counter(1), rhs = Counter(3) +- expression 4 operands: lhs = Counter(3), rhs = Counter(2) Number of file 0 mappings: 25 - Code(Counter(0)) at (prev + 9, 5) to (start + 0, 67) - Code(Counter(0)) at (prev + 1, 12) to (start + 0, 16) @@ -19,33 +20,35 @@ Number of file 0 mappings: 25 - Code(Counter(0)) at (prev + 0, 23) to (start + 0, 29) - Code(Counter(1)) at (prev + 0, 30) to (start + 0, 31) - Code(Zero) at (prev + 1, 16) to (start + 1, 10) -- Code(Counter(3)) at (prev + 3, 13) to (start + 0, 14) -- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 23) -- Code(Counter(3)) at (prev + 1, 16) to (start + 0, 20) -- Code(Counter(3)) at (prev + 1, 20) to (start + 0, 25) +- Code(Counter(2)) at (prev + 3, 13) to (start + 0, 14) +- Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 23) + = (c0 - c1) +- Code(Counter(2)) at (prev + 1, 16) to (start + 0, 20) +- Code(Counter(2)) at (prev + 1, 20) to (start + 0, 25) - Code(Zero) at (prev + 1, 27) to (start + 0, 31) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) -- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18) -- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 23) -- Code(Counter(3)) at (prev + 0, 24) to (start + 0, 25) -- Code(Counter(3)) at (prev + 0, 27) to (start + 0, 33) -- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35) - = ((c0 + c3) - (c1 + c2)) +- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18) +- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 23) +- Code(Counter(2)) at (prev + 0, 24) to (start + 0, 25) +- Code(Counter(2)) at (prev + 0, 27) to (start + 0, 33) +- Code(Expression(1, Sub)) at (prev + 0, 34) to (start + 0, 35) + = ((c0 + c2) - (c1 + c3)) - Code(Zero) at (prev + 1, 20) to (start + 1, 14) -- Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 15) - = (c2 - c3) +- Code(Expression(4, Sub)) at (prev + 3, 9) to (start + 0, 15) + = (c3 - c2) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) -Highest counter ID seen: c3 +Highest counter ID seen: c2 Function name: ::fmt -Raw bytes (137): 0x[01, 01, 04, 07, 0b, 01, 09, 05, 0d, 05, 09, 19, 01, 22, 05, 00, 43, 01, 01, 0c, 00, 11, 00, 00, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 0d, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 05, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 17, 09, 00, 18, 00, 19, 09, 00, 1b, 00, 21, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06] +Raw bytes (139): 0x[01, 01, 05, 01, 05, 0b, 0f, 01, 09, 0d, 05, 0d, 09, 19, 01, 22, 05, 00, 43, 01, 01, 0c, 00, 11, 00, 00, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 05, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 02, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 17, 09, 00, 18, 00, 19, 09, 00, 1b, 00, 21, 06, 00, 22, 00, 23, 12, 03, 09, 00, 0f, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/loops_branches.rs -Number of expressions: 4 -- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(2, Add) -- expression 1 operands: lhs = Counter(0), rhs = Counter(2) -- expression 2 operands: lhs = Counter(1), rhs = Counter(3) -- expression 3 operands: lhs = Counter(1), rhs = Counter(2) +Number of expressions: 5 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(3, Add) +- expression 2 operands: lhs = Counter(0), rhs = Counter(2) +- expression 3 operands: lhs = Counter(3), rhs = Counter(1) +- expression 4 operands: lhs = Counter(3), rhs = Counter(2) Number of file 0 mappings: 25 - Code(Counter(0)) at (prev + 34, 5) to (start + 0, 67) - Code(Counter(0)) at (prev + 1, 12) to (start + 0, 17) @@ -57,9 +60,10 @@ Number of file 0 mappings: 25 - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 19) - Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21) - Code(Counter(0)) at (prev + 0, 23) to (start + 0, 29) -- Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31) +- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 31) - Code(Counter(2)) at (prev + 2, 13) to (start + 0, 14) -- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 23) +- Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 23) + = (c0 - c1) - Code(Counter(2)) at (prev + 1, 16) to (start + 0, 21) - Code(Zero) at (prev + 0, 22) to (start + 1, 14) - Code(Counter(2)) at (prev + 2, 20) to (start + 0, 25) @@ -69,12 +73,12 @@ Number of file 0 mappings: 25 - Code(Counter(2)) at (prev + 1, 17) to (start + 0, 23) - Code(Counter(2)) at (prev + 0, 24) to (start + 0, 25) - Code(Counter(2)) at (prev + 0, 27) to (start + 0, 33) -- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35) - = ((c0 + c2) - (c1 + c3)) -- Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 15) - = (c1 - c2) +- Code(Expression(1, Sub)) at (prev + 0, 34) to (start + 0, 35) + = ((c0 + c2) - (c3 + c1)) +- Code(Expression(4, Sub)) at (prev + 3, 9) to (start + 0, 15) + = (c3 - c2) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) -Highest counter ID seen: c3 +Highest counter ID seen: c2 Function name: loops_branches::main Raw bytes (54): 0x[01, 01, 00, 0a, 01, 37, 01, 00, 0a, 01, 01, 09, 00, 13, 01, 00, 16, 00, 1f, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 09, 00, 15, 01, 00, 18, 00, 23, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 12, 01, 01, 01, 00, 02] diff --git a/tests/coverage/nested_loops.cov-map b/tests/coverage/nested_loops.cov-map index 649c65d8590ba..598068714b9a1 100644 --- a/tests/coverage/nested_loops.cov-map +++ b/tests/coverage/nested_loops.cov-map @@ -1,26 +1,26 @@ Function name: nested_loops::main -Raw bytes (164): 0x[01, 01, 14, 07, 47, 05, 11, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 3f, 05, 01, 09, 4b, 3f, 05, 15, 01, 09, 47, 4b, 01, 0d, 05, 15, 05, 01, 18, 01, 01, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 02, 13, 00, 20, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 0d, 01, 12, 00, 17, 11, 01, 10, 00, 16, 02, 01, 11, 00, 16, 26, 01, 0d, 00, 0e, 26, 01, 0d, 00, 13, 26, 01, 0d, 00, 13, 26, 01, 10, 00, 16, 15, 01, 11, 00, 18, 15, 01, 14, 00, 1b, 2e, 01, 15, 00, 21, 36, 01, 18, 02, 12, 42, 03, 0d, 00, 0e, 4e, 02, 09, 00, 17, 01, 02, 01, 00, 02] +Raw bytes (164): 0x[01, 01, 14, 07, 47, 05, 0d, 01, 11, 47, 05, 01, 11, 47, 05, 01, 11, 47, 05, 01, 11, 47, 05, 01, 11, 3f, 05, 01, 09, 4b, 3f, 05, 15, 01, 09, 47, 4b, 01, 11, 05, 15, 05, 01, 18, 01, 01, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 02, 13, 00, 20, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 09, 01, 12, 00, 17, 0d, 01, 10, 00, 16, 02, 01, 11, 00, 16, 26, 01, 0d, 00, 0e, 26, 01, 0d, 00, 13, 26, 01, 0d, 00, 13, 26, 01, 10, 00, 16, 15, 01, 11, 00, 18, 15, 01, 14, 00, 1b, 2e, 01, 15, 00, 21, 36, 01, 18, 02, 12, 42, 03, 0d, 00, 0e, 4e, 02, 09, 00, 17, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/nested_loops.rs Number of expressions: 20 - expression 0 operands: lhs = Expression(1, Add), rhs = Expression(17, Add) -- expression 1 operands: lhs = Counter(1), rhs = Counter(4) -- expression 2 operands: lhs = Counter(0), rhs = Counter(3) +- expression 1 operands: lhs = Counter(1), rhs = Counter(3) +- expression 2 operands: lhs = Counter(0), rhs = Counter(4) - expression 3 operands: lhs = Expression(17, Add), rhs = Counter(1) -- expression 4 operands: lhs = Counter(0), rhs = Counter(3) +- expression 4 operands: lhs = Counter(0), rhs = Counter(4) - expression 5 operands: lhs = Expression(17, Add), rhs = Counter(1) -- expression 6 operands: lhs = Counter(0), rhs = Counter(3) +- expression 6 operands: lhs = Counter(0), rhs = Counter(4) - expression 7 operands: lhs = Expression(17, Add), rhs = Counter(1) -- expression 8 operands: lhs = Counter(0), rhs = Counter(3) +- expression 8 operands: lhs = Counter(0), rhs = Counter(4) - expression 9 operands: lhs = Expression(17, Add), rhs = Counter(1) -- expression 10 operands: lhs = Counter(0), rhs = Counter(3) +- expression 10 operands: lhs = Counter(0), rhs = Counter(4) - expression 11 operands: lhs = Expression(15, Add), rhs = Counter(1) - expression 12 operands: lhs = Counter(0), rhs = Counter(2) - expression 13 operands: lhs = Expression(18, Add), rhs = Expression(15, Add) - expression 14 operands: lhs = Counter(1), rhs = Counter(5) - expression 15 operands: lhs = Counter(0), rhs = Counter(2) - expression 16 operands: lhs = Expression(17, Add), rhs = Expression(18, Add) -- expression 17 operands: lhs = Counter(0), rhs = Counter(3) +- expression 17 operands: lhs = Counter(0), rhs = Counter(4) - expression 18 operands: lhs = Counter(1), rhs = Counter(5) - expression 19 operands: lhs = Counter(1), rhs = Counter(0) Number of file 0 mappings: 24 @@ -34,18 +34,18 @@ Number of file 0 mappings: 24 - Code(Counter(2)) at (prev + 0, 21) to (start + 0, 24) - Code(Counter(2)) at (prev + 1, 13) to (start + 0, 18) - Code(Counter(2)) at (prev + 0, 21) to (start + 0, 24) -- Code(Counter(3)) at (prev + 1, 18) to (start + 0, 23) -- Code(Counter(4)) at (prev + 1, 16) to (start + 0, 22) +- Code(Counter(2)) at (prev + 1, 18) to (start + 0, 23) +- Code(Counter(3)) at (prev + 1, 16) to (start + 0, 22) - Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 22) - = ((c1 + c4) - (c0 + c3)) + = ((c1 + c3) - (c0 + c4)) - Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 14) - = ((c0 + c3) - c1) + = ((c0 + c4) - c1) - Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 19) - = ((c0 + c3) - c1) + = ((c0 + c4) - c1) - Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 19) - = ((c0 + c3) - c1) + = ((c0 + c4) - c1) - Code(Expression(9, Sub)) at (prev + 1, 16) to (start + 0, 22) - = ((c0 + c3) - c1) + = ((c0 + c4) - c1) - Code(Counter(5)) at (prev + 1, 17) to (start + 0, 24) - Code(Counter(5)) at (prev + 1, 20) to (start + 0, 27) - Code(Expression(11, Sub)) at (prev + 1, 21) to (start + 0, 33) @@ -53,7 +53,7 @@ Number of file 0 mappings: 24 - Code(Expression(13, Sub)) at (prev + 1, 24) to (start + 2, 18) = ((c1 + c5) - (c0 + c2)) - Code(Expression(16, Sub)) at (prev + 3, 13) to (start + 0, 14) - = ((c0 + c3) - (c1 + c5)) + = ((c0 + c4) - (c1 + c5)) - Code(Expression(19, Sub)) at (prev + 2, 9) to (start + 0, 23) = (c1 - c0) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) diff --git a/tests/coverage/simple_match.cov-map b/tests/coverage/simple_match.cov-map index cbd6c7ca52fd1..bc5a7e7b4bef4 100644 --- a/tests/coverage/simple_match.cov-map +++ b/tests/coverage/simple_match.cov-map @@ -1,5 +1,5 @@ Function name: simple_match::main -Raw bytes (99): 0x[01, 01, 05, 01, 05, 09, 01, 09, 01, 09, 13, 01, 0d, 11, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 09, 05, 09, 00, 0d, 0a, 05, 0d, 00, 16, 0d, 02, 0d, 00, 0e, 0a, 02, 11, 02, 12, 0d, 04, 0d, 07, 0e, 0d, 01, 11, 00, 1e, 0d, 02, 15, 00, 16, 0e, 07, 0d, 00, 0f, 01, 03, 01, 00, 02] +Raw bytes (99): 0x[01, 01, 05, 01, 05, 09, 01, 09, 01, 09, 13, 01, 0d, 11, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 01, 05, 09, 00, 0d, 0a, 05, 0d, 00, 16, 0d, 02, 0d, 00, 0e, 0a, 02, 11, 02, 12, 0d, 04, 0d, 07, 0e, 0d, 01, 11, 00, 1e, 0d, 02, 15, 00, 16, 0e, 07, 0d, 00, 0f, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/simple_match.rs Number of expressions: 5 @@ -18,7 +18,7 @@ Number of file 0 mappings: 17 - Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) = (c0 - c1) -- Code(Counter(2)) at (prev + 5, 9) to (start + 0, 13) +- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 13) - Code(Expression(2, Sub)) at (prev + 5, 13) to (start + 0, 22) = (c2 - c0) - Code(Counter(3)) at (prev + 2, 13) to (start + 0, 14) diff --git a/tests/coverage/try_error_result.cov-map b/tests/coverage/try_error_result.cov-map index e08f429615328..53757ef8a9bd6 100644 --- a/tests/coverage/try_error_result.cov-map +++ b/tests/coverage/try_error_result.cov-map @@ -62,77 +62,77 @@ Number of file 0 mappings: 8 Highest counter ID seen: c1 Function name: try_error_result::test1 -Raw bytes (82): 0x[01, 01, 04, 07, 05, 01, 09, 05, 01, 05, 09, 0e, 01, 0d, 01, 00, 1d, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 05, 05, 09, 00, 0e, 09, 02, 09, 01, 11, 09, 04, 0d, 00, 1a, 02, 02, 0d, 00, 11, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02] +Raw bytes (82): 0x[01, 01, 04, 07, 09, 01, 05, 09, 01, 09, 05, 0e, 01, 0d, 01, 00, 1d, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 01, 05, 09, 00, 0e, 05, 02, 09, 01, 11, 05, 04, 0d, 00, 1a, 02, 02, 0d, 00, 11, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/try_error_result.rs Number of expressions: 4 -- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Counter(2) -- expression 2 operands: lhs = Counter(1), rhs = Counter(0) -- expression 3 operands: lhs = Counter(1), rhs = Counter(2) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2) +- expression 1 operands: lhs = Counter(0), rhs = Counter(1) +- expression 2 operands: lhs = Counter(2), rhs = Counter(0) +- expression 3 operands: lhs = Counter(2), rhs = Counter(1) Number of file 0 mappings: 14 - Code(Counter(0)) at (prev + 13, 1) to (start + 0, 29) - Code(Counter(0)) at (prev + 1, 9) to (start + 1, 18) - Code(Counter(0)) at (prev + 1, 21) to (start + 0, 23) -- Code(Counter(1)) at (prev + 5, 9) to (start + 0, 14) -- Code(Counter(2)) at (prev + 2, 9) to (start + 1, 17) -- Code(Counter(2)) at (prev + 4, 13) to (start + 0, 26) +- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 14) +- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 17) +- Code(Counter(1)) at (prev + 4, 13) to (start + 0, 26) - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 17) - = ((c0 + c2) - c1) + = ((c0 + c1) - c2) - Code(Expression(0, Sub)) at (prev + 0, 41) to (start + 0, 42) - = ((c0 + c2) - c1) + = ((c0 + c1) - c2) - Code(Zero) at (prev + 1, 13) to (start + 0, 17) - Code(Zero) at (prev + 0, 42) to (start + 0, 43) - Code(Expression(2, Sub)) at (prev + 4, 13) to (start + 0, 17) - = (c1 - c0) + = (c2 - c0) - Code(Zero) at (prev + 0, 42) to (start + 0, 43) - Code(Expression(3, Sub)) at (prev + 3, 5) to (start + 0, 11) - = (c1 - c2) + = (c2 - c1) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c2 +Highest counter ID seen: c1 Function name: try_error_result::test2 -Raw bytes (443): 0x[01, 01, 3d, 0d, 11, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 4f, 53, 1d, 57, 19, 11, 15, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 53, 57, 19, 11, 15, 0d, 4f, 53, 1d, 57, 19, 11, 15, 41, 6b, 21, 25, 41, 21, 41, 6b, 21, 25, 09, 8f, 01, 93, 01, 2d, 0d, 29, 09, 0d, 09, 0d, 09, 93, 01, 0d, 29, 09, 8f, 01, 93, 01, 2d, 0d, 29, 45, a7, 01, 31, 35, 45, 31, 45, a7, 01, 31, 35, 49, bb, 01, 39, 3d, 49, 39, 49, bb, 01, 39, 3d, 05, 09, c7, 01, 09, cb, 01, 3d, cf, 01, 39, d3, 01, 35, d7, 01, 31, db, 01, 2d, df, 01, 29, e3, 01, 25, e7, 01, 21, eb, 01, 1d, ef, 01, 19, f3, 01, 15, 05, 11, 39, 01, 3d, 01, 00, 1d, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 1a, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 05, 05, 09, 00, 0e, 09, 02, 09, 01, 11, 09, 04, 0d, 00, 1a, 0d, 02, 0d, 00, 13, 0d, 00, 14, 00, 1f, 11, 00, 2f, 00, 30, 02, 00, 31, 00, 35, 02, 00, 45, 00, 4f, 02, 00, 50, 00, 62, 02, 01, 0d, 00, 13, 02, 02, 11, 00, 1c, 15, 01, 11, 00, 12, 36, 02, 11, 00, 15, 36, 02, 11, 00, 1b, 36, 01, 15, 00, 27, 4a, 02, 11, 00, 14, 36, 00, 17, 00, 1d, 36, 00, 1e, 00, 29, 19, 00, 41, 00, 42, 3e, 00, 43, 00, 47, 1d, 00, 5f, 00, 60, 4a, 01, 0d, 00, 17, 66, 01, 11, 00, 14, 41, 00, 17, 00, 1d, 41, 00, 1e, 00, 29, 21, 00, 41, 00, 42, 62, 00, 43, 00, 47, 25, 00, 60, 00, 61, 66, 01, 0d, 00, 17, 8a, 01, 04, 11, 00, 14, 7e, 00, 17, 00, 1d, 7e, 00, 1e, 00, 29, 29, 00, 42, 00, 43, 82, 01, 00, 44, 00, 48, 2d, 00, 61, 00, 62, 8a, 01, 01, 0d, 00, 17, a2, 01, 01, 11, 00, 14, 45, 00, 17, 00, 1d, 45, 01, 12, 00, 1d, 31, 00, 36, 00, 37, 9e, 01, 01, 12, 00, 16, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 17, b6, 01, 01, 11, 00, 14, 49, 00, 17, 00, 1d, 49, 01, 12, 00, 1d, 39, 01, 11, 00, 12, b2, 01, 01, 12, 00, 16, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 17, be, 01, 03, 05, 00, 0b, c2, 01, 01, 01, 00, 02] +Raw bytes (443): 0x[01, 01, 3d, 09, 0d, 09, 57, 0d, 15, 09, 57, 0d, 15, 09, 57, 0d, 15, 09, 4f, 53, 1d, 57, 19, 0d, 15, 09, 57, 0d, 15, 09, 57, 0d, 15, 09, 53, 57, 19, 0d, 15, 09, 4f, 53, 1d, 57, 19, 0d, 15, 41, 6b, 21, 25, 41, 21, 41, 6b, 21, 25, 05, 8f, 01, 93, 01, 2d, 09, 29, 05, 09, 05, 09, 05, 93, 01, 09, 29, 05, 8f, 01, 93, 01, 2d, 09, 29, 45, a7, 01, 31, 35, 45, 31, 45, a7, 01, 31, 35, 49, bb, 01, 39, 3d, 49, 39, 49, bb, 01, 39, 3d, 11, 05, c7, 01, 05, cb, 01, 3d, cf, 01, 39, d3, 01, 35, d7, 01, 31, db, 01, 2d, df, 01, 29, e3, 01, 25, e7, 01, 21, eb, 01, 1d, ef, 01, 19, f3, 01, 15, 11, 0d, 39, 01, 3d, 01, 00, 1d, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 1a, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 01, 05, 09, 00, 0e, 05, 02, 09, 01, 11, 05, 04, 0d, 00, 1a, 09, 02, 0d, 00, 13, 09, 00, 14, 00, 1f, 0d, 00, 2f, 00, 30, 02, 00, 31, 00, 35, 02, 00, 45, 00, 4f, 02, 00, 50, 00, 62, 02, 01, 0d, 00, 13, 02, 02, 11, 00, 1c, 15, 01, 11, 00, 12, 36, 02, 11, 00, 15, 36, 02, 11, 00, 1b, 36, 01, 15, 00, 27, 4a, 02, 11, 00, 14, 36, 00, 17, 00, 1d, 36, 00, 1e, 00, 29, 19, 00, 41, 00, 42, 3e, 00, 43, 00, 47, 1d, 00, 5f, 00, 60, 4a, 01, 0d, 00, 17, 66, 01, 11, 00, 14, 41, 00, 17, 00, 1d, 41, 00, 1e, 00, 29, 21, 00, 41, 00, 42, 62, 00, 43, 00, 47, 25, 00, 60, 00, 61, 66, 01, 0d, 00, 17, 8a, 01, 04, 11, 00, 14, 7e, 00, 17, 00, 1d, 7e, 00, 1e, 00, 29, 29, 00, 42, 00, 43, 82, 01, 00, 44, 00, 48, 2d, 00, 61, 00, 62, 8a, 01, 01, 0d, 00, 17, a2, 01, 01, 11, 00, 14, 45, 00, 17, 00, 1d, 45, 01, 12, 00, 1d, 31, 00, 36, 00, 37, 9e, 01, 01, 12, 00, 16, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 17, b6, 01, 01, 11, 00, 14, 49, 00, 17, 00, 1d, 49, 01, 12, 00, 1d, 39, 01, 11, 00, 12, b2, 01, 01, 12, 00, 16, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 17, be, 01, 03, 05, 00, 0b, c2, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/try_error_result.rs Number of expressions: 61 -- expression 0 operands: lhs = Counter(3), rhs = Counter(4) -- expression 1 operands: lhs = Counter(3), rhs = Expression(21, Add) -- expression 2 operands: lhs = Counter(4), rhs = Counter(5) -- expression 3 operands: lhs = Counter(3), rhs = Expression(21, Add) -- expression 4 operands: lhs = Counter(4), rhs = Counter(5) -- expression 5 operands: lhs = Counter(3), rhs = Expression(21, Add) -- expression 6 operands: lhs = Counter(4), rhs = Counter(5) -- expression 7 operands: lhs = Counter(3), rhs = Expression(19, Add) +- expression 0 operands: lhs = Counter(2), rhs = Counter(3) +- expression 1 operands: lhs = Counter(2), rhs = Expression(21, Add) +- expression 2 operands: lhs = Counter(3), rhs = Counter(5) +- expression 3 operands: lhs = Counter(2), rhs = Expression(21, Add) +- expression 4 operands: lhs = Counter(3), rhs = Counter(5) +- expression 5 operands: lhs = Counter(2), rhs = Expression(21, Add) +- expression 6 operands: lhs = Counter(3), rhs = Counter(5) +- expression 7 operands: lhs = Counter(2), rhs = Expression(19, Add) - expression 8 operands: lhs = Expression(20, Add), rhs = Counter(7) - expression 9 operands: lhs = Expression(21, Add), rhs = Counter(6) -- expression 10 operands: lhs = Counter(4), rhs = Counter(5) -- expression 11 operands: lhs = Counter(3), rhs = Expression(21, Add) -- expression 12 operands: lhs = Counter(4), rhs = Counter(5) -- expression 13 operands: lhs = Counter(3), rhs = Expression(21, Add) -- expression 14 operands: lhs = Counter(4), rhs = Counter(5) -- expression 15 operands: lhs = Counter(3), rhs = Expression(20, Add) +- expression 10 operands: lhs = Counter(3), rhs = Counter(5) +- expression 11 operands: lhs = Counter(2), rhs = Expression(21, Add) +- expression 12 operands: lhs = Counter(3), rhs = Counter(5) +- expression 13 operands: lhs = Counter(2), rhs = Expression(21, Add) +- expression 14 operands: lhs = Counter(3), rhs = Counter(5) +- expression 15 operands: lhs = Counter(2), rhs = Expression(20, Add) - expression 16 operands: lhs = Expression(21, Add), rhs = Counter(6) -- expression 17 operands: lhs = Counter(4), rhs = Counter(5) -- expression 18 operands: lhs = Counter(3), rhs = Expression(19, Add) +- expression 17 operands: lhs = Counter(3), rhs = Counter(5) +- expression 18 operands: lhs = Counter(2), rhs = Expression(19, Add) - expression 19 operands: lhs = Expression(20, Add), rhs = Counter(7) - expression 20 operands: lhs = Expression(21, Add), rhs = Counter(6) -- expression 21 operands: lhs = Counter(4), rhs = Counter(5) +- expression 21 operands: lhs = Counter(3), rhs = Counter(5) - expression 22 operands: lhs = Counter(16), rhs = Expression(26, Add) - expression 23 operands: lhs = Counter(8), rhs = Counter(9) - expression 24 operands: lhs = Counter(16), rhs = Counter(8) - expression 25 operands: lhs = Counter(16), rhs = Expression(26, Add) - expression 26 operands: lhs = Counter(8), rhs = Counter(9) -- expression 27 operands: lhs = Counter(2), rhs = Expression(35, Add) +- expression 27 operands: lhs = Counter(1), rhs = Expression(35, Add) - expression 28 operands: lhs = Expression(36, Add), rhs = Counter(11) -- expression 29 operands: lhs = Counter(3), rhs = Counter(10) -- expression 30 operands: lhs = Counter(2), rhs = Counter(3) -- expression 31 operands: lhs = Counter(2), rhs = Counter(3) -- expression 32 operands: lhs = Counter(2), rhs = Expression(36, Add) -- expression 33 operands: lhs = Counter(3), rhs = Counter(10) -- expression 34 operands: lhs = Counter(2), rhs = Expression(35, Add) +- expression 29 operands: lhs = Counter(2), rhs = Counter(10) +- expression 30 operands: lhs = Counter(1), rhs = Counter(2) +- expression 31 operands: lhs = Counter(1), rhs = Counter(2) +- expression 32 operands: lhs = Counter(1), rhs = Expression(36, Add) +- expression 33 operands: lhs = Counter(2), rhs = Counter(10) +- expression 34 operands: lhs = Counter(1), rhs = Expression(35, Add) - expression 35 operands: lhs = Expression(36, Add), rhs = Counter(11) -- expression 36 operands: lhs = Counter(3), rhs = Counter(10) +- expression 36 operands: lhs = Counter(2), rhs = Counter(10) - expression 37 operands: lhs = Counter(17), rhs = Expression(41, Add) - expression 38 operands: lhs = Counter(12), rhs = Counter(13) - expression 39 operands: lhs = Counter(17), rhs = Counter(12) @@ -143,8 +143,8 @@ Number of expressions: 61 - expression 44 operands: lhs = Counter(18), rhs = Counter(14) - expression 45 operands: lhs = Counter(18), rhs = Expression(46, Add) - expression 46 operands: lhs = Counter(14), rhs = Counter(15) -- expression 47 operands: lhs = Counter(1), rhs = Counter(2) -- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(2) +- expression 47 operands: lhs = Counter(4), rhs = Counter(1) +- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(1) - expression 49 operands: lhs = Expression(50, Add), rhs = Counter(15) - expression 50 operands: lhs = Expression(51, Add), rhs = Counter(14) - expression 51 operands: lhs = Expression(52, Add), rhs = Counter(13) @@ -156,48 +156,48 @@ Number of expressions: 61 - expression 57 operands: lhs = Expression(58, Add), rhs = Counter(7) - expression 58 operands: lhs = Expression(59, Add), rhs = Counter(6) - expression 59 operands: lhs = Expression(60, Add), rhs = Counter(5) -- expression 60 operands: lhs = Counter(1), rhs = Counter(4) +- expression 60 operands: lhs = Counter(4), rhs = Counter(3) Number of file 0 mappings: 57 - Code(Counter(0)) at (prev + 61, 1) to (start + 0, 29) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15) - Code(Counter(0)) at (prev + 0, 18) to (start + 0, 26) - Code(Counter(0)) at (prev + 1, 9) to (start + 1, 18) - Code(Counter(0)) at (prev + 1, 21) to (start + 0, 23) -- Code(Counter(1)) at (prev + 5, 9) to (start + 0, 14) -- Code(Counter(2)) at (prev + 2, 9) to (start + 1, 17) -- Code(Counter(2)) at (prev + 4, 13) to (start + 0, 26) -- Code(Counter(3)) at (prev + 2, 13) to (start + 0, 19) -- Code(Counter(3)) at (prev + 0, 20) to (start + 0, 31) -- Code(Counter(4)) at (prev + 0, 47) to (start + 0, 48) +- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 14) +- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 17) +- Code(Counter(1)) at (prev + 4, 13) to (start + 0, 26) +- Code(Counter(2)) at (prev + 2, 13) to (start + 0, 19) +- Code(Counter(2)) at (prev + 0, 20) to (start + 0, 31) +- Code(Counter(3)) at (prev + 0, 47) to (start + 0, 48) - Code(Expression(0, Sub)) at (prev + 0, 49) to (start + 0, 53) - = (c3 - c4) + = (c2 - c3) - Code(Expression(0, Sub)) at (prev + 0, 69) to (start + 0, 79) - = (c3 - c4) + = (c2 - c3) - Code(Expression(0, Sub)) at (prev + 0, 80) to (start + 0, 98) - = (c3 - c4) + = (c2 - c3) - Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 19) - = (c3 - c4) + = (c2 - c3) - Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 28) - = (c3 - c4) + = (c2 - c3) - Code(Counter(5)) at (prev + 1, 17) to (start + 0, 18) - Code(Expression(13, Sub)) at (prev + 2, 17) to (start + 0, 21) - = (c3 - (c4 + c5)) + = (c2 - (c3 + c5)) - Code(Expression(13, Sub)) at (prev + 2, 17) to (start + 0, 27) - = (c3 - (c4 + c5)) + = (c2 - (c3 + c5)) - Code(Expression(13, Sub)) at (prev + 1, 21) to (start + 0, 39) - = (c3 - (c4 + c5)) + = (c2 - (c3 + c5)) - Code(Expression(18, Sub)) at (prev + 2, 17) to (start + 0, 20) - = (c3 - (((c4 + c5) + c6) + c7)) + = (c2 - (((c3 + c5) + c6) + c7)) - Code(Expression(13, Sub)) at (prev + 0, 23) to (start + 0, 29) - = (c3 - (c4 + c5)) + = (c2 - (c3 + c5)) - Code(Expression(13, Sub)) at (prev + 0, 30) to (start + 0, 41) - = (c3 - (c4 + c5)) + = (c2 - (c3 + c5)) - Code(Counter(6)) at (prev + 0, 65) to (start + 0, 66) - Code(Expression(15, Sub)) at (prev + 0, 67) to (start + 0, 71) - = (c3 - ((c4 + c5) + c6)) + = (c2 - ((c3 + c5) + c6)) - Code(Counter(7)) at (prev + 0, 95) to (start + 0, 96) - Code(Expression(18, Sub)) at (prev + 1, 13) to (start + 0, 23) - = (c3 - (((c4 + c5) + c6) + c7)) + = (c2 - (((c3 + c5) + c6) + c7)) - Code(Expression(25, Sub)) at (prev + 1, 17) to (start + 0, 20) = (c16 - (c8 + c9)) - Code(Counter(16)) at (prev + 0, 23) to (start + 0, 29) @@ -209,17 +209,17 @@ Number of file 0 mappings: 57 - Code(Expression(25, Sub)) at (prev + 1, 13) to (start + 0, 23) = (c16 - (c8 + c9)) - Code(Expression(34, Sub)) at (prev + 4, 17) to (start + 0, 20) - = (c2 - ((c3 + c10) + c11)) + = (c1 - ((c2 + c10) + c11)) - Code(Expression(31, Sub)) at (prev + 0, 23) to (start + 0, 29) - = (c2 - c3) + = (c1 - c2) - Code(Expression(31, Sub)) at (prev + 0, 30) to (start + 0, 41) - = (c2 - c3) + = (c1 - c2) - Code(Counter(10)) at (prev + 0, 66) to (start + 0, 67) - Code(Expression(32, Sub)) at (prev + 0, 68) to (start + 0, 72) - = (c2 - (c3 + c10)) + = (c1 - (c2 + c10)) - Code(Counter(11)) at (prev + 0, 97) to (start + 0, 98) - Code(Expression(34, Sub)) at (prev + 1, 13) to (start + 0, 23) - = (c2 - ((c3 + c10) + c11)) + = (c1 - ((c2 + c10) + c11)) - Code(Expression(40, Sub)) at (prev + 1, 17) to (start + 0, 20) = (c17 - (c12 + c13)) - Code(Counter(17)) at (prev + 0, 23) to (start + 0, 29) @@ -241,8 +241,8 @@ Number of file 0 mappings: 57 - Code(Expression(45, Sub)) at (prev + 2, 13) to (start + 0, 23) = (c18 - (c14 + c15)) - Code(Expression(47, Sub)) at (prev + 3, 5) to (start + 0, 11) - = (c1 - c2) + = (c4 - c1) - Code(Expression(48, Sub)) at (prev + 1, 1) to (start + 0, 2) - = (((((((((((((c1 + c4) + c5) + c6) + c7) + c8) + c9) + c10) + c11) + c12) + c13) + c14) + c15) - c2) + = (((((((((((((c4 + c3) + c5) + c6) + c7) + c8) + c9) + c10) + c11) + c12) + c13) + c14) + c15) - c1) Highest counter ID seen: c18 diff --git a/tests/coverage/unicode.cov-map b/tests/coverage/unicode.cov-map index bbfa8b940c6d7..b118c847e8fff 100644 --- a/tests/coverage/unicode.cov-map +++ b/tests/coverage/unicode.cov-map @@ -1,5 +1,5 @@ Function name: unicode::main -Raw bytes (58): 0x[01, 01, 02, 05, 01, 01, 0d, 0a, 01, 0e, 01, 00, 0a, 02, 01, 09, 00, 0c, 05, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 23, 09, 00, 29, 00, 44, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02] +Raw bytes (58): 0x[01, 01, 02, 05, 01, 01, 0d, 0a, 01, 0e, 01, 00, 0a, 02, 01, 09, 00, 0c, 01, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 23, 09, 00, 29, 00, 44, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/unicode.rs Number of expressions: 2 @@ -9,7 +9,7 @@ Number of file 0 mappings: 10 - Code(Counter(0)) at (prev + 14, 1) to (start + 0, 10) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 12) = (c1 - c0) -- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 27) +- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 27) - Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 0, 40) = (c1 - c0) - Code(Counter(0)) at (prev + 2, 8) to (start + 0, 35) diff --git a/tests/rustdoc/jump-to-def/assoc-items.rs b/tests/rustdoc/jump-to-def/assoc-items.rs index 01beb8dd7618a..a434fa7e6053e 100644 --- a/tests/rustdoc/jump-to-def/assoc-items.rs +++ b/tests/rustdoc/jump-to-def/assoc-items.rs @@ -26,8 +26,9 @@ impl C { pub fn wat() {} } -//@ has - '//a[@href="{{channel}}/core/fmt/macros/macro.Debug.html"]' 'Debug' -//@ has - '//a[@href="{{channel}}/core/cmp/macro.PartialEq.html"]' 'PartialEq' +// These two links must not change and in particular must contain `/derive.`! +//@ has - '//a[@href="{{channel}}/core/fmt/macros/derive.Debug.html"]' 'Debug' +//@ has - '//a[@href="{{channel}}/core/cmp/derive.PartialEq.html"]' 'PartialEq' #[derive(Debug, PartialEq)] pub struct Bar; impl Trait for Bar { diff --git a/tests/rustdoc/jump-to-def/derive-macro.rs b/tests/rustdoc/jump-to-def/derive-macro.rs new file mode 100644 index 0000000000000..24deac047883c --- /dev/null +++ b/tests/rustdoc/jump-to-def/derive-macro.rs @@ -0,0 +1,24 @@ +// This test ensures that the same link is generated in both intra-doc links +// and in jump to def links. + +//@ compile-flags: -Zunstable-options --generate-link-to-definition + +#![crate_name = "foo"] + +// First we check intra-doc links. +//@ has 'foo/struct.Bar.html' +//@ has - '//a[@href="{{channel}}/core/fmt/macros/derive.Debug.html"]' 'Debug' +//@ has - '//a[@href="{{channel}}/core/cmp/derive.PartialEq.html"]' 'PartialEq' + +// We also check the "title" attributes. +//@ has - '//a[@href="{{channel}}/core/fmt/macros/derive.Debug.html"]/@title' 'derive core::fmt::macros::Debug' +//@ has - '//a[@href="{{channel}}/core/cmp/derive.PartialEq.html"]/@title' 'derive core::cmp::PartialEq' + +// Then we check that they are the same in jump to def. + +/// [Debug][derive@Debug] and [PartialEq][derive@PartialEq] +//@ has 'src/foo/derive-macro.rs.html' +//@ has - '//a[@href="{{channel}}/core/fmt/macros/derive.Debug.html"]' 'Debug' +//@ has - '//a[@href="{{channel}}/core/cmp/derive.PartialEq.html"]' 'PartialEq' +#[derive(Debug, PartialEq)] +pub struct Bar; diff --git a/tests/ui/borrowck/buffer-reuse-pattern-issue-147694.rs b/tests/ui/borrowck/buffer-reuse-pattern-issue-147694.rs new file mode 100644 index 0000000000000..c30e21d220e22 --- /dev/null +++ b/tests/ui/borrowck/buffer-reuse-pattern-issue-147694.rs @@ -0,0 +1,63 @@ +fn process_data(_: &[&[u8]]) {} + +fn test_buffer_cleared_after_use() { + let sources = vec![vec![1u8, 2, 3, 4, 5], vec![6, 7, 8, 9]]; + let mut buffer: Vec<&[u8]> = vec![]; + //~^ NOTE variable `buffer` declared here + + for source in sources { + let data: Vec = source; + //~^ NOTE binding `data` declared here + buffer.extend(data.split(|x| *x == 3)); + //~^ ERROR `data` does not live long enough + //~| NOTE borrowed value does not live long enough + //~| NOTE borrow later used here + //~| NOTE `buffer` is a collection that stores borrowed references, but `data` does not live long enough to be stored in it + //~| HELP buffer reuse with borrowed references requires unsafe code or restructuring + process_data(&buffer); + buffer.clear(); + } //~ NOTE `data` dropped here while still borrowed +} + +fn test_buffer_cleared_at_start() { + let sources = vec![vec![1u8, 2, 3, 4, 5], vec![6, 7, 8, 9]]; + let mut buffer: Vec<&[u8]> = vec![]; + //~^ NOTE variable `buffer` declared here + + for source in sources { + buffer.clear(); + //~^ NOTE borrow later used here + let data: Vec = source; + //~^ NOTE binding `data` declared here + buffer.extend(data.split(|x| *x == 3)); + //~^ ERROR `data` does not live long enough + //~| NOTE borrowed value does not live long enough + //~| NOTE `buffer` is a collection that stores borrowed references, but `data` does not live long enough to be stored in it + //~| HELP buffer reuse with borrowed references requires unsafe code or restructuring + process_data(&buffer); + } //~ NOTE `data` dropped here while still borrowed +} + +fn test_no_explicit_clear() { + let sources = vec![vec![1u8, 2, 3, 4, 5], vec![6, 7, 8, 9]]; + let mut buffer: Vec<&[u8]> = vec![]; + //~^ NOTE variable `buffer` declared here + + for source in sources { + let data: Vec = source; + //~^ NOTE binding `data` declared here + buffer.extend(data.split(|x| *x == 3)); + //~^ ERROR `data` does not live long enough + //~| NOTE borrowed value does not live long enough + //~| NOTE borrow later used here + //~| NOTE `buffer` is a collection that stores borrowed references, but `data` does not live long enough to be stored in it + //~| HELP buffer reuse with borrowed references requires unsafe code or restructuring + process_data(&buffer); + } //~ NOTE `data` dropped here while still borrowed +} + +fn main() { + test_buffer_cleared_after_use(); + test_buffer_cleared_at_start(); + test_no_explicit_clear(); +} diff --git a/tests/ui/borrowck/buffer-reuse-pattern-issue-147694.stderr b/tests/ui/borrowck/buffer-reuse-pattern-issue-147694.stderr new file mode 100644 index 0000000000000..e8b4b06604c3d --- /dev/null +++ b/tests/ui/borrowck/buffer-reuse-pattern-issue-147694.stderr @@ -0,0 +1,64 @@ +error[E0597]: `data` does not live long enough + --> $DIR/buffer-reuse-pattern-issue-147694.rs:11:23 + | +LL | let mut buffer: Vec<&[u8]> = vec![]; + | ---------- variable `buffer` declared here +... +LL | let data: Vec = source; + | ---- binding `data` declared here +LL | +LL | buffer.extend(data.split(|x| *x == 3)); + | ------ ^^^^ borrowed value does not live long enough + | | + | borrow later used here +... +LL | } + | - `data` dropped here while still borrowed + | + = note: `buffer` is a collection that stores borrowed references, but `data` does not live long enough to be stored in it + = help: buffer reuse with borrowed references requires unsafe code or restructuring + +error[E0597]: `data` does not live long enough + --> $DIR/buffer-reuse-pattern-issue-147694.rs:32:23 + | +LL | let mut buffer: Vec<&[u8]> = vec![]; + | ---------- variable `buffer` declared here +... +LL | buffer.clear(); + | ------ borrow later used here +LL | +LL | let data: Vec = source; + | ---- binding `data` declared here +LL | +LL | buffer.extend(data.split(|x| *x == 3)); + | ^^^^ borrowed value does not live long enough +... +LL | } + | - `data` dropped here while still borrowed + | + = note: `buffer` is a collection that stores borrowed references, but `data` does not live long enough to be stored in it + = help: buffer reuse with borrowed references requires unsafe code or restructuring + +error[E0597]: `data` does not live long enough + --> $DIR/buffer-reuse-pattern-issue-147694.rs:49:23 + | +LL | let mut buffer: Vec<&[u8]> = vec![]; + | ---------- variable `buffer` declared here +... +LL | let data: Vec = source; + | ---- binding `data` declared here +LL | +LL | buffer.extend(data.split(|x| *x == 3)); + | ------ ^^^^ borrowed value does not live long enough + | | + | borrow later used here +... +LL | } + | - `data` dropped here while still borrowed + | + = note: `buffer` is a collection that stores borrowed references, but `data` does not live long enough to be stored in it + = help: buffer reuse with borrowed references requires unsafe code or restructuring + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/c-variadic/naked-invalid.rs b/tests/ui/c-variadic/naked-invalid.rs new file mode 100644 index 0000000000000..2cc4aaafbfcc0 --- /dev/null +++ b/tests/ui/c-variadic/naked-invalid.rs @@ -0,0 +1,44 @@ +//@ add-minicore +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 +//@ ignore-backends: gcc + +#![feature(no_core, lang_items, rustc_attrs)] +#![feature(c_variadic, c_variadic_naked_functions, abi_x86_interrupt, naked_functions_rustic_abi)] +#![crate_type = "rlib"] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[repr(C)] +#[lang = "va_list"] +pub struct VaList; + +#[unsafe(naked)] +unsafe extern "sysv64" fn c_variadic_sysv64(_: ...) { + naked_asm!("ret") +} + +#[unsafe(naked)] +unsafe extern "C" fn c_variadic_c(_: ...) { + naked_asm!("ret") +} + +#[unsafe(naked)] +unsafe extern "Rust" fn c_variadic_rust(_: ...) { + //~^ ERROR `...` is not supported for `extern "Rust"` naked functions + naked_asm!("ret") +} + +#[unsafe(naked)] +unsafe extern "x86-interrupt" fn c_variadic_x86_interrupt(_: ...) { + //~^ ERROR `...` is not supported for `extern "x86-interrupt"` naked functions + naked_asm!("ret") +} + +#[unsafe(naked)] +unsafe extern "nonsense" fn c_variadic_x86_nonsense(_: ...) { + //~^ ERROR invalid ABI: found `nonsense` + naked_asm!("ret") +} diff --git a/tests/ui/c-variadic/naked-invalid.stderr b/tests/ui/c-variadic/naked-invalid.stderr new file mode 100644 index 0000000000000..a1fc8c1664272 --- /dev/null +++ b/tests/ui/c-variadic/naked-invalid.stderr @@ -0,0 +1,31 @@ +error: `...` is not supported for `extern "Rust"` naked functions + --> $DIR/naked-invalid.rs:29:41 + | +LL | unsafe extern "Rust" fn c_variadic_rust(_: ...) { + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: C-variadic function must have a compatible calling convention + +error: `...` is not supported for `extern "x86-interrupt"` naked functions + --> $DIR/naked-invalid.rs:35:59 + | +LL | unsafe extern "x86-interrupt" fn c_variadic_x86_interrupt(_: ...) { + | ---------------------- ^^^^^^ + | | + | `extern "x86-interrupt"` because of this + | + = help: C-variadic function must have a compatible calling convention + +error[E0703]: invalid ABI: found `nonsense` + --> $DIR/naked-invalid.rs:41:15 + | +LL | unsafe extern "nonsense" fn c_variadic_x86_nonsense(_: ...) { + | ^^^^^^^^^^ invalid ABI + | + = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0703`. diff --git a/tests/ui/c-variadic/naked.rs b/tests/ui/c-variadic/naked.rs index 46b59395485c5..73664206d9ced 100644 --- a/tests/ui/c-variadic/naked.rs +++ b/tests/ui/c-variadic/naked.rs @@ -1,14 +1,14 @@ //@ run-pass //@ only-x86_64 //@ only-linux -#![feature(c_variadic)] +#![feature(c_variadic, c_variadic_naked_functions)] #[repr(C)] #[derive(Debug, PartialEq)] struct Data(i32, f64); #[unsafe(naked)] -unsafe extern "C" fn c_variadic(_: ...) -> Data { +unsafe extern "sysv64" fn c_variadic_sysv64(_: ...) -> Data { // This assembly was generated with GCC, because clang/LLVM is unable to // optimize out the spilling of all registers to the stack. core::arch::naked_asm!( @@ -32,9 +32,20 @@ unsafe extern "C" fn c_variadic(_: ...) -> Data { ) } +#[unsafe(naked)] +unsafe extern "C" fn c_variadic_c(_: ...) -> Data { + core::arch::naked_asm!( + "jmp {}", + sym c_variadic_sysv64, + ) +} + fn main() { unsafe { - assert_eq!(c_variadic(1, 2.0), Data(1, 2.0)); - assert_eq!(c_variadic(123, 4.56), Data(123, 4.56)); + assert_eq!(c_variadic_sysv64(1, 2.0), Data(1, 2.0)); + assert_eq!(c_variadic_sysv64(123, 4.56), Data(123, 4.56)); + + assert_eq!(c_variadic_c(1, 2.0), Data(1, 2.0)); + assert_eq!(c_variadic_c(123, 4.56), Data(123, 4.56)); } } diff --git a/tests/ui/c-variadic/same-program-multiple-abis-arm.rs b/tests/ui/c-variadic/same-program-multiple-abis-arm.rs index 1445bbb47bbd3..fbc5573c5d76c 100644 --- a/tests/ui/c-variadic/same-program-multiple-abis-arm.rs +++ b/tests/ui/c-variadic/same-program-multiple-abis-arm.rs @@ -2,6 +2,7 @@ //@ only-arm //@ ignore-thumb (this test uses arm assembly) //@ only-eabihf (the assembly below requires float hardware support) +#![feature(c_variadic, c_variadic_naked_functions)] // Check that multiple c-variadic calling conventions can be used in the same program. // @@ -9,14 +10,6 @@ // argument list, so C programs that use multiple c-variadic calling conventions are unlikely // to come up. Here we validate that our codegen backends do in fact generate correct code. -extern "C" { - fn variadic_c(_: f64, _: ...) -> f64; -} - -extern "aapcs" { - fn variadic_aapcs(_: f64, _: ...) -> f64; -} - fn main() { unsafe { assert_eq!(variadic_c(1.0, 2.0, 3.0), 1.0 + 2.0 + 3.0); @@ -51,10 +44,11 @@ fn main() { // // > This section applies only to non-variadic functions. For a variadic function the base standard // > is always used both for argument passing and result return. -core::arch::global_asm!( - r#" -{variadic_c}: -{variadic_aapcs}: + +#[unsafe(naked)] +unsafe extern "aapcs" fn variadic_aapcs(_: f64, _: ...) -> f64 { + core::arch::naked_asm!( + r#" sub sp, sp, #12 stmib sp, {{r2, r3}} vmov d0, r0, r1 @@ -71,6 +65,10 @@ core::arch::global_asm!( add sp, sp, #12 bx lr "#, - variadic_c = sym variadic_c, - variadic_aapcs = sym variadic_aapcs, -); + ) +} + +#[unsafe(naked)] +unsafe extern "C" fn variadic_c(_: f64, _: ...) -> f64 { + core::arch::naked_asm!("b {}", sym variadic_aapcs) +} diff --git a/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs b/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs index aff8ab613c431..b54b63289f343 100644 --- a/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs +++ b/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs @@ -1,5 +1,6 @@ //@ run-pass //@ only-x86_64 +#![feature(c_variadic, c_variadic_naked_functions)] // Check that multiple c-variadic calling conventions can be used in the same program. // @@ -7,14 +8,6 @@ // argument list, so C programs that use multiple c-variadic calling conventions are unlikely // to come up. Here we validate that our codegen backends do in fact generate correct code. -extern "sysv64" { - fn variadic_sysv64(_: u32, _: ...) -> u32; -} - -extern "win64" { - fn variadic_win64(_: u32, _: ...) -> u32; -} - fn main() { unsafe { assert_eq!(variadic_win64(1, 2, 3), 1 + 2 + 3); @@ -37,9 +30,11 @@ fn main() { // a + b + c // } // ``` -core::arch::global_asm!( - r#" -{variadic_sysv64}: + +#[unsafe(naked)] +unsafe extern "sysv64" fn variadic_sysv64(_: u32, _: ...) -> u32 { + core::arch::naked_asm!( + r#" sub rsp, 88 test al, al je .LBB0_7 @@ -93,8 +88,14 @@ core::arch::global_asm!( add eax, dword ptr [rcx] add rsp, 88 ret + "#, + ) +} -{variadic_win64}: +#[unsafe(naked)] +unsafe extern "win64" fn variadic_win64(_: u32, _: ...) -> u32 { + core::arch::naked_asm!( + r#" push rax mov qword ptr [rsp + 40], r9 mov qword ptr [rsp + 24], rdx @@ -106,6 +107,5 @@ core::arch::global_asm!( pop rcx ret "#, - variadic_win64 = sym variadic_win64, - variadic_sysv64 = sym variadic_sysv64, -); + ) +} diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs index b3da4ff0120cc..d921f5cff627f 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs @@ -21,6 +21,11 @@ async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) { //~| ERROR functions cannot be both `async` and C-variadic } +// Async on its own is also not allowed. +async unsafe extern "cmse-nonsecure-entry" fn async_is_not_allowed() { + //~^ ERROR `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures +} + // Below are the lang items that are required for a program that defines an `async` function. // Without them, the ICE that is tested for here is not reached for this target. For now they are in // this file, but they may be moved into `minicore` if/when other `#[no_core]` tests want to use diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr index 948f8f5747b0e..5b0924d6f2aff 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr @@ -24,5 +24,12 @@ LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: aborting due to 3 previous errors +error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures + --> $DIR/c-variadic.rs:25:1 + | +LL | async unsafe extern "cmse-nonsecure-entry" fn async_is_not_allowed() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0798`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs index 4b320ded79432..023f50d636bfe 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs @@ -89,3 +89,13 @@ extern "cmse-nonsecure-entry" fn identity_impl_trait_nested( //~^ ERROR `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures v } + +const extern "cmse-nonsecure-entry" fn const_fn_works(x: u8) -> u8 { + x +} + +const CONST: u8 = const_fn_works(0); + +fn fn_ptr_works(f: extern "cmse-nonsecure-entry" fn(_: u8) -> u8) -> u8 { + f(0) +} diff --git a/tests/ui/feature-gates/feature-gate-c_variadic-naked-functions.rs b/tests/ui/feature-gates/feature-gate-c_variadic-naked-functions.rs new file mode 100644 index 0000000000000..bf52c4d0cf526 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-c_variadic-naked-functions.rs @@ -0,0 +1,27 @@ +//@ add-minicore +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 +//@ ignore-backends: gcc + +#![feature(no_core, lang_items, rustc_attrs)] +#![feature(c_variadic, abi_x86_interrupt, naked_functions_rustic_abi)] +#![crate_type = "rlib"] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[repr(C)] +#[lang = "va_list"] +pub struct VaList; + +#[unsafe(naked)] +unsafe extern "sysv64" fn c_variadic_sysv64(_: ...) { + //~^ ERROR Naked c-variadic `extern "sysv64"` functions are unstable + naked_asm!("ret") +} + +#[unsafe(naked)] +unsafe extern "C" fn c_variadic_c(_: ...) { + naked_asm!("ret") +} diff --git a/tests/ui/feature-gates/feature-gate-c_variadic-naked-functions.stderr b/tests/ui/feature-gates/feature-gate-c_variadic-naked-functions.stderr new file mode 100644 index 0000000000000..fc44747a4fadb --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-c_variadic-naked-functions.stderr @@ -0,0 +1,13 @@ +error[E0658]: Naked c-variadic `extern "sysv64"` functions are unstable + --> $DIR/feature-gate-c_variadic-naked-functions.rs:19:1 + | +LL | unsafe extern "sysv64" fn c_variadic_sysv64(_: ...) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #148767 for more information + = help: add `#![feature(c_variadic_naked_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/for/iter_from_mac_call.rs b/tests/ui/for/iter_from_mac_call.rs new file mode 100644 index 0000000000000..8df21456222c4 --- /dev/null +++ b/tests/ui/for/iter_from_mac_call.rs @@ -0,0 +1,26 @@ +macro_rules! deref { + ($e:expr) => { *$e }; +} + +fn f1<'a>(mut iter: Box>) { + for item in deref!(iter) { *item = 0 } + //~^ ERROR `dyn Iterator` is not an iterator +} + +fn f2(x: &mut i32) { + for _item in deref!(x) {} + //~^ ERROR `i32` is not an iterator +} + +struct Wrapped(i32); + +macro_rules! borrow_deref { + ($e:expr) => { &mut *$e }; +} + +fn f3<'a>(mut iter: Box>) { + for Wrapped(item) in borrow_deref!(iter) { *item = 0 } + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/for/iter_from_mac_call.stderr b/tests/ui/for/iter_from_mac_call.stderr new file mode 100644 index 0000000000000..e62efb250e299 --- /dev/null +++ b/tests/ui/for/iter_from_mac_call.stderr @@ -0,0 +1,35 @@ +error[E0277]: `dyn Iterator` is not an iterator + --> $DIR/iter_from_mac_call.rs:6:17 + | +LL | for item in deref!(iter) { *item = 0 } + | ^^^^^^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` + | + = note: the trait bound `dyn Iterator: IntoIterator` is not satisfied + = note: required for `dyn Iterator` to implement `IntoIterator` +help: consider mutably borrowing here + | +LL | for item in &mut deref!(iter) { *item = 0 } + | ++++ + +error[E0277]: `i32` is not an iterator + --> $DIR/iter_from_mac_call.rs:11:18 + | +LL | for _item in deref!(x) {} + | ^^^^^^^^^ `i32` is not an iterator + | + = help: the trait `Iterator` is not implemented for `i32` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required for `i32` to implement `IntoIterator` + +error[E0308]: mismatched types + --> $DIR/iter_from_mac_call.rs:22:9 + | +LL | for Wrapped(item) in borrow_deref!(iter) { *item = 0 } + | ^^^^^^^^^^^^^ ------------------- this is an iterator with items of type `&mut i32` + | | + | expected `i32`, found `Wrapped` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-52126-assign-op-invariance.stderr b/tests/ui/issues/issue-52126-assign-op-invariance.stderr index af9553e5cf382..dd38a1061baaa 100644 --- a/tests/ui/issues/issue-52126-assign-op-invariance.stderr +++ b/tests/ui/issues/issue-52126-assign-op-invariance.stderr @@ -4,13 +4,18 @@ error[E0597]: `line` does not live long enough LL | for line in vec!["123456789".to_string(), "12345678".to_string()] { | ---- binding `line` declared here LL | let v: Vec<&str> = line.split_whitespace().collect(); - | ^^^^ borrowed value does not live long enough + | - ^^^^ borrowed value does not live long enough + | | + | variable `v` declared here ... LL | acc += cnt2; | --- borrow later used here ... LL | } | - `line` dropped here while still borrowed + | + = note: `v` is a collection that stores borrowed references, but `line` does not live long enough to be stored in it + = help: buffer reuse with borrowed references requires unsafe code or restructuring error: aborting due to 1 previous error diff --git a/tests/ui/range/range-to-iterator-suggestion-issue-147749.rs b/tests/ui/range/range-to-iterator-suggestion-issue-147749.rs new file mode 100644 index 0000000000000..8bcdffc136872 --- /dev/null +++ b/tests/ui/range/range-to-iterator-suggestion-issue-147749.rs @@ -0,0 +1,38 @@ +fn main() { + for x in (..4).rev() { + //~^ ERROR `RangeTo<{integer}>` is not an iterator + //~| HELP consider using a bounded `Range` by adding a concrete starting value + let _ = x; + } + + for x in (..=4).rev() { + //~^ ERROR `std::ops::RangeToInclusive<{integer}>` is not an iterator + //~| HELP consider using a bounded `RangeInclusive` by adding a concrete starting value + let _ = x; + } + + // should not suggest for `iter` method + let _v: Vec<_> = (..5).iter().collect(); + //~^ ERROR no method named `iter` found + + for _x in (..'a').rev() {} + //~^ ERROR `RangeTo` is not an iterator + //~| HELP consider using a bounded `Range` by adding a concrete starting value + + for _x in (..='a').rev() {} + //~^ ERROR `std::ops::RangeToInclusive` is not an iterator + //~| HELP consider using a bounded `RangeInclusive` by adding a concrete starting value + + for _x in (..-10).rev() {} + //~^ ERROR `RangeTo<{integer}>` is not an iterator + //~| HELP consider using a bounded `Range` by adding a concrete starting value + + for _x in (..=-10).rev() {} + //~^ ERROR `std::ops::RangeToInclusive<{integer}>` is not an iterator + //~| HELP consider using a bounded `RangeInclusive` by adding a concrete starting value + + let end_val = 10; + for _x in (..-end_val).rev() {} + //~^ ERROR `RangeTo<{integer}>` is not an iterator + //~| HELP consider using a bounded `Range` by adding a concrete starting value +} diff --git a/tests/ui/range/range-to-iterator-suggestion-issue-147749.stderr b/tests/ui/range/range-to-iterator-suggestion-issue-147749.stderr new file mode 100644 index 0000000000000..cb109de20a06a --- /dev/null +++ b/tests/ui/range/range-to-iterator-suggestion-issue-147749.stderr @@ -0,0 +1,114 @@ +error[E0599]: `RangeTo<{integer}>` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:2:20 + | +LL | for x in (..4).rev() { + | ^^^ `RangeTo<{integer}>` is not an iterator + | + = note: the following trait bounds were not satisfied: + `RangeTo<{integer}>: Iterator` + which is required by `&mut RangeTo<{integer}>: Iterator` + = note: you might have meant to use a bounded `Range` +help: consider using a bounded `Range` by adding a concrete starting value + | +LL | for x in (0..4).rev() { + | + + +error[E0599]: `std::ops::RangeToInclusive<{integer}>` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:8:21 + | +LL | for x in (..=4).rev() { + | ^^^ `std::ops::RangeToInclusive<{integer}>` is not an iterator + | + = note: the following trait bounds were not satisfied: + `std::ops::RangeToInclusive<{integer}>: Iterator` + which is required by `&mut std::ops::RangeToInclusive<{integer}>: Iterator` + = note: you might have meant to use a bounded `RangeInclusive` +help: consider using a bounded `RangeInclusive` by adding a concrete starting value + | +LL | for x in (0..=4).rev() { + | + + +error[E0599]: no method named `iter` found for struct `RangeTo` in the current scope + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:15:28 + | +LL | let _v: Vec<_> = (..5).iter().collect(); + | ^^^^ method not found in `RangeTo<{integer}>` + +error[E0599]: `RangeTo` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:18:23 + | +LL | for _x in (..'a').rev() {} + | ^^^ `RangeTo` is not an iterator + | + = note: the following trait bounds were not satisfied: + `RangeTo: Iterator` + which is required by `&mut RangeTo: Iterator` + = note: you might have meant to use a bounded `Range` +help: consider using a bounded `Range` by adding a concrete starting value + | +LL | for _x in (/* start */..'a').rev() {} + | +++++++++++ + +error[E0599]: `std::ops::RangeToInclusive` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:22:24 + | +LL | for _x in (..='a').rev() {} + | ^^^ `std::ops::RangeToInclusive` is not an iterator + | + = note: the following trait bounds were not satisfied: + `std::ops::RangeToInclusive: Iterator` + which is required by `&mut std::ops::RangeToInclusive: Iterator` + = note: you might have meant to use a bounded `RangeInclusive` +help: consider using a bounded `RangeInclusive` by adding a concrete starting value + | +LL | for _x in (/* start */..='a').rev() {} + | +++++++++++ + +error[E0599]: `RangeTo<{integer}>` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:26:23 + | +LL | for _x in (..-10).rev() {} + | ^^^ `RangeTo<{integer}>` is not an iterator + | + = note: the following trait bounds were not satisfied: + `RangeTo<{integer}>: Iterator` + which is required by `&mut RangeTo<{integer}>: Iterator` + = note: you might have meant to use a bounded `Range` +help: consider using a bounded `Range` by adding a concrete starting value + | +LL | for _x in (/* start */..-10).rev() {} + | +++++++++++ + +error[E0599]: `std::ops::RangeToInclusive<{integer}>` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:30:24 + | +LL | for _x in (..=-10).rev() {} + | ^^^ `std::ops::RangeToInclusive<{integer}>` is not an iterator + | + = note: the following trait bounds were not satisfied: + `std::ops::RangeToInclusive<{integer}>: Iterator` + which is required by `&mut std::ops::RangeToInclusive<{integer}>: Iterator` + = note: you might have meant to use a bounded `RangeInclusive` +help: consider using a bounded `RangeInclusive` by adding a concrete starting value + | +LL | for _x in (/* start */..=-10).rev() {} + | +++++++++++ + +error[E0599]: `RangeTo<{integer}>` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:35:28 + | +LL | for _x in (..-end_val).rev() {} + | ^^^ `RangeTo<{integer}>` is not an iterator + | + = note: the following trait bounds were not satisfied: + `RangeTo<{integer}>: Iterator` + which is required by `&mut RangeTo<{integer}>: Iterator` + = note: you might have meant to use a bounded `Range` +help: consider using a bounded `Range` by adding a concrete starting value + | +LL | for _x in (/* start */..-end_val).rev() {} + | +++++++++++ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/span/borrowck-let-suggestion-suffixes.rs b/tests/ui/span/borrowck-let-suggestion-suffixes.rs index ad556f281df12..c8acbfadacd37 100644 --- a/tests/ui/span/borrowck-let-suggestion-suffixes.rs +++ b/tests/ui/span/borrowck-let-suggestion-suffixes.rs @@ -3,6 +3,7 @@ fn id(x: T) -> T { x } fn f() { let old = ['o']; // statement 0 let mut v1 = Vec::new(); // statement 1 + //~^ NOTE variable `v1` declared here let mut v2 = Vec::new(); // statement 2 @@ -13,6 +14,8 @@ fn f() { v2.push(&young[0]); // statement 4 //~^ ERROR `young[_]` does not live long enough //~| NOTE borrowed value does not live long enough + //~| NOTE `v1` is a collection that stores borrowed references, but `young[_]` does not live long enough to be stored in it + //~| HELP buffer reuse with borrowed references requires unsafe code or restructuring } //~ NOTE `young[_]` dropped here while still borrowed let mut v3 = Vec::new(); // statement 5 diff --git a/tests/ui/span/borrowck-let-suggestion-suffixes.stderr b/tests/ui/span/borrowck-let-suggestion-suffixes.stderr index 78cadc8c694ec..cdffbd2145fc4 100644 --- a/tests/ui/span/borrowck-let-suggestion-suffixes.stderr +++ b/tests/ui/span/borrowck-let-suggestion-suffixes.stderr @@ -1,6 +1,9 @@ error[E0597]: `young[_]` does not live long enough - --> $DIR/borrowck-let-suggestion-suffixes.rs:13:17 + --> $DIR/borrowck-let-suggestion-suffixes.rs:14:17 | +LL | let mut v1 = Vec::new(); // statement 1 + | ------ variable `v1` declared here +... LL | let young = ['y']; // statement 3 | ----- binding `young` declared here ... @@ -12,9 +15,12 @@ LL | } ... LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref(); | -- borrow later used here + | + = note: `v1` is a collection that stores borrowed references, but `young[_]` does not live long enough to be stored in it + = help: buffer reuse with borrowed references requires unsafe code or restructuring error[E0716]: temporary value dropped while borrowed - --> $DIR/borrowck-let-suggestion-suffixes.rs:20:14 + --> $DIR/borrowck-let-suggestion-suffixes.rs:23:14 | LL | v3.push(&id('x')); // statement 6 | ^^^^^^^ - temporary value is freed at the end of this statement @@ -31,7 +37,7 @@ LL ~ v3.push(&binding); // statement 6 | error[E0716]: temporary value dropped while borrowed - --> $DIR/borrowck-let-suggestion-suffixes.rs:30:18 + --> $DIR/borrowck-let-suggestion-suffixes.rs:33:18 | LL | v4.push(&id('y')); | ^^^^^^^ - temporary value is freed at the end of this statement @@ -44,7 +50,7 @@ LL | v4.use_ref(); = note: consider using a `let` binding to create a longer lived value error[E0716]: temporary value dropped while borrowed - --> $DIR/borrowck-let-suggestion-suffixes.rs:41:14 + --> $DIR/borrowck-let-suggestion-suffixes.rs:44:14 | LL | v5.push(&id('z')); | ^^^^^^^ - temporary value is freed at the end of this statement diff --git a/tests/ui/span/regions-escape-loop-via-vec.stderr b/tests/ui/span/regions-escape-loop-via-vec.stderr index 18c6cd4809303..46d70e7482f34 100644 --- a/tests/ui/span/regions-escape-loop-via-vec.stderr +++ b/tests/ui/span/regions-escape-loop-via-vec.stderr @@ -23,6 +23,9 @@ LL | _y.push(&mut z); error[E0597]: `z` does not live long enough --> $DIR/regions-escape-loop-via-vec.rs:7:17 | +LL | let mut _y = vec![&mut x]; + | ------ variable `_y` declared here +LL | while x < 10 { LL | let mut z = x; | ----- binding `z` declared here LL | _y.push(&mut z); @@ -32,6 +35,9 @@ LL | _y.push(&mut z); ... LL | } | - `z` dropped here while still borrowed + | + = note: `_y` is a collection that stores borrowed references, but `z` does not live long enough to be stored in it + = help: buffer reuse with borrowed references requires unsafe code or restructuring error[E0503]: cannot use `x` because it was mutably borrowed --> $DIR/regions-escape-loop-via-vec.rs:9:9 diff --git a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs index a71657316ae60..ad1ff56190c2f 100644 --- a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs +++ b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs @@ -6,6 +6,7 @@ fn main() { for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { //~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator + //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator eprintln!("{} {}", src, dest); } @@ -13,6 +14,7 @@ fn main() { for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { //~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator + //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator eprintln!("{} {}", src, dest); } } diff --git a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr index 103fb7bbfe11c..07a54d574df49 100644 --- a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr +++ b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr @@ -30,7 +30,7 @@ help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator - --> $DIR/invalid-suggest-deref-issue-127590.rs:13:54 + --> $DIR/invalid-suggest-deref-issue-127590.rs:14:54 | LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { | -------------- ^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator @@ -48,7 +48,7 @@ LL + for (src, dest) in std::iter::zip(fields.iter(), variant.iter().clone() | error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator - --> $DIR/invalid-suggest-deref-issue-127590.rs:13:24 + --> $DIR/invalid-suggest-deref-issue-127590.rs:14:24 | LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator @@ -60,6 +60,30 @@ help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 4 previous errors +error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator + --> $DIR/invalid-suggest-deref-issue-127590.rs:6:24 + | +LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator + | + = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` +help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` + = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator + --> $DIR/invalid-suggest-deref-issue-127590.rs:14:24 + | +LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator + | + = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` +help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` + = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`.